{
    "auth.errors.invalid_callback": "Invalid callback",
    "auth.scope_popup.close_hint": "You can close this window.",
    "admin.extensions.toggle_aria": "Toggle extension :alias",
    "admin.extensions.edit_aria": "Edit extension :alias",
    "admin.cloudbot.usage_title": "Message usage",
    "admin.cloudbot.usage_empty": "No data yet.",
    "admin.cloudbot.sent": "Sent",
    "admin.cloudbot.failed": "Failed",
    "admin.cloudbot.peak_30s": "Peak (30s)",
    "admin.cloudbot.helix_bucket": "Helix bucket (1 min)",
    "admin.cloudbot.helix_unseen": "no response seen yet",
    "admin.cloudbot.status_title": "Status",
    "admin.cloudbot.connect_title": "Connection",
    "admin.groups.delete_confirm_message": "Members lose access granted by this group.",
    "admin.groups.delete_confirm_title": "Delete user group :name?",
    "admin.groups.toggle_aria": "Toggle user group :name",
    "admin.user_groups.edit_aria": "Edit user group :name",
    "admin.tts.title": "TTS Usage",
    "admin.tts.period": "Period",
    "admin.tts.neural_quota": "Neural quota",
    "admin.tts.standard_quota": "Standard quota",
    "admin.tts.characters": "characters",
    "admin.tts.est_cost": "Estimated cost",
    "admin.tts.properties_period": "Properties with usage in this period",
    "admin.tts.neural": "Neural",
    "admin.tts.standard": "Standard",
    "admin.tts.of_neural_cap": "of neural cap",
    "admin.tts.cap_exhausted": "Neural cap exhausted",
    "admin.tts.near_abuse_fuse": "Near abuse limit",
    "admin.tts.empty": "No TTS usage in this period.",
    "admin.users.title": "Users",
    "admin.users.add": "Add User",
    "admin.users.search_placeholder": "Search users…",
    "admin.users.open_property": "Open Property",
    "admin.users.grant_access": "Grant Access",
    "admin.users.revoke_access": "Revoke Access",
    "admin.users.stats": "Stats",
    "admin.users.edit": "Edit",
    "admin.users.remove": "Remove",
    "admin.users.remove_confirm_title": "Remove :login?",
    "admin.users.remove_confirm_message": "This permanently deletes the account and all of its data. The Twitch identity is preserved.",
    "admin.users.loading_more": "Loading more…",
    "admin.users.deleted_flash": "Account :user has been removed",
    "admin.users.access_revoked_flash": "Access for :user has been revoked",
    "admin.waitlist.group_label": "Group",
    "events.delete_blocked": "This event is still used in one or more graphs. Remove the trigger nodes first.",
    "events.empty_state": "Nothing connected yet. Install Commands or Keywords, or register a Twitch event to get started.",
    "events.registrations.retry_button": "Retry",
    "events.registrations.retry_only_failed": "Only failed registrations can be retried.",
    "events.registrations.retry_queued": "Retry queued for :event on property #:property",
    "events.registrations.retry_tooltip": "Reset retry counter and re-queue immediately",
    "events.branch.add_tooltip": "Add success/failure branch",
    "events.branch.error_reason": "Failure reason",
    "events.branch.lane_empty": "No action yet.",
    "events.branch.on_failure": "On failure",
    "events.branch.on_success": "On success",
    "events.branch.result_tokens": "Branch variables",
    "events.recipe.created": "Automation created",
    "events.wizard.title": "New automation",
    "events.wizard.when": "When this happens",
    "events.wizard.then": "Do this",
    "events.wizard.configure": "Customise",
    "events.wizard.show_advanced": "Show advanced",
    "events.wizard.message_placeholder": "Type a message. Insert a value with the picker.",
    "events.wizard.configure_in_editor": "This reaction has no simple options. Tweak it in the editor after creating.",
    "events.wizard.sender": "Send from",
    "events.wizard.create": "Create automation",
    "events.tagline": "Connect reactions to events. Register Twitch events and attach actions.",
    "events.unregister_confirm": "Unregister this event from your property? Connected actions stay configured but stop firing until the event is registered again.",
    "events.user_event.identifier_hint": "Event identifier: sent as `user.{key}`. Lowercase letters, digits, underscores; must start with a letter.",
    "events.user_event.no_pins_hint": "No pins yet. Pin-less events fire just for the effect (handy for cross-graph signals).",
    "graphs.builder.empty": "No flow packages yet.",
    "graphs.builder.title": "Flows",
    "graphs.channel_vars.steam_url": "Steam Store Link",
    "graphs.channel_vars.steam_url_help": "Steam store page for the current category. Empty if it's not a Steam game.",
    "graphs.detach.confirm_title": "Detach this flow?",
    "graphs.list.editor_button": "Editor",
    "graphs.list.delete_confirm": "This permanently removes the graph and its run history.",
    "graphs.list.delete_confirm_title": "Delete :name?",
    "graphs.list.last_run": "last run",
    "graphs.list.nodes": "Nodes",
    "graphs.list.share_button": "Share",
    "graphs.list.update_available": "Update available",
    "graphs.editor.create_title": "New flow",
    "graphs.editor.no_actions_yet": "No actions connected yet. Add one below to make this trigger do something.",
    "graphs.editor.no_node_for_type": "No node accepts a :type connection.",
    "graphs.editor.scope_grant_unsaved_title": "Unsaved changes will be lost",
    "graphs.editor.scope_grant_unsaved_message": "You have unsaved changes that will be lost during the Twitch sign-in. Save first, then click Grant again. Continue without saving?",
    "graphs.editor.scope_grant_continue": "Continue without saving",
    "graphs.editor.promote_button": "Convert to Flow",
    "graphs.editor.promote_tooltip": "Convert this trigger's actions into a visual flow",
    "graphs.editor.promote_needs_flow": "Install the Event Flows extension first to convert this trigger.",
    "graphs.editor.promote_confirm_title": "Convert to a visual flow?",
    "graphs.editor.promote_confirm": "All currently-wired actions move into the new flow; this view will then show one Custom Flow row instead.",
    "graphs.editor.promote_confirm_cta": "Convert",
    "graphs.editor.promoted_toast": "Converted to flow",
    "graphs.editor.promoted_label": "Promoted from the flat-action setup; edit visually here.",
    "graphs.inline.editing": "Editing",
    "graphs.node.not_configured": "Not configured yet",
    "graphs.editor.rename": "Rename",
    "graphs.editor.saved_ago": "Saved :ago",
    "graphs.editor.unsaved": "Unsaved changes",
    "graphs.editor.active": "Active",
    "graphs.editor.test_run": "Test run",
    "graphs.editor.more_actions": "More actions",
    "graphs.editor.variables": "Variables",
    "graphs.editor.save_before_share": "Save before sharing",
    "graphs.configure.conflict_no_longer_linked": "This graph is no longer linked. Reloading.",
    "graphs.configure.discard": "Discard changes",
    "graphs.configure.discard_message": "Your edits will be lost.",
    "graphs.configure.discard_title": "Discard unsaved changes?",
    "graphs.configure.empty": "Nothing to configure.",
    "graphs.configure.resource_missing": "Resource no longer exists",
    "graphs.configure.save_failed": "Could not save configuration",
    "graphs.configure.saved": "Configuration saved",
    "graphs.configure.tab_canvas": "Canvas",
    "graphs.configure.tab_configure": "Configure",
    "graphs.configure.validation_summary": ":count field(s) need attention",
    "graphs.configure.activate": "Activate",
    "graphs.configure.activate_anyway": "Activate anyway?",
    "graphs.configure.activate_warning": "Some fields still need attention. The flow may not run correctly.",
    "graphs.configure.active": "Active",
    "graphs.configure.basics_title": "Basics",
    "graphs.configure.paused": "Paused",
    "graphs.configure.field_name": "Name",
    "graphs.configure.field_description": "Description",
    "graphs.configure.grant_scopes": "Grant scopes",
    "graphs.configure.helper.command_link": "No commands yet, create one under Extensions, Commands.",
    "graphs.configure.helper.keyword_link": "No keywords yet, create one under Extensions, Keywords.",
    "graphs.configure.helper.reward_link": "No rewards yet, create one in your Twitch dashboard or via Streambridge Rewards.",
    "graphs.configure.status_banner.ready": "Fully configured, but not active yet. Switch it on with the toggle in the top right.",
    "graphs.configure.status_banner.missing_scopes": "{count} scope(s) not granted",
    "graphs.configure.status_banner.missing_refs": "{count} resource(s) not linked",
    "graphs.configure.status_banner.missing_params": "{count} field(s) incomplete",
    "graphs.counter_ref.pick": "– pick a counter –",
    "graphs.counter_ref.per_stream": "per stream",
    "graphs.counter_ref.empty": "No counters yet, create one under Extensions, Counters.",
    "graphs.configure.references_title": "References",
    "graphs.configure.references_ready": "{ready}/{total} ready",
    "graphs.expose.exposed_toggle": "Exposed on import",
    "graphs.expose.node_title_label": "Node title",
    "graphs.expose.node_title_help": "Shown as the section heading in the Configurator.",
    "graphs.expose.node_title_required": "Name this node before exposing its fields.",
    "graphs.expose.help_field": "Help",
    "graphs.expose.help_placeholder": "Shown to streamers when they import",
    "graphs.expose.label_field": "Label",
    "graphs.expose.label_help": "Empty defaults to '{key}'",
    "graphs.expose.panel_title": "Expose '{key}'",
    "graphs.expose.required_disabled_boolean": "Boolean fields always have a value",
    "graphs.expose.required_field": "Required at import",
    "graphs.expose.required_help": "Wizard blocks if default is empty",
    "graphs.expose.tooltip_connection_ref": "Connection refs are always cleared on import",
    "graphs.expose.tooltip_exposable": "Expose this field on import",
    "graphs.expose.tooltip_resource_ref": "Resource refs are always exposed on import",
    "graphs.expose.clear_value_field": "Don't copy current value",
    "graphs.expose.clear_value_help": "When shared, this field stays editable but ships empty. The recipient enters their own value. Use it for secrets like webhook URLs or API keys.",
    "graphs.gate.condition_intro": "Fires only when these values match:",
    "graphs.history.restored": "Flow restored",
    "graphs.inputtext.example_placeholder": "Text",
    "graphs.inputtext.insert_variable": "Insert variable",
    "graphs.inputtext.no_match": "No matching variables. Press Escape to keep \":text\" as text.",
    "graphs.inputtext.no_variables": "No matching variables.",
    "graphs.inputtext.picker_tip": "Type { in the text to open this list at the cursor.",
    "graphs.inputtext.preview_label": "Preview:",
    "graphs.inputtext.search_placeholder": "Search variable…",
    "graphs.inputtext.var_enriched_help": "Empty if the user can't be found.",
    "graphs.install.cap_exceeded": "Too many resources of one type to auto-create",
    "graphs.install.enable_extension": "Enable",
    "graphs.install.extension_required": "Extension required",
    "graphs.install.failed": "Install failed.",
    "graphs.install.grant_scopes": "Grant scopes",
    "graphs.install.grant_scopes_bulk": "Grant permissions (:count)",
    "graphs.install.install_extension": "Install extension",
    "graphs.install.install_extensions_bulk": "Install extensions (:count)",
    "graphs.install.install": "Install",
    "graphs.install.installing_to": "Installing to :property",
    "graphs.install.missing_extensions_error": "Missing extensions: :list",
    "graphs.install.open_editor": "Open in Editor",
    "graphs.install.prereq_count_unmet": ":count prerequisites unmet",
    "graphs.install.prerequisites": "Prerequisites",
    "graphs.install.recheck": "Re-check",
    "graphs.install.scope_required": "Scope required",
    "graphs.install.share_link_name_default": "Imported graph",
    "graphs.install.share_link_name_from": "Graph from @{sharer}",
    "graphs.install.share_link_invalid": "Share link expired or invalid",
    "graphs.install.success": "Flow installed successfully.",
    "graphs.install.switch_property": "Switch",
    "graphs.install.extensions_required": "Extensions required",
    "graphs.install.flow_name_label": "Flow name",
    "graphs.install.modal_title": "Install flow",
    "graphs.install.scopes_grant_later": "Missing scopes can be granted after install.",
    "graphs.install.scopes_needed": "Scopes needed",
    "graphs.install.upgrade_tier": "Upgrade tier",
    "graphs.install.will_create": "Will be created for you",
    "graphs.install.you_will_wire": "You'll need to assign after install",
    "graphs.install.string_invalid": "That flow string could not be read.",
    "graphs.install.string_label": "Flow string",
    "graphs.install.string_paste_help": "Paste a flow string to import it.",
    "graphs.install.string_import_button": "Import",
    "graphs.install.lineage_title": "You already have this flow",
    "graphs.install.lineage_update": "Update my existing copy",
    "graphs.install.lineage_new_copy": "Create a new copy",
    "graphs.import.string_unrecognized": "This is not a valid flow string.",
    "graphs.import.string_corrupted": "This flow string looks corrupted or incomplete. Copy it again.",
    "graphs.import.string_version_mismatch": "This flow was created on a newer version and cannot be imported yet.",
    "graphs.import.string_unknown_node": "This flow uses a block this server does not recognise.",
    "graphs.inspector.wired_label": "connected",
    "graphs.linked.by_author": "by :author",
    "graphs.linked.check_updates": "Check for updates",
    "graphs.linked.detach": "Detach",
    "graphs.linked.shared_fallback": "Shared flow",
    "graphs.linked.source.marketplace": "Marketplace",
    "graphs.linked.source.share_link": "Imported",
    "graphs.linked.update": "Update",
    "graphs.linked.update_available": "Update available",
    "graphs.marketplace.title": "Flow Marketplace",
    "marketplace.usage.button": "How to use",
    "marketplace.usage.title": "How to use :name",
    "marketplace.usage.empty": "This package has no usage notes yet.",
    "graphs.node.orphan": "Orphan (no registry entry)",
    "graphs.node.tag_event": "Event",
    "graphs.node.tag_logic": "Logic",
    "graphs.node.tag_action": "Action",
    "graphs.palette.group_events": "Events",
    "graphs.palette.group_logic": "Logic",
    "graphs.palette.group_actions": "Actions",
    "graphs.page.empty": "No flows yet. Create one to chain events to actions visually.",
    "graphs.page.new_button": "New flow",
    "graphs.page.subtitle": ":count flows · :active active",
    "graphs.page.title": "Event Flows",
    "graphs.ref_picker.placeholder": "Select…",
    "graphs.ref_picker.none": "None",
    "graphs.ref_picker.new": "New",
    "graphs.ref_picker.edit": "Edit",
    "graphs.ref_picker.empty_createable": "Nothing here yet. Use + to create one.",
    "graphs.ref_picker.empty_pick": "Nothing to pick yet.",
    "graphs.ref_picker.loading": "Loading…",
    "graphs.ref_picker.badge_external": "External",
    "graphs.placement.no_asset_hint": "Select an asset first to position it.",
    "graphs.placement.click_to_place": "Click to place the asset",
    "graphs.placement.x": "X %",
    "graphs.placement.y": "Y %",
    "graphs.placement.width": "Width %",
    "graphs.placement.preset_original": "Original size",
    "graphs.placement.preset_fill": "Fit into widget",
    "graphs.placement.reset": "Reset",
    "graphs.placement.edit": "Edit…",
    "graphs.placement.summary_default": "Centered (default)",
    "graphs.placement.summary_custom": "Custom",
    "graphs.placement.done": "Done",
    "graphs.publish.secrets_warning": "This graph may contain inline secrets (Bearer tokens, API keys). Remove the value before sharing, or enable \"Don't copy current value\" on the field.",
    "graphs.share.modal_title": "Share this flow",
    "graphs.share.publish_to_marketplace_help": "Publish to the Flow Marketplace.",
    "graphs.share.export_string_title": "Copy as code string",
    "graphs.share.export_string_help": "Generate a self-contained string anyone can paste to import this flow. Works off-platform.",
    "graphs.share.export_string_button": "Generate string",
    "graphs.share.export_string_label": "Flow string",
    "graphs.share.context_failed": "Could not open sharing.",
    "graphs.share.copy_string": "Copy string",
    "graphs.share.export_failed": "Could not generate the flow string.",
    "graphs.share.secret_ack": "I understand this string is permanent and will contain the flagged values.",
    "graphs.test_run.dry_label": "Dry run (no real actions)",
    "graphs.test_run.dry_short": "Dry run",
    "graphs.test_run.empty_payload": "This trigger has no data fields, the event data will be empty.",
    "graphs.test_run.real_label": "Real run: sends chat, hits URLs, triggers real actions.",
    "graphs.test_run.real_short": "Real run!",
    "graphs.test_run.title": "Test run with sample data",
    "graphs.wizard.auto_enable": "Activate immediately",
    "graphs.wizard.field_invalid_identifier": "Only letters, digits, dash, and underscore.",
    "graphs.wizard.field_invalid_number": "Must be a valid number.",
    "graphs.wizard.field_max": "At most {max}.",
    "graphs.wizard.field_min": "At least {min}.",
    "graphs.wizard.field_not_in_options": "Value not in the option list.",
    "graphs.wizard.field_required": "This field is required.",
    "graphs.wizard.name_label": "Name on my channel",
    "graphs.wizard.title": "Install Graph",
    "graphs.wizard.unknown_type_hint": "Field type '{type}' has no renderer. Value is passed as text.",
    "graphs.tabs.editor": "Editor",
    "graphs.tabs.variables": "Variables",
    "graphs.variables.create_button": "Add variable",
    "graphs.variables.empty_state": "No variables defined yet.",
    "graphs.variables.scope_property": "Property-wide",
    "graphs.variables.scope_graph": "Graph only",
    "graphs.variables.types.string": "Text",
    "graphs.variables.types.number": "Number",
    "graphs.variables.types.boolean": "Yes/No",
    "graphs.variables.slug_label": "Slug",
    "graphs.variables.slug_help": "Used as {var.<slug>} in templates",
    "graphs.variables.picker_group": "Variables",
    "graphs.variables.pick_placeholder": "Pick a variable",
    "graphs.run_context.picker_group": "Run Context",
    "graphs.variables.type_label": "Type",
    "graphs.variables.default_label": "Default value",
    "graphs.variables.scope_label": "Visibility",
    "graphs.variables.confirm_delete": "Delete this variable? Existing references will fall back to empty.",
    "graphs.variables.confirm_reset": "Reset to default? The stored value will be lost.",
    "graphs.variables.reset_button": "Reset",
    "graphs.variables.delete_button": "Delete",
    "graphs.variables.scope_locked_help": "Visibility cannot be changed after creation.",
    "graphs.variables.aria_edit": "Edit variable :slug",
    "graphs.variables.aria_reset": "Reset variable :slug",
    "graphs.variables.aria_delete": "Delete variable :slug",
    "graphs.ctx.set_node.label": "Set Context",
    "graphs.ctx.set_node.slug_help": "Pickable as {ctx.<slug>} in this graph's templates",
    "graphs.cond.add_branch": "Add branch",
    "graphs.cond.remove_branch": "Remove branch",
    "graphs.cond.default_lane": "Default",
    "graphs.cond.field_placeholder": "Select field",
    "graphs.cond.label_placeholder": "Branch label (optional)",
    "graphs.cond.branch_enabled": "Enabled",
    "graphs.cond.op_contains": "contains",
    "graphs.cond.op_matches": "matches regex",
    "graphs.cond.field_search": "Search field…",
    "graphs.cond.move_branch": "Move branch",
    "graphs.cond.branch_count": ":n branch(es)",
    "graphs.cond.rule_empty": "Choose a condition…",
    "graphs.cond.when_label": "When",
    "graphs.command_modal.title_new": "New Command",
    "graphs.command_modal.title_edit": "Edit Command:",
    "graphs.command_modal.keyword_label": "Command",
    "graphs.command_modal.keyword_placeholder": "e.g. hug",
    "graphs.command_modal.aliases_label": "Aliases",
    "graphs.command_modal.aliases_placeholder": "Add an alias",
    "graphs.command_modal.audience_label": "Who may trigger this",
    "graphs.command_modal.cooldown_global_label": "Channel cooldown (s)",
    "graphs.command_modal.cooldown_user_label": "Per-user cooldown (s)",
    "graphs.command_modal.delete_title": "Delete command :keyword?",
    "graphs.command_modal.delete_message": "This permanently removes the command and its aliases.",
    "graphs.command_modal.delete_confirm": "Delete command",
    "graphs.keyword_modal.title_new": "New Keyword",
    "graphs.keyword_modal.title_edit": "Edit Keyword",
    "graphs.keyword_modal.phrases_label": "Phrases",
    "graphs.keyword_modal.phrases_placeholder": "Add a phrase",
    "graphs.keyword_modal.match_mode_label": "Match mode",
    "graphs.keyword_modal.match_word": "Whole word",
    "graphs.keyword_modal.match_contains": "Contains",
    "graphs.keyword_modal.case_sensitive_label": "Case sensitive",
    "graphs.keyword_modal.audience_label": "Who may trigger this",
    "graphs.keyword_modal.cooldown_global_label": "Channel cooldown (s)",
    "graphs.keyword_modal.cooldown_user_label": "Per-user cooldown (s)",
    "graphs.keyword_modal.delete_title": "Delete keyword?",
    "graphs.keyword_modal.delete_message": "This permanently removes the keyword.",
    "graphs.keyword_modal.delete_confirm": "Delete keyword",
    "graphs.res_modal.enabled_label": "Enabled",
    "marketing.welcome.actions_pitch": "Reply in chat, post to Discord, fire a webhook, update your browser source. Each action is a distinct step: you add as many as the workflow needs. The platform doesn't prescribe what \"responding to a follow\" means. You do.",
    "marketing.welcome.canvas_pitch": "Connect events to actions on the canvas. When a viewer follows, subs, or triggers a keyword, your workflow fires. The result is visible immediately in the audit log.",
    "marketing.welcome.cta_short": "Drop, connect, save.",
    "marketing.welcome.login_cta": "Sign in with Twitch",
    "marketing.welcome.realtime_claim": "In real time. No missed events.",
    "marketing.welcome.realtime_pitch": "Follows, subs, raids, commands, keywords: Streambridge receives them via Twitch Events (Follows, Subs, Bits) the moment they happen. A complete audit log shows you exactly what fired, in order, with the outcome. When something doesn't behave as expected, you'll find out in seconds, not after your stream ends.",
    "marketing.welcome.splash_tagline": "Streambridge, freshly dressed.",
    "marketing.welcome.status_badge": "In development",
    "marketing.welcome.tagline": "Visual workflows: connect events to actions.",
    "tags.cancel": "Cancel",
    "tags.clear_filter": "Clear filter",
    "ui.back": "Back",
    "ui.next": "Next",
    "ui.nav.overview": "Overview",
    "ui.nav.extensions": "Extensions",
    "ui.nav.discover": "Discover",
    "ui.nav.channel": "Channel",
    "ui.nav.add_extension": "Add extension",
    "ui.nav.reorder_featured": "Reorder",
    "ui.nav.save_order": "Save order",
    "ui.badge_new": "New",
    "ui.stale.save_rejected": "This resource was changed elsewhere in the meantime. Reload the editor and re-apply your changes.",
    "ui.stale.changed_externally": "This page was changed elsewhere in the meantime.",
    "ui.stale.unsaved_hint": "You have unsaved changes, reloading discards them.",
    "ui.stale.reload": "Reload",
    "ui.combobox.select": "Select…",
    "ui.combobox.search": "Search…",
    "ui.combobox.no_matches": "No matches.",
    "ui.combobox.empty": "Nothing here yet.",
    "ui.combobox.none": "None",
    "ui.token.remove": "Remove",
    "ui.user_picker.type_to_search": "Type at least 2 characters to search.",
    "ui.user_picker.searching": "Searching…",
    "ui.companion.stats_title": "Usage",
    "ui.companion.stats_uses": "Uses",
    "ui.companion.stats_last_used": "Last used",
    "ui.companion.stats_empty": "Not used yet.",
    "ui.companion.concept_actions_title": "Actions",
    "ui.companion.concept_actions_body": "Once this is triggered, its actions run in order. You can chain several actions one after another.",
    "ui.companion.concept_timer_modes_title": "Single & Rotation",
    "ui.companion.concept_timer_modes_body": "Single fires all actions on every interval. With Rotation, one rotation entry fires per interval with all its actions, in order, looping back to the first after the last.",
    "ui.companion.concept_variables_title": "Using variables",
    "ui.companion.concept_variables_body": "In text fields you can insert variables like {user.name}. When this runs they are replaced with the real value, here the viewer's name.",
    "ui.companion.concept_variables_custom": "You can also create your own custom variables. Depending on their setting, they're available everywhere.",
    "ui.companion.concept_configure_title": "Configuring",
    "ui.companion.concept_configure_body": "Fill in the required references and fields below, then switch Active on to make it run. The banner above lists anything still missing.",
    "ui.companion.concept_variables_empty": "No custom variables created yet.",
    "ui.companion.concept_context_title": "Context",
    "ui.companion.concept_context_body": "The context is the data that comes with the trigger, such as who caused it and with which details. These values are available to you as variables.",
    "ui.twitch_category.clear_aria": "Remove :name",
    "ui.twitch_category.search_placeholder": "Search Twitch categories…",
    "ui.unsaved_changes": "Unsaved changes",
    "ui.palette.search_placeholder": "Search, jump, run …",
    "ui.palette.trigger": "Search or jump to …",
    "ui.palette.group_actions": "Actions",
    "ui.palette.group_navigation": "Navigation",
    "ui.palette.open_extension": "Open :name",
    "ui.palette.action_new_command": "Create new command",
    "ui.palette.action_new_flow": "Create new event flow",
    "ui.palette.no_results": "No matches.",
    "ui.palette.shortcut_ctrl": "Ctrl",
    "ui.mcp_tokens.card_label": "MCP Access",
    "ui.mcp_tokens.card_description": "Let AI agents manage your channel through access tokens.",
    "ui.mcp_tokens.title": "MCP Access Tokens",
    "ui.mcp_tokens.intro": "Access tokens let AI agents manage your own channel on your behalf. Each token only gets the abilities you pick.",
    "ui.mcp_tokens.endpoint_hint": "AI agents connect through the MCP server at this address, sending the token as Bearer in the Authorization header:",
    "ui.mcp_tokens.copy_hint": "Copy this token now. It is only shown once.",
    "ui.mcp_tokens.name_label": "Token name",
    "ui.mcp_tokens.abilities_label": "Abilities",
    "ui.mcp_tokens.create": "Create token",
    "ui.mcp_tokens.revoke": "Revoke",
    "ui.mcp_tokens.revoke_title": "Revoke token?",
    "ui.mcp_tokens.revoke_message": "Tools using this token lose access immediately.",
    "ui.mcp_tokens.empty": "No tokens yet.",
    "ui.mcp_tokens.last_used": "Last used",
    "ui.mcp_tokens.claude_label": "Claude Code (one command):",
    "ui.mcp_tokens.json_label": "Other MCP clients (JSON config):",
    "tags.delete": "Delete",
    "tags.delete_confirm_button": "Delete tag",
    "tags.delete_confirm_unused": "Delete tag «:name»?",
    "tags.delete_confirm_used": "Delete tag «:name»? :n items will lose this tag.",
    "tags.delete_title": "Delete tag?",
    "tags.edit": "Edit",
    "tags.empty": "No tags yet.",
    "tags.field_label": "Tags",
    "tags.filter_label": "Filter by tags",
    "tags.manage": "Manage tags",
    "tags.max_reached": "Up to :max tags per item.",
    "tags.no_results": "No items match these tags.",
    "tags.pick_color": "Pick color",
    "tags.placeholder": "Add a tag",
    "tags.rename_collision": "A tag «:name» already exists.",
    "tags.rename_error": "Could not rename the tag.",
    "tags.rename_label": "Rename tag",
    "tags.save": "Save",
    "tags.suggestion_create": "Create new: :name",
    "tags.usage_count": ":n items",
    "widgets.alert_lane.label": "Alert lane",
    "widgets.alert_lane.author_default": "Author default",
    "widgets.alert_lane.shared": "Shared lane",
    "widgets.alert_lane.own": "Own lane",
    "widgets.alert_lane.live": "Instant (no queue)",
    "widgets.alert_lane.help": "How this widget's alerts line up with other alert widgets.",
    "widgets.audio_out.copy_url_title": "Audio Browsersource URL",
    "widgets.audio_out.copy_button": "Copy",
    "widgets.audio_out.copied_feedback": "Copied",
    "widgets.audio_out.pending_create_tooltip": "Created on save",
    "widgets.audio_out.paused_warning": "Audio paused for this scene",
    "widgets.media_out.created_flash": "Media scene \":name\" created. Add its browsersource URL to OBS to see video and image alerts.",
    "widgets.chatbox.global_emotes_hint": "Show Twitch emotes in chat messages.",
    "widgets.chatbox.tagline": "A chatbox widget shows the live chat from these messages.",
    "widgets.compositions.title": "Compositions",
    "widgets.compositions.subtitle": "Animated alert building blocks for the Play action",
    "widgets.compositions.new": "New composition",
    "widgets.compositions.empty": "No compositions yet. Create your first one.",
    "widgets.compositions.context_free": "No context",
    "widgets.compositions.from_package": "From package",
    "widgets.compositions.duration_min": "min. :s s",
    "widgets.compositions.elements_count": ":n elements",
    "widgets.compositions.delete_title": "Delete composition?",
    "widgets.compositions.delete_body": "Actions pointing at it will then run into nothing.",
    "widgets.compositions.name": "Name",
    "widgets.compositions.context": "Context",
    "widgets.compositions.add_element": "Add element",
    "widgets.compositions.el_text": "Text",
    "widgets.compositions.el_media": "Media",
    "widgets.compositions.el_sound": "Sound",
    "widgets.compositions.el_tts": "TTS",
    "widgets.compositions.cap_reached": "Max 10 elements",
    "widgets.compositions.remove_element": "Remove element",
    "widgets.compositions.reorder_element": "Drag to reorder",
    "widgets.compositions.start_label": "Start",
    "widgets.compositions.start_immediate": "Immediate",
    "widgets.compositions.start_after": "After :name",
    "widgets.compositions.offset": "Offset (ms)",
    "widgets.compositions.section_content": "Content",
    "widgets.compositions.section_phases": "Phases",
    "widgets.compositions.phase_in": "In",
    "widgets.compositions.phase_hold": "Hold",
    "widgets.compositions.phase_out": "Out",
    "widgets.compositions.template": "Template",
    "widgets.compositions.size": "Size",
    "widgets.compositions.align": "Alignment",
    "widgets.compositions.align_left": "Left",
    "widgets.compositions.align_center": "Center",
    "widgets.compositions.align_right": "Right",
    "widgets.compositions.color": "Color",
    "widgets.compositions.stroke_color": "Outline color",
    "widgets.compositions.stroke_width": "Outline width",
    "widgets.compositions.var_colors": "Variable colors",
    "widgets.compositions.font": "Font",
    "widgets.compositions.asset": "File",
    "widgets.compositions.fit": "Fit",
    "widgets.compositions.fit_contain": "Contain",
    "widgets.compositions.fit_cover": "Cover",
    "widgets.compositions.volume": "Volume",
    "widgets.compositions.lang": "Language",
    "widgets.compositions.preset_none": "No transition",
    "widgets.compositions.preset_fade": "Fade",
    "widgets.compositions.preset_slide_up": "Slide up",
    "widgets.compositions.preset_slide_down": "Slide down",
    "widgets.compositions.preset_slide_left": "Slide left",
    "widgets.compositions.preset_slide_right": "Slide right",
    "widgets.compositions.preset_zoom": "Zoom",
    "widgets.compositions.duration_warn": "Over 50s of known duration. Late elements may get cut off.",
    "widgets.compositions.vars_unresolved": "These placeholders don't match the selected context: :vars",
    "widgets.compositions.el_unresolved_vars": "Contains variables that don't exist in the selected context.",
    "widgets.compositions.preview": "Preview",
    "widgets.compositions.stop": "Stop",
    "widgets.compositions.export_json": "Export as JSON",
    "widgets.compositions.export_json_help": "Asset paths must point to files in the widget bundle.",
    "widgets.compositions.export_copied": "Copied to clipboard",
    "widgets.editor.axis_h": "H",
    "widgets.editor.axis_w": "W",
    "widgets.editor.close_panel": "Close panel",
    "widgets.editor.config_title": "Configuration",
    "widgets.editor.config_title_variant": "Configuration · :label",
    "widgets.editor.duplicate": "Duplicate",
    "widgets.editor.inherited_hint": "Default",
    "widgets.editor.layer_back": "Send backward",
    "widgets.editor.layer_front": "Bring forward",
    "widgets.editor.open_panel": "Open settings",
    "widgets.editor.overridden": "overridden",
    "widgets.editor.override_promote": "Click to override",
    "widgets.editor.override_remove": "Remove override",
    "widgets.editor.position_size": "Position & Size",
    "widgets.editor.rail_title": "Widgets",
    "widgets.editor.remove_widget": "Remove widget",
    "widgets.editor.remove_widget_confirm": "Remove this widget from the scene?",
    "widgets.editor.scene_settings": "Scene",
    "widgets.editor.show_rail": "Show widgets",
    "widgets.editor.theme": "Theme",
    "widgets.editor.theme_none": "None",
    "widgets.editor.theme_title": "Scene theme",
    "widgets.editor.variation_add": "Variation",
    "widgets.editor.variation_banner": "You are editing the variation “:label”. Base values are dimmed.",
    "widgets.editor.variation_base": "Base",
    "widgets.editor.zoom_fit": "Fit view",
    "widgets.editor.zoom_in": "Zoom in",
    "widgets.editor.zoom_out": "Zoom out",
    "widgets.fonts.cat_display": "Display",
    "widgets.fonts.cat_handwriting": "Script",
    "widgets.fonts.cat_monospace": "Mono",
    "widgets.fonts.cat_sans_serif": "Sans",
    "widgets.fonts.cat_serif": "Serif",
    "widgets.fonts.search": "Search fonts...",
    "widgets.settings.font_custom": "Custom font",
    "widgets.settings.list_add": "Add entry",
    "widgets.settings.repeater_add": "Add row",
    "widgets.variants.title": "Variations",
    "widgets.variants.empty": "No variations. Events use the base settings.",
    "widgets.variants.unnamed": "Unnamed variation",
    "widgets.variants.no_overrides": "Overrides nothing yet",
    "widgets.variants.add": "Add variation",
    "widgets.variants.delete_confirm": "Delete this variation?",
    "widgets.variants.label": "Label",
    "widgets.variants.event": "Event",
    "widgets.variants.match": "Condition mode",
    "widgets.variants.match_all": "All conditions match",
    "widgets.variants.match_any": "Any condition matches",
    "widgets.variants.rules": "Conditions",
    "widgets.variants.add_rule": "Add condition",
    "widgets.variants.rules_empty_hint": "No conditions: this variation applies to every such event.",
    "widgets.variants.move_up": "Move up",
    "widgets.variants.move_down": "Move down",
    "widgets.variants.delete": "Delete variation",
    "widgets.version.label": "Version",
    "widgets.version.current_option": ":version (active)",
    "widgets.version.newer_available": "Newer version available",
    "widgets.version.manage": "Manage version",
    "widgets.manifest.mode": "Delivery",
    "widgets.manifest.mode_live": "Instant (state)",
    "widgets.manifest.mode_alert": "Alert (queued)",
    "widgets.manifest.lane": "Lane",
    "widgets.manifest.ack": "Completion",
    "widgets.manifest.ack_auto": "Automatic (duration)",
    "widgets.manifest.ack_manual": "Widget reports done",
    "widgets.manifest.duration_config_key": "Duration from setting",
    "widgets.manifest.duration_ms": "Fixed duration (ms)",
    "widgets.alert_lane.too_many_lanes": "Too many distinct alert lanes in this scene (max :max).",
    "widgets.save.package_not_installed": "That widget package is not installed for this property.",
    "widgets.save.theme_override_not_allowed": "This widget does not allow per-instance theme overrides.",
    "widgets.save.theme_not_installed": "That theme package is not installed for this property.",
    "widgets.save.widgets_gone": "Some widgets no longer exist. Please reload the editor.",
    "(add a trigger node)": "(add a trigger node)",
    "(empty template)": "(empty template)",
    "(no changelog)": "(no changelog)",
    "(no url)": "(no url)",
    "+ Alias": "+ Alias",
    "01 — The visual editor": "01: The visual editor",
    "02 — Every Twitch event, live": "02: Every Twitch event, live",
    "03 — Actions that go anywhere": "03: Actions that go anywhere",
    ":login is already linked as a bot for this property.": ":login is already linked as a bot for this property.",
    ":login is now linked as a bot for :property. You can close this window.": ":login is now linked as a bot for :property. You can close this window.",
    ":login is now linked. You can close this window.": ":login is now linked. You can close this window.",
    ":n aliases": ":n aliases",
    ":ok registered, :n failed": ":ok registered, :n failed",
    "A chatbox widget shows the live chat from these messages.": "A chatbox widget shows the live chat from these messages.",
    "A command !:keyword already exists. Switch to “Link existing” to attach the Quote graph to it without changing its current settings.": "A command !:keyword already exists. Switch to “Link existing” to attach the Quote graph to it without changing its current settings.",
    "A direct word about where this is.": "A direct word about where this is.",
    "A follower alert plays a sound effect when someone follows.": "A follower alert plays a sound effect when someone follows.",
    "A follower alert plays an animation.": "A follower alert plays an animation.",
    "A streamer-built platform. Rebuilt properly.": "A streamer-built platform. Rebuilt properly.",
    "Access": "Access",
    "Action added": "Action added",
    "Action configuration screenshot": "Action configuration screenshot",
    "Action removed": "Action removed",
    "Action updated": "Action updated",
    "Actions": "Actions",
    "Activate immediately": "Activate immediately",
    "Active in categories": "Active in categories",
    "Add Bot": "Add Bot",
    "Add Event": "Add Event",
    "Add New User": "Add New User",
    "Add Node": "Add Node",
    "Add Pin": "Add Pin",
    "Add User": "Add User",
    "Add a phrase…": "Add a phrase…",
    "Add a trigger node first": "Add a trigger node first",
    "Add a trigger node to the graph before running a test.": "Add a trigger node to the graph before running a test.",
    "Add action": "Add action",
    "Add alias": "Add alias",
    "Add alias to !:keyword": "Add alias to !:keyword",
    "Add an event to your property": "Add an event to your property",
    "Add at least one phrase.": "Add at least one phrase.",
    "Add command": "Add command",
    "Add option": "Add option",
    "Add tag": "Add tag",
    "Add tags…": "Add tags…",
    "Admin": "Admin",
    "Administration": "Administration",
    "Admins have unconditional access to every current and future extension on this property. Selecting this hides the per-extension permission picker below — admins do not need it.": "Admins have unconditional access to every current and future extension on this property. Selecting this hides the per-extension permission picker below: admins do not need it.",
    "Alias": "Alias",
    "Alias keyword": "Alias keyword",
    "Aliases": "Aliases",
    "All": "All",
    "All :n aliases drop with it. The auto-generated graph also goes.": "All :n aliases drop with it. The auto-generated graph also goes.",
    "All :provider events are already registered.": "All :provider events are already registered.",
    "All required scopes already granted. No sign-in needed.": "All required scopes already granted. No sign-in needed.",
    "All sources": "All sources",
    "All tags": "All tags",
    "All triggers": "All triggers",
    "All types": "All types",
    "Alpha means honest.": "Alpha means honest.",
    "Alpha — early access open": "Alpha: early access open",
    "Already have access?": "Already have access?",
    "Always subscribed because your Twitch account is connected": "Always subscribed because your Twitch account is connected",
    "App-Level Permissions": "App-Level Permissions",
    "App-level memberships (e.g. alpha/beta). These grant access to any extension linked to the group.": "App-level memberships (e.g. alpha/beta). These grant access to any extension linked to the group.",
    "Apply Now": "Apply Now",
    "Apply for Access": "Apply for Access",
    "Apply for Early Access": "Apply for Early Access",
    "Apply for early access.": "Apply for early access.",
    "Apply with Twitch": "Apply with Twitch",
    "Approve": "Approve",
    "Approved": "Approved",
    "Approved :email": "Approved :email",
    "Audience": "Audience",
    "Audio": "Audio",
    "Audio Out scene \":name\" created. Paste the OBS URL into your scene collection.": "Audio Out scene \":name\" created. Paste the OBS URL into your scene collection.",
    "Audit Log": "Audit Log",
    "Audit log screenshot": "Audit log screenshot",
    "BTTV and FFZ emotes are loaded directly from their respective servers.": "BTTV and FFZ emotes are loaded directly from their respective servers.",
    "Back": "Back",
    "Back to Configure": "Back to Configure",
    "Background color": "Background color",
    "Basics": "Basics",
    "graphs.share.builder_unlock": "Becoming a Streambridge Builder unlocks marketplace publishing.",
    "Behavior": "Behavior",
    "Body": "Body",
    "Bot Accounts": "Bot Accounts",
    "Bot already linked": "Bot already linked",
    "Bot limit reached": "Bot limit reached",
    "Bot limit reached. Remove one to add another.": "Bot limit reached. Remove one to add another.",
    "Bot linked": "Bot linked",
    "Broadcaster (primary)": "Broadcaster (primary)",
    "Browse": "Browse",
    "Build automations": "Build automations",
    "Builder access required": "Builder access required",
    "Built for how streamers actually think.": "Built for how streamers actually think.",
    "Cancel": "Cancel",
    "Captures a memorable line. Snapshots the current Twitch category automatically.": "Captures a memorable line. Snapshots the current Twitch category automatically.",
    "Case-sensitive": "Case-sensitive",
    "Category-bound": "Category-bound",
    "Change in the trigger node's picker.": "Change in the trigger node's picker.",
    "Changelog": "Changelog",
    "Channel": "Channel",
    "Channel Point Reward": "Channel Point Reward",
    "Channel cooldown (s)": "Channel cooldown (s)",
    "Check Updates": "Check Updates",
    "Choose files": "Choose files",
    "Choose group…": "Choose group…",
    "Close": "Close",
    "Close window": "Close window",
    "Color": "Color",
    "Color for :label": "Color for :label",
    "Coming with the Viewer Groups feature.": "Coming with the Viewer Groups feature.",
    "Command": "Command",
    "Command removed": "Command removed",
    "Command saved": "Command saved",
    "Command updated": "Command updated",
    "Commands": "Commands",
    "Configure": "Configure",
    "Confirm before continuing": "Confirm before continuing",
    "Confirm bot link": "Confirm bot link",
    "Connect your channel": "Connect your channel",
    "Connection": "Connection",
    "Connection #:id": "Connection #:id",
    "Connection refs are always cleared on import": "Connection refs are always cleared on import",
    "Connection refs will be remapped to Primary on import": "Connection refs will be remapped to Primary on import",
    "Contains — anywhere in message": "Contains: anywhere in message",
    "Continue to :provider": "Continue to :provider",
    "Continue with Twitch": "Continue with Twitch",
    "Cooldowns": "Cooldowns",
    "Copied!": "Copied!",
    "Copy to Clipboard": "Copy to Clipboard",
    "Cost (channel points)": "Cost (channel points)",
    "Could not identify Twitch account": "Could not identify Twitch account",
    "Counter": "Counter",
    "Create": "Create",
    "Create :slot command": "Create :slot command",
    "Create A New User Group": "Create A New User Group",
    "Create Reward": "Create Reward",
    "Create Role": "Create Role",
    "Create Share Link": "Create Share Link",
    "Create a new Form": "Create a new Form",
    "Create new": "Create new",
    "Custom Event": "Custom Event",
    "Dashboard": "Dashboard",
    "Date format": "Date format",
    "Declined": "Declined",
    "Default — (no sender configured)": "Default: (no sender configured)",
    "Default — :label": "Default: :label",
    "Default — broadcaster primary": "Default: broadcaster primary",
    "Defaults": "Defaults",
    "Delete": "Delete",
    "Delete !:keyword?": "Delete !:keyword?",
    "Delete (Del)": "Delete (Del)",
    "Delete :label": "Delete :label",
    "Delete :name?": "Delete :name?",
    "Delete alias": "Delete alias",
    "Delete alias !:keyword": "Delete alias !:keyword",
    "Delete alias !:keyword?": "Delete alias !:keyword?",
    "Delete asset": "Delete asset",
    "Delete command": "Delete command",
    "Delete failed.": "Delete failed.",
    "Delete quote #:n": "Delete quote #:n",
    "Delete quote #:n? This cannot be undone — the number stays retired and won't be reused.": "Delete quote #:n? This cannot be undone: the number stays retired and won't be reused.",
    "Delete reward?": "Delete reward?",
    "Delete tag :label?": "Delete tag :label?",
    "Delete this custom event? This cannot be undone.": "Delete this custom event? This cannot be undone.",
    "Description": "Description",
    "Detach": "Detach",
    "Detach this graph?": "Detach this graph?",
    "Detaching removes the link to the source. You'll be able to edit everything but won't receive future updates.": "Detaching removes the link to the source. You'll be able to edit everything but won't receive future updates.",
    "Disable": "Disable",
    "Disable this action": "Disable this action",
    "Disabled rewards do not appear in the redemption menu.": "Disabled rewards do not appear in the redemption menu.",
    "Display Name": "Display Name",
    "Drag to reorder": "Drag to reorder",
    "Duplicate (Ctrl+D)": "Duplicate (Ctrl+D)",
    "Each command below materialises as a chat trigger plus an editable graph. Add only the ones you want — skip Edit if you don't need it. The default response is a simple \"Quote #N: text\"; open the graph to customise.": "Each command below materialises as a chat trigger plus an editable graph. Add only the ones you want, skip Edit if you don't need it. The default response is a simple \"Quote #N: text\"; open the graph to customise.",
    "Each response segment must be a plain string or a {v,p?} variable object.": "Each response segment must be a plain string or a {v,p?} variable object.",
    "Edit": "Edit",
    "Edit !:keyword": "Edit !:keyword",
    "Edit :name": "Edit :name",
    "Edit :phrase": "Edit :phrase",
    "Edit Custom Event": "Edit Custom Event",
    "Edit Role: :name": "Edit Role: :name",
    "Edit User :user": "Edit User :user",
    "Edit User Group: :name": "Edit User Group: :name",
    "Edit command": "Edit command",
    "Edit command:": "Edit command:",
    "Edit event schema": "Edit event schema",
    "Edit keyword:": "Edit keyword:",
    "Edit trigger: :label": "Edit trigger: :label",
    "Edited": "Edited",
    "Enable": "Enable",
    "Enable :title": "Enable :title",
    "Enable this action": "Enable this action",
    "Enabled": "Enabled",
    "Enter a field explanation": "Enter a field explanation",
    "Enter a field label": "Enter a field label",
    "Enter trigger phrase…": "Enter trigger phrase…",
    "Event :key unregistered": "Event :key unregistered",
    "Event Graphs": "Event Graphs",
    "Event registered": "Event registered",
    "Events": "Events",
    "Every available event is already registered for this property.": "Every available event is already registered for this property.",
    "Example:": "Example:",
    "Existing command": "Existing command",
    "Expose this field on import": "Expose this field on import",
    "Exposed params": "Exposed params",
    "Extension :alias installed": "Extension :alias installed",
    "Extension :alias uninstalled": "Extension :alias uninstalled",
    "Extension :extension has been successfully disabled": "Extension :extension has been successfully disabled",
    "Extension :extension has been successfully enabled": "Extension :extension has been successfully enabled",
    "Extension :extension saved": "Extension :extension saved",
    "Extension: :name": "Extension: :name",
    "Extensions": "Extensions",
    "Extensions - Administration": "Extensions - Administration",
    "Extensions are the building blocks: Commands, Keywords, Loyalty, and more. Install what applies to your channel. Each one adds the events and actions it knows about.": "Extensions are the building blocks: Commands, Keywords, Loyalty, and more. Install what applies to your channel. Each one adds the events and actions it knows about.",
    "Extensions index screenshot": "Extensions index screenshot",
    "External": "External",
    "Failed to create share link.": "Failed to create share link.",
    "Failed to load consent info. Please retry.": "Failed to load consent info. Please retry.",
    "Fetch data from external hosts": "Fetch data from external hosts",
    "Field Explanation": "Field Explanation",
    "Field Label": "Field Label",
    "Field Name": "Field Name",
    "Filter by number, text, or category…": "Filter by number, text, or category…",
    "Form Generator": "Form Generator",
    "Free tier cap reached for category-bound rewards. Remove a binding from another reward, or upgrade to Premium, before adding categories here.": "Free tier cap reached for category-bound rewards. Remove a binding from another reward, or upgrade to Premium, before adding categories here.",
    "Free tier cap reached: :used / :limit category-bound rewards. Existing bindings keep working; new bindings are blocked until you upgrade or unbind one.": "Free tier cap reached: :used / :limit category-bound rewards. Existing bindings keep working; new bindings are blocked until you upgrade or unbind one.",
    "Free tier — active category bindings: :used / :limit.": "Free tier: active category bindings: :used / :limit.",
    "From :label": "From :label",
    "Gate": "Gate",
    "Generate a one-time share link.": "Generate a one-time share link.",
    "Grant Access": "Grant Access",
    "Grant property access to moderators, define role-based permissions.": "Grant property access to moderators, define role-based permissions.",
    "Graph": "Graph",
    "Graph Marketplace": "Graph Marketplace",
    "Graph installed successfully.": "Graph installed successfully.",
    "Graph removed": "Graph removed",
    "Graph saved": "Graph saved",
    "Graph updated": "Graph updated",
    "Graphs": "Graphs",
    "Groups": "Groups",
    "Header-Name: value\\nAnother-Header: value": "Header-Name: value\\nAnother-Header: value",
    "Headers": "Headers",
    "Here's what's different.": "Here's what's different.",
    "Hey :name,": "Hey :name,",
    "Hi there,": "Hi there,",
    "Hide upload": "Hide upload",
    "How it works": "How it works",
    "I rebuilt this from scratch after eight years because the old version had too much debt and too little trust in the core design. This version is built properly — and the alpha is the proof of that claim, not a claim about the product being finished. If you're the kind of streamer who wants to be early and shape what this becomes, you're who I built this for.": "I rebuilt this from scratch after eight years because the old version had too much debt and too little trust in the core design. This version is built properly. And the alpha is the proof of that claim, not a claim about the product being finished. If you're the kind of streamer who wants to be early and shape what this becomes, you're who I built this for.",
    "ID": "ID",
    "Icon Left": "Icon Left",
    "Icon Right": "Icon Right",
    "If the button doesn't work, copy and paste this link into your browser:": "If the button doesn't work, copy and paste this link into your browser:",
    "Images": "Images",
    "Import from :sharer": "Import from :sharer",
    "Import from code": "Import from code",
    "Import shared graph": "Import shared graph",
    "In the meantime there's nothing more to do. You can close this tab and come back later.": "In the meantime there's nothing more to do. You can close this tab and come back later.",
    "Inputs": "Inputs",
    "Inputs / Outputs": "Inputs / Outputs",
    "Inspector": "Inspector",
    "Install": "Install",
    "Install :name": "Install :name",
    "Install Graph": "Install Graph",
    "Install extensions": "Install extensions",
    "Install failed.": "Install failed.",
    "marketing.waitlist.title": "Join the Streambridge waitlist",
    "Key": "Key",
    "Keyword": "Keyword",
    "Keyword (without !)": "Keyword (without !)",
    "Keyword editor screenshot": "Keyword editor screenshot",
    "Keyword removed": "Keyword removed",
    "Keyword saved": "Keyword saved",
    "Keyword updated": "Keyword updated",
    "Keywords": "Keywords",
    "Label": "Label",
    "Leave": "Leave",
    "Leave all groups empty to allow everyone. Matches are OR-combined — a viewer only needs to satisfy one group.": "Leave all groups empty to allow everyone. Matches are OR-combined: a viewer only needs to satisfy one group.",
    "Leave empty": "Leave empty",
    "Leave empty to keep this reward always active. When set, the reward is auto-enabled while the stream sits in one of these categories and auto-disabled otherwise.": "Leave empty to keep this reward always active. When set, the reward is auto-enabled while the stream sits in one of these categories and auto-disabled otherwise.",
    "Let's go": "Let's go",
    "Link already used": "Link already used",
    "Link existing": "Link existing",
    "Link expired": "Link expired",
    "Link not found": "Link not found",
    "Link this Twitch account as a bot?": "Link this Twitch account as a bot?",
    "Linked": "Linked",
    "Linked to": "Linked to",
    "List": "List",
    "Literal value (string)": "Literal value (string)",
    "Loading…": "Loading…",
    "Log in": "Log in",
    "auth.login.to_app": "Log in to Streambridge",
    "Log out": "Log out",
    "Login": "Login",
    "Logout": "Logout",
    "Major": "Major",
    "Make this the default sender for Commands/Keywords with no explicit sender": "Make this the default sender for Commands/Keywords with no explicit sender",
    "Manage uploaded images, audio and video.": "Manage uploaded images, audio and video.",
    "Managed": "Managed",
    "Marketplace": "Marketplace",
    "Match mode": "Match mode",
    "Media Center": "Media Center",
    "Members": "Members",
    "Members of linked UserGroups can access this extension regardless of property-level role. Useful for alpha/beta rollouts.": "Members of linked UserGroups can access this extension regardless of property-level role. Useful for alpha/beta rollouts.",
    "Method": "Method",
    "Minor": "Minor",
    "Missing permissions": "Missing permissions",
    "Missing scopes": "Missing scopes",
    "More actions": "More actions",
    "My Graph Packages": "My Graph Packages",
    "Name": "Name",
    "Name on my property": "Name on my property",
    "New Command": "New Command",
    "New Custom Event": "New Custom Event",
    "New Graph": "New Graph",
    "New Graph Package": "New Graph Package",
    "New Keyword": "New Keyword",
    "New Reward": "New Reward",
    "New alias keyword": "New alias keyword",
    "New command": "New command",
    "New custom event": "New custom event",
    "New exposed params": "New exposed params",
    "New resource refs": "New resource refs",
    "New tag label": "New tag label",
    "Newest": "Newest",
    "No": "No",
    "No access": "No access",
    "No administrative activity logged yet on this property.": "No administrative activity logged yet on this property.",
    "No aliases yet.": "No aliases yet.",
    "No app-level permissions registered yet.": "No app-level permissions registered yet.",
    "No audit entries yet.": "No audit entries yet.",
    "No bot accounts linked yet.": "No bot accounts linked yet.",
    "No chat-writable connections linked yet. Grant the user:write:chat scope on an account to add it.": "No chat-writable connections linked yet. Grant the user:write:chat scope on an account to add it.",
    "No commands configured on this property yet.": "No commands configured on this property yet.",
    "No commands yet. Create one to get your chat bot talking.": "No commands yet. Create one to get your chat bot talking.",
    "No custom events yet — click + to create one.": "No custom events yet: click + to create one.",
    "No enabled UserGroup holds the `app.grant_access` permission. Create one before approving anyone — approval needs a group to attach.": "No enabled UserGroup holds the `app.grant_access` permission. Create one before approving anyone: approval needs a group to attach.",
    "No exposed params to configure.": "No exposed params to configure.",
    "No extensions enabled yet. Ask your admin to enable one.": "No extensions enabled yet. Ask your admin to enable one.",
    "No graph packages yet.": "No graph packages yet.",
    "No graphs yet. Create one to chain events to responses visually.": "No graphs yet. Create one to chain events to responses visually.",
    "No keywords configured on this property yet.": "No keywords configured on this property yet.",
    "No keywords yet. Create one to have the bot react to phrases in chat.": "No keywords yet. Create one to have the bot react to phrases in chat.",
    "No matches.": "No matches.",
    "No media found.": "No media found.",
    "No members yet.": "No members yet.",
    "No pending event registration found.": "No pending event registration found.",
    "No permissions available. Install extensions to get permissions.": "No permissions available. Install extensions to get permissions.",
    "No published graphs yet.": "No published graphs yet.",
    "No quotes match your filter.": "No quotes match your filter.",
    "No quotes yet. Mods can capture one in chat with the Add command.": "No quotes yet. Mods can capture one in chat with the Add command.",
    "No resources to configure.": "No resources to configure.",
    "No rewards match the filter.": "No rewards match the filter.",
    "No rewards yet. Click \"Sync now\" to import existing Twitch rewards, or create a new one.": "No rewards yet. Click \"Sync now\" to import existing Twitch rewards, or create a new one.",
    "No roles yet. Create one to grant extension permissions to your editors.": "No roles yet. Create one to grant extension permissions to your editors.",
    "No scopes required": "No scopes required",
    "No tags yet — create one below.": "No tags yet: create one below.",
    "No tags yet.": "No tags yet.",
    "No top-level commands available to link. All your existing commands are already linked or aliases.": "No top-level commands available to link. All your existing commands are already linked or aliases.",
    "No trace entries — graph had no executable path from the trigger.": "No trace entries: graph had no executable path from the trigger.",
    "No triggers match the current filter.": "No triggers match the current filter.",
    "No user groups defined yet.": "No user groups defined yet.",
    "No versions published yet.": "No versions published yet.",
    "No waitlist requests yet.": "No waitlist requests yet.",
    "Node": "Node",
    "Not linked": "Not linked",
    "OK": "OK",
    "On the waitlist": "On the waitlist",
    "One event. As many actions as you need.": "One event. As many actions as you need.",
    "One header per line, name and value separated by a colon.": "One header per line, name and value separated by a colon.",
    "Only continue if you actually intend to give this channel chat-write access via your Twitch account. If you weren't expecting this prompt, close this tab — your account stays untouched.": "Only continue if you actually intend to give this channel chat-write access via your Twitch account. If you weren't expecting this prompt, close this tab: your account stays untouched.",
    "Only while live": "Only while live",
    "Only while offline": "Only while offline",
    "Open": "Open",
    "Open Property": "Open Property",
    "Open graph": "Open graph",
    "Open in :owner": "Open in :owner",
    "Open in Editor": "Open in Editor",
    "Open this link in a private browser window where you are logged into your bot's Twitch account. It's single-use and expires in 15 minutes.": "Open this link in a private browser window where you are logged into your bot's Twitch account. It's single-use and expires in 15 minutes.",
    "Optional. Up to 200 characters — shown above the redeem button on Twitch.": "Optional. Up to 200 characters, shown above the redeem button on Twitch.",
    "Options": "Options",
    "Outputs": "Outputs",
    "Override active": "Override active",
    "Page :current of :last (:total entries)": "Page :current of :last (:total entries)",
    "Paste the share code you received from the graph's author.": "Paste the share code you received from the graph's author.",
    "Patch": "Patch",
    "Path (e.g. data.email)": "Path (e.g. data.email)",
    "Paused": "Paused",
    "Paused rewards stay visible but cannot be redeemed.": "Paused rewards stay visible but cannot be redeemed.",
    "Pending review": "Pending review",
    "Pending verification link": "Pending verification link",
    "Per-user cooldown (s)": "Per-user cooldown (s)",
    "Permission": "Permission",
    "Permissions": "Permissions",
    "Permissions Twitch will request": "Permissions Twitch will request",
    "Persistent": "Persistent",
    "Phrase": "Phrase",
    "Phrases": "Phrases",
    "Pick a trigger first.": "Pick a trigger first.",
    "Pick a trigger to configure the test-run.": "Pick a trigger to configure the test-run.",
    "Pick existing": "Pick existing",
    "Pick the events you want to react to. Provider scopes are batched into a single sign-in per provider; events from different providers go through separate sign-ins.": "Pick the events you want to react to. Provider scopes are batched into a single sign-in per provider; events from different providers go through separate sign-ins.",
    "Pin IDs must start with a lowercase letter and contain only lowercase letters, digits, and underscores.": "Pin IDs must start with a lowercase letter and contain only lowercase letters, digits, and underscores.",
    "Pin signature exposed as data ports on Fire / Trigger nodes.": "Pin signature exposed as data ports on Fire / Trigger nodes.",
    "Pin to nav": "Pin to nav",
    "Pins": "Pins",
    "Plain text or JSON. {variable.name} placeholders are substituted at fire time. Limited to 1MB.": "Plain text or JSON. {variable.name} placeholders are substituted at fire time. Limited to 1MB.",
    "Platform foundation": "Platform foundation",
    "Play audio": "Play audio",
    "Preferred default sender — click to clear": "Preferred default sender, click to clear",
    "Premium tier — unlimited category-bound rewards.": "Premium tier: unlimited category-bound rewards.",
    "Primary connections cannot be removed here.": "Primary connections cannot be removed here.",
    "Profile": "Profile",
    "Profile Settings": "Profile Settings",
    "Promote to Marketplace": "Promote to Marketplace",
    "Prompt": "Prompt",
    "Public": "Public",
    "Publish": "Publish",
    "Publish New Version": "Publish New Version",
    "Publish failed.": "Publish failed.",
    "Publish to the Graph Marketplace.": "Publish to the Graph Marketplace.",
    "Quick Share": "Quick Share",
    "Quota full": "Quota full",
    "Quote #:n deleted": "Quote #:n deleted",
    "Quote :slot command removed": "Quote :slot command removed",
    "Quote :slot command saved": "Quote :slot command saved",
    "Quote Settings": "Quote Settings",
    "Quote list": "Quote list",
    "Quotes": "Quotes",
    "Read chat messages": "Read chat messages",
    "Re-run": "Re-run",
    "Receive new followers": "Receive new followers",
    "Redeem": "Redeem",
    "Register 1 event": "Register 1 event",
    "Registered": "Registered",
    "Registration failed: :reason": "Registration failed: :reason",
    "Reject": "Reject",
    "Rejected": "Rejected",
    "Rejected :email": "Rejected :email",
    "Remove": "Remove",
    "Remove alias :keyword": "Remove alias :keyword",
    "Remove from nav": "Remove from nav",
    "Remove pin": "Remove pin",
    "Remove this action": "Remove this action",
    "Remove this action?": "Remove this action?",
    "Remove this step": "Remove this step",
    "Remove this bot? The Twitch token will be revoked.": "Remove this bot? The Twitch token will be revoked.",
    "Remove this command? The auto-generated graph drops with it; the underlying chat command stays only if it was already yours before.": "Remove this command? The auto-generated graph drops with it; the underlying chat command stays only if it was already yours before.",
    "Rename": "Rename",
    "Rename alias :keyword": "Rename alias :keyword",
    "Replaces the text of an existing quote without changing its number, category, or timestamp.": "Replaces the text of an existing quote without changing its number, category, or timestamp.",
    "Requested scopes:": "Requested scopes:",
    "Require user input": "Require user input",
    "Required scopes": "Required scopes",
    "Requirements": "Requirements",
    "Requires stream.online / stream.offline events registered on this property, otherwise this filter blocks every trigger.": "Requires stream.online / stream.offline events registered on this property, otherwise this filter blocks every trigger.",
    "Reset override": "Reset override",
    "Resource refs are always exposed on import": "Resource refs are always exposed on import",
    "Response": "Response",
    "Response template": "Response template",
    "Returns a random quote when typed bare; with a number, returns that specific quote.": "Returns a random quote when typed bare; with a number, returns that specific quote.",
    "Returns a random text from a list": "Returns a random text from a list",
    "Returns the command trigger (what the user typed after !).": "Returns the command trigger (what the user typed after !).",
    "Returns the matched phrase.": "Returns the matched phrase.",
    "Returns the target ID": "Returns the target ID",
    "Returns the target channel name": "Returns the target channel name",
    "Returns the target followage. The format can be changed after selection.": "Returns the target followage. The format can be changed after selection.",
    "Returns the target name": "Returns the target name",
    "Returns the user ID": "Returns the user ID",
    "Returns the user channel name": "Returns the user channel name",
    "Returns the user followage. The format can be changed after selection.": "Returns the user followage. The format can be changed after selection.",
    "Returns the user name": "Returns the user name",
    "Review & install": "Review & install",
    "Review the consent details in the modal. Close to cancel.": "Review the consent details in the modal. Close to cancel.",
    "Reward": "Reward",
    "Reward Tag": "Reward Tag",
    "Rewards": "Rewards",
    "Rewards Settings": "Rewards Settings",
    "Role": "Role",
    "Role :role created": "Role :role created",
    "Role :role deleted": "Role :role deleted",
    "Role :role updated": "Role :role updated",
    "Role Name": "Role Name",
    "Role Settings": "Role Settings",
    "Role Type": "Role Type",
    "Roles": "Roles",
    "Roles & Moderators": "Roles & Moderators",
    "Run": "Run",
    "Run finished in :ms ms": "Run finished in :ms ms",
    "Save": "Save",
    "Save (Ctrl+S)": "Save (Ctrl+S)",
    "Save Command": "Save Command",
    "Save Keyword": "Save Keyword",
    "Save Reward": "Save Reward",
    "Save alias": "Save alias",
    "Save command": "Save command",
    "Save failed.": "Save failed.",
    "Save keyword": "Save keyword",
    "Search Twitch categories…": "Search Twitch categories…",
    "Search by Twitch username…": "Search by Twitch username…",
    "Search for variables (Ctrl + K)": "Search for variables (Ctrl + K)",
    "Search rewards…": "Search rewards…",
    "Search triggers": "Search triggers",
    "Search user…": "Search user…",
    "Search…": "Search…",
    "See how it works": "See how it works",
    "Select events": "Select events",
    "Sender account": "Sender account",
    "Sender account is missing the user:write:chat scope.": "Sender account is missing the user:write:chat scope.",
    "Sender account not found or not owned by this property.": "Sender account not found or not owned by this property.",
    "Sent by": "Sent by",
    "Server misconfigured": "Server misconfigured",
    "Settings": "Settings",
    "Share": "Share",
    "Share code": "Share code",
    "Share this graph": "Share this graph",
    "Shared graph": "Shared graph",
    "widgets.consent.badges.label": "Show badge images via Streambridge",
    "Show command": "Show command",
    "widgets.consent.emotes.label": "Show emote images via Streambridge",
    "Sign out": "Sign out",
    "Size": "Size",
    "Skip this version": "Skip this version",
    "Something went wrong.": "Something went wrong.",
    "Source Graph": "Source Graph",
    "Specific viewers": "Specific viewers",
    "Stream State": "Stream State",
    "Stream state": "Stream state",
    "extensions.rewards.config_title": "Streambridge configuration",
    "marketing.waitlist.alpha_intro": "Streambridge is in closed alpha. Hit the button below: you'll sign in with Twitch so we can capture your email, and we'll let you know by mail the moment you're approved.",
    "widgets.consent.badges.description": "Streambridge proxies badge images for the widget. Data is cached and not loaded directly from the provider.",
    "widgets.consent.emotes.description": "Streambridge proxies emote images for the widget. Data is cached and not loaded directly from the provider.",
    "widgets.consent.fonts.label": "Load fonts from external hosts",
    "widgets.consent.fonts.description": "The widget loads fonts and font stylesheets from external servers. Those servers see the IP address of your browsersource.",
    "widgets.consent.fonts.example": "A headline displayed in a Google Font.",
    "Subscribed because of installed extensions": "Subscribed because of installed extensions",
    "Sync now": "Sync now",
    "System": "System",
    "Tag label": "Tag label",
    "Tags": "Tags",
    "Tags are label + color pairs you can attach to rewards. They are property-scoped and used for filtering and visual grouping in the Rewards list.": "Tags are label + color pairs you can attach to rewards. They are property-scoped and used for filtering and visual grouping in the Rewards list.",
    "Tell us a little about your stream. We read every application.": "Tell us a little about your stream. We read every application.",
    "Test": "Test",
    "Test-Run": "Test-Run",
    "Test-Run panel": "Test-Run panel",
    "Test-run failed.": "Test-run failed.",
    "Thanks for signing up.": "Thanks for signing up.",
    "Thanks — you're on the list. We'll send an email to :email once your access is ready.": "Thanks. You're on the list. We'll send an email to :email once your access is ready.",
    "Thanks, :name.": "Thanks, :name.",
    "The Quote graph will fire alongside any existing actions on this command. Audience and cooldowns stay as the command already has them.": "The Quote graph will fire alongside any existing actions on this command. Audience and cooldowns stay as the command already has them.",
    "The auto-generated graph drops with it.": "The auto-generated graph drops with it.",
    "The bot verification flow is not fully configured on this server. Please contact the operator.": "The bot verification flow is not fully configured on this server. Please contact the operator.",
    "The following scopes were not granted: :missing. Please re-authorize and allow all requested permissions.": "The following scopes were not granted: :missing. Please re-authorize and allow all requested permissions.",
    "The key must start with a lowercase letter and contain only lowercase letters, digits, and underscores.": "The key must start with a lowercase letter and contain only lowercase letters, digits, and underscores.",
    "The parent command and its other aliases stay untouched.": "The parent command and its other aliases stay untouched.",
    "The phrase \":phrase\" is already used by another keyword.": "The phrase \":phrase\" is already used by another keyword.",
    "The verification link is invalid.": "The verification link is invalid.",
    "The visual editor isn't a gimmick. When your workflow spans four steps and two platforms, seeing it as a graph makes the difference between catching an error in 10 seconds or troubleshooting for an hour.": "The visual editor isn't a gimmick. When your workflow spans four steps and two platforms, seeing it as a graph makes the difference between catching an error in 10 seconds or troubleshooting for an hour.",
    "The widget can play audio clips inside the OBS browsersource.": "The widget can play audio clips inside the OBS browsersource.",
    "The widget is notified when someone follows your channel.": "The widget is notified when someone follows your channel.",
    "The widget loads data from external servers. Those servers see the IP address of your browsersource and can potentially track when your widget is active.": "The widget loads data from external servers. Those servers see the IP address of your browsersource and can potentially track when your widget is active.",
    "The widget receives every chat message — username, badges, emote positions — as it arrives in your chat.": "The widget receives every chat message (username, badges, emote positions) as it arrives in your chat.",
    "This Command is disabled — actions below stay configured but won't fire until you re-enable the Command.": "This Command is disabled: actions below stay configured but won't fire until you re-enable the Command.",
    "This Keyword is disabled — actions below stay configured but won't fire until you re-enable the Keyword.": "This Keyword is disabled: actions below stay configured but won't fire until you re-enable the Keyword.",
    "This Twitch event is not registered for this property — actions below stay configured but won't fire until you register the event.": "This Twitch event is not registered for this property: actions below stay configured but won't fire until you register the event.",
    "extensions.rewards.delete_managed_confirm": "This also removes the reward from Twitch when it is managed by Streambridge.",
    "This asset is used by scene :names — they will lose their background. Continue?": "This asset is used by scene :names — they will lose their background. Continue?",
    "This bot cannot be preferred — it lacks the user:write:chat scope.": "This bot cannot be preferred: it lacks the user:write:chat scope.",
    "events.consent.undocumented": "This event is not yet documented. The Streambridge team is on it.",
    "This is a reboot of a platform that ran for eight years. The foundation is modern, event-driven, and built to scale. What you build here won't need to be rebuilt when your channel grows.": "This is a reboot of a platform that ran for eight years. The foundation is modern, event-driven, and built to scale. What you build here won't need to be rebuilt when your channel grows.",
    "This is your primary account": "This is your primary account",
    "This link expired. Ask the property owner to generate a new one.": "This link expired. Ask the property owner to generate a new one.",
    "This link has already been used.": "This link has already been used.",
    "This node has no editable parameters.": "This node has no editable parameters.",
    "widgets.consent.permission_undocumented": "This permission is not yet documented. The Streambridge team is on it.",
    "This property already has the maximum number of bot accounts.": "This property already has the maximum number of bot accounts.",
    "This property already has the maximum of :max bot accounts.": "This property already has the maximum of :max bot accounts.",
    "This removes the tag from all rewards that carry it. The rewards themselves stay.": "This removes the tag from all rewards that carry it. The rewards themselves stay.",
    "extensions.rewards.external_readonly": "This reward was created in the Twitch UI and is not managed by Streambridge. Edit it from your Twitch dashboard; this view is read-only.",
    "extensions.rewards.delete_managed_confirm_short": "This will also remove it from Twitch when managed by Streambridge.",
    "extensions.rewards.delete_confirm_title": "Delete reward?",
    "extensions.rewards.toggle_enabled_aria": "Enable :title",
    "extensions.rewards.meta_uses": ":count redemptions (7d)",
    "extensions.rewards.meta_last_used": "last redeemed :time",
    "extensions.rewards.meta_never_used": "never redeemed",
    "Tier status": "Tier status",
    "Timer": "Timer",
    "Title": "Title",
    "Toggle": "Toggle",
    "Trace · :n entries": "Trace · :n entries",
    "Trigger": "Trigger",
    "Trigger anytime": "Trigger anytime",
    "Trigger is off.": "Trigger is off.",
    "Trigger on any Twitch event. Define exactly what happens in response. Configure conditions, cooldowns, and audience rules in one place — no YAML, no terminal, no deploy step. Save it and it runs.": "Trigger on any Twitch event. Define exactly what happens in response. Configure conditions, cooldowns, and audience rules in one place: no YAML, no terminal, no deploy step. Save it and it runs.",
    "Trigger:": "Trigger:",
    "Triggers": "Triggers",
    "Triggers:": "Triggers:",
    "Twitch authorization failed": "Twitch authorization failed",
    "Twitch badges": "Twitch badges",
    "Twitch events": "Twitch events",
    "Twitch global emotes shown alongside chat messages.": "Twitch global emotes shown alongside chat messages.",
    "Twitch rejected the authorization. Please try again.": "Twitch rejected the authorization. Please try again.",
    "Twitch returned without the expected parameters. Try again from the property owner's link.": "Twitch returned without the expected parameters. Try again from the property owner's link.",
    "Twitch scope:": "Twitch scope:",
    "Twitch subscriber badges in the chatbox widget.": "Twitch subscriber badges in the chatbox widget.",
    "Type": "Type",
    "Type the chat reply. Insert variables for runtime substitution.": "Type the chat reply. Insert variables for runtime substitution.",
    "URL": "URL",
    "Uninstall": "Uninstall",
    "Unregister": "Unregister",
    "Unregister failed: :err": "Unregister failed: :err",
    "Unregister this event from the property": "Unregister this event from the property",
    "Unsaved changes": "Unsaved changes",
    "Unsupported file type": "Unsupported file type",
    "Update": "Update",
    "Update Available": "Update Available",
    "Update available: v:v": "Update available: v:v",
    "Upload": "Upload",
    "Upload failed": "Upload failed",
    "Upload images, audio and video for your scenes and actions.": "Upload images, audio and video for your scenes and actions.",
    "Use \"Clear\" to fall back to the broadcaster.": "Use \"Clear\" to fall back to the broadcaster.",
    "Use existing": "Use existing",
    "Use the + Add button on the node to spawn another pin.": "Use the + Add button on the node to spawn another pin.",
    "Used by :ext": "Used by :ext",
    "Used by scenes": "Used by scenes",
    "User :user access has been granted": "User :user access has been granted",
    "User :user has been successfully updated": "User :user has been successfully updated",
    "User Group Name": "User Group Name",
    "User Groups": "User Groups",
    "User ID": "User ID",
    "User Information": "User Information",
    "User group :group created": "User group :group created",
    "User group :group deleted": "User group :group deleted",
    "User group :group disabled": "User group :group disabled",
    "User group :group enabled": "User group :group enabled",
    "User group :group updated": "User group :group updated",
    "UserGroups": "UserGroups",
    "Users": "Users",
    "Verification failed": "Verification failed",
    "Version": "Version",
    "Versions": "Versions",
    "Video": "Video",
    "Viewer groups": "Viewer groups",
    "Viewers must enter a text prompt when redeeming.": "Viewers must enter a text prompt when redeeming.",
    "Visit xeras.de": "Visit xeras.de",
    "Waitlist": "Waitlist",
    "Waitlist request is not pending.": "Waitlist request is not pending.",
    "We could not read your Twitch email — please try again and confirm the email scope.": "We could not read your Twitch email: please try again and confirm the email scope.",
    "We couldn't read the Twitch account that just authorized. Please try again.": "We couldn't read the Twitch account that just authorized. Please try again.",
    "We only ask for your Twitch email. No chat scopes, no channel access — that comes later when you're in.": "We only ask for your Twitch email. No chat scopes, no channel access: that comes later when you're in.",
    "We've received your request and are reviewing it. We read every application personally — you'll hear back via the email associated with your Twitch account when access is granted.": "We've received your request and are reviewing it. We read every application personally. You'll hear back via the email associated with your Twitch account when access is granted.",
    "auth.waitlist_email.heading": "Welcome to Streambridge",
    "What the widget is allowed to do": "What the widget is allowed to do",
    "What the widget reads": "What the widget reads",
    "When public is on, every property editor can use this extension. Otherwise access is granted via linked UserGroups (app-level) or property-level roles holding the permission above.": "When public is on, every property editor can use this extension. Otherwise access is granted via linked UserGroups (app-level) or property-level roles holding the permission above.",
    "When to trigger": "When to trigger",
    "Who changed what in this property, immutable history.": "Who changed what in this property, immutable history.",
    "Widget Event": "Widget Event",
    "Will be saved as:": "Will be saved as:",
    "Word boundary — exact phrase": "Word boundary: exact phrase",
    "Yes": "Yes",
    "You are about to link your currently signed-in Twitch account as a bot for the following channel:": "You are about to link your currently signed-in Twitch account as a bot for the following channel:",
    "You are acting as admin in :name (:login). All mutations are logged.": "You are acting as admin in :name (:login). All mutations are logged.",
    "You will be redirected to :provider to grant: ": "You will be redirected to :provider to grant: ",
    "You're authorizing your own streamer account. Bots must be a different Twitch account — use the sender dropdown in Commands/Keywords for primary-account responses.": "You're authorizing your own streamer account. Bots must be a different Twitch account: use the sender dropdown in Commands/Keywords for primary-account responses.",
    "You're in. Check your inbox or log in directly to get started.": "You're in. Check your inbox or log in directly to get started.",
    "You're on the list": "You're on the list",
    "You've used the alternatives.": "You've used the alternatives.",
    "auth.waitlist_email.subject": "Your Streambridge access is ready",
    "Your application wasn't approved this time.": "Your application wasn't approved this time.",
    "Your current settings will be preserved.": "Your current settings will be preserved.",
    "Your personal account — notifications, theme, connections.": "Your personal account: notifications, theme, connections.",
    "Your rules.": "Your rules.",
    "Your stream,": "Your stream,",
    "auth.waitlist_email.body": "Your waitlist request has been approved. You can log in with Twitch and start using Streambridge.",
    "Your workflow runs immediately.": "Your workflow runs immediately.",
    "actions": "actions",
    "alias": "alias",
    "alias of !:keyword": "alias of !:keyword",
    "alias of !:parent": "alias of !:parent",
    "applied": "applied",
    "attached": "attached",
    "automated.": "automated.",
    "by": "by",
    "case-sensitive": "case-sensitive",
    "category unknown": "category unknown",
    "centered on canvas": "centered on canvas",
    "common.back": "Back",
    "common.cancel": "Cancel",
    "common.continue": "Continue",
    "common.done": "Done",
    "common.next": "Next",
    "common.save": "Save",
    "consent.section.resources.title": "Resources to be created / used",
    "contains": "contains",
    "copied": "copied",
    "copy": "copy",
    "disabled": "disabled",
    "dry-run": "dry-run",
    "e.g. Soundalert": "e.g. Soundalert",
    "e.g. hello": "e.g. hello",
    "events.register.count": "[0,1] Register :count event|[2,*] Register :count events",
    "events.registered.count": "{0} no events|[1,1] :count event|[2,*] :count events",
    "events.automations.advanced_flow": "When :verb → advanced flow",
    "events.automations.advanced": "advanced flow",
    "events.automations.new": "New automation",
    "events.automations.no_match": "No automations match your search.",
    "events.automations.off": "off",
    "events.automations.reaction_one": "reaction",
    "events.automations.reaction_other": "reactions",
    "events.automations.search": "Search automations",
    "events.automations.sentence": "When :verb → :reactions",
    "events.automations.sort_alpha": "A-Z",
    "events.automations.sort_recent": "Recently edited",
    "events.automations.sort_trigger": "By trigger",
    "events.automations.title": "Automations",
    "events.verb.follow": "someone follows",
    "events.verb.subscribe": "someone subscribes",
    "events.verb.resub": "someone shares a resub",
    "events.verb.gift_sub": "someone gifts subs",
    "events.verb.cheer": "someone cheers bits",
    "events.verb.raid": "someone raids the channel",
    "events.verb.hype_train_begin": "a hype train starts",
    "events.verb.watch_streak": "a viewer shares a watch streak",
    "events.verb.first_appearance": "appears for the first time",
    "events.verb.stream_online": "the stream goes live",
    "events.verb.hype_train_end": "a hype train ends",
    "events.verb.stream_offline": "the stream goes offline",
    "events.verb.shoutout_receive": "you receive a shoutout",
    "events.verb.charity_donate": "someone donates to your charity",
    "events.verb.goal_begin": "a goal starts",
    "events.verb.poll_begin": "a poll starts",
    "events.verb.prediction_begin": "a prediction starts",
    "events.verb.ad_break_begin": "an ad break starts",
    "events.verb.chat_send": "Send a chat message",
    "events.verb.chat_announce": "Send an announcement",
    "events.verb.chat_shoutout": "Shout out a user",
    "events.verb.sound_play": "Play a sound",
    "events.verb.tts_speak": "Read it aloud",
    "events.verb.http_request": "Make an HTTP request",
    "events.verb.set_title": "Set the stream title",
    "events.verb.set_category": "Set the stream category",
    "events.verb.add_marker": "Add a stream marker",
    "events.verb.create_clip": "Create a clip",
    "events.preset.welcome_followers.title": "Welcome followers",
    "events.preset.welcome_followers.text": "Welcome {user.name}! 💜",
    "events.preset.thank_subs.title": "Thank subscribers",
    "events.preset.thank_subs.text": "Thanks for subscribing, {user.name}!",
    "events.preset.shoutout_raiders.title": "Shout out raiders",
    "events.preset.reward_watch_streaks.title": "Reward watch streaks",
    "events.preset.reward_watch_streaks.text": "{user.name} is on a watch streak! 🔥",
    "events.subscriptions.title": "Subscriptions & scopes",
    "events.connection_warning": "Removing pins may break connections; deleting the event is blocked while it's still connected.",
    "extensions.common.enabled": "Enabled",
    "extensions.common.count_active": ":count :noun · :active active",
    "extensions.common.count_only": ":count :noun",
    "extensions.common.actions_menu": "Actions",
    "extensions.common.delete": "Delete",
    "extensions.common.delete_confirm_title": "Delete this item?",
    "extensions.common.edit": "Edit",
    "extensions.common.copy_url": "Copy URL",
    "extensions.common.rotate_token": "Rotate token",
    "extensions.common.open_editor": "Open editor",
    "extensions.common.settings": "Settings",
    "extensions.common.reset_override": "Reset override",
    "extensions.common.search": "Search…",
    "extensions.common.filter_all": "All",
    "extensions.common.filter_active": "Active",
    "extensions.common.filter_paused": "Paused",
    "extensions.widgets.delete_confirm_title": "Delete scene :name?",
    "extensions.widgets.delete_confirm_message": "Active OBS browsersources for this scene will be disconnected. Widgets inside the scene are deleted with it.",
    "extensions.widgets.no_match": "No scenes match your filter.",
    "extensions.actions.count": ":count action|:count actions",
    "extensions.actions.reorder_hint": "Reorder by drag & drop",
    "extensions.commands.new_command": "New Command",
    "extensions.commands.search_placeholder": "Search commands…",
    "extensions.commands.filter_all": "All",
    "extensions.commands.filter_active": "Active",
    "extensions.commands.filter_paused": "Paused",
    "extensions.commands.status_paused": "Paused",
    "extensions.commands.audience_restricted": "Restricted",
    "extensions.commands.meta_actions_one": ":count action",
    "extensions.commands.meta_actions_other": ":count actions",
    "extensions.commands.meta_uses": ":count uses (7d)",
    "extensions.commands.meta_last_used": "last used :time",
    "extensions.commands.meta_never_used": "never used",
    "extensions.commands.no_filter_results": "No commands match the filter.",
    "extensions.commands.more_actions": "More",
    "extensions.commands.add_alias": "Add alias",
    "extensions.commands.toggle_enabled_aria": "Toggle !:keyword",
    "extensions.commands.edit_aria": "Edit command !:keyword",
    "extensions.commands.delete_confirm_title": "Delete !:keyword?",
    "extensions.commands.delete_confirm_message": "The command and its actions are removed for good.",
    "extensions.commands.flash_enabled": "!:keyword enabled",
    "extensions.commands.flash_disabled": "!:keyword paused",
    "extensions.commands.alias_taken": "The alias !:keyword is already taken.",
    "extensions.commands.gates_title": "Conditions",
    "extensions.commands.gates_help": "Extra checks that must pass before this command runs. A failed condition blocks the command without using up its cooldown.",
    "extensions.commands.gates_empty": "No conditions: runs for anyone, anytime.",
    "extensions.commands.gates_add": "Add condition",
    "extensions.commands.gate_unavailable": "Extension not installed",
    "extensions.commands.gates_response_add": "Reply when blocked",
    "extensions.commands.gates_response_label": "Reply when blocked",
    "extensions.commands.gates_response_remove": "Remove reply",
    "extensions.commands.form.basics": "Basics",
    "extensions.commands.form.keyword_label": "Keyword",
    "extensions.commands.form.keyword_placeholder": "e.g. hello",
    "extensions.commands.form.keyword_help": "Viewers trigger the command with !:keyword in chat.",
    "extensions.commands.form.aliases_label": "Aliases",
    "extensions.commands.form.aliases_placeholder": "e.g. a, alt",
    "extensions.commands.form.aliases_help": "Enter or comma separates multiple aliases.",
    "extensions.commands.form.audience": "Audience",
    "extensions.commands.form.cooldowns": "Cooldowns",
    "extensions.commands.form.channel_cooldown": "Channel cooldown",
    "extensions.commands.form.channel_cooldown_help": "Pause for the whole channel after each call.",
    "extensions.commands.form.channel_cooldown_placeholder": "no cooldown",
    "extensions.commands.form.user_cooldown": "Per-viewer cooldown",
    "extensions.commands.form.user_cooldown_help": "0 or empty: no per-viewer cooldown.",
    "extensions.commands.form.cooldown_suffix": "Sec.",
    "extensions.commands.gate_orphaned_health": ":count command(s) use a condition from an uninstalled extension. They are blocked until you remove the condition or reinstall the extension.",
    "extensions.command_slots.title": "Command slots",
    "extensions.counters.delete_confirm_title": "Delete counter :name?",
    "extensions.counters.delete_confirm_message": "The current value and history are gone for good. Graphs that read or write this counter keep working but will fall back to the default.",
    "extensions.counters.no_match": "No counters match your filter.",
    "extensions.keywords.meta_uses": ":count matches (7d)",
    "extensions.keywords.meta_last_used": "last match :time",
    "extensions.keywords.meta_never_used": "never matched",
    "extensions.keywords.delete_confirm_title": "Delete keyword :phrase?",
    "extensions.keywords.delete_confirm_message": "The auto-generated graph drops with it.",
    "extensions.keywords.no_match": "No keywords match your filter.",
    "extensions.keywords.toggle_enabled_aria": "Toggle keyword :phrase",
    "extensions.keywords.edit_aria": "Edit keyword :phrase",
    "extensions.overview.open_aria": "Open :name",
    "extensions.graph.description": "Build visual workflows that connect events to actions.",
    "extensions.graph.name": "Event Flows",
    "extensions.graph.permission.access.description": "Flow list and read-only canvas view.",
    "extensions.graph.permission.access.label": "View flows",
    "extensions.graph.permission.configure.description": "Linked-flow Configure tab, detach, apply or skip updates.",
    "extensions.graph.permission.configure.label": "Configure flows",
    "extensions.graph.permission.delete.description": "Remove flows from the property.",
    "extensions.graph.permission.delete.label": "Delete flows",
    "extensions.graph.permission.edit.description": "Create flows, edit, run test, restore versions.",
    "extensions.graph.permission.edit.label": "Edit flows",
    "extensions.graph.permission.import.description": "Install marketplace flows or share links.",
    "extensions.graph.permission.import.label": "Import flows",
    "extensions.graph.permission.publish.description": "Submit a flow to the marketplace as a builder.",
    "extensions.graph.permission.publish.label": "Publish flows",
    "extensions.graph.permission.share.description": "Generate a share link to a flow.",
    "extensions.graph.permission.share.label": "Share flows",
    "extensions.mod.action_ban": "Ban",
    "extensions.mod.action_delete": "Delete message",
    "extensions.mod.action_timeout": "Timeout",
    "extensions.mod.action_warning": "Warning",
    "extensions.mod.action_what_happens": "What happens",
    "extensions.mod.echo_reason": "Echo reason in chat",
    "extensions.mod.escalation_add_step": "Add step",
    "extensions.mod.escalation_hint": "The last step applies to every further violation.",
    "extensions.mod.escalation_title": "Escalation",
    "extensions.mod.reason_label": "Reason",
    "extensions.mod.strike_window_help": "How long a strike counts toward escalating to the next step.",
    "extensions.mod.timeout_duration": "Timeout duration (s)",
    "extensions.mod.violation_nth": "Violation :n",
    "expired": "expired",
    "founder": "founder",
    "global": "global",
    "graph #:id": "graph #:id",
    "graphs.usage_count": "{0} Not used in any graph|[1,1] Used in :count graph|[2,*] Used in :count graphs",
    "linked": "linked",
    "managed": "managed",
    "more": "more",
    "next:": "next:",
    "no cooldown": "no cooldown",
    "nodes": "nodes",
    "none": "none",
    "not registered": "not registered",
    "or drop files here": "or drop files here",
    "owned": "owned",
    "per user": "per user",
    "permissions": "permissions",
    "property": "property",
    "real-run": "real-run",
    "reset": "reset",
    "scopes": "scopes",
    "t+ms": "t+ms",
    "trace entries": "trace entries",
    "trigger off": "trigger off",
    "users": "users",
    "via Import-Link": "via Import-Link",
    "with care by Xeras": "with care by Xeras",
    "word boundary": "word boundary",
    "— pick a command —": "– pick a command –",
    "— pick a keyword —": "– pick a keyword –",
    "— pick a trigger —": "– pick a trigger –",
    "— pick an event —": "– pick an event –",
    "— select —": "– select –",
    "— standalone command —": "– standalone command –",
    "extensions.loyalty.import.error_active": "An import is already in progress for this property. Apply or discard it first.",
    "extensions.loyalty.import.error_not_staged": "This import is not ready to apply.",
    "extensions.loyalty.import.title": "Import / Migration",
    "extensions.loyalty.import.description": "Import viewer points and watchtime from another bot's export. Logins are matched to Twitch accounts; unmatched and bot rows are skipped.",
    "extensions.loyalty.import.source_format": "Source",
    "extensions.loyalty.import.file": "Export file (CSV)",
    "extensions.loyalty.import.min_points": "Minimum points",
    "extensions.loyalty.import.min_hours": "Minimum hours",
    "extensions.loyalty.import.run": "Start import",
    "extensions.loyalty.import.apply": "Apply",
    "extensions.loyalty.import.discard": "Discard",
    "extensions.loyalty.import.working": "Working …",
    "extensions.loyalty.import.uploading": "Uploading …",
    "extensions.loyalty.import.parsed": "Rows parsed",
    "extensions.loyalty.import.resolved": "Matched",
    "extensions.loyalty.import.bots": "Bots skipped",
    "extensions.loyalty.import.unresolved": "Not matched",
    "extensions.loyalty.import.will_import": "Will import",
    "extensions.loyalty.import.unresolved_list": "Show unmatched logins",
    "extensions.loyalty.import.confirm_apply": "This overwrites existing balances for :count viewers. Continue?",
    "extensions.loyalty.import.applied": "Import applied: :count viewers updated.",
    "extensions.loyalty.import.failed": "Import failed.",
    "extensions.loyalty.milestones_placeholder": "e.g. 1000",
    "extensions.loyalty.var_balance": "Balance",
    "extensions.loyalty.var_watchtime": "Watchtime",
    "extensions.loyalty.var_rank": "Rank",
    "extensions.loyalty.var_chat_messages": "Chat Messages",
    "extensions.loyalty.var_chat_words": "Chat Words",
    "extensions.loyalty.var_chat_emotes": "Chat Emotes",
    "extensions.loyalty.var_currency_name": "Currency Name",
    "extensions.loyalty.var_currency_icon": "Currency Icon",
    "extensions.loyalty.hide_bots": "Hide bots",
    "extensions.quotes.flash.created": "Quote #:n created.",
    "extensions.quotes.flash.updated": "Quote #:n updated.",
    "extensions.quotes.form.add_title": "Add quote",
    "extensions.quotes.form.category_help": "Optional. Searched from Twitch categories.",
    "extensions.quotes.form.category_label": "Category",
    "extensions.quotes.form.date_label": "Date",
    "extensions.quotes.form.edit_title": "Edit quote #:n",
    "extensions.quotes.form.save": "Save",
    "extensions.quotes.form.text_label": "Text",
    "extensions.quotes.index.add": "Add quote",
    "extensions.quotes.index.edit": "Edit",
    "extensions.quotes.index.edit_aria": "Edit quote #:n",
    "extensions.quotes.index.empty": "No quotes yet. Add one with “Add quote”, or let mods capture them in chat.",
    "extensions.quotes.delete_confirm_title": "Delete quote #:n?",
    "extensions.quotes.delete_confirm_message": "This cannot be undone. The number stays retired and won't be reused.",
    "extensions.quotes.no_match": "No quotes match your filter.",
    "extensions.quotes.filter_placeholder": "Filter by number, text, or category…",
    "extensions.timers.rotation.mode_single": "Single",
    "extensions.timers.rotation.mode_rotation": "Rotation",
    "extensions.timers.rotation.add_entry": "Rotation entry",
    "extensions.timers.rotation.entry_default_name": "Rotation :n",
    "extensions.timers.rotation.entries_count": ":n of :max",
    "extensions.timers.rotation.switch_back_blocked": "Switching back to Single needs exactly one rotation entry. Delete the other entries first.",
    "extensions.timers.rotation.delete_entry_title": "Delete rotation entry :name?",
    "extensions.timers.rotation.delete_entry_message": "Its attached actions drop with it on save.",
    "extensions.timers.rotation.delete_entry_confirm": "Delete entry",
    "extensions.timers.rotation.linked_graphs_note": "Linked graphs keep running on every interval, independent of the rotation.",
    "extensions.timers.rotation.mode_label": "Mode",
    "extensions.timers.rotation.list_badge": "Rotation · :n",
    "extensions.timers.meta_uses": ":count fires (7d)",
    "extensions.timers.meta_last_used": "last fired :time",
    "extensions.timers.meta_never_used": "never fired",
    "extensions.timers.delete_confirm_title": "Delete timer :name?",
    "extensions.timers.delete_confirm_message": "The schedule and any auto-generated chat reply graph drop with it.",
    "extensions.timers.no_match": "No timers match your filter.",
    "extensions.timers.toggle_enabled_aria": "Toggle timer :name",
    "extensions.timers.mode.label": "Timer type",
    "extensions.timers.mode.interval": "Recurring",
    "extensions.timers.mode.oneshot": "Countdown (one time)",
    "extensions.timers.oneshot.duration_label": "Duration (seconds)",
    "extensions.timers.oneshot.duration_help": "Length of the countdown. Start, pause, resume, stop and reset it from your flows with the Timer actions.",
    "extensions.timers.oneshot.chip": "Countdown",
    "graphs.format.duration.name": "Duration",
    "graphs.format.duration.preset.compact": "Compact (3h 24m)",
    "graphs.format.duration.preset.long": "Long (3 hours 24 minutes)",
    "graphs.format.duration.preset.clock": "Clock (1:23:45)",
    "graphs.format.date.name": "Date",
    "graphs.format.date.preset.short": "Short date (30.05.2026)",
    "graphs.format.date.preset.long": "Long date (30 May 2026)",
    "graphs.format.date.preset.datetime": "Date and time (UTC)",
    "graphs.format.date.preset.relative": "Relative (3 days ago)",
    "graphs.format.date.preset.elapsed": "Elapsed (4 weeks)",
    "graphs.format.date.input.auto": "Auto detect",
    "graphs.format.date.input.iso": "ISO 8601 string",
    "graphs.format.date.input.unix_s": "Unix timestamp (seconds)",
    "graphs.format.date.input.unix_ms": "Unix timestamp (milliseconds)",
    "graphs.format.formatter_label": "Format",
    "graphs.format.preset_label": "Preset",
    "graphs.format.input_label": "Input value",
    "graphs.format.none": "None",
    "graphs.format.raw": "Raw",
    "graphs.format.preview_label": "Preview",
    "connections.surface.title": "Sender & Connections",
    "connections.surface.subtitle": "Who writes to and moderates your channel.",
    "connections.surface.card_label": "Sender & Connections",
    "connections.surface.card_description": "Choose who Streambridge talks to chat as: your account, the shared Cloud Bot, or your own bot.",
    "connections.banner.title": "No chat-capable account connected yet",
    "connections.banner.body": "Streambridge needs a sender before it can write to your chat. Easiest: the shared Streambridge Cloud Bot, you just give it /mod.",
    "connections.banner.cta_cloud": "Use the Streambridge Cloud Bot",
    "connections.banner.manage": "or manage your connections here",
    "connections.banner.owner_hint": "Only the property owner can set this up, please ask them.",
    "connections.own.title": "Your account",
    "connections.own.emote_hint": "sends with your own emotes",
    "connections.own.grant": "Grant permissions",
    "connections.own.grant_chat": "Chat",
    "connections.own.grant_moderation": "Moderation",
    "connections.own.grant_broadcaster": "Broadcaster (title, category, ads)",
    "connections.cloud.title": "Streambridge Cloud Bot",
    "connections.cloud.subtitle": "shared bot, no permissions of your own needed",
    "connections.cloud.use": "Use Cloud Bot",
    "connections.cloud.mod_command_help": "in your chat, then check the status.",
    "connections.cloud.mod_copy": "Copy command",
    "connections.cloud.mod_copied": "Copied!",
    "connections.cloud.mod_check": "Check /mod status",
    "connections.cloud.not_provisioned": "The Cloud Bot is not available on this server yet.",
    "connections.cloud.stop": "Stop using",
    "connections.custom.title": "Your own bot",
    "connections.custom.empty": "Link your own bot account through a one-time link.",
    "connections.custom.add": "Add custom bot",
    "connections.custom.unlink": "Unlink",
    "connections.custom.linked_at": "linked :date",
    "connections.custom.pending": "Open this link in a browser signed in as the bot account:",
    "connections.active.badge": "active sender",
    "connections.active.set": "Set as active sender",
    "connections.class.chat": "Chat",
    "connections.class.moderation": "Moderation",
    "connections.class.broadcaster": "Broadcaster",
    "connections.class.ok": "ready",
    "connections.class.needs_mod": "needs /mod",
    "connections.class.needs_grant": "needs permission",
    "connections.operator.heading": "Streambridge Cloud Bot",
    "connections.operator.subtitle": "Connect and monitor the shared bot account.",
    "connections.operator.not_configured_title": "Not connected yet",
    "connections.operator.not_configured_body": "Set the bot's Twitch id in the environment, generate a connect link, then open it in a browser signed in as the bot account.",
    "connections.operator.redirect_missing": "The cloud-bot redirect URL is not configured on this server.",
    "connections.operator.generate": "Generate connect link",
    "connections.operator.reconnect": "Reconnect",
    "connections.operator.link_hint": "Open this link in a browser signed in as the bot account:",
    "connections.operator.copy": "Copy link",
    "connections.operator.copied": "Copied",
    "connections.operator.status_account": "Account",
    "connections.operator.status_scopes": "Permissions",
    "connections.operator.status_expiry": "Token expires",
    "connections.operator.status_refreshed": "Last refreshed",
    "connections.operator.status_enrolled": "Enrolled properties",
    "connections.operator.configured_id": "Configured Twitch id",
    "connections.operator.never": "never",
    "connections.operator.verify.eyebrow": "Confirm before continuing",
    "connections.operator.verify.headline": "Connect this account as the Streambridge Cloud Bot?",
    "connections.operator.verify.body": "You are about to connect your currently signed-in Twitch account as the global Streambridge Cloud Bot.",
    "connections.operator.verify.scopes_label": "Permissions Twitch will request",
    "connections.operator.verify.warn": "Only continue if this browser is signed in as the dedicated Streambridge bot account. If not, close this tab.",
    "connections.operator.verify.continue": "Continue with Twitch",
    "connections.operator.verify.cancel": "Cancel",
    "connections.operator.verify.close": "Close window",
    "connections.operator.verify.linked": "Connected",
    "connections.operator.verify.not_linked": "Not connected",
    "connections.operator.verify.result.success_title": "Cloud Bot connected",
    "connections.operator.verify.result.success_body": "The Streambridge Cloud Bot is now connected. You can close this window.",
    "connections.operator.verify.result.wrong_account_title": "Wrong account",
    "connections.operator.verify.result.wrong_account_body": "This Twitch account is not the configured Cloud Bot. Sign in as the correct bot account and try again.",
    "connections.operator.verify.result.not_found_title": "Link not found",
    "connections.operator.verify.result.not_found_body": "The connect link is invalid.",
    "connections.operator.verify.result.expired_title": "Link expired",
    "connections.operator.verify.result.expired_body": "This link expired. Generate a new one from the admin area.",
    "connections.operator.verify.result.consumed_title": "Link already used",
    "connections.operator.verify.result.consumed_body": "This link has already been used.",
    "connections.operator.verify.result.token_exchange_failed_title": "Twitch authorization failed",
    "connections.operator.verify.result.token_exchange_failed_body": "Twitch rejected the authorization. Please try again.",
    "connections.operator.verify.result.identity_lookup_failed_title": "Could not identify the Twitch account",
    "connections.operator.verify.result.identity_lookup_failed_body": "We could not read the Twitch account that just authorized. Please try again.",
    "connections.operator.verify.result.scopes_missing_title": "Missing permissions",
    "connections.operator.verify.result.scopes_missing_body": "Not all required permissions were granted. Please re-authorize and allow everything.",
    "connections.operator.verify.result.config_error_title": "Server misconfigured",
    "connections.operator.verify.result.config_error_body": "The cloud-bot connect flow is not fully configured on this server.",
    "connections.operator.verify.result.missing_params_title": "Authorization incomplete",
    "connections.operator.verify.result.missing_params_body": "Twitch returned without the expected parameters. Try the link again.",
    "connections.operator.verify.result.default_title": "Verification failed",
    "connections.operator.verify.result.default_body": "Something went wrong.",
    "onboarding.title": "Welcome to :app",
    "onboarding.fork.heading": "How do you want to set up your channel?",
    "onboarding.fork.fast_title": "Set me up with everything",
    "onboarding.fork.fast_description": "Install every feature and grant the permissions in one step. You can fine-tune everything later.",
    "onboarding.fork.fast_button": "Set me up",
    "onboarding.fork.guided_title": "Customize",
    "onboarding.fork.guided_description": "Pick exactly the features and events you want. Nothing is selected by default.",
    "onboarding.fork.guided_button": "Customize",
    "onboarding.step.chat_title": "Chat & Channel",
    "onboarding.step.events_title": "Channel events",
    "onboarding.step.summary_title": "Review & finish",
    "onboarding.group.chat_interactions": "Chat interactions",
    "onboarding.group.chat_moderation": "Chat moderation",
    "onboarding.group.channel_updates": "Channel updates",
    "onboarding.group.sender_account": "Sender account",
    "onboarding.item.channel_title_category": "Let automations change your stream title and category",
    "onboarding.events.intro": "Pick the channel events you want :app to track. Tracked events appear in your activity feed and can trigger automations.",
    "onboarding.summary.extensions": "Features to install",
    "onboarding.summary.events": "Events to track",
    "onboarding.summary.permissions": "Permissions we will request",
    "onboarding.summary.events_home_note": "The Events feature will also be installed so you can connect actions to these events.",
    "onboarding.action.next": "Next",
    "onboarding.action.back": "Back",
    "onboarding.action.skip": "Skip for now",
    "onboarding.action.finish": "Finish",
    "onboarding.action.run_again": "Run setup again",
    "onboarding.scope.user_read_chat": "Read your chat",
    "onboarding.scope.user_write_chat": "Send messages in your chat",
    "onboarding.scope.moderator_read_chatters": "See who is currently in your chat",
    "onboarding.scope.moderator_read_followers": "See who follows your channel",
    "onboarding.scope.channel_read_subscriptions": "See who subscribes to your channel",
    "onboarding.scope.bits_read": "See Bits cheered in your channel",
    "onboarding.scope.channel_manage_broadcast": "Change your stream title and category",
    "onboarding.scope.channel_read_redemptions": "See channel point redemptions",
    "onboarding.scope.channel_manage_redemptions": "Manage your channel point rewards",
    "onboarding.scope.moderator_manage_moderation": "Moderate your chat (timeouts, bans, chat settings)",
    "onboarding.fork.eyebrow": "Welcome to :app",
    "onboarding.fork.subtitle": "You can change anything later, nothing here is permanent.",
    "onboarding.fork.recommended": "Recommended",
    "onboarding.step.indicator": "Step :index of :total",
    "onboarding.step.chat_subtitle": "Choose the features you want. You can turn any of these on or off later in Settings.",
    "onboarding.group.selected": ":count selected",
    "onboarding.feature.commands": "Let viewers trigger replies and actions by typing ! commands in chat.",
    "onboarding.feature.keywords": "Reply automatically when chat mentions certain words, no ! needed.",
    "onboarding.feature.timers": "Post recurring messages on a schedule, only when chat is active.",
    "onboarding.feature.loyalty": "Reward regulars with points, and track watch time and viewer groups.",
    "onboarding.feature.mod": "Auto-moderate caps, spam, links and more, with your own rules and warnings.",
    "onboarding.event.follow": "When someone follows your channel.",
    "onboarding.event.subscribe": "When someone subscribes for the first time, or gets a gift sub.",
    "onboarding.event.subscription_message": "When a returning sub shares their resub message, with streak and months.",
    "onboarding.event.subscription_gift": "When someone gifts subscriptions to your community.",
    "onboarding.event.cheer": "When a viewer cheers with Bits in chat.",
    "onboarding.event.raid": "When another channel raids you with their viewers.",
    "onboarding.sender.title": "Add the bot to your chat",
    "onboarding.sender.optional": "Optional",
    "onboarding.sender.description": "To post in chat, :app uses a sending account. Paste this once in your chat to make it a moderator, you can do it now or any time later.",
    "onboarding.summary.intro": "Here is what we will set up. You will approve the permissions on Twitch in the next step.",
    "onboarding.summary.empty_title": "Nothing selected yet",
    "onboarding.summary.empty_desc": "Go back to pick features and events, or skip for now and set things up any time from Settings.",
    "onboarding.summary.trust": "We only ask for what your choices need. You will approve everything on Twitch in the next step, and you can change or revoke access any time.",
    "onboarding.success.title": "You're all set",
    "onboarding.success.description": ":app is connected and ready. Everything below is now live on your channel.",
    "onboarding.success.nothing": "Nothing installed yet, you can set things up any time from Settings.",
    "onboarding.success.features": "Features",
    "onboarding.success.events": "Events",
    "onboarding.success.open_dashboard": "Open dashboard",
    "dashboard.greeting": "Welcome back, :name",
    "dashboard.add_panel": "Add panel",
    "dashboard.edit.customize": "Customize",
    "dashboard.edit.done": "Done",
    "dashboard.empty.message": "Your dashboard is empty. Add your first panel.",
    "dashboard.empty.cta": "Add first panel",
    "dashboard.palette.title": "Add panel",
    "dashboard.palette.hint": "Click a card to add it to your dashboard.",
    "dashboard.activity_feed.title": "Activity",
    "dashboard.activity_feed.description": "Live events from your channel.",
    "dashboard.activity_feed.empty": "Your selected events show up here as they arrive.",
    "dashboard.activity_feed.field_title": "Title",
    "dashboard.activity_feed.field_events": "Events",
    "dashboard.activity_feed.field_limit": "Count",
    "dashboard.top_commands.title": "Top Commands",
    "dashboard.top_commands.description": "Your most-used commands over the last 7 days.",
    "dashboard.top_commands.field_title": "Title",
    "dashboard.top_commands.field_limit": "Count",
    "dashboard.top_commands.empty": "No command usage in the last 7 days yet.",
    "dashboard.top_commands.hint": "7 days",
    "dashboard.panel.settings": "Settings",
    "dashboard.panel.remove": "Remove",
    "dashboard.panel.refresh_failed": "Couldn't refresh",
    "dashboard.size.s": "S",
    "dashboard.size.m": "M",
    "dashboard.size.l": "L",
    "dashboard.size.full": "Full",
    "dashboard.feed.follow": "followed the channel",
    "dashboard.feed.sub_new": "subscribed",
    "dashboard.feed.sub_resub": "resubscribed · :n months",
    "dashboard.feed.gift": "gifted :n subs",
    "dashboard.feed.bits": "cheered :n bits",
    "dashboard.feed.raid": "raided with :n viewers",
    "dashboard.feed.shoutout": "received a shoutout",
    "dashboard.feed.live": "is now live",
    "dashboard.feed.update": "updated the channel info",
    "dashboard.feed.replay": "Show again",
    "dashboard.feed_chip.follow": "follow",
    "dashboard.feed_chip.sub": "sub",
    "dashboard.feed_chip.gift": "gift",
    "dashboard.feed_chip.bits": "bits",
    "dashboard.feed_chip.raid": "raid",
    "dashboard.feed_chip.shoutout": "shoutout",
    "dashboard.feed_chip.live": "live",
    "dashboard.feed_chip.update": "update",
    "dashboard.feed_time.just_now": "just now",
    "dashboard.feed_time.seconds": ":n s ago",
    "dashboard.feed_time.minutes": ":n min ago",
    "dashboard.feed_time.hours": ":n h ago",
    "dashboard.feed_time.days": ":n d ago",
    "dashboard.category.follow": "Follow",
    "dashboard.category.sub": "Sub",
    "dashboard.category.gifted_sub": "Gifted Sub",
    "dashboard.category.bits": "Bits",
    "dashboard.category.raid": "Raid",
    "dashboard.category.stream_start": "Stream start",
    "dashboard.category.channel_update": "Channel update",
    "dashboard.category.shoutout_recv": "Shoutout received",
    "dashboard.error.unknown_panel": "Unknown panel type.",
    "dashboard.error.invalid_settings": "Invalid panel settings.",
    "dashboard.metric.calls_today": "Calls today",
    "dashboard.metric.active_commands": "Active commands",
    "dashboard.metric.followers_today": "Followers today",
    "dashboard.metric.subs_today": "Subs today",
    "dashboard.stat.delta_vs_yesterday": ":pct % vs. yesterday",
    "dashboard.stat.paused": ":n paused",
    "dashboard.stat_tile.title": "Stat tile",
    "dashboard.stat_tile.description": "A single metric as a tile.",
    "dashboard.stat_tile.field_title": "Title",
    "dashboard.stat_tile.field_metric": "Metric",
    "dashboard.quick_actions.title": "Quick actions",
    "dashboard.quick_actions.description": "Shortcuts to the most common actions.",
    "dashboard.quick_actions.field_title": "Title",
    "dashboard.quick.new_command": "New command",
    "dashboard.quick.new_flow": "New flow",
    "dashboard.quick.upload_media": "Upload media",
    "dashboard.alert_queue.title": "Alert Queue",
    "dashboard.alert_queue.description": "Watch and moderate upcoming alerts.",
    "dashboard.alert_queue.field_title": "Title",
    "dashboard.alert_queue.paused": "Paused",
    "dashboard.alert_queue.dropped": ":n dropped",
    "dashboard.alert_queue.empty": "No alerts waiting.",
    "dashboard.alert_queue.idle": "Idle",
    "dashboard.alert_queue.waiting": ":n waiting",
    "dashboard.alert_queue.skip": "Skip",
    "dashboard.alert_queue.replay_unavailable": "This entry cannot be shown again.",
    "dashboard.roles.delete_confirm_message": "Members lose the permissions granted by this role.",
    "dashboard.roles.delete_confirm_title": "Delete role :name?",
    "dashboard.roles.edit_aria": "Edit role :name",
    "ui.audience.question": "Who may trigger this?",
    "ui.audience.all": "Everyone",
    "ui.audience.moderators": "Moderators",
    "ui.audience.vips": "VIPs",
    "ui.audience.subscribers": "Subscribers",
    "ui.audience.help_all": "“Everyone” selected: any viewer can trigger it. Deselect groups to restrict.",
    "ui.audience.or_hint": "Matches are OR-combined",
    "ui.audience.specific_label": "Additionally allow specific viewers",
    "ui.audience.specific_search": "Search by Twitch user login…",
    "graphs.node.trigger_twitch_follow_label": "New Follower",
    "graphs.node.trigger_twitch_follow_desc": "Triggered when someone follows the channel.",
    "graphs.node.trigger_twitch_watch_streak_label": "Watch Streak",
    "graphs.node.trigger_twitch_watch_streak_desc": "Triggered when a viewer shares a watch streak: they have watched several consecutive streams. Twitch delivers it when the viewer chooses to share it in chat, so it does not fire automatically for every viewer.",
    "graphs.node.trigger_twitch_first_appearance_label": "First Appearance",
    "graphs.node.trigger_twitch_first_appearance_desc": "Fires once per viewer per live stream the first time they are active in chat - their first message, or their own sub/resub if that comes first.",
    "graphs.node.trigger_twitch_subscribe_label": "New Subscriber",
    "graphs.node.trigger_twitch_subscribe_desc": "Fires when a viewer subscribes for the first time, or receives a gift sub.",
    "graphs.node.trigger_twitch_subscription_gift_label": "Gift Subscription",
    "graphs.node.trigger_twitch_subscription_gift_desc": "Fires when a user gifts subscriptions - once per batch.",
    "graphs.node.trigger_twitch_cheer_label": "Cheer",
    "graphs.node.trigger_twitch_cheer_desc": "Fires when a viewer cheers with Bits in chat.",
    "graphs.node.trigger_twitch_raid_label": "Incoming Raid",
    "graphs.node.trigger_twitch_raid_desc": "Fires when another channel raids this one.",
    "graphs.group.audience_growth": "Audience growth",
    "graphs.group.engagement": "Engagement",
    "graphs.group.support": "Support",
    "graphs.group.follower": "Follower",
    "graphs.group.viewer": "Viewer",
    "graphs.group.watch_streak": "Watch Streak",
    "graphs.group.first_appearance": "First Appearance",
    "graphs.group.subscriber": "Subscriber",
    "graphs.group.subscription": "Subscription",
    "graphs.group.cheerer": "Cheerer",
    "graphs.group.cheer": "Cheer",
    "graphs.group.raider": "Raider",
    "graphs.group.raid": "Raid",
    "graphs.exec.success": "Success",
    "graphs.port.user_id": "User ID",
    "graphs.port.user_login": "User Login",
    "graphs.port.user_display_name": "User Display Name",
    "graphs.port.user_channel": "User Channel",
    "graphs.port.followed_at": "Followed At",
    "graphs.port.streak_count": "Streak Count",
    "graphs.port.channel_points_awarded": "Channel Points Awarded",
    "graphs.port.kind": "Kind",
    "graphs.port.message": "Message",
    "graphs.port.resub_message": "Resub Message",
    "graphs.port.message_id": "Message ID",
    "graphs.port.message_text": "Message Text",
    "graphs.port.is_mod": "Is Mod",
    "graphs.port.is_subscriber": "Is Subscriber",
    "graphs.port.tier": "Tier",
    "graphs.port.is_gift": "Is Gift",
    "graphs.port.gifter_id": "Gifter ID",
    "graphs.port.gifter_login": "Gifter Login",
    "graphs.port.gifter_display_name": "Gifter Display Name",
    "graphs.port.gifted_this_run": "Gifted (this run)",
    "graphs.port.lifetime_total": "Lifetime Total",
    "graphs.port.is_anonymous": "Is Anonymous",
    "graphs.port.anonymous": "Anonymous",
    "graphs.port.bits": "Bits",
    "graphs.port.raider_id": "Raider ID",
    "graphs.port.raider_login": "Raider Login",
    "graphs.port.raider_display_name": "Raider Display Name",
    "graphs.port.raider_category": "Raider Category",
    "graphs.port.raider_title": "Raider Title",
    "graphs.port.viewers": "Viewers",
    "graphs.exec.blocked": "Blocked",
    "graphs.group.chatter": "Chatter",
    "graphs.group.message": "Message",
    "graphs.group.command": "Command",
    "graphs.group.target": "Target",
    "graphs.port.user_color": "User Color",
    "graphs.port.message_type": "Message Type",
    "graphs.port.badges": "Badges",
    "graphs.port.reply_to": "Reply To",
    "graphs.port.cheered_bits": "Cheered Bits",
    "graphs.port.is_channel_bot": "Is Channel Bot",
    "graphs.port.shared_chat_active": "Shared Chat: Active",
    "graphs.port.shared_chat_from_own_channel": "Shared Chat: From My Channel",
    "graphs.port.shared_chat_source_user_id": "Shared Chat: Source User ID",
    "graphs.port.shared_chat_source_user_login": "Shared Chat: Source User Login",
    "graphs.port.shared_chat_source_user_display_name": "Shared Chat: Source User Display Name",
    "graphs.port.command": "Command",
    "graphs.port.args": "Args",
    "graphs.port.args_text": "Args Text",
    "graphs.port.command_trigger": "Command Trigger",
    "graphs.port.command_args": "Command Args",
    "graphs.port.raw_message": "Raw Message",
    "graphs.port.target_id": "Target ID",
    "graphs.port.target_login": "Target Login",
    "graphs.port.target_display_name": "Target Display Name",
    "graphs.port.target_category": "Target Category",
    "graphs.port.target_stream_title": "Target Stream Title",
    "graphs.port.phrase": "Phrase",
    "graphs.port.match": "Match",
    "graphs.port.matched_phrase": "Matched Phrase",
    "graphs.port.title": "Title",
    "graphs.port.language": "Language",
    "graphs.port.category_id": "Category ID",
    "graphs.port.category_name": "Category Name",
    "graphs.port.content_classification_labels": "Content Classification Labels",
    "graphs.port.previous_title": "Previous Title",
    "graphs.port.previous_category_id": "Previous Category ID",
    "graphs.port.previous_category_name": "Previous Category Name",
    "graphs.option.trigger_anytime": "Trigger anytime",
    "graphs.option.only_while_live": "Only while live",
    "graphs.option.only_while_offline": "Only while offline",
    "graphs.param.audience": "Audience",
    "graphs.param.global_cooldown_seconds": "Global cooldown (s)",
    "graphs.param.user_cooldown_seconds": "Per-user cooldown (s)",
    "graphs.param.stream_state": "Stream state",
    "graphs.param.ignore_bots": "Ignore Bot Messages",
    "graphs.param.ignore_bots_help": "Skip messages from connected bot accounts. Self-emitted echoes from action.chat.send are always dropped earlier; this controls whether other bots in the channel fire this trigger.",
    "graphs.param.command_ref": "Command",
    "graphs.param.keyword_ref": "Keyword",
    "graphs.node.trigger_twitch_chat_message_label": "Chat Message",
    "graphs.node.trigger_twitch_chat_message_desc": "Every chat message, no filter. Heavy traffic; prefer Command or Keyword triggers unless you really need it all.",
    "graphs.node.trigger_twitch_chat_command_label": "Chat Command",
    "graphs.node.trigger_twitch_chat_command_desc": "Fires when a configured !command is typed in chat. Audience, cooldown, and stream-state rules are managed on the command itself.",
    "graphs.node.trigger_twitch_chat_keyword_label": "Chat Keyword",
    "graphs.node.trigger_twitch_chat_keyword_desc": "Fires when a configured phrase shows up in chat. Audience, cooldown, and stream-state rules are managed on the keyword itself.",
    "graphs.node.trigger_twitch_update_label": "Channel Update",
    "graphs.node.trigger_twitch_update_desc": "Fires when the broadcaster changes title, category, language, or content classification.",
    "graphs.node.trigger_twitch_update_title_label": "Channel Update Title",
    "graphs.node.trigger_twitch_update_title_desc": "Fires only when the broadcaster changes the stream title.",
    "graphs.node.trigger_twitch_update_category_label": "Channel Update Category",
    "graphs.node.trigger_twitch_update_category_desc": "Fires only when the broadcaster changes the stream category (game).",
    "graphs.node.trigger_twitch_ban_label": "Ban / Timeout",
    "graphs.node.trigger_twitch_ban_desc": "Fires when a viewer is banned or timed out.",
    "graphs.node.trigger_twitch_unban_label": "Unban",
    "graphs.node.trigger_twitch_unban_desc": "Fires when a banned viewer is unbanned.",
    "graphs.node.trigger_twitch_moderate_label": "Moderation Action",
    "graphs.node.trigger_twitch_moderate_desc": "Fires for every moderator action (ban/timeout/delete/mode toggles/warn/etc.). Discriminate via the action field.",
    "graphs.node.trigger_twitch_moderator_add_label": "Moderator Added",
    "graphs.node.trigger_twitch_moderator_add_desc": "Fires when a user is given moderator privileges.",
    "graphs.node.trigger_twitch_moderator_remove_label": "Moderator Removed",
    "graphs.node.trigger_twitch_moderator_remove_desc": "Fires when a user has moderator privileges removed.",
    "graphs.node.trigger_twitch_vip_add_label": "VIP Added",
    "graphs.node.trigger_twitch_vip_add_desc": "Fires when a user is given VIP status.",
    "graphs.node.trigger_twitch_vip_remove_label": "VIP Removed",
    "graphs.node.trigger_twitch_vip_remove_desc": "Fires when a user has VIP status removed.",
    "graphs.node.trigger_twitch_shield_mode_begin_label": "Shield Mode Begin",
    "graphs.node.trigger_twitch_shield_mode_begin_desc": "Fires when Shield Mode is activated.",
    "graphs.node.trigger_twitch_shield_mode_end_label": "Shield Mode End",
    "graphs.node.trigger_twitch_shield_mode_end_desc": "Fires when Shield Mode is deactivated.",
    "graphs.node.trigger_twitch_warning_send_label": "Warning Sent",
    "graphs.node.trigger_twitch_warning_send_desc": "Fires when a moderator sends a warning to a user.",
    "graphs.node.trigger_twitch_warning_acknowledge_label": "Warning Acknowledged",
    "graphs.node.trigger_twitch_warning_acknowledge_desc": "Fires when a user acknowledges a pending warning.",
    "graphs.node.trigger_twitch_unban_request_create_label": "Unban Request Created",
    "graphs.node.trigger_twitch_unban_request_create_desc": "Fires when a banned viewer submits an unban request.",
    "graphs.node.trigger_twitch_unban_request_resolve_label": "Unban Request Resolved",
    "graphs.node.trigger_twitch_unban_request_resolve_desc": "Fires when a moderator approves, denies, or cancels an unban request. For moderator info on the approve path, prefer the Unban trigger, it fires right after and uses the standard moderator_user_* field naming.",
    "graphs.node.trigger_twitch_suspicious_user_message_label": "Suspicious User Message",
    "graphs.node.trigger_twitch_suspicious_user_message_desc": "Fires when a flagged or restricted user sends a chat message.",
    "graphs.node.trigger_twitch_suspicious_user_update_label": "Suspicious User Updated",
    "graphs.node.trigger_twitch_suspicious_user_update_desc": "Fires when a moderator changes a viewer's trust status.",
    "graphs.node.trigger_twitch_chat_settings_update_label": "Chat Settings Update",
    "graphs.node.trigger_twitch_chat_settings_update_desc": "Fires when chat mode toggles change.",
    "graphs.port.moderator_id": "Moderator ID",
    "graphs.port.moderator_login": "Moderator Login",
    "graphs.port.moderator_display_name": "Moderator Display Name",
    "graphs.port.reason": "Reason",
    "graphs.port.banned_at": "Banned At",
    "graphs.port.ends_at": "Ends At",
    "graphs.port.is_permanent": "Is Permanent",
    "graphs.port.action": "Action",
    "graphs.port.started_at": "Started At",
    "graphs.port.ended_at": "Ended At",
    "graphs.port.rules_cited": "Rules Cited",
    "graphs.port.request_id": "Request ID",
    "graphs.port.request_text": "Request Text",
    "graphs.port.created_at": "Created At",
    "graphs.port.resolution_text": "Resolution Text",
    "graphs.port.status": "Status",
    "graphs.port.trust_status": "Trust Status",
    "graphs.port.shared_ban_chans": "Shared Ban Chans",
    "graphs.port.flag_types": "Flag Types",
    "graphs.port.ban_evasion": "Ban Evasion",
    "graphs.port.emote_only": "Emote-Only",
    "graphs.port.follower_only": "Follower-Only",
    "graphs.port.follower_duration": "Follower Duration",
    "graphs.port.slow_mode": "Slow Mode",
    "graphs.port.slow_wait_s": "Slow Wait (s)",
    "graphs.port.sub_only": "Sub-Only",
    "graphs.port.unique_chat": "Unique Chat",
    "graphs.node.trigger_twitch_stream_online_label": "Stream Online",
    "graphs.node.trigger_twitch_stream_online_desc": "Triggered when the channel goes live.",
    "graphs.node.trigger_twitch_stream_offline_label": "Stream Offline",
    "graphs.node.trigger_twitch_stream_offline_desc": "Triggered when the channel goes offline.",
    "graphs.node.trigger_twitch_chat_clear_label": "Chat Cleared",
    "graphs.node.trigger_twitch_chat_clear_desc": "Fires when a moderator clears all chat messages.",
    "graphs.node.trigger_twitch_chat_clear_user_messages_label": "Cleared User Messages",
    "graphs.node.trigger_twitch_chat_clear_user_messages_desc": "Fires when all messages from a specific user are removed from chat.",
    "graphs.node.trigger_twitch_chat_message_delete_label": "Chat Message Deleted",
    "graphs.node.trigger_twitch_chat_message_delete_desc": "Fires when a moderator deletes a single chat message.",
    "graphs.node.trigger_twitch_chat_notification_label": "Chat Notification",
    "graphs.node.trigger_twitch_chat_notification_desc": "System notification line: sub announcements, raids, gifts, charity receipts.",
    "graphs.node.trigger_twitch_chat_user_message_hold_label": "My Message Held",
    "graphs.node.trigger_twitch_chat_user_message_hold_desc": "Fires when AutoMod holds the user's own message.",
    "graphs.node.trigger_twitch_chat_user_message_update_label": "My AutoMod Message Updated",
    "graphs.node.trigger_twitch_chat_user_message_update_desc": "Fires when the user's held message is approved, denied, or expires.",
    "graphs.node.trigger_twitch_automod_message_hold_label": "AutoMod Hold",
    "graphs.node.trigger_twitch_automod_message_hold_desc": "Fires when AutoMod holds a chat message for moderator review.",
    "graphs.node.trigger_twitch_automod_message_update_label": "AutoMod Message Updated",
    "graphs.node.trigger_twitch_automod_message_update_desc": "Fires when an AutoMod-held message is approved, denied, or expires.",
    "graphs.node.trigger_twitch_automod_settings_update_label": "AutoMod Settings Update",
    "graphs.node.trigger_twitch_automod_settings_update_desc": "Fires when AutoMod severity levels change.",
    "graphs.node.trigger_twitch_automod_terms_update_label": "AutoMod Terms Update",
    "graphs.node.trigger_twitch_automod_terms_update_desc": "Fires when AutoMod term lists are changed.",
    "graphs.node.trigger_twitch_user_update_label": "User Account Update",
    "graphs.node.trigger_twitch_user_update_desc": "Fires when the property owner updates their Twitch account.",
    "graphs.node.trigger_twitch_user_whisper_message_label": "Whisper Received",
    "graphs.node.trigger_twitch_user_whisper_message_desc": "Fires when the property owner receives a whisper.",
    "graphs.node.trigger_twitch_shoutout_create_label": "Shoutout Sent",
    "graphs.node.trigger_twitch_shoutout_create_desc": "Fires when this channel sends a shoutout to another broadcaster.",
    "graphs.node.trigger_twitch_shoutout_receive_label": "Shoutout Received",
    "graphs.node.trigger_twitch_shoutout_receive_desc": "Fires when another broadcaster shouts out this channel.",
    "graphs.group.stream": "Stream",
    "graphs.group.shoutout": "Shoutout",
    "graphs.group.shouter": "Shouter",
    "graphs.port.category": "Category",
    "graphs.port.notice_type": "Notice Type",
    "graphs.port.chatter_id": "Chatter ID",
    "graphs.port.chatter_login": "Chatter Login",
    "graphs.port.chatter_display_name": "Chatter Display Name",
    "graphs.port.system_message": "System Message",
    "graphs.port.held_at": "Held At",
    "graphs.port.level": "Level",
    "graphs.port.from_automod": "From AutoMod",
    "graphs.port.terms": "Terms",
    "graphs.port.description": "Description",
    "graphs.port.email_verified": "Email Verified",
    "graphs.port.whisper_id": "Whisper ID",
    "graphs.port.whisper_text": "Whisper Text",
    "graphs.port.text": "Text",
    "graphs.port.from_id": "From ID",
    "graphs.port.from_login": "From Login",
    "graphs.port.from_display_name": "From Display Name",
    "graphs.port.overall_level": "Overall",
    "graphs.port.aggression": "Aggression",
    "graphs.port.bullying": "Bullying",
    "graphs.port.disability": "Disability",
    "graphs.port.misogyny": "Misogyny",
    "graphs.port.race_ethnicity_or_religion": "Race/Religion",
    "graphs.port.sex_based_terms": "Sex Terms",
    "graphs.port.sexuality_sex_or_gender": "Sexuality",
    "graphs.port.swearing": "Swearing",
    "graphs.port.shouter_id": "Shouter ID",
    "graphs.port.shouter_login": "Shouter Login",
    "graphs.port.shouter_display_name": "Shouter Display Name",
    "graphs.port.target_viewers": "Target Viewers",
    "graphs.port.cooldown_ends_at": "Cooldown Ends At",
    "graphs.port.cooldown_remaining": "Cooldown Remaining (s)",
    "graphs.port.cooldown_scope": "Cooldown Scope",
    "graphs.port.cooldown_ends": "Cooldown Ends",
    "graphs.port.target_cooldown_ends_at": "Target Cooldown",
    "graphs.exec.triggered": "Triggered",
    "graphs.node.trigger_user_event_label": "Custom Event",
    "graphs.node.trigger_user_event_desc": "Fires when a user-defined event is emitted from another graph.",
    "graphs.node.trigger_widget_event_label": "Widget Event",
    "graphs.node.trigger_widget_event_desc": "Fires when a widget bundle calls sb.emit() on the configured key.",
    "graphs.node.trigger_twitch_ad_break_begin_label": "Ad Break Begin",
    "graphs.node.trigger_twitch_ad_break_begin_desc": "Fires when a midroll ad break starts on the channel.",
    "graphs.node.trigger_twitch_ad_break_incoming_label": "Ad Break Incoming",
    "graphs.node.trigger_twitch_ad_break_incoming_desc": "Fires N seconds before an ad break starts. Configurable lead-time per node (default 60s, range 10-600). Multiple graphs can subscribe with different lead-times - each fires at its own configured offset.",
    "graphs.node.trigger_twitch_subscription_end_label": "Subscription Ended",
    "graphs.node.trigger_twitch_subscription_end_desc": "Fires when a viewer's subscription expires.",
    "graphs.node.trigger_twitch_subscription_message_label": "Resub Message",
    "graphs.node.trigger_twitch_subscription_message_desc": "Fires when a returning subscriber posts their resub message.",
    "graphs.node.trigger_twitch_bits_use_label": "Bits Used",
    "graphs.node.trigger_twitch_bits_use_desc": "Superset of Cheer - also Power-Ups, combos, message effects.",
    "graphs.node.trigger_twitch_channel_points_reward_add_label": "Reward Added",
    "graphs.node.trigger_twitch_channel_points_reward_add_desc": "Fires when a custom channel-points reward is created.",
    "graphs.node.trigger_twitch_channel_points_reward_update_label": "Reward Updated",
    "graphs.node.trigger_twitch_channel_points_reward_update_desc": "Fires when a custom channel-points reward is updated.",
    "graphs.node.trigger_twitch_channel_points_reward_remove_label": "Reward Removed",
    "graphs.node.trigger_twitch_channel_points_reward_remove_desc": "Fires when a custom channel-points reward is deleted.",
    "graphs.node.trigger_twitch_channel_points_redemption_update_label": "Redemption Updated",
    "graphs.node.trigger_twitch_channel_points_redemption_update_desc": "Fires when a custom-reward redemption is fulfilled or canceled.",
    "graphs.node.trigger_twitch_channel_points_automatic_redemption_add_label": "Automatic Reward Redemption",
    "graphs.node.trigger_twitch_channel_points_automatic_redemption_add_desc": "Built-in rewards: highlight my message, sub-mode bypass, emote unlocks, Power-Ups.",
    "graphs.node.trigger_twitch_shared_chat_begin_label": "Shared Chat Begin",
    "graphs.node.trigger_twitch_shared_chat_begin_desc": "Fires when this channel becomes active in a shared-chat session.",
    "graphs.node.trigger_twitch_shared_chat_update_label": "Shared Chat Update",
    "graphs.node.trigger_twitch_shared_chat_update_desc": "Fires when the shared-chat session's participants change.",
    "graphs.node.trigger_twitch_shared_chat_end_label": "Shared Chat End",
    "graphs.node.trigger_twitch_shared_chat_end_desc": "Fires when this channel leaves a shared-chat session.",
    "graphs.param.lead_time_seconds": "Lead Time (seconds)",
    "graphs.param.user_event_id": "Event",
    "graphs.param.emit_ref": "Emit",
    "graphs.port.duration_seconds": "Duration (seconds)",
    "graphs.port.is_automatic": "Is Automatic",
    "graphs.port.requester_user_id": "Requester User ID",
    "graphs.port.requester_user_login": "Requester Login",
    "graphs.port.requester_user_name": "Requester Display Name",
    "graphs.port.next_ad_at": "Next Ad At",
    "graphs.port.lead_time_seconds": "Lead Time (s)",
    "graphs.port.seconds_until_ad": "Seconds Until Ad",
    "graphs.port.snooze_count": "Snoozes Remaining",
    "graphs.port.was_gift": "Was Gift",
    "graphs.port.cumulative_months": "Cumulative Months",
    "graphs.port.streak_months": "Streak Months",
    "graphs.port.duration_months": "Duration Months",
    "graphs.port.type": "Type",
    "graphs.port.power_up_type": "Power-Up Type",
    "graphs.port.reward_id": "Reward ID",
    "graphs.port.reward_title": "Reward Title",
    "graphs.port.reward_cost": "Reward Cost",
    "graphs.port.reward_type": "Reward Type",
    "graphs.port.redemption_id": "Redemption ID",
    "graphs.port.user_input": "User Input",
    "graphs.port.redeemed_at": "Redeemed At",
    "graphs.port.points_used": "Points Used",
    "graphs.port.cost": "Cost",
    "graphs.port.prompt": "Prompt",
    "graphs.port.is_enabled": "Enabled",
    "graphs.port.is_paused": "Paused",
    "graphs.port.is_in_stock": "In Stock",
    "graphs.port.session_id": "Session ID",
    "graphs.port.host_id": "Host ID",
    "graphs.port.host_login": "Host Login",
    "graphs.port.host_display_name": "Host Display Name",
    "graphs.port.participants": "Participants",
    "graphs.port.poll_id": "Poll ID",
    "graphs.port.choices": "Choices",
    "graphs.port.prediction_id": "Prediction ID",
    "graphs.port.outcomes": "Outcomes",
    "graphs.port.locks_at": "Locks At",
    "graphs.port.locked_at": "Locked At",
    "graphs.port.winning_outcome_id": "Winning Outcome ID",
    "graphs.port.goal_id": "Goal ID",
    "graphs.port.current_amount": "Current Amount",
    "graphs.port.target_amount": "Target Amount",
    "graphs.port.is_achieved": "Is Achieved",
    "graphs.port.train_id": "Train ID",
    "graphs.port.total_points": "Total Points",
    "graphs.port.progress": "Progress",
    "graphs.port.goal": "Goal",
    "graphs.port.expires_at": "Expires At",
    "graphs.port.golden_kappa": "Golden Kappa",
    "graphs.port.final_level": "Final Level",
    "graphs.port.final_points": "Final Points",
    "graphs.port.donation_id": "Donation ID",
    "graphs.port.campaign_id": "Campaign ID",
    "graphs.port.charity_name": "Charity",
    "graphs.port.amount": "Amount",
    "graphs.port.decimals": "Decimals",
    "graphs.port.currency": "Currency",
    "graphs.port.current_currency": "Current Currency",
    "graphs.port.target_currency": "Target Currency",
    "graphs.port.stopped_at": "Stopped At",
    "graphs.node.trigger_twitch_poll_begin_label": "Poll Begin",
    "graphs.node.trigger_twitch_poll_begin_desc": "Fires when a poll is started.",
    "graphs.node.trigger_twitch_poll_progress_label": "Poll Progress",
    "graphs.node.trigger_twitch_poll_progress_desc": "Fires repeatedly while voters cast votes - high frequency.",
    "graphs.node.trigger_twitch_poll_end_label": "Poll End",
    "graphs.node.trigger_twitch_poll_end_desc": "Fires when a poll closes.",
    "graphs.node.trigger_twitch_prediction_begin_label": "Prediction Begin",
    "graphs.node.trigger_twitch_prediction_begin_desc": "Fires when a prediction is opened.",
    "graphs.node.trigger_twitch_prediction_progress_label": "Prediction Progress",
    "graphs.node.trigger_twitch_prediction_progress_desc": "Fires repeatedly while users predict - high frequency.",
    "graphs.node.trigger_twitch_prediction_lock_label": "Prediction Locked",
    "graphs.node.trigger_twitch_prediction_lock_desc": "Fires when betting on a prediction closes.",
    "graphs.node.trigger_twitch_prediction_end_label": "Prediction End",
    "graphs.node.trigger_twitch_prediction_end_desc": "Fires when a prediction is resolved or canceled.",
    "graphs.node.trigger_twitch_goal_begin_label": "Goal Begin",
    "graphs.node.trigger_twitch_goal_begin_desc": "Fires when the broadcaster starts a creator goal.",
    "graphs.node.trigger_twitch_goal_progress_label": "Goal Progress",
    "graphs.node.trigger_twitch_goal_progress_desc": "Fires when progress is made toward an active goal.",
    "graphs.node.trigger_twitch_goal_end_label": "Goal End",
    "graphs.node.trigger_twitch_goal_end_desc": "Fires when a creator goal ends - check is_achieved.",
    "graphs.node.trigger_twitch_hype_train_begin_label": "Hype Train Begin",
    "graphs.node.trigger_twitch_hype_train_begin_desc": "Fires when a Hype Train starts.",
    "graphs.node.trigger_twitch_hype_train_progress_label": "Hype Train Progress",
    "graphs.node.trigger_twitch_hype_train_progress_desc": "Fires for each Hype Train contribution.",
    "graphs.node.trigger_twitch_hype_train_end_label": "Hype Train End",
    "graphs.node.trigger_twitch_hype_train_end_desc": "Fires when a Hype Train ends.",
    "graphs.node.trigger_twitch_charity_campaign_donate_label": "Charity Donation",
    "graphs.node.trigger_twitch_charity_campaign_donate_desc": "Fires for each viewer donation to the active charity campaign.",
    "graphs.node.trigger_twitch_charity_campaign_start_label": "Charity Campaign Start",
    "graphs.node.trigger_twitch_charity_campaign_start_desc": "Fires when a charity campaign starts.",
    "graphs.node.trigger_twitch_charity_campaign_progress_label": "Charity Campaign Progress",
    "graphs.node.trigger_twitch_charity_campaign_progress_desc": "Fires as donations accumulate.",
    "graphs.node.trigger_twitch_charity_campaign_stop_label": "Charity Campaign Stop",
    "graphs.node.trigger_twitch_charity_campaign_stop_desc": "Fires when the broadcaster stops the charity campaign.",
    "graphs.node.flow_branch_label": "Branch",
    "graphs.node.flow_branch_desc": "Routes execution to true / false based on a boolean input.",
    "graphs.exec.true": "True",
    "graphs.exec.false": "False",
    "graphs.port.condition": "Condition",
    "graphs.node.flow_match_label": "Match",
    "graphs.node.flow_match_desc": "N-way exec dispatch on a string value. Add one Case pin per branch with the value to match against; the first matching case fires, or `default` when nothing matches. Strict string-equality after String() coerce: for ranges or operators, chain a Compare instead.",
    "graphs.exec.default": "Default",
    "graphs.port.value": "Value",
    "graphs.node.flow_cond_label": "Condition",
    "graphs.node.flow_cond_desc": "Ordered conditions, first match wins. Each \"When\" branch carries a condition (field + operator + value); the first satisfied branch fires, otherwise `default`. Operands are token-based, no connections required.",
    "graphs.node.flow_sequence_label": "Sequence",
    "graphs.node.flow_sequence_desc": "Fires multiple exec branches in order.",
    "graphs.node.flow_delay_label": "Delay",
    "graphs.node.flow_delay_desc": "Pauses this branch for the given number of seconds before continuing. Counts toward the 30s graph runtime cap. A single delay is capped at 25 seconds.",
    "graphs.exec.out": "Out",
    "graphs.port.seconds": "Seconds",
    "graphs.node.flow_for_loop_label": "For Loop",
    "graphs.node.flow_for_loop_desc": "Iterates from `from` to `to` inclusive (counts down if from > to). Index is exposed each iteration. Hard cap: 1000 iterations.",
    "graphs.exec.body": "Body",
    "graphs.exec.completed": "Completed",
    "graphs.port.from": "From",
    "graphs.port.to": "To",
    "graphs.port.index": "Index",
    "graphs.node.flow_while_label": "While",
    "graphs.node.flow_while_desc": "Repeats the body branch as long as `condition` is true. The condition re-evaluates each iteration: connect it from a Compare or Logic chain that reflects loop state. Hard cap: 1000 iterations.",
    "graphs.port.iteration": "Iteration",
    "graphs.node.flow_foreach_label": "For Each",
    "graphs.node.flow_foreach_desc": "Iterates over an array, firing the body branch once per element. Element + index are exposed as data outputs that update each iteration. Hard cap: 1000 items.",
    "graphs.port.array": "Array",
    "graphs.port.element": "Element",
    "graphs.node.flow_compare_label": "Compare",
    "graphs.node.flow_compare_desc": "Compares two values with a simple operator; routes to true / false based on the result.",
    "graphs.node.pure_compare_label": "Compare",
    "graphs.node.pure_compare_desc": "Compares two values; returns a boolean (use Branch to route on it).",
    "graphs.param.operator": "Operator",
    "graphs.port.left": "Left",
    "graphs.port.right": "Right",
    "graphs.port.result": "Result",
    "graphs.port.a": "A",
    "graphs.port.b": "B",
    "graphs.port.length": "Length",
    "graphs.port.object": "Object",
    "graphs.param.list_name": "List name",
    "graphs.param.path": "Path",
    "graphs.node.pure_list_label": "List",
    "graphs.node.pure_list_desc": "Reference to a persistent named list. Connect into array actions/readers instead of repeating the name everywhere.",
    "graphs.node.pure_array_length_label": "Array Length",
    "graphs.node.pure_array_length_desc": "Reads the size of an array; works on any array source (a List output, command args, split results).",
    "graphs.node.pure_array_at_label": "Array At Index",
    "graphs.node.pure_array_at_desc": "Reads the element at the given zero-based index. Works on any array source.",
    "graphs.node.pure_array_contains_label": "Array Contains",
    "graphs.node.pure_array_contains_desc": "True if the array contains the given value. Works on any array source.",
    "graphs.node.pure_object_get_label": "Get Property",
    "graphs.node.pure_object_get_desc": "Reads a value at a dotted path from an object (e.g. `data.user.email`).",
    "graphs.node.pure_object_from_pairs_label": "Build Object",
    "graphs.node.pure_object_from_pairs_desc": "Builds an object from typed input pins. Each pin contributes one key/value pair: the pin's label is the JSON key, the connected value is the value. Useful for HTTP headers and JSON bodies without a JSON.parse hack.",
    "graphs.node.pure_destructure_label": "Destructure Object",
    "graphs.node.pure_destructure_desc": "Splits an object into multiple typed outputs. Add a pin per field you want to expose; each pin has a label, type, and dotted path into the source object.",
    "graphs.node.pure_logic_and_label": "And",
    "graphs.node.pure_logic_and_desc": "Logical AND of two booleans.",
    "graphs.node.pure_logic_or_label": "Or",
    "graphs.node.pure_logic_or_desc": "Logical OR of two booleans.",
    "graphs.node.pure_logic_not_label": "Not",
    "graphs.node.pure_logic_not_desc": "Logical NOT of a boolean.",
    "graphs.node.pure_math_add_label": "Add",
    "graphs.node.pure_math_add_desc": "a + b.",
    "graphs.node.pure_math_sub_label": "Subtract",
    "graphs.node.pure_math_sub_desc": "a − b.",
    "graphs.node.pure_math_mul_label": "Multiply",
    "graphs.node.pure_math_mul_desc": "a × b.",
    "graphs.node.pure_math_div_label": "Divide",
    "graphs.node.pure_math_div_desc": "a ÷ b. Returns 0 on division by zero.",
    "graphs.node.pure_math_mod_label": "Modulo",
    "graphs.node.pure_math_mod_desc": "a mod b: remainder of a ÷ b. Returns 0 on b = 0. Sign matches `a` (JavaScript semantics).",
    "graphs.node.pure_math_min_label": "Min",
    "graphs.node.pure_math_min_desc": "Smallest of the connected numbers. Unconnected pins are ignored; returns 0 when none are connected.",
    "graphs.node.pure_math_max_label": "Max",
    "graphs.node.pure_math_max_desc": "Largest of the connected numbers. Unconnected pins are ignored; returns 0 when none are connected.",
    "graphs.node.pure_math_round_label": "Round",
    "graphs.node.pure_math_round_desc": "Rounds to the nearest integer; .5 rounds up.",
    "graphs.node.pure_math_floor_label": "Floor",
    "graphs.node.pure_math_floor_desc": "Rounds down to the nearest integer.",
    "graphs.node.pure_math_ceil_label": "Ceil",
    "graphs.node.pure_math_ceil_desc": "Rounds up to the nearest integer.",
    "graphs.node.pure_math_abs_label": "Absolute",
    "graphs.node.pure_math_abs_desc": "Absolute value; drops the sign.",
    "graphs.node.pure_string_upper_label": "Uppercase",
    "graphs.node.pure_string_upper_desc": "Converts a string to uppercase.",
    "graphs.node.pure_string_lower_label": "Lowercase",
    "graphs.node.pure_string_lower_desc": "Converts a string to lowercase.",
    "graphs.node.pure_string_trim_label": "Trim",
    "graphs.node.pure_string_trim_desc": "Strips leading and trailing whitespace.",
    "graphs.option.eq": "= equals",
    "graphs.option.ne": "≠ not equals",
    "graphs.option.lt": "< less than",
    "graphs.option.le": "≤ less-or-equal",
    "graphs.option.gt": "> greater than",
    "graphs.option.ge": "≥ greater-or-equal",
    "graphs.option.contains": "contains",
    "graphs.option.matches": "matches regex",
    "graphs.node.debug_log_label": "Debug Log",
    "graphs.node.debug_log_desc": "Logs the connected value (with an optional label) to the runtime log. Drop it inline as a checkpoint during graph development.",
    "graphs.port.label": "Label",
    "graphs.node.primitive_number_label": "Number",
    "graphs.node.primitive_number_desc": "Emits a fixed numeric value as an output.",
    "graphs.node.primitive_string_label": "String",
    "graphs.node.primitive_string_desc": "Emits a fixed text value as an output. No variable interpolation: for templates use ChatSend.text.",
    "graphs.node.primitive_boolean_label": "Boolean",
    "graphs.node.primitive_boolean_desc": "Emits a fixed true/false value as an output.",
    "graphs.param.value": "Value",
    "graphs.node.action_chat_send_label": "Send Chat Message",
    "graphs.node.action_chat_send_desc": "Posts a message to the channel chat via Twitch Helix.",
    "graphs.node.action_chat_announce_label": "Send Announcement",
    "graphs.node.action_chat_announce_desc": "Posts a Twitch announcement (highlighted chat line). Optionally choose a colour band.",
    "graphs.node.action_chat_shoutout_label": "Send Shoutout",
    "graphs.node.action_chat_shoutout_desc": "Sends a Twitch /shoutout to the target channel.",
    "graphs.node.action_moderation_ban_label": "Ban User",
    "graphs.node.action_moderation_ban_desc": "Permanently bans a user from chat. Optional reason is shown in the mod log.",
    "graphs.node.action_moderation_timeout_label": "Timeout User",
    "graphs.node.action_moderation_timeout_desc": "Times out a user for the given duration (1-1209600 seconds; Twitch caps at 14 days).",
    "graphs.node.action_moderation_unban_label": "Unban User",
    "graphs.node.action_moderation_unban_desc": "Removes a ban or timeout from the channel.",
    "graphs.node.action_moderation_delete_message_label": "Delete Chat Message",
    "graphs.node.action_moderation_delete_message_desc": "Removes one chat message by id. Empty Message ID clears the entire chat (equivalent to /clear).",
    "graphs.node.action_moderation_warn_label": "Warn User",
    "graphs.node.action_moderation_warn_desc": "Issues a Twitch warning. The user must acknowledge before chatting again.",
    "graphs.node.action_moderation_shield_mode_label": "Toggle Shield Mode",
    "graphs.node.action_moderation_shield_mode_desc": "Activates or deactivates Twitch Shield Mode on the channel.",
    "graphs.node.action_channel_set_title_label": "Set Channel Title",
    "graphs.node.action_channel_set_title_desc": "Updates the stream title.",
    "graphs.node.action_channel_set_category_label": "Set Channel Category",
    "graphs.node.action_channel_set_category_desc": "Updates the streamed game / category. Accepts either the Twitch category name (e.g. \"Hollow Knight\") or the numeric category id.",
    "graphs.node.action_stream_add_marker_label": "Add Stream Marker",
    "graphs.node.action_stream_add_marker_desc": "Drops a stream marker at the current playback position. Stream must be live.",
    "graphs.node.action_clip_create_label": "Create Clip",
    "graphs.node.action_clip_create_desc": "Creates a clip of the last few seconds of the live stream and returns its URL. The stream must be live; the clip needs a few seconds to finish before the link plays.",
    "graphs.port.clip_title": "Title",
    "graphs.port.clip_duration": "Duration",
    "graphs.port.clip_id": "Clip ID",
    "graphs.port.clip_url": "Clip URL",
    "graphs.port.edit_url": "Edit URL",
    "graphs.node.action_vip_add_label": "Add VIP",
    "graphs.node.action_vip_add_desc": "Grants VIP status on the channel.",
    "graphs.node.action_vip_remove_label": "Remove VIP",
    "graphs.node.action_vip_remove_desc": "Revokes VIP status on the channel.",
    "graphs.node.action_mod_add_label": "Add Moderator",
    "graphs.node.action_mod_add_desc": "Grants moderator privileges on the channel.",
    "graphs.node.action_mod_remove_label": "Remove Moderator",
    "graphs.node.action_mod_remove_desc": "Revokes moderator privileges on the channel.",
    "graphs.exec.sent": "Sent",
    "graphs.exec.error": "Error",
    "graphs.group.chat": "Chat",
    "graphs.group.channel": "Channel",
    "graphs.port.target_user_id": "Target User ID",
    "graphs.port.duration_s": "Duration (s)",
    "graphs.port.active": "Active",
    "graphs.port.marker_id": "Marker ID",
    "graphs.param.connection_id": "Sender account",
    "graphs.param.color": "Color",
    "graphs.option.primary": "Primary (default)",
    "graphs.option.blue": "Blue",
    "graphs.option.green": "Green",
    "graphs.option.orange": "Orange",
    "graphs.option.purple": "Purple",
    "graphs.node.action_user_fire_event_label": "Fire Custom Event",
    "graphs.node.action_user_fire_event_desc": "Emits a user-defined event. Pin inputs become the event data that bound Trigger nodes receive.",
    "graphs.node.action_counter_set_label": "Set Counter",
    "graphs.node.action_counter_set_desc": "Updates a persistent named counter. Connect a Counter node into Counter to choose which one.",
    "graphs.node.action_array_push_label": "Push to List",
    "graphs.node.action_array_push_desc": "Appends a value to a persistent named list. Connect a List node into Array.",
    "graphs.node.action_array_pop_label": "Pop from List",
    "graphs.node.action_array_pop_desc": "Removes the front element from a persistent named list (FIFO). Connect a List node into Array.",
    "graphs.node.action_array_remove_label": "Remove from List",
    "graphs.node.action_array_remove_desc": "Drops every occurrence of a value from a persistent named list. Connect a List node into Array.",
    "graphs.node.action_array_clear_label": "Clear List",
    "graphs.node.action_array_clear_desc": "Empties a persistent named list. Connect a List node into Array.",
    "graphs.node.action_var_set_label": "Set Variable",
    "graphs.node.action_var_set_desc": "Writes a new value to a property or graph variable. Last-write-wins.",
    "graphs.node.action_var_reset_label": "Reset Variable",
    "graphs.node.action_var_reset_desc": "Clears the stored value of a variable. Subsequent reads return the declared default.",
    "graphs.node.action_cooldown_skip_label": "Skip Cooldown",
    "graphs.node.action_cooldown_skip_desc": "Cancels this run's cooldown so the command or keyword is not put on cooldown when the graph finishes.",
    "graphs.node.action_ctx_set_label": "Set Context",
    "graphs.node.action_ctx_set_desc": "Pushes a value into the current run context, pickable as {ctx.<slug>} in text fields with variable support.",
    "graphs.exec.done": "Done",
    "graphs.exec.popped": "Popped",
    "graphs.exec.empty": "Empty",
    "graphs.exec.removed": "Removed",
    "graphs.exec.not_found": "Not found",
    "graphs.port.counter": "Counter",
    "graphs.param.mode": "Mode",
    "graphs.param.variable_id": "Variable",
    "graphs.param.slug": "Slug",
    "graphs.param.slug_help": "Pickable as {ctx.<slug>} in this graph's templates",
    "graphs.option.set_to_value": "Set to value",
    "graphs.option.increment_by_value": "Increment by value",
    "graphs.option.decrement_by_value": "Decrement by value",
    "graphs.node.action_http_request_label": "HTTP Request",
    "graphs.node.action_http_request_desc": "Performs an outbound HTTP call. Body has dual semantics on GET/HEAD: a string body is url-encoded and appended to the URL path (e.g. /summary/ + \"Berlin (Stadt)\" → /summary/Berlin%20%28Stadt%29), an object body becomes a query-string (?k=v&k2=v2). For other methods, body is sent as the request body (objects auto-stringified to JSON).",
    "graphs.node.action_twitch_start_commercial_label": "Start Commercial",
    "graphs.node.action_twitch_start_commercial_desc": "Starts a midroll commercial of the given length on the broadcaster's channel. Twitch enforces an 8-minute cooldown between commercials; on cooldown the call resolves through the Failure branch with retry_after_seconds populated.",
    "graphs.node.action_twitch_get_user_info_label": "Get User Info",
    "graphs.node.action_twitch_get_user_info_desc": "Looks up a user via Helix and returns whether they are a Mod, VIP, Subscriber, or Follower of this channel, plus their login + display name. Cached 60s per (property, user) inside the runtime. Missing scopes degrade gracefully: the corresponding boolean returns false with a debug-log warning, the Success branch still fires.",
    "graphs.node.action_tts_speak_label": "Speak (TTS)",
    "graphs.node.action_tts_speak_desc": "Reads the given text aloud through every active Audio-Out scene. Text is normalized (anti-screaming, URL cleanup, emoji strip, char-limit 250) before synthesis.",
    "graphs.node.action_sound_play_label": "Play Sound",
    "graphs.node.action_sound_play_desc": "Plays an audio asset through every active Audio-Out scene.",
    "graphs.node.action_text_filter_profanity_label": "Filter Profanity",
    "graphs.node.action_text_filter_profanity_desc": "Scans text against curated DE+EN profanity lists plus optional adhoc words. Routes to the \"Clean\" or \"Blocked\" branch and outputs the (optionally masked) text and match metadata.",
    "graphs.node.action_widgets_play_media_label": "Play Media",
    "graphs.node.action_widgets_play_media_desc": "Plays a video or image asset through the Media Player widget, one alert at a time, optionally with an extra sound track.",
    "graphs.node.action_widgets_play_composition_label": "Play Composition",
    "graphs.node.action_widgets_play_composition_desc": "Plays an alert composition on a named stage. Runs through the alert queue.",
    "graphs.node.action_widgets_play_composition_param_composition": "Composition",
    "graphs.node.action_widgets_play_composition_param_stage": "Stage",
    "graphs.port.sound_asset": "Sound Track",
    "graphs.param.mute_video": "Mute video audio",
    "graphs.param.mute_video_help": "Silences only the video's own audio track. The sound track keeps playing.",
    "graphs.param.repeat": "Repetitions",
    "graphs.param.repeat_help": "Plays the video this many times in a row. Ignored for images.",
    "graphs.param.placement": "Placement",
    "graphs.param.placement_help": "Position and size inside the media widget. Without a value the asset fills the whole widget.",
    "events.verb.play_media": "Play a video or image",
    "graphs.exec.started": "Started",
    "graphs.exec.failed": "Failed",
    "graphs.exec.looked_up": "Looked up",
    "graphs.exec.clean": "Clean",
    "graphs.port.url": "URL",
    "graphs.port.body": "Body",
    "graphs.port.headers": "Headers",
    "graphs.port.response_body": "Response Body",
    "graphs.port.response_headers": "Response Headers",
    "graphs.port.length_s": "Length (s)",
    "graphs.port.retry_after_s": "Retry after (s)",
    "graphs.port.is_vip": "Is VIP",
    "graphs.port.is_follower": "Is Follower",
    "graphs.port.volume": "Volume",
    "graphs.port.asset": "Asset",
    "graphs.port.asset_name": "Asset Name",
    "graphs.port.extra_words": "Extra Words",
    "graphs.port.replacement": "Replacement",
    "graphs.port.had_match": "Had Match",
    "graphs.port.matched_words": "Matched Words",
    "graphs.param.method": "Method",
    "graphs.param.length": "Length",
    "graphs.param.language": "Language",
    "graphs.param.voice": "Voice",
    "graphs.option.get": "GET",
    "graphs.option.head": "HEAD",
    "graphs.option.post": "POST",
    "graphs.option.put": "PUT",
    "graphs.option.patch": "PATCH",
    "graphs.option.delete": "DELETE",
    "graphs.option.thirty_seconds": "30 seconds",
    "graphs.option.sixty_seconds": "60 seconds",
    "graphs.option.ninety_seconds": "90 seconds",
    "graphs.option.two_minutes": "2 minutes",
    "graphs.option.two_thirty_minutes": "2:30 minutes",
    "graphs.option.three_minutes": "3 minutes",
    "graphs.option.lang_de_de": "German (DE)",
    "graphs.option.lang_en_us": "English (US)",
    "graphs.option.voice_default": "Channel default",
    "graphs.option.voice_emma": "Emma",
    "graphs.option.voice_hans": "Hans",
    "graphs.option.voice_sarah": "Sarah",
    "graphs.option.voice_felix": "Felix",
    "graphs.option.voice_evelyn": "Evelyn",
    "graphs.option.voice_mia": "Mia",
    "graphs.option.voice_liam": "Liam",
    "graphs.option.voice_benjamin": "Benjamin",
    "graphs.tts.play_sample": "Play sample",
    "extensions.tts.settings_title": "Text-to-Speech",
    "extensions.tts.settings_card_description": "Default voice for spoken output in your stream.",
    "extensions.tts.settings_saved": "Settings saved.",
    "extensions.tts.profanity_section_title": "Word filter",
    "extensions.tts.profanity_mode_label": "Filter mode",
    "extensions.tts.profanity_mode_off": "Off",
    "extensions.tts.profanity_mode_mask": "Mask matched words",
    "extensions.tts.profanity_mode_block": "Skip the whole message",
    "extensions.tts.profanity_mode_help": "Applied to every spoken text before it is synthesized.",
    "extensions.tts.profanity_custom_words_label": "Custom words",
    "extensions.tts.profanity_custom_words_help": "One word per line. Matched anywhere inside a word.",
    "errors.tts.custom_word_too_long": "Custom words may be at most 64 characters long.",
    "errors.tts.too_many_custom_words": "Too many custom words (maximum 200).",
    "errors.tts.unknown_voice": "Unknown voice.",
    "graphs.port.search": "Search",
    "graphs.port.replace": "Replace",
    "graphs.port.start": "Start",
    "graphs.port.date_value": "Date value",
    "graphs.port.milliseconds": "Milliseconds",
    "graphs.port.iso": "ISO 8601",
    "graphs.port.unix_seconds": "Unix seconds",
    "graphs.port.category_since": "Category Since",
    "graphs.port.category_seconds": "Category Seconds",
    "graphs.port.stream_delay": "Stream Delay",
    "graphs.port.tags": "Tags",
    "graphs.port.branded_content": "Branded Content",
    "graphs.port.steam_store_link": "Steam Store Link",
    "graphs.port.length_s_help": "Length Twitch actually started (echo of the requested length on success, 0 on failure).",
    "graphs.port.retry_after_s_help": "Cooldown remaining when Twitch returned 429. 0 on success or non-rate-limit failures.",
    "graphs.port.message_help": "Twitch's message field on success, or the error message on failure.",
    "graphs.port.user_id_help": "Numeric Twitch user id. Connect from a trigger's user_id output or any user-emitting upstream node.",
    "graphs.port.milliseconds_help": "Milliseconds since 1970-01-01T00:00:00Z.",
    "graphs.port.iso_help": "ISO 8601 string in UTC, e.g. 2026-05-16T13:42:11.123Z.",
    "graphs.port.unix_seconds_help": "Seconds since 1970-01-01T00:00:00Z (floor of milliseconds/1000).",
    "graphs.port.title_help": "Current stream title.",
    "graphs.port.category_help": "Current Twitch category / game name.",
    "graphs.port.category_since_help": "ISO 8601 timestamp the current category was set (empty if unknown). Resets on category change and stream start.",
    "graphs.port.category_seconds_help": "Seconds since the category was set (0 if unknown).",
    "graphs.port.language_help": "Two-letter language code the broadcaster set on the channel.",
    "graphs.port.user_login_help": "Broadcaster's URL slug (e.g. xeras).",
    "graphs.port.user_display_name_help": "Broadcaster's display name (e.g. Xeras).",
    "graphs.port.stream_delay_help": "Configured stream delay in seconds.",
    "graphs.port.tags_help": "Stream tags.",
    "graphs.port.branded_content_help": "Whether the stream is flagged as branded content.",
    "graphs.port.steam_store_link_help": "store.steampowered.com/app/<id> for the current category, empty if not a Steam game.",
    "graphs.param.template": "Template",
    "graphs.param.preset": "Preset",
    "graphs.param.input": "Input",
    "graphs.param.min": "Min",
    "graphs.param.max": "Max",
    "graphs.option.duration_compact": "Compact (3h 24m)",
    "graphs.option.duration_long": "Long (3 hours 24 minutes)",
    "graphs.option.duration_clock": "Clock (1:23:45)",
    "graphs.option.date_short": "Short date (30.05.2026)",
    "graphs.option.date_long": "Long date (30 May 2026)",
    "graphs.option.date_datetime": "Date and time (UTC)",
    "graphs.option.date_relative": "Relative (3 days ago)",
    "graphs.option.date_elapsed": "Elapsed (4 weeks)",
    "graphs.option.input_auto": "Auto detect",
    "graphs.option.input_iso": "ISO 8601 string",
    "graphs.option.input_unix_seconds": "Unix timestamp (seconds)",
    "graphs.option.input_unix_milliseconds": "Unix timestamp (milliseconds)",
    "graphs.node.pure_string_concat_label": "Concat Strings",
    "graphs.node.pure_string_concat_desc": "Joins multiple strings end to end.",
    "graphs.node.pure_format_label": "Format",
    "graphs.node.pure_format_desc": "Turns an InputText template (with variables and pickers) into a string. The same template engine ChatSend.text uses, but as an output: feed the result into HTTP body, JSON construction, or further string ops.",
    "graphs.node.pure_string_replace_label": "Replace",
    "graphs.node.pure_string_replace_desc": "Replaces every occurrence of `search` with `replace` in `value`. No regex: literal match.",
    "graphs.node.pure_string_substring_label": "Substring",
    "graphs.node.pure_string_substring_desc": "Cuts characters from `value` starting at `start`, up to `length` characters. Negative or missing `length` reads to the end.",
    "graphs.node.pure_string_length_label": "String Length",
    "graphs.node.pure_string_length_desc": "Number of characters in the string.",
    "graphs.node.pure_format_duration_label": "Format Duration",
    "graphs.node.pure_format_duration_desc": "Formats a number of seconds into a human-readable duration (e.g. 3h 24m). Same formatter as the InputText format option.",
    "graphs.node.pure_format_date_label": "Format Date",
    "graphs.node.pure_format_date_desc": "Formats an ISO 8601 string or Unix timestamp into a readable date. Auto-detects the input kind by default; absolute times are shown in UTC.",
    "graphs.node.pure_random_int_label": "Random Int",
    "graphs.node.pure_random_int_desc": "Random integer in [min, max] (inclusive).",
    "graphs.node.pure_random_choice_label": "Random Choice",
    "graphs.node.pure_random_choice_desc": "Picks one element of an array at random.",
    "graphs.node.pure_date_now_label": "Now",
    "graphs.node.pure_date_now_desc": "Current wall-clock timestamp at the moment this node executes. Returns fresh values on each call: two Now nodes in the same graph (with delay in between) report different times.",
    "graphs.node.pure_channel_info_label": "Get Channel Info",
    "graphs.node.pure_channel_info_desc": "Current channel data for the property this graph runs in. Re-reads live state on each call. Connect Category Since into Format Date, Category Seconds into Compare.",
    "graphs.node.pure_channel_steam_url_label": "Steam Store Link",
    "graphs.node.pure_channel_steam_url_desc": "Steam store page for the channel's current category. Empty when the category is not a Steam game. A separate node so its lookup only runs when connected.",
    "graphs.node.pure_variable_label": "Get Variable",
    "graphs.node.pure_variable_desc": "Reads the current value of a property or graph variable.",
    "graphs.node.pure_select_label": "Select",
    "graphs.node.pure_select_desc": "Outputs one of two values based on a condition. Both inputs are evaluated; use Branch for flow routing.",
    "graphs.node.pure_ctx_get_label": "Get Context",
    "graphs.node.pure_ctx_get_desc": "Reads a value by slug from the current run context (written by Set Context). Memoized per run, so place it after the matching Set Context.",
    "graphs.port.if_true": "If True",
    "graphs.port.if_false": "If False",
    "graphs.param.default": "Default",
    "graphs.param.separator": "Separator",
    "graphs.node.convert_to_string_label": "To String",
    "graphs.node.convert_to_string_desc": "Coerces any value to a string.",
    "graphs.node.convert_to_number_label": "To Number",
    "graphs.node.convert_to_number_desc": "Parses a string to a number. Returns Default when the input is empty or unparseable: set Default to 1 to make optional command args fall back cleanly (e.g. `!counter +` → 1, `!counter + 5` → 5).",
    "graphs.node.convert_to_boolean_label": "To Boolean",
    "graphs.node.convert_to_boolean_desc": "Coerces any value to a boolean (truthy-check; \"0\"/\"false\"/\"\" are false).",
    "graphs.node.convert_json_stringify_label": "JSON Stringify",
    "graphs.node.convert_json_stringify_desc": "Serialises an object or array to a JSON string.",
    "graphs.node.convert_json_parse_label": "JSON Parse",
    "graphs.node.convert_json_parse_desc": "Parses a JSON string. Invalid input → null.",
    "graphs.node.convert_string_split_label": "Split String",
    "graphs.node.convert_string_split_desc": "Splits a string on a separator into an array.",
    "graphs.node.convert_string_url_encode_label": "URL Encode",
    "graphs.node.convert_string_url_encode_desc": "Percent-encodes a string for safe inclusion in a URL (RFC 3986 component encoding). Spaces become %20, special chars are escaped: required for arbitrary user input in URL paths or query strings.",
    "graphs.node.convert_array_join_label": "Join Array",
    "graphs.node.convert_array_join_desc": "Joins array elements into a string with a separator.",
    "graphs.group.advanced": "Advanced",
    "graphs.group.alerts": "Alerts",
    "extensions.discord.title": "Discord",
    "extensions.discord.add": "Webhook",
    "extensions.discord.empty": "No webhooks yet. Add one to post to Discord.",
    "extensions.discord.disabled": "disabled",
    "extensions.discord.form.label": "Label",
    "extensions.discord.form.label_help": "e.g. #stream-events, for your reference only.",
    "extensions.discord.form.url": "Webhook URL",
    "extensions.discord.form.create_title": "Add webhook",
    "extensions.discord.form.edit_title": "Edit webhook",
    "extensions.discord.form.url_edit_help": "Leave blank to keep the saved URL.",
    "extensions.discord.edit_aria": "Edit webhook :label",
    "extensions.discord.delete_confirm_title": "Delete webhook?",
    "extensions.discord.delete_confirm_message": "The webhook is removed. Graphs that use it will take the Error branch.",
    "extensions.discord.errors.invalid_webhook_url": "Please enter a valid Discord webhook URL (https://discord.com/api/webhooks/…).",
    "extensions.discord.flash.created": "Webhook created.",
    "extensions.discord.flash.updated": "Webhook saved.",
    "extensions.discord.flash.deleted": "Webhook deleted.",
    "extensions.discord.tutorial.title": "How to create a webhook",
    "extensions.discord.tutorial.body": "1. Discord → Server Settings\n2. Integrations → Webhooks\n3. \"New Webhook\" → choose a channel\n4. \"Copy Webhook URL\" and paste it here.",
    "builder.api_tokens.title": "API Tokens",
    "builder.api_tokens.intro": "Personal access tokens let AI agents and other tools use the Builder API on your behalf. Each token only gets the abilities you pick.",
    "builder.api_tokens.copy_hint": "Copy this token now. It is only shown once.",
    "builder.api_tokens.name_label": "Token name",
    "builder.api_tokens.abilities_label": "Abilities",
    "builder.api_tokens.create": "Create token",
    "builder.api_tokens.revoke": "Revoke",
    "builder.api_tokens.revoke_title": "Revoke token?",
    "builder.api_tokens.revoke_message": "Tools using this token lose access immediately.",
    "builder.api_tokens.empty": "No tokens yet.",
    "builder.api_tokens.last_used": "Last used",
    "builder.api_tokens.endpoint_hint": "AI agents connect through the MCP server at this address, sending the token as Bearer in the Authorization header. The connected agent can build both widgets and event flows:",
    "builder.api_tokens.claude_label": "Claude Code (one command):",
    "builder.api_tokens.json_label": "Other MCP clients (JSON config):",
    "builder.editor.preview": "Preview",
    "builder.editor.help": "Help",
    "builder.assets.group_label": "Assets",
    "builder.assets.add": "Add file",
    "builder.assets.drop_hint": "Drop images or sounds here to add them",
    "builder.assets.delete": "Delete",
    "builder.assets.delete_confirm": "Delete this file? Widget code that references it will stop working.",
    "builder.assets.size_label": "Size",
    "builder.assets.no_preview": "No preview available for this file.",
    "builder.assets.error_type": "Only images (png, jpg, gif, webp, svg) and sounds (mp3, ogg, wav) are allowed.",
    "builder.assets.error_file_size": "Each file must be 5 MB or smaller.",
    "builder.assets.error_bundle_size": "The bundle would exceed the 25 MB total limit.",
    "builder.assets.upload_failed": "Upload failed. Please try again.",
    "builder.assets.delete_failed": "Delete failed. Please try again.",
    "builder.assets.insert_code": "Insert in code",
    "builder.assets.copy_path": "Copy path",
    "builder.assets.copied": "Copied",
    "builder.config_schema.widget_writable": "Widget can write this value",
    "builder.config_schema.widget_writable_help": "The widget may update this value at runtime and it is saved (for example a counter that survives reloads). The value set in the scene acts as start value and reset.",
    "builder.config_schema.type_list": "List",
    "builder.config_schema.item_type": "Entry type",
    "builder.config_schema.asset_kind": "Asset type",
    "builder.config_schema.asset_kind_audio": "Audio",
    "builder.config_schema.asset_kind_image": "Image",
    "builder.config_schema.asset_kind_video": "Video",
    "builder.config_schema.multiline": "Multi-line",
    "builder.config_schema.slider": "Show as slider",
    "builder.config_schema.slider_suffix": "Suffix (e.g. %)",
    "builder.config_schema.slider_step": "Step",
    "builder.config_schema.group": "Group",
    "builder.config_schema.group_help": "Fields with the same group appear as one section.",
    "builder.config_schema.overridable": "Variations may override",
    "builder.config_schema.overridable_help": "Off = streamers cannot vary this field per event.",
    "builder.config_schema.show_if": "Show only when",
    "builder.config_schema.show_if_help": "Show this field only when another field matches.",
    "builder.config_schema.show_if_field": "Field",
    "builder.config_schema.show_if_op": "Comparison",
    "builder.config_schema.show_if_value": "Value",
    "builder.config_schema.list_min_max_help": "Min/Max bound the number of entries.",
    "builder.config_schema.drag_sort": "Drag to reorder",
    "builder.form_builder.catalog_title": "Form fields",
    "builder.form_builder.field_text": "Text",
    "builder.form_builder.field_number": "Number",
    "builder.form_builder.field_toggle": "Toggle",
    "builder.form_builder.field_dropdown": "Dropdown",
    "builder.form_builder.field_color": "Color",
    "builder.form_builder.field_template": "Template text",
    "builder.form_builder.field_asset": "Asset",
    "builder.form_builder.field_command": "Command",
    "builder.form_builder.field_counter": "Counter",
    "builder.form_builder.field_timer": "Timer",
    "builder.form_builder.field_keyword": "Keyword",
    "builder.form_builder.field_reward": "Reward",
    "builder.form_builder.field_viewer_group": "Viewer group",
    "builder.form_builder.field_font": "Font",
    "builder.form_builder.field_repeater": "Repeater",
    "builder.form_builder.tile_hint": "Drag onto the form, or click to append",
    "builder.form_builder.canvas_empty": "Drag a field from the left to start building the form.",
    "builder.form_builder.canvas_drop_tail": "Drop here to add at the end",
    "builder.form_builder.drop_blocked": "Repeaters cannot be nested",
    "builder.form_builder.group_empty": "Drag fields here, they repeat together as one row",
    "builder.form_builder.untitled": "Untitled field",
    "builder.form_builder.panel_empty": "Select a field on the form to edit its settings.",
    "builder.form_builder.panel_repeater_hint": "Rows repeat this group's sub-fields. Drag fields into the group on the canvas.",
    "builder.form_builder.number_mode": "Number format",
    "builder.form_builder.number_int": "Whole number",
    "builder.form_builder.number_float": "Decimal",
    "builder.form_builder.min_rows": "Min rows",
    "builder.form_builder.max_rows": "Max rows",
    "builder.form_builder.warn_missing_key": "Key required",
    "builder.form_builder.warn_enum_options": "Add at least one option",
    "builder.form_builder.warn_repeater_fields": "Add at least one sub-field",
    "builder.form_builder.show_if_chip": "only if",
    "builder.form_builder.delete_field": "Remove field",
    "builder.form_builder.key_duplicate": "This key is already used by a sibling field.",
    "builder.permissions.fonts_hint": "Fonts and their stylesheets from third-party hosts (style-src + font-src). For Google Fonts declare fonts.googleapis.com and fonts.gstatic.com.",
    "builder.preview.title": "Preview",
    "builder.preview.connected": "Connected",
    "builder.preview.connecting": "Connecting…",
    "builder.preview.live": "Live Preview",
    "builder.preview.placeholder": "Preview opens in a separate window. Use the Preview button above.",
    "builder.test_panel.trigger_label": "⚡ Test",
    "builder.test_panel.title": "Fire a test event",
    "builder.test_panel.event_label": "Event",
    "builder.test_panel.no_events": "This widget does not subscribe to any events.",
    "builder.test_panel.fields_label": "Sample data",
    "builder.test_panel.no_fields": "This event has no editable sample data.",
    "builder.test_panel.fire_once": "Fire once",
    "builder.test_panel.loop_start": "Loop",
    "builder.test_panel.loop_stop": "Stop loop",
    "builder.test_panel.interval_label": "Every",
    "builder.test_panel.interval_suffix": "s",
    "builder.test_panel.waiting_ready": "Waiting for the widget to load…",
    "builder.test_panel.pipeline_hint": "Also fires connected scene sessions (OBS).",
    "builder.settings.usage_section": "Usage",
    "builder.settings.usage_label": "How to use (markdown)",
    "builder.settings.usage_help": "Consumer-facing setup notes. Shown read-only in the \"How to use\" popup from the marketplace and the scene editor. Plain markdown.",
    "builder.help.title": "Author reference",
    "builder.help.events_heading": "Events this widget receives",
    "builder.help.events_empty": "This widget subscribes to no events yet.",
    "builder.help.event_fields_heading": "Fields on the sample event",
    "builder.help.event_no_fields": "No sample fields for this event.",
    "builder.help.sdk_heading": "Widget SDK",
    "builder.help.sdk_intro": "The host exposes a global Streambridge object. Wait for it, then read config, listen for events, and send events back.",
    "builder.help.tokens_heading": "Theme and config values",
    "builder.help.tokens_config": "Config values",
    "builder.help.tokens_theme": "Theme tokens",
    "builder.help.tokens_empty": "None defined for this widget.",
    "builder.help.assets_heading": "Referencing uploaded files",
    "builder.help.assets_intro": "Uploaded images and sounds live under assets/. Reference them by relative path from your code.",
    "builder.help.assets_note": "This is separate from ctx.assets, which resolves Twitch badges and emotes only.",
    "builder.help.config_fields_heading": "Config fields (stage 2)",
    "builder.help.config_fields_intro": "Additive config_schema properties: list, item, asset_kind, multiline, group, show_if, overridable. Every field stays valid without them; see manifest.v1.json for the authoritative schema.",
    "builder.help.config_fields_caching": "Variations swap the effective config right before each event, so read config inside your event handlers (ctx.on(...)), never once at startup. Config cached at Streambridge.ready() never sees per-event overrides; ctx.onConfigUpdate fires on every swap.",
    "builder.help.config_fields_asset_ref": "asset-ref config values are ids for the streamer's own property assets (their uploaded sound/image library), not your bundle files. Your bundle receives the id via config and resolves playback itself; bundle-relative files (assets/logo.png) stay plain paths, unrelated to this type.",
    "builder.help.close": "Close",
    "migrate.hub.card_label": "Import from StreamElements",
    "migrate.hub.card_description": "Bring your StreamElements variables into this channel.",
    "migrate.title": "Import from StreamElements",
    "migrate.upload.heading": "Upload your StreamElements export",
    "migrate.upload.hint": "Select the .zip export file (max 50 MB).",
    "migrate.upload.file_label": "Export file",
    "migrate.upload.submit": "Upload",
    "migrate.progress.staging": "Reading your export…",
    "migrate.progress.applying": "Importing…",
    "migrate.review.heading": "Review what will be imported",
    "migrate.review.summary": ":ready ready, :conflict already exist",
    "migrate.review.col_source": "StreamElements name",
    "migrate.review.col_slug": "Variable",
    "migrate.review.col_type": "Type",
    "migrate.review.col_default": "Default value",
    "migrate.review.renamed": "renamed from \":name\"",
    "migrate.review.conflict_hint": "A variable with this name already exists and will be skipped.",
    "migrate.review.skipped_heading": "Not imported yet",
    "migrate.review.skipped_hint": "These blocks were in your export but aren't supported yet: :blocks",
    "migrate.review.empty": "Nothing to import from this export.",
    "migrate.review.apply": "Import :count variables",
    "migrate.done.heading": "Import complete",
    "migrate.done.summary": ":applied variables imported, :skipped skipped",
    "migrate.done.partial_heading": "Some rows could not be imported",
    "migrate.done.to_variables": "View variables",
    "migrate.done.restart": "Start a new import",
    "migrate.error.active": "An import is already in progress for this channel.",
    "migrate.error.timeout": "This is taking longer than expected. Reload the page to check the status.",
    "migrate.error.generic": "Something went wrong. Please try again.",
    "errors.migrate.active": "An import is already in progress for this channel.",
    "errors.migrate.not_staged": "This import is not ready to apply yet."
}
