From 02b0000117e6b9136ed9014d9eb2c1655ccb7761 Mon Sep 17 00:00:00 2001
From: ceruleandeep
Date: Sat, 5 Oct 2024 17:26:28 +1000
Subject: [PATCH 1/7] Add clickable buttons in Welcome chat message.
Add bool `uses_system_ui` on system messages to override sanitizer for buttons when set
Modify uponSanitizeAttribute DOMPurify hook to allow unmangled class names on attributes in some cases
Add event listener for .drawer-opener to open a navbar drawer
---
public/script.js | 192 ++++++++++++++++----------
public/scripts/templates/welcome.html | 124 ++++++++++-------
public/style.css | 5 +-
3 files changed, 200 insertions(+), 121 deletions(-)
diff --git a/public/script.js b/public/script.js
index 68cd86ed3..d82373400 100644
--- a/public/script.js
+++ b/public/script.js
@@ -293,10 +293,17 @@ DOMPurify.addHook('afterSanitizeAttributes', function (node) {
}
});
-DOMPurify.addHook('uponSanitizeAttribute', (_, data, config) => {
+DOMPurify.addHook('uponSanitizeAttribute', (node, data, config) => {
if (!config['MESSAGE_SANITIZE']) {
return;
}
+
+ /* Retain the classes on UI elements of messages that interact with the main UI */
+ const permittedNodeTypes = ['BUTTON', 'DIV'];
+ if (config['MESSAGE_ALLOW_SYSTEM_UI'] && node.classList.contains('menu_button') && permittedNodeTypes.includes(node.nodeName)) {
+ return;
+ }
+
switch (data.attrName) {
case 'class': {
if (data.attrValue) {
@@ -650,7 +657,8 @@ async function getSystemMessages() {
force_avatar: system_avatar,
is_user: false,
is_system: true,
- mes: await renderTemplateAsync('welcome', { displayVersion }),
+ uses_system_ui: true,
+ mes: await renderTemplateAsync('welcome', { displayVersion } ),
},
group: {
name: systemUserName,
@@ -1916,9 +1924,10 @@ export async function sendTextareaMessage() {
* @param {boolean} isSystem If the message was sent by the system
* @param {boolean} isUser If the message was sent by the user
* @param {number} messageId Message index in chat array
+ * @param {object} [sanitizerOverrides] DOMPurify sanitizer option overrides
* @returns {string} HTML string
*/
-export function messageFormatting(mes, ch_name, isSystem, isUser, messageId) {
+export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, sanitizerOverrides = {}) {
if (!mes) {
return '';
}
@@ -2029,7 +2038,7 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId) {
}
/** @type {any} */
- const config = { MESSAGE_SANITIZE: true, ADD_TAGS: ['custom-style'] };
+ const config = { MESSAGE_SANITIZE: true, ADD_TAGS: ['custom-style'], ...sanitizerOverrides };
mes = encodeStyleTags(mes);
mes = DOMPurify.sanitize(mes, config);
mes = decodeStyleTags(mes);
@@ -2234,6 +2243,18 @@ export function addCopyToCodeBlocks(messageElement) {
}
+/**
+ * Adds a single message to the chat.
+ * @param {object} mes Message object
+ * @param {object} [options] Options
+ * @param {string} [options.type='normal'] Message type
+ * @param {number} [options.insertAfter=null] Message ID to insert the new message after
+ * @param {boolean} [options.scroll=true] Whether to scroll to the new message
+ * @param {number} [options.insertBefore=null] Message ID to insert the new message before
+ * @param {number} [options.forceId=null] Force the message ID
+ * @param {boolean} [options.showSwipes=true] Whether to show swipe buttons
+ * @returns {void}
+ */
export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll = true, insertBefore = null, forceId = null, showSwipes = true } = {}) {
let messageText = mes['mes'];
const momentDate = timestampToMoment(mes.send_date);
@@ -2262,7 +2283,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll
} else if (this_chid === undefined) {
avatarImg = system_avatar;
} else {
- if (characters[this_chid].avatar != 'none') {
+ if (characters[this_chid].avatar !== 'none') {
avatarImg = getThumbnailUrl('avatar', characters[this_chid].avatar);
} else {
avatarImg = default_avatar;
@@ -2277,12 +2298,16 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll
avatarImg = mes['force_avatar'];
}
+ // if mes.uses_system_ui is true, set an override on the sanitizer options
+ const sanitizerOverrides = mes.uses_system_ui ? { MESSAGE_ALLOW_SYSTEM_UI: true } : {};
+
messageText = messageFormatting(
messageText,
mes.name,
isSystem,
mes.is_user,
chat.indexOf(mes),
+ sanitizerOverrides,
);
const bias = messageFormatting(mes.extra?.bias ?? '', '', false, false, -1);
let bookmarkLink = mes?.extra?.bookmark_link ?? '';
@@ -2330,7 +2355,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll
}
//shows or hides the Prompt display button
- let mesIdToFind = type == 'swipe' ? params.mesId - 1 : params.mesId; //Number(newMessage.attr('mesId'));
+ let mesIdToFind = type === 'swipe' ? params.mesId - 1 : params.mesId; //Number(newMessage.attr('mesId'));
//if we have itemized messages, and the array isn't null..
if (params.isUser === false && Array.isArray(itemizedPrompts) && itemizedPrompts.length > 0) {
@@ -2651,7 +2676,7 @@ export function sendSystemMessage(type, text, extra = {}) {
newMessage.mes = text;
}
- if (type == system_message_types.SLASH_COMMANDS) {
+ if (type === system_message_types.SLASH_COMMANDS) {
newMessage.mes = getSlashCommandsHelp();
}
@@ -2665,7 +2690,7 @@ export function sendSystemMessage(type, text, extra = {}) {
chat.push(newMessage);
addOneMessage(newMessage);
is_send_press = false;
- if (type == system_message_types.SLASH_COMMANDS) {
+ if (type === system_message_types.SLASH_COMMANDS) {
const browser = new SlashCommandBrowser();
const spinner = document.querySelector('#chat .last_mes .custom-slashHelp');
const parent = spinner.parentElement;
@@ -7854,7 +7879,7 @@ function openAlternateGreetings() {
if (menu_type !== 'create') {
await createOrEditCharacter();
}
- }
+ },
});
for (let index = 0; index < getArray().length; index++) {
@@ -9070,6 +9095,90 @@ function doTogglePanels() {
return '';
}
+/**
+ * Event handler to open a navbar drawer when a drawer open button is clicked.
+ * Handles click events on .drawer-opener elements.
+ * Opens the drawer associated with the clicked button according to the data-target attribute.
+ * @returns {void}
+ */
+function doDrawerOpenClick() {
+ const targetDrawerID = $(this).attr('data-target');
+ const drawer = $(`#${targetDrawerID}`);
+ const drawerToggle = drawer.find('.drawer-toggle');
+ const drawerWasOpenAlready = drawerToggle.parent().find('.drawer-content').hasClass('openDrawer');
+ if (drawerWasOpenAlready || drawer.hasClass('resizing') ) { return; }
+ doNavbarIconClick.call(drawerToggle);
+}
+
+/**
+ * Event handler to open or close a navbar drawer when a navbar icon is clicked.
+ * Handles click events on .drawer-toggle elements.
+ * @returns {void}
+ */
+function doNavbarIconClick() {
+ var icon = $(this).find('.drawer-icon');
+ var drawer = $(this).parent().find('.drawer-content');
+ if (drawer.hasClass('resizing')) { return; }
+ var drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer');
+ let targetDrawerID = $(this).parent().find('.drawer-content').attr('id');
+ const pinnedDrawerClicked = drawer.hasClass('pinnedOpen');
+
+ if (!drawerWasOpenAlready) { //to open the drawer
+ $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {
+ await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
+ });
+ $('.openIcon').toggleClass('closedIcon openIcon');
+ $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');
+ icon.toggleClass('openIcon closedIcon');
+ drawer.toggleClass('openDrawer closedDrawer');
+
+ //console.log(targetDrawerID);
+ if (targetDrawerID === 'right-nav-panel') {
+ $(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle({
+ duration: 200,
+ easing: 'swing',
+ start: function () {
+ jQuery(this).css('display', 'flex'); //flex needed to make charlist scroll
+ },
+ complete: async function () {
+ favsToHotswap();
+ await delay(50);
+ $(this).closest('.drawer-content').removeClass('resizing');
+ $('#rm_print_characters_block').trigger('scroll');
+ },
+ });
+ } else {
+ $(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle(200, 'swing', async function () {
+ await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
+ });
+ }
+
+ // Set the height of "autoSetHeight" textareas within the drawer to their scroll height
+ if (!CSS.supports('field-sizing', 'content')) {
+ $(this).closest('.drawer').find('.drawer-content textarea.autoSetHeight').each(async function () {
+ await resetScrollHeight($(this));
+ return;
+ });
+ }
+
+ } else if (drawerWasOpenAlready) { //to close manually
+ icon.toggleClass('closedIcon openIcon');
+
+ if (pinnedDrawerClicked) {
+ $(drawer).addClass('resizing').slideToggle(200, 'swing', async function () {
+ await delay(50); $(this).removeClass('resizing');
+ });
+ }
+ else {
+ $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {
+ await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
+ });
+ }
+
+ drawer.toggleClass('closedDrawer openDrawer');
+ }
+}
+
function addDebugFunctions() {
const doBackfill = async () => {
for (const message of chat) {
@@ -10659,69 +10768,8 @@ jQuery(async function () {
stopScriptExecution();
});
- $('.drawer-toggle').on('click', function () {
- var icon = $(this).find('.drawer-icon');
- var drawer = $(this).parent().find('.drawer-content');
- if (drawer.hasClass('resizing')) { return; }
- var drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer');
- let targetDrawerID = $(this).parent().find('.drawer-content').attr('id');
- const pinnedDrawerClicked = drawer.hasClass('pinnedOpen');
-
- if (!drawerWasOpenAlready) { //to open the drawer
- $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {
- await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
- });
- $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon');
- $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');
- icon.toggleClass('openIcon closedIcon');
- drawer.toggleClass('openDrawer closedDrawer');
-
- //console.log(targetDrawerID);
- if (targetDrawerID === 'right-nav-panel') {
- $(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle({
- duration: 200,
- easing: 'swing',
- start: function () {
- jQuery(this).css('display', 'flex'); //flex needed to make charlist scroll
- },
- complete: async function () {
- favsToHotswap();
- await delay(50);
- $(this).closest('.drawer-content').removeClass('resizing');
- $('#rm_print_characters_block').trigger('scroll');
- },
- });
- } else {
- $(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle(200, 'swing', async function () {
- await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
- });
- }
-
- // Set the height of "autoSetHeight" textareas within the drawer to their scroll height
- if (!CSS.supports('field-sizing', 'content')) {
- $(this).closest('.drawer').find('.drawer-content textarea.autoSetHeight').each(async function () {
- await resetScrollHeight($(this));
- return;
- });
- }
-
- } else if (drawerWasOpenAlready) { //to close manually
- icon.toggleClass('closedIcon openIcon');
-
- if (pinnedDrawerClicked) {
- $(drawer).addClass('resizing').slideToggle(200, 'swing', async function () {
- await delay(50); $(this).removeClass('resizing');
- });
- }
- else {
- $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {
- await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
- });
- }
-
- drawer.toggleClass('closedDrawer openDrawer');
- }
- });
+ $(document).on('click', '.drawer-opener', doDrawerOpenClick);
+ $('.drawer-toggle').on('click', doNavbarIconClick);
$('html').on('touchstart mousedown', function (e) {
var clickTarget = $(e.target);
diff --git a/public/scripts/templates/welcome.html b/public/scripts/templates/welcome.html
index 82eb07097..df887c3ad 100644
--- a/public/scripts/templates/welcome.html
+++ b/public/scripts/templates/welcome.html
@@ -1,65 +1,95 @@
- {{displayVersion}}
+ {{displayVersion}}
- Want to update?
+ Want to update?
How to start chatting?
- -
- Click
and select a Chat API.
-
- -
- Click
and pick a character.
-
+ -
+ Click
+
+ and select a
+
+
+ Chat API.
+
+ -
+ Click
+
+ and pick a character.
+
-
-
- You can browse a list of bundled characters in the
-
-
- Download Extensions & Assets
-
-
- menu within
-
-
- .
-
+
+
+ You can add more
+
+ or
+
+ from other websites.
+
+ Go to the
+
+ Download Extensions & Assets
+ menu within
+
+
+
+ to install additional features.
+
+
Confused or lost?
Still have questions?
diff --git a/public/style.css b/public/style.css
index 01a49ab9f..6ee4f6d60 100644
--- a/public/style.css
+++ b/public/style.css
@@ -1208,8 +1208,9 @@ textarea.autoSetHeight {
}
input,
-select {
- font-family: var(--mainFontFamily);
+select,
+button {
+ font-family: var(--mainFontFamily), sans-serif;
font-size: var(--mainFontSize);
color: var(--SmartThemeBodyColor);
}
From ebe2929dfd8ad3f83975ad1fa8ecba37f66cc311 Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Sat, 5 Oct 2024 17:07:17 +0300
Subject: [PATCH 2/7] Localize chat timestamps
---
public/index.html | 2 +-
public/lib/moment-with-locales.min.js | 2 ++
public/lib/moment-with-locales.min.js.map | 1 +
public/lib/moment.min.js | 2 --
public/lib/moment.min.js.map | 1 -
public/scripts/i18n.js | 1 +
6 files changed, 5 insertions(+), 4 deletions(-)
create mode 100644 public/lib/moment-with-locales.min.js
create mode 100644 public/lib/moment-with-locales.min.js.map
delete mode 100644 public/lib/moment.min.js
delete mode 100644 public/lib/moment.min.js.map
diff --git a/public/index.html b/public/index.html
index 132d4d4bf..9a71ba897 100644
--- a/public/index.html
+++ b/public/index.html
@@ -6636,7 +6636,7 @@
-
+
diff --git a/public/lib/moment-with-locales.min.js b/public/lib/moment-with-locales.min.js
new file mode 100644
index 000000000..8a6c9b475
--- /dev/null
+++ b/public/lib/moment-with-locales.min.js
@@ -0,0 +1,2 @@
+!function(e,a){"object"==typeof exports&&"undefined"!=typeof module?module.exports=a():"function"==typeof define&&define.amd?define(a):e.moment=a()}(this,function(){"use strict";var E;function c(){return E.apply(null,arguments)}function F(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function z(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function l(e,a){return Object.prototype.hasOwnProperty.call(e,a)}function N(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var a in e)if(l(e,a))return;return 1}function L(e){return void 0===e}function J(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function R(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function C(e,a){for(var t=[],s=e.length,n=0;n>>0,s=0;sFe(e)?(r=e+1,a-Fe(e)):(r=e,a);return{year:r,dayOfYear:t}}function aa(e,a,t){var s,n,r=Xe(e.year(),a,t),r=Math.floor((e.dayOfYear()-r-1)/7)+1;return r<1?s=r+ta(n=e.year()-1,a,t):r>ta(e.year(),a,t)?(s=r-ta(e.year(),a,t),n=e.year()+1):(n=e.year(),s=r),{week:s,year:n}}function ta(e,a,t){var s=Xe(e,a,t),a=Xe(e+1,a,t);return(Fe(e)-s+a)/7}s("w",["ww",2],"wo","week"),s("W",["WW",2],"Wo","isoWeek"),h("w",r,u),h("ww",r,a),h("W",r,u),h("WW",r,a),Se(["w","ww","W","WW"],function(e,a,t,s){a[s.substr(0,1)]=f(e)});function sa(e,a){return e.slice(a,7).concat(e.slice(0,a))}s("d",0,"do","day"),s("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),s("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),s("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),s("e",0,0,"weekday"),s("E",0,0,"isoWeekday"),h("d",r),h("e",r),h("E",r),h("dd",function(e,a){return a.weekdaysMinRegex(e)}),h("ddd",function(e,a){return a.weekdaysShortRegex(e)}),h("dddd",function(e,a){return a.weekdaysRegex(e)}),Se(["dd","ddd","dddd"],function(e,a,t,s){s=t._locale.weekdaysParse(e,s,t._strict);null!=s?a.d=s:Y(t).invalidWeekday=e}),Se(["d","e","E"],function(e,a,t,s){a[s]=f(e)});var na="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ra="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),da="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),_a=m,ia=m,oa=m;function ma(){function e(e,a){return a.length-e.length}for(var a,t,s,n=[],r=[],d=[],_=[],i=0;i<7;i++)s=U([2e3,1]).day(i),a=we(this.weekdaysMin(s,"")),t=we(this.weekdaysShort(s,"")),s=we(this.weekdays(s,"")),n.push(a),r.push(t),d.push(s),_.push(a),_.push(t),_.push(s);n.sort(e),r.sort(e),d.sort(e),_.sort(e),this._weekdaysRegex=new RegExp("^("+_.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+d.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+r.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+n.join("|")+")","i")}function ua(){return this.hours()%12||12}function la(e,a){s(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),a)})}function Ma(e,a){return a._meridiemParse}s("H",["HH",2],0,"hour"),s("h",["hh",2],0,ua),s("k",["kk",2],0,function(){return this.hours()||24}),s("hmm",0,0,function(){return""+ua.apply(this)+de(this.minutes(),2)}),s("hmmss",0,0,function(){return""+ua.apply(this)+de(this.minutes(),2)+de(this.seconds(),2)}),s("Hmm",0,0,function(){return""+this.hours()+de(this.minutes(),2)}),s("Hmmss",0,0,function(){return""+this.hours()+de(this.minutes(),2)+de(this.seconds(),2)}),la("a",!0),la("A",!1),h("a",Ma),h("A",Ma),h("H",r,M),h("h",r,u),h("k",r,u),h("HH",r,a),h("hh",r,a),h("kk",r,a),h("hmm",ye),h("hmmss",_),h("Hmm",ye),h("Hmmss",_),k(["H","HH"],D),k(["k","kk"],function(e,a,t){e=f(e);a[D]=24===e?0:e}),k(["a","A"],function(e,a,t){t._isPm=t._locale.isPM(e),t._meridiem=e}),k(["h","hh"],function(e,a,t){a[D]=f(e),Y(t).bigHour=!0}),k("hmm",function(e,a,t){var s=e.length-2;a[D]=f(e.substr(0,s)),a[Pe]=f(e.substr(s)),Y(t).bigHour=!0}),k("hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[D]=f(e.substr(0,s)),a[Pe]=f(e.substr(s,2)),a[Oe]=f(e.substr(n)),Y(t).bigHour=!0}),k("Hmm",function(e,a,t){var s=e.length-2;a[D]=f(e.substr(0,s)),a[Pe]=f(e.substr(s))}),k("Hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[D]=f(e.substr(0,s)),a[Pe]=f(e.substr(s,2)),a[Oe]=f(e.substr(n))});m=Ne("Hours",!0);var ha,ca={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ie,monthsShort:Ue,week:{dow:0,doy:6},weekdays:na,weekdaysMin:da,weekdaysShort:ra,meridiemParse:/[ap]\.?m?\.?/i},g={},La={};function Ya(e){return e&&e.toLowerCase().replace("_","-")}function ya(e){for(var a,t,s,n,r=0;r=a&&function(e,a){for(var t=Math.min(e.length,a.length),s=0;s=a-1)break;a--}r++}return ha}function fa(a){var e,t;if(void 0===g[a]&&"undefined"!=typeof module&&module&&module.exports&&(t=a)&&t.match("^[^/\\\\]*$"))try{e=ha._abbr,require("./locale/"+a),ka(e)}catch(e){g[a]=null}return g[a]}function ka(e,a){return e&&((a=L(a)?Da(e):pa(e,a))?ha=a:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),ha._abbr}function pa(e,a){if(null===a)return delete g[e],null;var t,s=ca;if(a.abbr=e,null!=g[e])ae("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=g[e]._config;else if(null!=a.parentLocale)if(null!=g[a.parentLocale])s=g[a.parentLocale]._config;else{if(null==(t=fa(a.parentLocale)))return La[a.parentLocale]||(La[a.parentLocale]=[]),La[a.parentLocale].push({name:e,config:a}),null;s=t._config}return g[e]=new ne(se(s,a)),La[e]&&La[e].forEach(function(e){pa(e.name,e.config)}),ka(e),g[e]}function Da(e){var a;if(!(e=e&&e._locale&&e._locale._abbr?e._locale._abbr:e))return ha;if(!F(e)){if(a=fa(e))return a;e=[e]}return ya(e)}function Ta(e){var a=e._a;return a&&-2===Y(e).overflow&&(a=a[je]<0||11Ce(a[p],a[je])?xe:a[D]<0||24ta(r,i,o)?Y(s)._overflowWeeks=!0:null!=m?Y(s)._overflowWeekday=!0:(u=ea(r,d,_,i,o),s._a[p]=u.year,s._dayOfYear=u.dayOfYear)),null!=e._dayOfYear&&(n=Aa(e._a[p],t[p]),(e._dayOfYear>Fe(n)||0===e._dayOfYear)&&(Y(e)._overflowDayOfYear=!0),m=Qe(n,0,e._dayOfYear),e._a[je]=m.getUTCMonth(),e._a[xe]=m.getUTCDate()),a=0;a<3&&null==e._a[a];++a)e._a[a]=l[a]=t[a];for(;a<7;a++)e._a[a]=l[a]=null==e._a[a]?2===a?1:0:e._a[a];24===e._a[D]&&0===e._a[Pe]&&0===e._a[Oe]&&0===e._a[We]&&(e._nextDay=!0,e._a[D]=0),e._d=(e._useUTC?Qe:$e).apply(null,l),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[D]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(Y(e).weekdayMismatch=!0)}}function Fa(e){if(e._f===c.ISO_8601)Pa(e);else if(e._f===c.RFC_2822)Wa(e);else{e._a=[],Y(e).empty=!0;for(var a,t,s,n,r,d=""+e._i,_=d.length,i=0,o=le(e._f,e._locale).match(_e)||[],m=o.length,u=0;ue.valueOf():e.valueOf()"}),u.toJSON=function(){return this.isValid()?this.toISOString():null},u.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},u.unix=function(){return Math.floor(this.valueOf()/1e3)},u.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},u.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},u.eraName=function(){for(var e,a=this.localeData().eras(),t=0,s=a.length;tthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},u.isLocal=function(){return!!this.isValid()&&!this._isUTC},u.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},u.isUtc=Za,u.isUTC=Za,u.zoneAbbr=function(){return this._isUTC?"UTC":""},u.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},u.dates=e("dates accessor is deprecated. Use date instead.",i),u.months=e("months accessor is deprecated. Use month instead",Ke),u.years=e("years accessor is deprecated. Use year instead",ze),u.zone=e("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,a){return null!=e?(this.utcOffset(e="string"!=typeof e?-e:e,a),this):-this.utcOffset()}),u.isDSTShifted=e("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){var e,a;return L(this._isDSTShifted)&&(Z(e={},this),(e=za(e))._a?(a=(e._isUTC?U:w)(e._a),this._isDSTShifted=this.isValid()&&0>>0,s=0;sAe(e)?(r=e+1,t-Ae(e)):(r=e,t);return{year:r,dayOfYear:n}}function qe(e,t,n){var s,i,r=ze(e.year(),t,n),r=Math.floor((e.dayOfYear()-r-1)/7)+1;return r<1?s=r+P(i=e.year()-1,t,n):r>P(e.year(),t,n)?(s=r-P(e.year(),t,n),i=e.year()+1):(i=e.year(),s=r),{week:s,year:i}}function P(e,t,n){var s=ze(e,t,n),t=ze(e+1,t,n);return(Ae(e)-s+t)/7}s("w",["ww",2],"wo","week"),s("W",["WW",2],"Wo","isoWeek"),t("week","w"),t("isoWeek","W"),n("week",5),n("isoWeek",5),v("w",p),v("ww",p,w),v("W",p),v("WW",p,w),Te(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=g(e)});function Be(e,t){return e.slice(t,7).concat(e.slice(0,t))}s("d",0,"do","day"),s("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),s("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),s("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),s("e",0,0,"weekday"),s("E",0,0,"isoWeekday"),t("day","d"),t("weekday","e"),t("isoWeekday","E"),n("day",11),n("weekday",11),n("isoWeekday",11),v("d",p),v("e",p),v("E",p),v("dd",function(e,t){return t.weekdaysMinRegex(e)}),v("ddd",function(e,t){return t.weekdaysShortRegex(e)}),v("dddd",function(e,t){return t.weekdaysRegex(e)}),Te(["dd","ddd","dddd"],function(e,t,n,s){s=n._locale.weekdaysParse(e,s,n._strict);null!=s?t.d=s:m(n).invalidWeekday=e}),Te(["d","e","E"],function(e,t,n,s){t[s]=g(e)});var Je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Qe="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Xe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Ke=k,et=k,tt=k;function nt(){function e(e,t){return t.length-e.length}for(var t,n,s,i=[],r=[],a=[],o=[],u=0;u<7;u++)s=l([2e3,1]).day(u),t=M(this.weekdaysMin(s,"")),n=M(this.weekdaysShort(s,"")),s=M(this.weekdays(s,"")),i.push(t),r.push(n),a.push(s),o.push(t),o.push(n),o.push(s);i.sort(e),r.sort(e),a.sort(e),o.sort(e),this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+r.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function st(){return this.hours()%12||12}function it(e,t){s(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function rt(e,t){return t._meridiemParse}s("H",["HH",2],0,"hour"),s("h",["hh",2],0,st),s("k",["kk",2],0,function(){return this.hours()||24}),s("hmm",0,0,function(){return""+st.apply(this)+r(this.minutes(),2)}),s("hmmss",0,0,function(){return""+st.apply(this)+r(this.minutes(),2)+r(this.seconds(),2)}),s("Hmm",0,0,function(){return""+this.hours()+r(this.minutes(),2)}),s("Hmmss",0,0,function(){return""+this.hours()+r(this.minutes(),2)+r(this.seconds(),2)}),it("a",!0),it("A",!1),t("hour","h"),n("hour",13),v("a",rt),v("A",rt),v("H",p),v("h",p),v("k",p),v("HH",p,w),v("hh",p,w),v("kk",p,w),v("hmm",ge),v("hmmss",we),v("Hmm",ge),v("Hmmss",we),D(["H","HH"],x),D(["k","kk"],function(e,t,n){e=g(e);t[x]=24===e?0:e}),D(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),D(["h","hh"],function(e,t,n){t[x]=g(e),m(n).bigHour=!0}),D("hmm",function(e,t,n){var s=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s)),m(n).bigHour=!0}),D("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s,2)),t[N]=g(e.substr(i)),m(n).bigHour=!0}),D("Hmm",function(e,t,n){var s=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s))}),D("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s,2)),t[N]=g(e.substr(i))});k=de("Hours",!0);var at,ot={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ce,monthsShort:Ue,week:{dow:0,doy:6},weekdays:Je,weekdaysMin:Xe,weekdaysShort:Qe,meridiemParse:/[ap]\.?m?\.?/i},R={},ut={};function lt(e){return e&&e.toLowerCase().replace("_","-")}function ht(e){for(var t,n,s,i,r=0;r=t&&function(e,t){for(var n=Math.min(e.length,t.length),s=0;s=t-1)break;t--}r++}return at}function dt(t){var e;if(void 0===R[t]&&"undefined"!=typeof module&&module&&module.exports&&null!=t.match("^[^/\\\\]*$"))try{e=at._abbr,require("./locale/"+t),ct(e)}catch(e){R[t]=null}return R[t]}function ct(e,t){return e&&((t=o(t)?mt(e):ft(e,t))?at=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),at._abbr}function ft(e,t){if(null===t)return delete R[e],null;var n,s=ot;if(t.abbr=e,null!=R[e])Q("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=R[e]._config;else if(null!=t.parentLocale)if(null!=R[t.parentLocale])s=R[t.parentLocale]._config;else{if(null==(n=dt(t.parentLocale)))return ut[t.parentLocale]||(ut[t.parentLocale]=[]),ut[t.parentLocale].push({name:e,config:t}),null;s=n._config}return R[e]=new K(X(s,t)),ut[e]&&ut[e].forEach(function(e){ft(e.name,e.config)}),ct(e),R[e]}function mt(e){var t;if(!(e=e&&e._locale&&e._locale._abbr?e._locale._abbr:e))return at;if(!a(e)){if(t=dt(e))return t;e=[e]}return ht(e)}function _t(e){var t=e._a;return t&&-2===m(e).overflow&&(t=t[O]<0||11We(t[Y],t[O])?b:t[x]<0||24P(r,u,l)?m(s)._overflowWeeks=!0:null!=h?m(s)._overflowWeekday=!0:(d=$e(r,a,o,u,l),s._a[Y]=d.year,s._dayOfYear=d.dayOfYear)),null!=e._dayOfYear&&(i=bt(e._a[Y],n[Y]),(e._dayOfYear>Ae(i)||0===e._dayOfYear)&&(m(e)._overflowDayOfYear=!0),h=Ze(i,0,e._dayOfYear),e._a[O]=h.getUTCMonth(),e._a[b]=h.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=c[t]=n[t];for(;t<7;t++)e._a[t]=c[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[x]&&0===e._a[T]&&0===e._a[N]&&0===e._a[Ne]&&(e._nextDay=!0,e._a[x]=0),e._d=(e._useUTC?Ze:je).apply(null,c),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[x]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(m(e).weekdayMismatch=!0)}}function Tt(e){if(e._f===f.ISO_8601)St(e);else if(e._f===f.RFC_2822)Ot(e);else{e._a=[],m(e).empty=!0;for(var t,n,s,i,r,a=""+e._i,o=a.length,u=0,l=ae(e._f,e._locale).match(te)||[],h=l.length,d=0;de.valueOf():e.valueOf()"}),i.toJSON=function(){return this.isValid()?this.toISOString():null},i.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},i.unix=function(){return Math.floor(this.valueOf()/1e3)},i.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},i.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},i.eraName=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;nthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},i.isLocal=function(){return!!this.isValid()&&!this._isUTC},i.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},i.isUtc=At,i.isUTC=At,i.zoneAbbr=function(){return this._isUTC?"UTC":""},i.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},i.dates=e("dates accessor is deprecated. Use date instead.",ke),i.months=e("months accessor is deprecated. Use month instead",Ge),i.years=e("years accessor is deprecated. Use year instead",Ie),i.zone=e("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?(this.utcOffset(e="string"!=typeof e?-e:e,t),this):-this.utcOffset()}),i.isDSTShifted=e("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var e,t={};return $(t,this),(t=Nt(t))._a?(e=(t._isUTC?l:W)(t._a),this._isDSTShifted=this.isValid()&&0 response.json());
localeData = await getLocaleData(localeFile);
applyLocale();
From 60fef3ee99705be644c25e578b666344af8af81d Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Sat, 5 Oct 2024 19:45:41 +0300
Subject: [PATCH 3/7] Restyle welcome
---
public/script.js | 4 +-
public/scripts/templates/welcome.html | 149 +++++++++++++-------------
public/style.css | 6 ++
3 files changed, 81 insertions(+), 78 deletions(-)
diff --git a/public/script.js b/public/script.js
index d82373400..7651cf3fd 100644
--- a/public/script.js
+++ b/public/script.js
@@ -658,7 +658,7 @@ async function getSystemMessages() {
is_user: false,
is_system: true,
uses_system_ui: true,
- mes: await renderTemplateAsync('welcome', { displayVersion } ),
+ mes: await renderTemplateAsync('welcome', { displayVersion }),
},
group: {
name: systemUserName,
@@ -9106,7 +9106,7 @@ function doDrawerOpenClick() {
const drawer = $(`#${targetDrawerID}`);
const drawerToggle = drawer.find('.drawer-toggle');
const drawerWasOpenAlready = drawerToggle.parent().find('.drawer-content').hasClass('openDrawer');
- if (drawerWasOpenAlready || drawer.hasClass('resizing') ) { return; }
+ if (drawerWasOpenAlready || drawer.hasClass('resizing')) { return; }
doNavbarIconClick.call(drawerToggle);
}
diff --git a/public/scripts/templates/welcome.html b/public/scripts/templates/welcome.html
index df887c3ad..eaf49b986 100644
--- a/public/scripts/templates/welcome.html
+++ b/public/scripts/templates/welcome.html
@@ -1,95 +1,92 @@
- {{displayVersion}}
+ {{displayVersion}}
- Want to update?
+ Want to update?
-
How to start chatting?
- -
- Click
-
- and select a
-
-
- Chat API.
-
- -
- Click
-
- and pick a character.
-
+ -
+ Click
+
+ and connect to an
+
+
+ API.
+
+ -
+ Click
+
+ and pick a character.
+
-
- You can add more
-
- or
-
- from other websites.
+
+ You can add more
+
+ or
+
+ from other websites.
+
+
+ Go to the
- Go to the
+ Download Extensions & Assets
+ menu within
- Download Extensions & Assets
- menu within
+
-
+ to install additional features.
+
- to install additional features.
-
-
-
Confused or lost?
-
Still have questions?
-
diff --git a/public/style.css b/public/style.css
index 6ee4f6d60..8bb8d5809 100644
--- a/public/style.css
+++ b/public/style.css
@@ -314,6 +314,12 @@ input[type='checkbox']:focus-visible {
display: inline-block;
}
+.mes_text ol,
+.mes_text ul {
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
.mes_text br,
.mes_bias br {
content: ' ';
From 24300642dd6cdf678b9da03bf2b88874f0d00ac2 Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Sat, 5 Oct 2024 19:48:20 +0300
Subject: [PATCH 4/7] Cleaner HTML Diff
---
public/scripts/templates/welcome.html | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/public/scripts/templates/welcome.html b/public/scripts/templates/welcome.html
index eaf49b986..202609012 100644
--- a/public/scripts/templates/welcome.html
+++ b/public/scripts/templates/welcome.html
@@ -57,9 +57,7 @@
Confused or lost?
-
- - click these
- icons!
+ - click these icons!
-
Enter
/?
in the chat bar
@@ -84,8 +82,7 @@
-
-
+
Contact the developers
From 1055f2e1b74c2f91afe3aa84d473010174d9a939 Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Sat, 5 Oct 2024 20:09:54 +0300
Subject: [PATCH 5/7] Support more pairs of international quotes
---
public/script.js | 34 ++++++++++++++++++++++++++--------
1 file changed, 26 insertions(+), 8 deletions(-)
diff --git a/public/script.js b/public/script.js
index 872932e63..6077b0b7c 100644
--- a/public/script.js
+++ b/public/script.js
@@ -2002,15 +2002,33 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, san
});
}
- mes = mes.replace(/```[\s\S]*?```|``[\s\S]*?``|`[\s\S]*?`|(".+?")|(\u201C.+?\u201D)/gm, function (match, p1, p2) {
- if (p1) {
- return '"' + p1.replace(/"/g, '') + '"
';
- } else if (p2) {
- return '“' + p2.replace(/\u201C|\u201D/g, '') + '”
';
- } else {
- return match;
+ mes = mes.replace(
+ /```[\s\S]*?```|``[\s\S]*?``|`[\s\S]*?`|(".*?")|(\u201C.*?\u201D)|(\u00AB.*?\u00BB)|(\u300C.*?\u300D)|(\u300E.*?\u300F)|(\uFF02.*?\uFF02)/gm,
+ function (match, p1, p2, p3, p4, p5, p6) {
+ if (p1) {
+ // English double quotes
+ return `"${p1.slice(1, -1)}"
`;
+ } else if (p2) {
+ // Curly double quotes “ ”
+ return `“${p2.slice(1, -1)}”
`;
+ } else if (p3) {
+ // Guillemets « »
+ return `«${p3.slice(1, -1)}»
`;
+ } else if (p4) {
+ // Corner brackets 「 」
+ return `「${p4.slice(1, -1)}」
`;
+ } else if (p5) {
+ // White corner brackets 『 』
+ return `『${p5.slice(1, -1)}』
`;
+ } else if (p6) {
+ // Fullwidth quotes " "
+ return `"${p6.slice(1, -1)}"
`;
+ } else {
+ // Return the original match if no quotes are found
+ return match;
+ }
}
- });
+ );
// Restore double quotes in tags
if (!power_user.encode_tags) {
From a5be8898527c2ded026fb1faa0f33c181050a457 Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Sat, 5 Oct 2024 20:14:07 +0300
Subject: [PATCH 6/7] Extend quote list for TTS
---
public/scripts/extensions/tts/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/scripts/extensions/tts/index.js b/public/scripts/extensions/tts/index.js
index 802d51f9c..4c5314af0 100644
--- a/public/scripts/extensions/tts/index.js
+++ b/public/scripts/extensions/tts/index.js
@@ -474,7 +474,7 @@ async function processTtsQueue() {
}
if (extension_settings.tts.narrate_quoted_only) {
- const special_quotes = /[“”«»]/g; // Extend this regex to include other special quotes
+ const special_quotes = /[“”«»「」『』""]/g; // Extend this regex to include other special quotes
text = text.replace(special_quotes, '"');
const matches = text.match(/".*?"/g); // Matches text inside double quotes, non-greedily
const partJoiner = (ttsProvider?.separator || ' ... ');
From 912525fdd9c546b57a1b818fa56744d999b2fa3e Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Sun, 6 Oct 2024 19:13:01 +0300
Subject: [PATCH 7/7] Add missing import
---
public/scripts/group-chats.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js
index aebf565f6..237cd4021 100644
--- a/public/scripts/group-chats.js
+++ b/public/scripts/group-chats.js
@@ -70,12 +70,12 @@ import {
animation_duration,
depth_prompt_role_default,
shouldAutoContinue,
- this_chid,
} from '../script.js';
import { printTagList, createTagMapFromList, applyTagsOnCharacterSelect, tag_map, applyTagsOnGroupSelect } from './tags.js';
import { FILTER_TYPES, FilterHelper } from './filters.js';
import { isExternalMediaAllowed } from './chats.js';
import { POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
+import { t } from './i18n.js';
export {
selected_group,