Work on tl

383d46fe4daeb5bd81b6c3b1c6ca212e0b79e682

Yokayo <nonameutubecomm@gmail.com>

7 files changed, +82 -32Showing whitespace changes
public/index.html+1 -1
@@ -4120,7 +4120,7 @@
4120 <input id="movingUImode" type="checkbox" />4120 <input id="movingUImode" type="checkbox" />
4121 <small data-i18n="Movable UI Panels">MovingUI&nbsp;<i class="fa-solid fa-desktop"></i></small>4121 <small data-i18n="Movable UI Panels">MovingUI&nbsp;<i class="fa-solid fa-desktop"></i></small>
4122 </label>4122 </label>
4123 <div data-newbie-hidden id="movingUIreset" title="Reset MovingUI panel sizes/locations." class="menu_button margin0" data-i18n="[title]Reset MovingUI panel sizes/locations."><i class=" fa-solid fa-recycle margin-r5"></i> Reset</div>4123 <div data-newbie-hidden id="movingUIreset" title="Reset MovingUI panel sizes/locations." class="menu_button margin0" data-i18n="[title]Reset MovingUI panel sizes/locations."><i class=" fa-solid fa-recycle margin-r5"></i> <span data-i18n="mui_reset">Reset</span></div>
4124 </div>4124 </div>
4125 <div data-newbie-hidden id="MovingUI-presets-block" class="flex-container alignitemscenter">4125 <div data-newbie-hidden id="MovingUI-presets-block" class="flex-container alignitemscenter">
4126 <div class="flex-container alignItemsFlexEnd">4126 <div class="flex-container alignItemsFlexEnd">
public/locales/ru-ru.json+54 -7
@@ -43,7 +43,7 @@
43 "Smoothing Factor": "Коэффициент сглаживания",43 "Smoothing Factor": "Коэффициент сглаживания",
44 "No Repeat Ngram Size": "Размер no_repeat_ngram",44 "No Repeat Ngram Size": "Размер no_repeat_ngram",
45 "Min Length": "Мин. длина",45 "Min Length": "Мин. длина",
46 "Alternative server URL (leave empty to use the default value).": "Альтернативный URL сервера (оставьте пустым для стандартного значения)",46 "Alternative server URL (leave empty to use the default value).": "URL альтернативного сервера (оставьте пустым для стандартного значения)",
47 "Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "Удалите свой личный OAI API Key из панели API, и ТОЛЬКО ПОСЛЕ ЭТОГО вводите что-то сюда",47 "Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "Удалите свой личный OAI API Key из панели API, и ТОЛЬКО ПОСЛЕ ЭТОГО вводите что-то сюда",
48 "We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "Мы не сможем предоставить помощь с проблемами, с которыми вы столкнетесь при использовании неофициальных прокси для OpenAI",48 "We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "Мы не сможем предоставить помощь с проблемами, с которыми вы столкнетесь при использовании неофициальных прокси для OpenAI",
49 "Context Size (tokens)": "Размер контекста (в токенах)",49 "Context Size (tokens)": "Размер контекста (в токенах)",
@@ -186,7 +186,7 @@
186 "Generate only one line per request": "Генерировать одну строку на запрос",186 "Generate only one line per request": "Генерировать одну строку на запрос",
187 "Misc. Settings": "Доп. настройки",187 "Misc. Settings": "Доп. настройки",
188 "Auto-Continue": "Авто-продолжение",188 "Auto-Continue": "Авто-продолжение",
189 "Collapse Consecutive Newlines": "Сворачивать последовательные новые строки",189 "Collapse Consecutive Newlines": "Сворачивать неск. новых строк в одну",
190 "Allow for Chat Completion APIs": "Разрешить для Chat Completion API",190 "Allow for Chat Completion APIs": "Разрешить для Chat Completion API",
191 "Target length (tokens)": "Целевая длина (в токенах)",191 "Target length (tokens)": "Целевая длина (в токенах)",
192 "World Info": "Информация о мире",192 "World Info": "Информация о мире",
@@ -373,7 +373,7 @@
373 "Prefer Character Card Prompt": "Приоритет промпту из карточки персонажа",373 "Prefer Character Card Prompt": "Приоритет промпту из карточки персонажа",
374 "Prefer Character Card Jailbreak": "Приоритет джейлбрейку из карточки персонажа",374 "Prefer Character Card Jailbreak": "Приоритет джейлбрейку из карточки персонажа",
375 "Press Send to continue": "Кнопка отправки продолжает сообщение",375 "Press Send to continue": "Кнопка отправки продолжает сообщение",
376 "Quick 'Continue' button": "Кнопка быстрого продолжения",376 "Quick 'Continue' button": "Быстрое продолжение",
377 "Log prompts to console": "Выводить промпты в консоль",377 "Log prompts to console": "Выводить промпты в консоль",
378 "Never resize avatars": "Не менять размер аватарок",378 "Never resize avatars": "Не менять размер аватарок",
379 "Show avatar filenames": "Показывать названия файлов аватарок",379 "Show avatar filenames": "Показывать названия файлов аватарок",
@@ -495,7 +495,7 @@
495 "(Write a comma-separated list of tags)": "(Список тегов через запятую)",495 "(Write a comma-separated list of tags)": "(Список тегов через запятую)",
496 "(A brief description of the personality)": "(Краткое описание личности)",496 "(A brief description of the personality)": "(Краткое описание личности)",
497 "(Circumstances and context of the interaction)": "(Обстоятельства и контекст этого диалога)",497 "(Circumstances and context of the interaction)": "(Обстоятельства и контекст этого диалога)",
498 "(Examples of chat dialog. Begin each example with START on a new line.)": "(Примеры диалога. Начинайте каждый пример с START или новой линией.)",498 "(Examples of chat dialog. Begin each example with START on a new line.)": "(Примеры диалога. Начинайте каждый пример с START или новой строкой.)",
499 "Type here...": "Пишите здесь...",499 "Type here...": "Пишите здесь...",
500 "Comma separated (required)": "Через запятую (обязательное поле)",500 "Comma separated (required)": "Через запятую (обязательное поле)",
501 "What this keyword should mean to the AI, sent verbatim": "Что это ключевое слово должно означать для ИИ, отправляется дословно",501 "What this keyword should mean to the AI, sent verbatim": "Что это ключевое слово должно означать для ИИ, отправляется дословно",
@@ -552,7 +552,7 @@
552 "Click to set a new User Name": "Нажмите, чтобы задать новое имя пользователя.",552 "Click to set a new User Name": "Нажмите, чтобы задать новое имя пользователя.",
553 "Click to lock your selected persona to the current chat. Click again to remove the lock.": "Нажмите, чтобы закрепить выбранную персону для текущего чата. Нажмите еще раз, чтобы открепить.",553 "Click to lock your selected persona to the current chat. Click again to remove the lock.": "Нажмите, чтобы закрепить выбранную персону для текущего чата. Нажмите еще раз, чтобы открепить.",
554 "Click to set user name for all messages": "Нажмите, чтобы задать имя пользователя для всех сообщений.",554 "Click to set user name for all messages": "Нажмите, чтобы задать имя пользователя для всех сообщений.",
555 "Create a dummy persona": "Создать персону-болванку",555 "Create a dummy persona": "Создать пустую персону",
556 "Character Management": "Управление персонажами",556 "Character Management": "Управление персонажами",
557 "Locked = Character Management panel will stay open": "Закреплено = Панель управление персонажами останется открытой",557 "Locked = Character Management panel will stay open": "Закреплено = Панель управление персонажами останется открытой",
558 "Select/Create Characters": "Выбрать/Создать персонажа",558 "Select/Create Characters": "Выбрать/Создать персонажа",
@@ -625,7 +625,7 @@
625 "Automatically select a background based on the chat context": "Автоматический выбор фона в зависимости от контекста чата",625 "Automatically select a background based on the chat context": "Автоматический выбор фона в зависимости от контекста чата",
626 "Filter": "Фильтр",626 "Filter": "Фильтр",
627 "Exclude message from prompts": "Исключить сообщение из промпта",627 "Exclude message from prompts": "Исключить сообщение из промпта",
628 "Include message in prompts": "Включить сообщение в подсказки",628 "Include message in prompts": "Включить сообщение в промпт",
629 "Create checkpoint": "Создать чекпоинт",629 "Create checkpoint": "Создать чекпоинт",
630 "Create Branch": "Создать ветку",630 "Create Branch": "Создать ветку",
631 "Embed file or image": "Вставить файл или изображение",631 "Embed file or image": "Вставить файл или изображение",
@@ -1661,5 +1661,52 @@
1661 "ext_regex_ai_output_desc": "Сообщения, полученные от API",1661 "ext_regex_ai_output_desc": "Сообщения, полученные от API",
1662 "ext_regex_sts_desc": "Сообщения, отправленные с помощью команд STscript",1662 "ext_regex_sts_desc": "Сообщения, отправленные с помощью команд STscript",
1663 "ext_regex_wi_desc": "Содержимое лорбуков и миров. Для работы требует включения флажка \"Только промпт\"!",1663 "ext_regex_wi_desc": "Содержимое лорбуков и миров. Для работы требует включения флажка \"Только промпт\"!",
1664 "ext_regex_only_format_display_desc": "История чата не изменится, замена будет осуществляться только в отображаемом сообщении (в UI)"1664 "ext_regex_only_format_display_desc": "История чата не изменится, замена будет осуществляться только в отображаемом сообщении (в UI)",
1665 "Prefer Character Card Instructions": "Приоритет инструкциям из карточек",
1666 "If checked and the character card contains a Post-History Instructions override, use that instead": "Если в карточке персонажа имеется собственная инструкция после истории, в промпт попадёт именно она",
1667 "Auto-select Input Text": "Автовыделение вводимого текста",
1668 "Enable auto-select of input text in some text fields when clicking/selecting them. Applies to popup input textboxes, and possible other custom input fields.": "Автоматически выделять вводимый текст в некоторых текстовых полях при клике/выборе. Работает для вспл. окон и различных кастомных полей ввода.",
1669 "Reset MovingUI panel sizes/locations.": "Сбросить расположение и размеры панелей MovingUI.",
1670 "mui_reset": "Сброс",
1671 "Quick 'Impersonate' button": "Быстрое перевоплощение",
1672 "Show a button in the input area to ask the AI to impersonate your character for a single message": "Показать в поле ввода кнопку, по нажатии на которую ИИ сгенерирует одно сообщение от лица вашего персонажа.",
1673 "Separators as Stop Strings": "Разделители как стоп-строки",
1674 "Names as Stop Strings": "Имена как стоп-строки",
1675 "Add Character and User names to a list of stopping strings.": "Добавлять имена персонажа и пользователя в список стоп-строк.",
1676 "Allow Post-History Instructions": "Разрешить инструкции после истории",
1677 "context_allow_post_history_instructions": "Добавлять в конец промпта инструкции после истории. Работает только при наличии таких инструкций в карточке И при включенной опции ''Приоритет инструкциям из карточек''.\nНЕ РЕКОМЕНДУЕТСЯ ДЛЯ МОДЕЛЕЙ TEXT COMPLETION, МОЖЕТ ПОРТИТЬ ВЫХОДНОЙ ТЕКСТ.",
1678 "First User Prefix": "Первый префикс пользователя",
1679 "Inserted before the first User's message.": "Вставляется перед первым сообщением пользователя.",
1680 "Last User Prefix": "Последний префикс пользователя",
1681 "instruct_last_input_sequence": "Вставляется перед последним сообщением пользователя.",
1682 "Inserted before a User message and as a last prompt line when impersonating.": "Вставляется перед сообщением пользователя в качестве последней строки промпта при перевоплощении.",
1683 "Inserted before a System (added by slash commands or extensions) message.": "Вставляется перед сообщением системы (может быть добавлено слэш-командой или расширением).",
1684 "Load Asset List": "Загрузить список ресурсов",
1685 "Never add character names.": "Не вставлять имя персонажа.",
1686 "Don't add character names unless necessary.": "Вставлять имя персонажа только когда это необходимо.",
1687 "character_names_none": "Не добавлять имена персонажей в качестве префикса. Может повредить качеству ответов в групповых чатах, используйте с осторожностью.",
1688 "Auxiliary": "Вспомогательный",
1689 "Post-History Instructions": "Инструкции после истории",
1690 "Current persona updated": "Текущая персона изменена",
1691 "Your messages will now be sent as ${0}": "Ваши сообщения будут отправляться от лица ${0}",
1692 "Copied!": "Скопировано!",
1693 "Are you sure you want to delete this message?": "Вы точно хотите удалить это сообщение?",
1694 "Delete Message": "Удалить сообщение",
1695 "Delete Swipe": "Удалить свайп",
1696 "Could not get a reply from API. Check your connection settings / API key and try again.": "Не удалось получить ответ от API. Проверьте настройки соединения и API-ключ и повторите попытку.",
1697 "Connecting To Proxy": "Подключение к прокси",
1698 "Are you sure you want to connect to the following proxy URL?": "Вы точно хотите соединиться с прокси по этому адресу?",
1699 "API connection successful!": "Соединение с API установлено!",
1700 "Proxy Saved": "Прокси сохранена",
1701 "Proxy Deleted": "Прокси удалена",
1702 "Could not find proxy with name '${0}'": "Не удалось найти прокси с названием '${0}'",
1703 "Proxy preset '${0}' not found in proxies array.": "Пресет с названием '${0}' не найден в списке прокси.",
1704 "Please wait for the previous request to complete.": "Пожалуйста, дождитесь окончания обработки предыдущего запроса."
1705 "Start new chat?": "Начать новый чат?",
1706 "If necessary, you can later restore this chat file from the /backups folder": "При необходимости этот чат можно будет восстановить из папки /backups",
1707 "Also delete the current chat file": "Также удалить текущий чат",
1708 "chat_rename_1": "Введите новое имя чата:",
1709 "chat_rename_2": "!!Не используйте имя уже существующего файла, это приведёт к ошибке!!",
1710 "chat_rename_3": "Будут разрушены связи между чатами-чекпоинтами.",
1711 "chat_rename_4": "Расширение '.jsonl' дописывать не нужно."
1665}1712}
public/script.js+7 -16
@@ -2191,7 +2191,7 @@ export function addCopyToCodeBlocks(messageElement) {
2191 codeBlocks.get(i).appendChild(copyButton);2191 codeBlocks.get(i).appendChild(copyButton);
2192 copyButton.addEventListener('pointerup', function (event) {2192 copyButton.addEventListener('pointerup', function (event) {
2193 navigator.clipboard.writeText(codeBlocks.get(i).innerText);2193 navigator.clipboard.writeText(codeBlocks.get(i).innerText);
2194 toastr.info('Copied!', '', { timeOut: 2000 });2194 toastr.info(t`Copied!`, '', { timeOut: 2000 });
2195 });2195 });
2196 }2196 }
2197 }2197 }
@@ -6309,7 +6309,7 @@ export function setUserName(value) {
6309 console.log(`User name changed to ${name1}`);6309 console.log(`User name changed to ${name1}`);
6310 $('#your_name').val(name1);6310 $('#your_name').val(name1);
6311 if (power_user.persona_show_notifications) {6311 if (power_user.persona_show_notifications) {
6312 toastr.success(`Your messages will now be sent as ${name1}`, 'Current persona updated');6312 toastr.success(t`Your messages will now be sent as ${name1}`, t`Current persona updated`);
6313 }6313 }
6314 saveSettingsDebounced();6314 saveSettingsDebounced();
6315}6315}
@@ -9530,11 +9530,7 @@ jQuery(async function () {
9530 const oldFileNameFull = $(this).closest('.select_chat_block_wrapper').find('.select_chat_block_filename').text();9530 const oldFileNameFull = $(this).closest('.select_chat_block_wrapper').find('.select_chat_block_filename').text();
9531 const oldFileName = oldFileNameFull.replace('.jsonl', '');9531 const oldFileName = oldFileNameFull.replace('.jsonl', '');
95329532
9533 const popupText = `<h3>Enter the new name for the chat:<h3>9533 const popupText = await renderTemplateAsync('chatRename');
9534 <small>!!Using an existing filename will produce an error!!<br>
9535 This will break the link between checkpoint chats.<br>
9536 No need to add '.jsonl' at the end.<br>
9537 </small>`;
9538 const newName = await callPopup(popupText, 'input', oldFileName);9534 const newName = await callPopup(popupText, 'input', oldFileName);
95399535
9540 if (!newName || newName == oldFileName) {9536 if (!newName || newName == oldFileName) {
@@ -9742,12 +9738,7 @@ jQuery(async function () {
9742 else if (id == 'option_start_new_chat') {9738 else if (id == 'option_start_new_chat') {
9743 if ((selected_group || this_chid !== undefined) && !is_send_press) {9739 if ((selected_group || this_chid !== undefined) && !is_send_press) {
9744 let deleteCurrentChat = false;9740 let deleteCurrentChat = false;
9745 const result = await Popup.show.confirm('Start new chat?', `9741 const result = await Popup.show.confirm(t`Start new chat?`, await renderTemplateAsync('newChatConfirm'), {
9746 <label for="del_chat_checkbox" class="checkbox_label justifyCenter"
9747 title="If necessary, you can later restore this chat file from the /backups folder">
9748 <input type="checkbox" id="del_chat_checkbox" />
9749 <small>Also delete the current chat file</small>
9750 </label>`, {
9751 onClose: () => deleteCurrentChat = !!$('#del_chat_checkbox').prop('checked'),9742 onClose: () => deleteCurrentChat = !!$('#del_chat_checkbox').prop('checked'),
9752 });9743 });
9753 if (!result) {9744 if (!result) {
@@ -10259,10 +10250,10 @@ jQuery(async function () {
1025910250
10260 let deleteOnlySwipe = false;10251 let deleteOnlySwipe = false;
10261 if (power_user.confirm_message_delete && fromSlashCommand !== true) {10252 if (power_user.confirm_message_delete && fromSlashCommand !== true) {
10262 const result = await callGenericPopup('Are you sure you want to delete this message?', POPUP_TYPE.CONFIRM, null, {10253 const result = await callGenericPopup(t`Are you sure you want to delete this message?`, POPUP_TYPE.CONFIRM, null, {
10263 okButton: canDeleteSwipe ? 'Delete Swipe' : 'Delete Message',10254 okButton: canDeleteSwipe ? t`Delete Swipe` : t`Delete Message`,
10264 cancelButton: 'Cancel',10255 cancelButton: 'Cancel',
10265 customButtons: canDeleteSwipe ? ['Delete Message'] : null,10256 customButtons: canDeleteSwipe ? [t`Delete Message`] : null,
10266 });10257 });
10267 if (!result) {10258 if (!result) {
10268 return;10259 return;
public/scripts/openai.js+9 -8
@@ -74,6 +74,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashComma
74import { renderTemplateAsync } from './templates.js';74import { renderTemplateAsync } from './templates.js';
75import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';75import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
76import { Popup, POPUP_RESULT } from './popup.js';76import { Popup, POPUP_RESULT } from './popup.js';
77import { t } from './i18n.js';
7778
78export {79export {
79 openai_messages_count,80 openai_messages_count,
@@ -425,7 +426,7 @@ async function validateReverseProxy() {
425 const rememberKey = `Proxy_SkipConfirm_${getStringHash(oai_settings.reverse_proxy)}`;426 const rememberKey = `Proxy_SkipConfirm_${getStringHash(oai_settings.reverse_proxy)}`;
426 const skipConfirm = localStorage.getItem(rememberKey) === 'true';427 const skipConfirm = localStorage.getItem(rememberKey) === 'true';
427428
428 const confirmation = skipConfirm || await Popup.show.confirm('Connecting To Proxy', `<span>Are you sure you want to connect to the following proxy URL?</span><var>${DOMPurify.sanitize(oai_settings.reverse_proxy)}</var>`);429 const confirmation = skipConfirm || await Popup.show.confirm(t`Connecting To Proxy`, await renderTemplateAsync('proxyConnectionWarning', {proxyURL: DOMPurify.sanitize(oai_settings.reverse_proxy)}));
429430
430 if (!confirmation) {431 if (!confirmation) {
431 toastr.error('Update or remove your reverse proxy settings.');432 toastr.error('Update or remove your reverse proxy settings.');
@@ -4673,17 +4674,17 @@ function toggleChatCompletionForms() {
4673async function testApiConnection() {4674async function testApiConnection() {
4674 // Check if the previous request is still in progress4675 // Check if the previous request is still in progress
4675 if (is_send_press) {4676 if (is_send_press) {
4676 toastr.info('Please wait for the previous request to complete.');4677 toastr.info(t`Please wait for the previous request to complete.`);
4677 return;4678 return;
4678 }4679 }
46794680
4680 try {4681 try {
4681 const reply = await sendOpenAIRequest('quiet', [{ 'role': 'user', 'content': 'Hi' }]);4682 const reply = await sendOpenAIRequest('quiet', [{ 'role': 'user', 'content': 'Hi' }]);
4682 console.log(reply);4683 console.log(reply);
4683 toastr.success('API connection successful!');4684 toastr.success(t`API connection successful!`);
4684 }4685 }
4685 catch (err) {4686 catch (err) {
4686 toastr.error('Could not get a reply from API. Check your connection settings / API key and try again.');4687 toastr.error(t`Could not get a reply from API. Check your connection settings / API key and try again.`);
4687 }4688 }
4688}4689}
46894690
@@ -4837,7 +4838,7 @@ function onProxyPresetChange() {
4837 if (selectedPreset) {4838 if (selectedPreset) {
4838 setProxyPreset(selectedPreset.name, selectedPreset.url, selectedPreset.password);4839 setProxyPreset(selectedPreset.name, selectedPreset.url, selectedPreset.password);
4839 } else {4840 } else {
4840 console.error(`Proxy preset "${value}" not found in proxies array.`);4841 console.error(t`Proxy preset '${value}' not found in proxies array.`);
4841 }4842 }
4842 saveSettingsDebounced();4843 saveSettingsDebounced();
4843}4844}
@@ -4849,7 +4850,7 @@ $('#save_proxy').on('click', async function () {
48494850
4850 setProxyPreset(presetName, reverseProxy, proxyPassword);4851 setProxyPreset(presetName, reverseProxy, proxyPassword);
4851 saveSettingsDebounced();4852 saveSettingsDebounced();
4852 toastr.success('Proxy Saved');4853 toastr.success(t`Proxy Saved`);
4853 if ($('#openai_proxy_preset').val() !== presetName) {4854 if ($('#openai_proxy_preset').val() !== presetName) {
4854 const option = document.createElement('option');4855 const option = document.createElement('option');
4855 option.text = presetName;4856 option.text = presetName;
@@ -4883,9 +4884,9 @@ $('#delete_proxy').on('click', async function () {
48834884
4884 saveSettingsDebounced();4885 saveSettingsDebounced();
4885 $('#openai_proxy_preset').val(selected_proxy.name);4886 $('#openai_proxy_preset').val(selected_proxy.name);
4886 toastr.success('Proxy Deleted');4887 toastr.success(t`Proxy Deleted`);
4887 } else {4888 } else {
4888 toastr.error(`Could not find proxy with name "${presetName}"`);4889 toastr.error(t`Could not find proxy with name '${presetName}'`);
4889 }4890 }
4890});4891});
48914892
public/scripts/templates/chatRename.html+6 -0
@@ -0,0 +1,6 @@
1<h3 data-i18n="chat_rename_1">Enter the new name for the chat:</h3>
2<small>
3 <span data-i18n="chat_rename_2">!!Using an existing filename will produce an error!!</span><br>
4 <span data-i18n="chat_rename_3">This will break the link between checkpoint chats.</span><br>
5 <span data-i18n="chat_rename_4">No need to add '.jsonl' at the end.</span><br>
6</small>
\ No newline at end of file6 \ No newline at end of file
public/scripts/templates/newChatConfirm.html+4 -0
@@ -0,0 +1,4 @@
1<label for="del_chat_checkbox" class="checkbox_label justifyCenter" data-i18n="[title]If necessary, you can later restore this chat file from the /backups folder" title="If necessary, you can later restore this chat file from the /backups folder">
2 <input type="checkbox" id="del_chat_checkbox" />
3 <small data-i18n="Also delete the current chat file">Also delete the current chat file</small>
4</label>
\ No newline at end of file4 \ No newline at end of file
public/scripts/templates/proxyConnectionWarning.html+1 -0
@@ -0,0 +1 @@
1<span data-i18n="Are you sure you want to connect to the following proxy URL?">Are you sure you want to connect to the following proxy URL?</span><var>{{proxyURL}}</var>
\ No newline at end of file1 \ No newline at end of file