Merge branch 'SillyTavern:staging' into staging
This commit is contained in:
commit
2637f94240
|
@ -6,6 +6,7 @@ public/backgrounds/
|
|||
public/groups/
|
||||
public/group chats/
|
||||
public/worlds/
|
||||
public/user/
|
||||
public/css/bg_load.css
|
||||
public/themes/
|
||||
public/OpenAI Settings/
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* Extensions */
|
||||
#extensions_url {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#extensions_status {
|
||||
/* margin-bottom: 10px; */
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.extensions_block input[type="submit"]:hover {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.extensions_block input[type="checkbox"] {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
label[for="extensions_autoconnect"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.extensions_url_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.extensions_url_block h4 {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.extensions_block {
|
||||
clear: both;
|
||||
padding: 0.05px;
|
||||
}
|
||||
|
||||
.extensions_info {
|
||||
text-align: left;
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
.extensions_info h3 {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.extensions_info h4 {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.extensions_info p {
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.extensions_info .disabled {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.extensions_info .toggle_enable {
|
||||
color: lightgreen;
|
||||
}
|
||||
|
||||
.extensions_info .toggle_disable {
|
||||
color: rgb(238, 144, 144);
|
||||
}
|
||||
|
||||
.extensions_info .extension_enabled {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.extensions_info .extension_disabled {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.extensions_info .extension_missing {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
input.extension_missing[type="checkbox"] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#extensions_list .disabled {
|
||||
text-decoration: line-through;
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.update-button {
|
||||
margin-right: 10px;
|
||||
display: inline-flex;
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
.avatar_collage {
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar_collage img {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.collage_2 .img_1 {
|
||||
left: 0;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 100%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.collage_2 .img_2 {
|
||||
left: 50%;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 100%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.collage_3 .img_1 {
|
||||
left: 0;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_3 .img_2 {
|
||||
left: 50%;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_3 .img_3 {
|
||||
left: 0;
|
||||
top: 50%;
|
||||
max-width: 100%;
|
||||
max-height: 50%;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_4 .img_1 {
|
||||
left: 0;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_4 .img_2 {
|
||||
left: 50%;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_4 .img_3 {
|
||||
left: 0;
|
||||
top: 50%;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_4 .img_4 {
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
|
@ -0,0 +1,419 @@
|
|||
/*will apply to anything 1000px or less. this catches ipads, horizontal phones, and vertical phones)*/
|
||||
@media screen and (max-width: 1000px) {
|
||||
|
||||
.bg_button {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mes_text img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#extensions_settings,
|
||||
#extensions_settings2 {
|
||||
width: 100% !important;
|
||||
min-width: 100% !important;
|
||||
}
|
||||
|
||||
body:not(.waifuMode) .zoomed_avatar {
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 30;
|
||||
overflow: hidden;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
top: 50px;
|
||||
aspect-ratio: 2 / 3;
|
||||
width: fit-content;
|
||||
max-height: calc(60vh - 60px);
|
||||
max-height: calc(60svh - 60px);
|
||||
max-width: 90vw;
|
||||
max-width: 90svw;
|
||||
}
|
||||
|
||||
.world_entry_thin_controls,
|
||||
#persona-management-block,
|
||||
#character_popup .flex-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#WIMultiSelector {
|
||||
align-self: normal;
|
||||
}
|
||||
|
||||
.WIEntryContentAndMemo {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.WIEntryContentAndMemo .world_entry_thin_controls {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.world_entry_form_control.world_entry_form_horizontal {
|
||||
/* flex-direction: column; */
|
||||
align-items: flex-start;
|
||||
row-gap: 0.5rem;
|
||||
}
|
||||
|
||||
.world_entry_form_control.world_entry_form_horizontal .world_popup_expander {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* #world_popup_header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
} */
|
||||
|
||||
#world_popup_header .world_popup_expander {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body {
|
||||
touch-action: none;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
|
||||
}
|
||||
|
||||
.drawer-content {
|
||||
min-width: unset;
|
||||
width: 100%;
|
||||
max-height: calc(100vh - 45px);
|
||||
max-height: calc(100svh - 45px);
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 5px;
|
||||
border: 1px solid var(--grey30);
|
||||
}
|
||||
|
||||
#select_chat_popup {
|
||||
align-items: start;
|
||||
height: min-content;
|
||||
align-content: start;
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
#top-settings-holder,
|
||||
#top-bar {
|
||||
position: fixed;
|
||||
padding-top: 8px;
|
||||
width: 100vw;
|
||||
width: 100svw;
|
||||
}
|
||||
|
||||
#bg1,
|
||||
#bg_custom {
|
||||
height: 100vh !important;
|
||||
height: 100svh !important;
|
||||
width: 100vw !important;
|
||||
width: 100svw !important;
|
||||
background-position: center;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#sheld,
|
||||
#character_popup,
|
||||
.drawer-content
|
||||
|
||||
/* ,
|
||||
#world_popup */
|
||||
{
|
||||
max-height: calc(100vh - 40px);
|
||||
max-height: calc(100svh - 40px);
|
||||
width: 100% !important;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
left: 0 !important;
|
||||
resize: none !important;
|
||||
top: 40px;
|
||||
}
|
||||
|
||||
.wi-settings {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#character_popup,
|
||||
#world_popup {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#character_popup,
|
||||
#send_form {
|
||||
border: 1px solid var(--grey30);
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2));
|
||||
max-width: 100dvw;
|
||||
}
|
||||
|
||||
#chat {
|
||||
border-left: 1px solid var(--grey30);
|
||||
border-right: 1px solid var(--grey30);
|
||||
border-bottom: 1px solid var(--grey30);
|
||||
align-items: start;
|
||||
align-content: start;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden
|
||||
}
|
||||
|
||||
.mes_buttons {
|
||||
font-size: calc(var(--mainFontSize)*1.2);
|
||||
}
|
||||
|
||||
.drag-grabber,
|
||||
.pull-tab {
|
||||
display: none !important;
|
||||
|
||||
}
|
||||
|
||||
#showRawPrompt,
|
||||
#groupCurrentMemberPopoutButton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#right-nav-panel,
|
||||
#left-nav-panel,
|
||||
#floatingPrompt,
|
||||
#cfgConfig {
|
||||
height: calc(100vh - 45px);
|
||||
height: calc(100svh - 45px);
|
||||
min-width: 100% !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
overflow-y: hidden;
|
||||
border-left: 1px solid var(--grey30);
|
||||
border-right: 1px solid var(--grey30);
|
||||
border-bottom: 1px solid var(--grey30);
|
||||
border-radius: 0 0 20px 20px;
|
||||
top: 40px !important;
|
||||
left: 0 !important;
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2));
|
||||
}
|
||||
|
||||
#floatingPrompt,
|
||||
#cfgConfig {
|
||||
height: min-content;
|
||||
}
|
||||
|
||||
#right-nav-panel h4 {
|
||||
margin: 5px auto;
|
||||
}
|
||||
|
||||
#result_info {
|
||||
font-size: calc(var(--mainFontSize) - .1rem);
|
||||
}
|
||||
|
||||
/* .avatar_div {
|
||||
margin-top: 5px;
|
||||
} */
|
||||
|
||||
#character_popup {
|
||||
width: 100%;
|
||||
border-radius: 0 0 20px 20px;
|
||||
margin-top: 0px;
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.drawer25pWidth {
|
||||
flex-basis: max(calc(100% / 4 - 10px), 190px);
|
||||
}
|
||||
|
||||
.drawer33pWidth {
|
||||
flex-basis: max(calc(100% / 3 - 10px), 190px);
|
||||
}
|
||||
|
||||
.expression-holder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.waifuMode #sheld {
|
||||
height: 40vh;
|
||||
height: 40svh;
|
||||
top: 60vh;
|
||||
top: 60svh;
|
||||
bottom: 0 !important;
|
||||
}
|
||||
|
||||
body.waifuMode .expression-holder {
|
||||
/*display: inline;*/
|
||||
|
||||
max-width: 100vw;
|
||||
height: 100vh;
|
||||
width: max-content;
|
||||
margin: 0 auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
body.waifuMode img.expression {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
body.waifuMode .zoomed_avatar {
|
||||
width: fit-content;
|
||||
max-height: calc(60vh - 60px);
|
||||
max-height: calc(60svh - 60px);
|
||||
max-width: 90vw;
|
||||
max-width: 90svw;
|
||||
}
|
||||
|
||||
.scrollableInner {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: calc(100vh - 90px);
|
||||
max-height: calc(100svh - 90px);
|
||||
}
|
||||
|
||||
.horde_multiple_hint {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#bg_menu_content {
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
/*landscape mode phones and ipads*/
|
||||
@media screen and (max-width: 1000px) and (orientation: landscape) {
|
||||
body.waifuMode img.expression {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.tag.excluded:after {
|
||||
top: unset;
|
||||
bottom: unset;
|
||||
}
|
||||
|
||||
body:not(.waifuMode) .zoomed_avatar {
|
||||
|
||||
width: fit-content;
|
||||
max-height: calc(60vh - 60px);
|
||||
max-height: calc(60svh - 60px);
|
||||
max-width: 90vw;
|
||||
max-width: 90svw;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*portrait mode phones*/
|
||||
@media screen and (max-width: 450px) {
|
||||
|
||||
body:not(.waifuMode) .zoomed_avatar {
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
max-height: 50vh;
|
||||
max-width: 50vh;
|
||||
width: 50vw;
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 30;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
top: 50px;
|
||||
aspect-ratio: 2 / 3;
|
||||
}
|
||||
|
||||
.drawer25pWidth {
|
||||
flex-basis: max(calc(100% / 2 - 10px), 180px);
|
||||
}
|
||||
|
||||
.drawer33pWidth {
|
||||
flex-basis: max(calc(100% / 2 - 10px), 180px);
|
||||
}
|
||||
|
||||
.BGSampleTitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tag.excluded:after {
|
||||
top: unset;
|
||||
bottom: unset;
|
||||
}
|
||||
}
|
||||
|
||||
/*iOS specific*/
|
||||
@supports (-webkit-touch-callout: none) {
|
||||
body {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#top-bar {
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
#sheld {
|
||||
margin: unset;
|
||||
padding: unset;
|
||||
width: unset;
|
||||
height: unset;
|
||||
min-width: unset;
|
||||
max-width: unset;
|
||||
min-height: unset;
|
||||
max-height: unset;
|
||||
width: 100vw;
|
||||
width: 100svw;
|
||||
height: calc(100vh - 40px);
|
||||
height: calc(100svh - 40px);
|
||||
padding-right: max(env(safe-area-inset-right), 0px);
|
||||
padding-left: max(env(safe-area-inset-left), 0px);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
body.PWA #sheld {
|
||||
padding-right: max(env(safe-area-inset-right), 2px);
|
||||
padding-left: max(env(safe-area-inset-left), 2px);
|
||||
padding-bottom: max(env(safe-area-inset-bottom), 15px);
|
||||
|
||||
}
|
||||
|
||||
#character_popup,
|
||||
#world_popup,
|
||||
#left-nav-panel,
|
||||
#right-nav-panel,
|
||||
.drawer-content {
|
||||
width: unset;
|
||||
height: unset;
|
||||
min-width: unset;
|
||||
max-width: unset;
|
||||
min-height: unset;
|
||||
max-height: unset;
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2));
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin: 0 auto;
|
||||
height: calc(100vh - 70px);
|
||||
height: calc(100svh - 70px);
|
||||
width: calc(100% - 5px);
|
||||
max-height: calc(100vh - 70px);
|
||||
max-height: calc(100svh - 70px);
|
||||
max-width: calc(100% - 5px);
|
||||
|
||||
}
|
||||
|
||||
#character_popup,
|
||||
#world_popup,
|
||||
.drawer-content {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.scrollableInner {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#horde_model {
|
||||
height: unset;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
/* GROUP CHATS */
|
||||
|
||||
.group_pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#rm_group_chats_block .tag.filterByGroups {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#rm_button_group_chats h2 {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
color: rgb(188, 193, 200, 1);
|
||||
border: 1px solid #333;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
padding: 6px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#rm_group_chats_block {
|
||||
display: none;
|
||||
align-items: flex-start;
|
||||
padding: 0 5px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#rm_group_chats_block h3,
|
||||
#rm_group_chats_block h5 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#rm_group_buttons>div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#rm_group_buttons .checkbox {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#rm_group_buttons .checkbox h4 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#rm_group_buttons>input {
|
||||
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#rm_group_buttons>input:disabled {
|
||||
filter: brightness(0.3);
|
||||
cursor: unset;
|
||||
}
|
||||
|
||||
#rm_group_members,
|
||||
#rm_group_add_members {
|
||||
margin-top: 0.25rem;
|
||||
margin-bottom: 0.5rem;
|
||||
border: 1px solid grey;
|
||||
border-radius: 10px;
|
||||
background-color: var(--black30a);
|
||||
}
|
||||
|
||||
#rm_group_buttons_expander {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#rm_group_delete {
|
||||
color: rgb(190, 0, 0);
|
||||
}
|
||||
|
||||
#rm_group_members:empty {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#rm_group_members:empty::before {
|
||||
content: 'Group is empty';
|
||||
|
||||
font-weight: bolder;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
#rm_group_add_members:empty {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#rm_group_add_members_header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
column-gap: 10px;
|
||||
}
|
||||
|
||||
#rm_group_add_members_header input {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#rm_group_add_members:empty::before {
|
||||
content: 'No characters available';
|
||||
|
||||
font-weight: bolder;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.group_member_icon {
|
||||
display: flex;
|
||||
column-gap: 10px;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.group_member {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.group_member .group_member_name {
|
||||
flex-grow: 1;
|
||||
margin-left: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: calc(100% - 110px);
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.group_member_icon .flex-container {
|
||||
gap: 0px;
|
||||
}
|
||||
|
||||
#rm_group_members .right_menu_button,
|
||||
#rm_group_add_members .right_menu_button {
|
||||
padding: 0px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#rm_group_members .right_menu_button[data-action="speak"],
|
||||
#rm_group_members .group_member:not(.disabled) .right_menu_button[data-action="disable"] {
|
||||
opacity: 0.4;
|
||||
filter: brightness(0.5);
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
/* #rm_group_members .right_menu_button[data-action="speak"]:hover, */
|
||||
#rm_group_members .group_member:not(.disabled) .right_menu_button[data-action="disable"]:hover {
|
||||
opacity: inherit;
|
||||
filter: drop-shadow(0px 0px 5px rgb(243, 166, 65));
|
||||
}
|
||||
|
||||
#rm_group_members .group_member.disabled .right_menu_button[data-action="enable"] {
|
||||
filter: drop-shadow(0px 0px 5px rgb(243, 166, 65));
|
||||
}
|
||||
|
||||
|
||||
#rm_group_members .right_menu_button[data-action="speak"]:hover {
|
||||
opacity: inherit;
|
||||
filter: drop-shadow(0px 0px 5px rgb(153, 255, 153));
|
||||
}
|
||||
|
||||
/* Rules for icon display */
|
||||
#rm_group_add_members .right_menu_button:not([data-action="add"], [data-action="view"]),
|
||||
#rm_group_members .right_menu_button[data-action="add"],
|
||||
#rm_group_members .group_member.disabled .right_menu_button[data-action="disable"],
|
||||
#rm_group_members .group_member:not(.disabled) .right_menu_button[data-action="enable"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.group_select {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.group_select:hover {
|
||||
background-color: var(--white30a);
|
||||
}
|
||||
|
||||
.group_select .avatar {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.group_select .group_icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.group_select .group_fav_icon {
|
||||
filter: drop-shadow(0px 0px 1px black);
|
||||
color: #c5b457;
|
||||
font-size: 12px;
|
||||
order: -1;
|
||||
margin-left: -18px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.group_member .avatar {
|
||||
flex-shrink: 0;
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/* Customize the Select2 container */
|
||||
.select2-container {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
/* Customize the dropdown */
|
||||
.select2-dropdown {
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
border: 1px solid var(--white30a) !important;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 5px black;
|
||||
text-shadow: 0px 0px calc(var(--shadowWidth) * 1px) var(--SmartThemeShadowColor);
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)*2));
|
||||
color: var(--SmartThemeBodyColor);
|
||||
z-index: 40000;
|
||||
}
|
||||
|
||||
.select2-selection__clear {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice__remove {
|
||||
padding: revert;
|
||||
border-right: 1px solid var(--white30a);
|
||||
font-size: 1.1em;
|
||||
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice__display {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
/* Customize the search input */
|
||||
.select2-search__field {
|
||||
background-color: var(--black30a);
|
||||
color: var(--SmartThemeBodyColor);
|
||||
border: 1px solid var(--white30a);
|
||||
border-radius: 7px;
|
||||
font-family: "Noto Sans", "Noto Color Emoji", sans-serif;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
/* Customize the selected option */
|
||||
.select2-selection--single {
|
||||
border: 1px solid var(--SmartThemeShadowColor);
|
||||
border-radius: 4px;
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
}
|
||||
|
||||
/* Customize the selected option text */
|
||||
.select2-selection__rendered {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
/* Customize the option list item */
|
||||
.select2-results__option {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple {
|
||||
background-color: var(--black30a);
|
||||
color: var(--SmartThemeBodyColor);
|
||||
border: 1px solid var(--white30a);
|
||||
border-radius: 7px;
|
||||
font-family: "Noto Sans", "Noto Color Emoji", sans-serif;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
.select2-container.select2-container--focus .select2-selection--multiple {
|
||||
border: 1px solid var(--white30a);
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice {
|
||||
border-radius: 5px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-sizing: border-box;
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: var(--black30a);
|
||||
border-color: var(--white30a);
|
||||
font-size: calc(var(--mainFontSize) - 5%);
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
.select2-results .select2-results__option--selectable {
|
||||
background-color: unset;
|
||||
color: var(--SmartThemeBodyColor);
|
||||
opacity: 0.5;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Customize the hovered option list item */
|
||||
.select2-results .select2-results__option--highlighted.select2-results__option--selectable {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: unset;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Customize the option list item */
|
||||
.select2-results__option {
|
||||
padding-left: 30px;
|
||||
/* Add some padding to make room for the checkbox */
|
||||
}
|
||||
|
||||
/* Add the custom checkbox */
|
||||
.select2-results__option:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border: 1px solid var(--white30a);
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice__remove {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
/* Add the custom checkbox checkmark */
|
||||
.select2-results__option--selected.select2-results__option:before {
|
||||
content: '\2713';
|
||||
font-weight: bold;
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
text-align: center;
|
||||
line-height: 14px;
|
||||
}
|
|
@ -0,0 +1,419 @@
|
|||
.text_warning {
|
||||
color: rgb(220 173 16);
|
||||
}
|
||||
|
||||
.text_danger {
|
||||
color: var(--fullred);
|
||||
}
|
||||
|
||||
.m-t-1 {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.m-t-2 {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.m-t-3 {
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
.m-t-4 {
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
.m-t-5 {
|
||||
margin-top: 5em;
|
||||
}
|
||||
|
||||
.m-b-1 {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.m-b-2 {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.m-b-3 {
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
|
||||
.m-b-4 {
|
||||
margin-bottom: 4em;
|
||||
}
|
||||
|
||||
.m-b-5 {
|
||||
margin-bottom: 5em;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.margin-bot-10px,
|
||||
.marginBot10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.marginTop10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.marginBot5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.marginTop5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.marginTopBot5 {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.margin5 {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.overflowYAuto {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.heightMinContent {
|
||||
height: min-content;
|
||||
}
|
||||
|
||||
.justifySpaceBetween {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.alignitemsflexstart {
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.alignItemsFlexEnd {
|
||||
align-items: flex-end !important;
|
||||
}
|
||||
|
||||
.alignSelfStart {
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.gap5px {
|
||||
gap: 5px !important;
|
||||
}
|
||||
|
||||
.gap10px {
|
||||
gap: 10px !important;
|
||||
}
|
||||
|
||||
.wide10pMinFit {
|
||||
width: 10%;
|
||||
min-width: fit-content;
|
||||
}
|
||||
|
||||
.wide100pLess70px {
|
||||
width: calc(100% - 70px);
|
||||
}
|
||||
|
||||
.wideMax100px {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.widthUnset {
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.no-border {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.no-shadow {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.height100pSpaceEvenly {
|
||||
align-content: space-evenly;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.height32px {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.TxtLrgBoldCenter {
|
||||
text-align: center;
|
||||
font-size: large;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.margin-right-10px {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
.success {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.failure {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.optional {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.monospace {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.expander {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.redOverlayGlow {
|
||||
color: #800;
|
||||
opacity: 0.8 !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
.width100p {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.flexNoGap {
|
||||
gap: unset !important;
|
||||
}
|
||||
|
||||
.flexGrow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.flexnowrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.alignitemscenter {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.alignitemsstart {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.overflow-hidden {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.maxWidth200px {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.alignContentFlexStart {
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.overflowHidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.padding5 {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.padding10 {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.margin0 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.margin0auto {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.margin-r5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.flex1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex2 {
|
||||
flex: 2 !important;
|
||||
}
|
||||
|
||||
.flexFlowColumn {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.wideMinContent {
|
||||
width: min-content;
|
||||
}
|
||||
|
||||
.flexWide50p {
|
||||
flex: 50%;
|
||||
}
|
||||
|
||||
.wide50p {
|
||||
width: 50% !important;
|
||||
}
|
||||
|
||||
.wide25p {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.wide30p {
|
||||
width: 30% !important;
|
||||
}
|
||||
|
||||
.justifyLeft {
|
||||
text-align: start;
|
||||
justify-content: left;
|
||||
margin-left: unset;
|
||||
}
|
||||
|
||||
.justifyCenter {
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.justifyContentSpaceAround {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.justifyContentFlexStart {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.justifyContentFlexEnd {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.spaceEvenly {
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.spaceBetween {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.widthNatural {
|
||||
width: unset !important;
|
||||
min-width: unset !important;
|
||||
max-width: unset !important;
|
||||
}
|
||||
|
||||
.widthFreeExpand {
|
||||
width: -webkit-fill-available;
|
||||
width: -moz-available;
|
||||
}
|
||||
|
||||
.wide100p {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wide50p {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.wide50px {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.indent20p {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
/*used to fix smallness of certain FontAwesome glyph which break button squareness*/
|
||||
/*currently used on: CharList Import*/
|
||||
|
||||
.faSmallFontSquareFix {
|
||||
font-size: calc(var(--mainFontSize) *1.25);
|
||||
width: calc(var(--mainFontSize) *1.95);
|
||||
}
|
||||
|
||||
.textarea_compact {
|
||||
font-size: calc(var(--mainFontSize) * 0.9);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.katex-html {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hoverglow:hover {
|
||||
opacity: 1 !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.debug-red {
|
||||
border: 1px solid red !important;
|
||||
}
|
||||
|
||||
.debug-yellow {
|
||||
border: 1px solid yellow !important;
|
||||
}
|
||||
|
||||
.debug-green {
|
||||
border: 1px solid green !important;
|
||||
}
|
||||
|
||||
.debug-blue {
|
||||
border: 1px solid blue !important;
|
||||
}
|
||||
|
||||
.debug-purple {
|
||||
border: 1px solid purple !important;
|
||||
}
|
||||
|
||||
.fontsize80p {
|
||||
font-size: calc(var(--mainFontSize) * 0.8) !important;
|
||||
}
|
||||
|
||||
.fontsize60p {
|
||||
font-size: calc(var(--mainFontSize) * 0.6) !important;
|
||||
}
|
||||
|
||||
.paddingTopBot5 {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.paddingLeftRight5 {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.heightFitContent {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.widthFitContent {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.flexGap5 {
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.flexGap10 {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.opacity1 {
|
||||
opacity: 1 !important;
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
#tags_div {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.tag_controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tag_view_item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: baseline;
|
||||
gap: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.tag_view_name {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tag_view_counter {
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.tag_delete {
|
||||
padding-right: 0;
|
||||
color: var(--SmartThemeBodyColor) !important;
|
||||
}
|
||||
|
||||
.tag {
|
||||
border-radius: 5px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-sizing: border-box;
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: var(--black30a);
|
||||
border-color: var(--white50a);
|
||||
padding: 0.1rem 0.2rem;
|
||||
font-size: calc(var(--mainFontSize) - 5%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
gap: 10px;
|
||||
width: fit-content;
|
||||
min-width: 0;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
.rm_tag_filter .tag:not(.actionable) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tag.actionable {
|
||||
border-radius: 50%;
|
||||
aspect-ratio: 1 / 1;
|
||||
min-height: calc(var(--mainFontSize) * 2);
|
||||
min-width: calc(var(--mainFontSize) * 2);
|
||||
font-size: calc(var(--mainFontSize) * 1);
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tagListHint {
|
||||
align-self: center;
|
||||
display: flex;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.tag_remove {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
gap: 0.2rem;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
#tagList.tags {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
#tagList .tag {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.tags.tags_inline {
|
||||
opacity: 0.6;
|
||||
column-gap: 0.2rem;
|
||||
row-gap: 0.2rem;
|
||||
justify-content: flex-start;
|
||||
max-height: 66%;
|
||||
overflow: hidden;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.tag_name {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tags_inline .tag {
|
||||
font-size: calc(var(--mainFontSize) - 15%);
|
||||
padding: 0 0.15rem;
|
||||
}
|
||||
|
||||
.rm_tag_controls {
|
||||
display: flex;
|
||||
column-gap: 10px;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.rm_tag_filter .tag {
|
||||
cursor: pointer;
|
||||
opacity: 0.6;
|
||||
filter: brightness(0.8);
|
||||
}
|
||||
|
||||
.tags_view,
|
||||
.open_alternate_greetings {
|
||||
margin: 0;
|
||||
aspect-ratio: 1 / 1;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.tag.selected {
|
||||
opacity: 1 !important;
|
||||
filter: none !important;
|
||||
}
|
||||
|
||||
.tag.excluded {
|
||||
opacity: 1 !important;
|
||||
filter: saturate(0.4) !important;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.tag.excluded:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
content: "\d7";
|
||||
font-size: calc(var(--mainFontSize) *3);
|
||||
color: red;
|
||||
line-height: calc(var(--mainFontSize)*1.3);
|
||||
text-align: center;
|
||||
text-shadow: 1px 1px 0px black,
|
||||
-1px -1px 0px black,
|
||||
-1px 1px 0px black,
|
||||
1px -1px 0px black;
|
||||
opacity: 1;
|
||||
}
|
|
@ -0,0 +1,367 @@
|
|||
body.tts .mes[is_user="true"] .mes_narrate,
|
||||
body.tts .mes[is_system="true"] .mes_narrate {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.sd .sd_message_gen,
|
||||
body.translate .mes_translate,
|
||||
body.tts .mes_narrate {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
body.no-hotswap .hotswap {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body.no-timer .mes_timer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body.no-timestamps .timestamp,
|
||||
body.no-mesIDDisplay .mesIDDisplay,
|
||||
body.no-modelIcons .icon-svg {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*char list grid mode*/
|
||||
|
||||
body.charListGrid #rm_print_characters_block {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select {
|
||||
width: 30%;
|
||||
align-items: flex-start;
|
||||
height: min-content;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select .ch_name,
|
||||
body.charListGrid #rm_print_characters_block .group_select .ch_name {
|
||||
width: 100%;
|
||||
max-width: 100px;
|
||||
text-align: center;
|
||||
font-size: calc(var(--mainFontSize) * .8);
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select .character_name_block {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select .character_select_container {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .group_select {
|
||||
width: 30%;
|
||||
height: min-content;
|
||||
align-items: center !important;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .group_select .group_name_block {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .ch_description,
|
||||
body.charListGrid #rm_print_characters_block .tags_inline,
|
||||
body.charListGrid #rm_print_characters_block .character_version,
|
||||
body.charListGrid #rm_print_characters_block .ch_avatar_url {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*big avatars mode page-wide changes*/
|
||||
|
||||
body.big-avatars .character_select .avatar {
|
||||
flex: unset;
|
||||
}
|
||||
|
||||
body:not(.big-avatars) .avatar {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
body.big-avatars .avatar {
|
||||
width: 60px;
|
||||
height: 90px;
|
||||
/* width: unset; */
|
||||
border-style: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
/* align-self: unset; */
|
||||
overflow: visible;
|
||||
border-radius: 10px;
|
||||
flex: 1
|
||||
}
|
||||
|
||||
body.big-avatars #user_avatar_block .avatar,
|
||||
body.big-avatars #user_avatar_block .avatar_upload {
|
||||
height: 90px;
|
||||
width: 60px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
body.big-avatars #user_avatar_block .avatar img {
|
||||
height: 90px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
body.big-avatars .avatar img {
|
||||
width: 60px;
|
||||
height: 90px;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
border: 1px solid var(--black30a);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
body:not(.big-avatars) .avatar_collage {
|
||||
min-width: 50px;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
body:not(.big-avatars) .avatar_collage img {
|
||||
border-radius: 0% !important;
|
||||
}
|
||||
|
||||
body.big-avatars .avatar_collage {
|
||||
min-width: 60px;
|
||||
max-width: 60px;
|
||||
aspect-ratio: 2 / 3;
|
||||
}
|
||||
|
||||
body.big-avatars .ch_description {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
white-space: normal;
|
||||
text-overflow: unset;
|
||||
}
|
||||
|
||||
/* border radius for big avatars collages */
|
||||
|
||||
body.big-avatars .collage_2 .img_1 {
|
||||
border-radius: 10px 0 0 10px !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_2 .img_2 {
|
||||
border-radius: 0 10px 10px 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_3 .img_1 {
|
||||
border-radius: 10px 0 0 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_3 .img_2 {
|
||||
border-radius: 0 10px 0 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_3 .img_3 {
|
||||
border-radius: 0 0 10px 10px !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_4 .img_1 {
|
||||
border-radius: 10px 0 0 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_4 .img_2 {
|
||||
border-radius: 0 10px 0 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_4 .img_3 {
|
||||
border-radius: 0 0 0 10px !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_4 .img_4 {
|
||||
border-radius: 0 0 10px 0 !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*bubble chat style*/
|
||||
|
||||
body.bubblechat .mes {
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background-color: var(--SmartThemeBotMesBlurTintColor);
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid var(--white30a);
|
||||
}
|
||||
|
||||
body.bubblechat .mes[is_user="true"] {
|
||||
background-color: var(--SmartThemeUserMesBlurTintColor);
|
||||
}
|
||||
|
||||
|
||||
/* Document Style */
|
||||
|
||||
body.documentstyle #chat .mes:not(.last_mes) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
body.documentstyle .last_mes {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .mes .mes_text {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .mes .mes_block {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .mes .mes_text {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .last_mes .mes_text {
|
||||
margin-left: 20px;
|
||||
min-height: 70px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .last_mes:has(> .del_checkbox[style*="display: block"]) .mes_text {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .last_mes .swipe_left {
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .mes .mesAvatarWrapper,
|
||||
body.documentstyle #chat .mes .mes_block .ch_name .name_text,
|
||||
body.documentstyle #chat .mes .mes_block .ch_name .timestamp,
|
||||
body.documentstyle .mes:not(.last_mes) .ch_name .mes_buttons {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*FastUI blur removal*/
|
||||
|
||||
body.no-blur * {
|
||||
backdrop-filter: unset !important;
|
||||
}
|
||||
|
||||
body.no-blur #send_form.no-connection {
|
||||
background-color: rgba(100, 0, 0, 0.9) !important;
|
||||
}
|
||||
|
||||
body.no-blur #bg1,
|
||||
body.no-blur #bg_custom {
|
||||
filter: unset;
|
||||
|
||||
}
|
||||
|
||||
body:not(.bubblechat).no-blur #chat,
|
||||
body.no-blur #top-bar,
|
||||
body.no-blur #send_form {
|
||||
background-color: var(--SmartThemeBlurTintColor) !important;
|
||||
}
|
||||
|
||||
body.no-blur #options,
|
||||
body.no-blur .ui-widget-content,
|
||||
body.no-blur #floatingPrompt,
|
||||
body.no-blur #extensionsMenu,
|
||||
body.no-blur .list-group,
|
||||
body.no-blur #character_popup,
|
||||
body.no-blur #world_popup,
|
||||
body.no-blur #dialogue_popup,
|
||||
body.no-blur #select_chat_popup,
|
||||
body.no-blur .drawer-content,
|
||||
body.no-blur .select2-results__options {
|
||||
background-color: black !important;
|
||||
}
|
||||
|
||||
/* wAIfu mode*/
|
||||
|
||||
body.waifuMode #top-bar {
|
||||
border-radius: 0 0 20px 20px;
|
||||
border: 1px solid var(--grey30a);
|
||||
}
|
||||
|
||||
body.waifuMode #sheld {
|
||||
height: 40vh;
|
||||
height: 40svh;
|
||||
top: calc(100% - 40vh);
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
body.waifuMode #chat {
|
||||
border-top: 1px solid var(--grey30a);
|
||||
border-radius: 20px 20px 0 0;
|
||||
}
|
||||
|
||||
body.waifuMode #expression-wrapper {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
body.waifuMode .expression-holder {
|
||||
max-height: 90vh;
|
||||
max-width: 90vw;
|
||||
height: 90vh;
|
||||
width: fit-content;
|
||||
bottom: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 2;
|
||||
margin: 0 auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
body.waifuMode .zoomed_avatar {
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
max-height: 90vh;
|
||||
max-width: 90vh;
|
||||
width: calc((100vw - var(--sheldWidth)) /2);
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 29;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
top: 50px;
|
||||
aspect-ratio: 2 / 3;
|
||||
}
|
||||
|
||||
/* movingUI*/
|
||||
|
||||
body.movingUI .drag-grabber {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
body.movingUI #sheld,
|
||||
body.movingUI .drawer-content,
|
||||
body.movingUI #expression-holder,
|
||||
body.movingUI .zoomed_avatar,
|
||||
body.movingUI #floatingPrompt,
|
||||
body.movingUI #groupMemberListPopout {
|
||||
resize: both;
|
||||
}
|
||||
|
||||
#expression-image.default,
|
||||
#expression-holder:has(.default) {
|
||||
height: 120px;
|
||||
margin-top: 0;
|
||||
top: 50px;
|
||||
}
|
||||
|
||||
/*No Text Shadows Mode*/
|
||||
|
||||
body.noShadows * {
|
||||
text-shadow: none !important;
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
.world_info_select_block {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: baseline;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.budget_cap_note {
|
||||
flex-basis: 100%;
|
||||
line-height: 0.1;
|
||||
}
|
||||
|
||||
#world_popup {
|
||||
min-height: 100px;
|
||||
min-width: 100px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
flex-direction: column;
|
||||
z-index: 3010;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.WIEntryContentAndMemo {
|
||||
width: 100% !important;
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
|
||||
.WIEntryContentAndMemo .world_entry_thin_controls {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#world_popup_bottom_holder {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#world_popup_bottom_holder div {
|
||||
width: fit-content;
|
||||
user-select: none;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.world_popup_logo_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#world_popup_header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#world_popup_header h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#form_rename_world {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
opacity: 0.8;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
#form_rename_world input[type="submit"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#form_world_import {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#world_popup_header h5 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.world_popup_expander {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#world_popup_entries_list {
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#world_popup_entries_list:empty {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#world_popup_entries_list:empty::before {
|
||||
content: 'No entries exist. Try creating one!';
|
||||
font-size: calc(var(--mainFontSize) + .5rem);
|
||||
font-weight: bolder;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.world_entry_form_control {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.world_entry_thin_controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
/* .world_entry_thin_controls>div {
|
||||
flex: 1;
|
||||
} */
|
||||
|
||||
.world_entry_form_control label h4 {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.world_entry_form_control label h5 {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.world_entry_form_control textarea {
|
||||
height: auto;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.delete_entry_button {
|
||||
height: min-content;
|
||||
}
|
||||
|
||||
.world_entry_form_control.world_entry_form_horizontal {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.world_entry_form_control input[type=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.world_entry_form_horizontal h5 {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.world_entry_form_control .checkbox {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
column-gap: 10px;
|
||||
}
|
||||
|
||||
.world_entry_form_control .checkbox h4 {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.world_entry_form_radios label {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.world_entry_form_radios h4 {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#world_popup h5 {
|
||||
color: var(--grey70);
|
||||
}
|
||||
|
||||
/* possible place for WI Entry header styling */
|
||||
/* .world_entry_form .inline-drawer-header {
|
||||
background-color: var(--SmartThemeShadowColor);
|
||||
} */
|
|
@ -48,7 +48,19 @@
|
|||
<script type="module" src="lib/swiped-events.js"></script>
|
||||
<script type="module" src="lib/eventemitter.js"></script>
|
||||
<script type="module" src="scripts/power-user.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/st-tailwind.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/tags.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/rm-groups.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/group-avatars.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/toggle-dependent.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/world-info.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/extensions-panel.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/select2-overrides.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/mobile-styles.css">
|
||||
|
||||
<link rel="stylesheet" href="css/bg_load.css">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<script>
|
||||
|
@ -131,7 +143,7 @@
|
|||
<div class="checked fa-solid fa-lock "></div>
|
||||
</label>
|
||||
</div>
|
||||
<div data-i18n="clickslidertips" class="toggle-description flex-container justifyLeft wide100p editable-slider-notification">
|
||||
<div data-i18n="clickslidertips" class="toggle-description wide100p editable-slider-notification">
|
||||
Click slider numbers to input manually.
|
||||
</div>
|
||||
<div class="scrollableInner">
|
||||
|
@ -1785,22 +1797,27 @@
|
|||
<input id="use-mancer-api-checkbox" type="checkbox" />
|
||||
</label>
|
||||
</div>
|
||||
<div id="mancer-api-ui" style="display:none;">
|
||||
<h4 data-i18n="Mancer API key">Mancer API key</h4>
|
||||
<div class="flex-container">
|
||||
<input id="api_key_mancer" name="api_key_mancer" class="text_pole flex1 wide100p" maxlength="500" size="35" type="text" autocomplete="off">
|
||||
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_mancer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex-container flexFlowColumn">
|
||||
<div id="mancer_api_subpanel" class="flex-container flexFlowColumn" style="display:none;">
|
||||
<h4 data-i18n="Mancer API key">Mancer API key</h4>
|
||||
<div class="flex-container">
|
||||
<input id="api_key_mancer" name="api_key_mancer" class="text_pole flex1 wide100p" maxlength="500" size="35" type="text" autocomplete="off">
|
||||
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_mancer">
|
||||
</div>
|
||||
</div>
|
||||
<div data-for="api_key_mancer" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page.">
|
||||
For privacy reasons, your API key will be hidden after you reload the page.
|
||||
</div>
|
||||
<div class="flex1">
|
||||
<h4 data-i18n="Mancer API url">Mancer API url</h4>
|
||||
<small>Example: https://neuro.mancer.tech/webui/MODEL/api</small>
|
||||
<input id="mancer_api_url_text" name="mancer_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div id="tgwebui_api_subpanel" class="flex-container flexFlowColumn">
|
||||
<div class="flex1">
|
||||
<h4 data-i18n="Blocking API url">Blocking API url</h4>
|
||||
<small>Example: http://127.0.0.1:5000/</small>
|
||||
<small>Example: http://127.0.0.1:5000/api</small>
|
||||
<input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2144,7 +2161,7 @@
|
|||
<small data-i18n="Input Sequence">Input Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_input_sequence" class="text_pole textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_input_sequence" class="text_pole textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2152,7 +2169,7 @@
|
|||
<small data-i18n="Output Sequence">Output Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_output_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_output_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2160,7 +2177,7 @@
|
|||
<small data-i18n="Last Sequence">Last Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_last_output_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_last_output_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2170,7 +2187,7 @@
|
|||
<small data-i18n="System Sequence">System Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_system_sequence" class="text_pole textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_system_sequence" class="text_pole textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2178,7 +2195,7 @@
|
|||
<small data-i18n="Stop Sequence">Stop Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_stop_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_stop_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2186,7 +2203,7 @@
|
|||
<small data-i18n="Separator">Separator</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_separator_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_separator_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3696,9 +3713,7 @@
|
|||
<small>
|
||||
<span data-i18n="Content">
|
||||
Content
|
||||
<span>(Tokens:
|
||||
<span class="world_entry_form_token_counter">0</span>
|
||||
)
|
||||
<span>(Tokens: <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>)
|
||||
</span>
|
||||
</span>
|
||||
</small>
|
||||
|
@ -4339,4 +4354,4 @@
|
|||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"input_sequence": "### Instruction:",
|
||||
"last_output_sequence": "### Response (2 paragraphs, engaging, natural, authentic, descriptive, creative):",
|
||||
"input_sequence": "\n### Instruction:",
|
||||
"last_output_sequence": "\n### Response (2 paragraphs, engaging, natural, authentic, descriptive, creative):",
|
||||
"macro": true,
|
||||
"name": "Roleplay",
|
||||
"names": true,
|
||||
"output_sequence": "### Response:",
|
||||
"output_sequence": "\n### Response:",
|
||||
"separator_sequence": "",
|
||||
"stop_sequence": "",
|
||||
"system_prompt": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}.\n\nAvoid repetition, don't loop. Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions.",
|
||||
"system_prompt": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}.\n\nAvoid repetition, don't loop. Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions.\n",
|
||||
"system_sequence": "",
|
||||
"wrap": true
|
||||
}
|
||||
|
|
|
@ -2378,10 +2378,6 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
abortController = new AbortController();
|
||||
}
|
||||
|
||||
if (main_api == 'novel' && quiet_prompt) {
|
||||
quiet_prompt = adjustNovelInstructionPrompt(quiet_prompt);
|
||||
}
|
||||
|
||||
// OpenAI doesn't need instruct mode. Use OAI main prompt instead.
|
||||
const isInstruct = power_user.instruct.enabled && main_api !== 'openai';
|
||||
const isImpersonate = type == "impersonate";
|
||||
|
@ -2470,6 +2466,11 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
}
|
||||
}
|
||||
|
||||
if (quiet_prompt) {
|
||||
quiet_prompt = substituteParams(quiet_prompt);
|
||||
quiet_prompt = main_api == 'novel' ? adjustNovelInstructionPrompt(quiet_prompt) : quiet_prompt;
|
||||
}
|
||||
|
||||
if (true === dryRun ||
|
||||
(online_status != 'no_connection' && this_chid != undefined && this_chid !== 'invalid-safety-id')) {
|
||||
let textareaText;
|
||||
|
@ -5402,9 +5403,8 @@ async function getSettings(type) {
|
|||
setWorldInfoSettings(settings.world_info_settings ?? settings, data);
|
||||
|
||||
api_server_textgenerationwebui = settings.api_server_textgenerationwebui;
|
||||
$("#textgenerationwebui_api_url_text").val(
|
||||
api_server_textgenerationwebui
|
||||
);
|
||||
$("#textgenerationwebui_api_url_text").val(api_server_textgenerationwebui);
|
||||
$("#mancer_api_url_text").val(api_server_textgenerationwebui);
|
||||
api_use_mancer_webui = settings.api_use_mancer_webui
|
||||
$('#use-mancer-api-checkbox').prop("checked", api_use_mancer_webui);
|
||||
$('#use-mancer-api-checkbox').trigger("change");
|
||||
|
@ -5768,7 +5768,6 @@ export async function displayPastChats() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
displayChats(''); // Display all by default
|
||||
|
||||
|
@ -7518,7 +7517,7 @@ $(document).ready(function () {
|
|||
$("#character_search_bar").val("").trigger("input");
|
||||
});
|
||||
|
||||
$(document).on("click", ".character_select", function() {
|
||||
$(document).on("click", ".character_select", function () {
|
||||
const id = $(this).attr("chid");
|
||||
selectCharacterById(id);
|
||||
});
|
||||
|
@ -8002,7 +8001,9 @@ $(document).ready(function () {
|
|||
|
||||
$("#use-mancer-api-checkbox").on("change", function (e) {
|
||||
const enabled = $("#use-mancer-api-checkbox").prop("checked");
|
||||
$("#mancer-api-ui").toggle(enabled);
|
||||
$("#mancer_api_subpanel").toggle(enabled);
|
||||
$("#tgwebui_api_subpanel").toggle(!enabled);
|
||||
|
||||
api_use_mancer_webui = enabled;
|
||||
saveSettingsDebounced();
|
||||
getStatus();
|
||||
|
@ -8010,8 +8011,9 @@ $(document).ready(function () {
|
|||
|
||||
$("#api_button_textgenerationwebui").click(async function (e) {
|
||||
e.stopPropagation();
|
||||
if ($("#textgenerationwebui_api_url_text").val() != "") {
|
||||
let value = formatTextGenURL($("#textgenerationwebui_api_url_text").val().trim(), api_use_mancer_webui);
|
||||
const url_source = api_use_mancer_webui ? "#mancer_api_url_text" : "#textgenerationwebui_api_url_text";
|
||||
if ($(url_source).val() != "") {
|
||||
let value = formatTextGenURL($(url_source).val().trim(), api_use_mancer_webui);
|
||||
if (!value) {
|
||||
callPopup("Please enter a valid URL.<br/>WebUI URLs should end with <tt>/api</tt><br/>Enable 'Relaxed API URLs' to allow other paths.", 'text');
|
||||
return;
|
||||
|
@ -8022,9 +8024,13 @@ $(document).ready(function () {
|
|||
await writeSecret(SECRET_KEYS.MANCER, mancer_key);
|
||||
}
|
||||
|
||||
$("#textgenerationwebui_api_url_text").val(value);
|
||||
$(url_source).val(value);
|
||||
$("#api_loading_textgenerationwebui").css("display", "inline-block");
|
||||
$("#api_button_textgenerationwebui").css("display", "none");
|
||||
|
||||
if (api_use_mancer_webui) {
|
||||
textgenerationwebui_settings.streaming_url = value.replace("http", "ws") + "/v1/stream";
|
||||
}
|
||||
api_server_textgenerationwebui = value;
|
||||
main_api = "textgenerationwebui";
|
||||
saveSettingsDebounced();
|
||||
|
|
|
@ -499,7 +499,7 @@ async function moduleWorker() {
|
|||
const context = getContext();
|
||||
|
||||
// non-characters not supported
|
||||
if (!context.groupId && context.characterId === undefined) {
|
||||
if (!context.groupId && (context.characterId === undefined || context.characterId === 'invalid-safety-id')) {
|
||||
removeExpression();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
substituteParams,
|
||||
saveSettingsDebounced,
|
||||
systemUserName,
|
||||
hideSwipeButtons,
|
||||
|
@ -14,7 +13,8 @@ import {
|
|||
} from "../../../script.js";
|
||||
import { getApiUrl, getContext, extension_settings, doExtrasFetch, modules } from "../../extensions.js";
|
||||
import { selected_group } from "../../group-chats.js";
|
||||
import { stringFormat, initScrollHeight, resetScrollHeight, timestampToMoment, getCharaFilename } from "../../utils.js";
|
||||
import { stringFormat, initScrollHeight, resetScrollHeight, timestampToMoment, getCharaFilename, saveBase64AsFile } from "../../utils.js";
|
||||
import { humanizedDateTime } from "../../RossAscends-mods.js";
|
||||
export { MODULE_NAME };
|
||||
|
||||
// Wraps a string into monospace font-face span
|
||||
|
@ -512,7 +512,7 @@ function getQuietPrompt(mode, trigger) {
|
|||
return trigger;
|
||||
}
|
||||
|
||||
return substituteParams(stringFormat(extension_settings.sd.prompts[mode], trigger));
|
||||
return stringFormat(extension_settings.sd.prompts[mode], trigger);
|
||||
}
|
||||
|
||||
function processReply(str) {
|
||||
|
@ -537,6 +537,7 @@ function processReply(str) {
|
|||
return str;
|
||||
}
|
||||
|
||||
|
||||
function getRawLastMessage() {
|
||||
const context = getContext();
|
||||
const lastMessage = context.chat.slice(-1)[0].mes,
|
||||
|
@ -565,6 +566,10 @@ async function generatePicture(_, trigger, message, callback) {
|
|||
const quiet_prompt = getQuietPrompt(generationType, trigger);
|
||||
const context = getContext();
|
||||
|
||||
// if context.characterId is not null, then we get context.characters[context.characterId].avatar, else we get groupId and context.groups[groupId].id
|
||||
// sadly, groups is not an array, but is a dict with keys being index numbers, so we have to filter it
|
||||
const characterName = context.characterId ? context.characters[context.characterId].name : context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]].id.toString();
|
||||
|
||||
const prevSDHeight = extension_settings.sd.height;
|
||||
const prevSDWidth = extension_settings.sd.width;
|
||||
const aspectRatio = extension_settings.sd.width / extension_settings.sd.height;
|
||||
|
@ -580,8 +585,10 @@ async function generatePicture(_, trigger, message, callback) {
|
|||
// Round to nearest multiple of 64
|
||||
extension_settings.sd.width = Math.round(extension_settings.sd.height * 1.8 / 64) * 64;
|
||||
const callbackOriginal = callback;
|
||||
callback = function (prompt, base64Image) {
|
||||
const imgUrl = `url(${base64Image})`;
|
||||
callback = async function (prompt, base64Image) {
|
||||
const imagePath = base64Image;
|
||||
const imgUrl = `url('${encodeURIComponent(base64Image)}')`;
|
||||
|
||||
if ('forceSetBackground' in window) {
|
||||
forceSetBackground(imgUrl);
|
||||
} else {
|
||||
|
@ -590,9 +597,9 @@ async function generatePicture(_, trigger, message, callback) {
|
|||
}
|
||||
|
||||
if (typeof callbackOriginal === 'function') {
|
||||
callbackOriginal(prompt, base64Image);
|
||||
callbackOriginal(prompt, imagePath);
|
||||
} else {
|
||||
sendMessage(prompt, base64Image);
|
||||
sendMessage(prompt, imagePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -604,7 +611,7 @@ async function generatePicture(_, trigger, message, callback) {
|
|||
context.deactivateSendButtons();
|
||||
hideSwipeButtons();
|
||||
|
||||
await sendGenerationRequest(generationType, prompt, callback);
|
||||
await sendGenerationRequest(generationType, prompt, characterName, callback);
|
||||
} catch (err) {
|
||||
console.trace(err);
|
||||
throw new Error('SD prompt text generation failed.')
|
||||
|
@ -644,19 +651,31 @@ async function generatePrompt(quiet_prompt) {
|
|||
return processReply(reply);
|
||||
}
|
||||
|
||||
async function sendGenerationRequest(generationType, prompt, callback) {
|
||||
async function sendGenerationRequest(generationType, prompt, characterName = null, callback) {
|
||||
const prefix = generationType !== generationMode.BACKGROUND
|
||||
? combinePrefixes(extension_settings.sd.prompt_prefix, getCharacterPrefix())
|
||||
: extension_settings.sd.prompt_prefix;
|
||||
|
||||
if (extension_settings.sd.horde) {
|
||||
await generateHordeImage(prompt, prefix, callback);
|
||||
await generateHordeImage(prompt, prefix, characterName, callback);
|
||||
} else {
|
||||
await generateExtrasImage(prompt, prefix, callback);
|
||||
await generateExtrasImage(prompt, prefix, characterName, callback);
|
||||
}
|
||||
}
|
||||
|
||||
async function generateExtrasImage(prompt, prefix, callback) {
|
||||
/**
|
||||
* Generates an "extras" image using a provided prompt and other settings,
|
||||
* then saves the generated image and either invokes a callback or sends a message with the image.
|
||||
*
|
||||
* @param {string} prompt - The main instruction used to guide the image generation.
|
||||
* @param {string} prefix - Additional context or prefix to guide the image generation.
|
||||
* @param {string} characterName - The name used to determine the sub-directory for saving.
|
||||
* @param {function} [callback] - Optional callback function invoked with the prompt and saved image.
|
||||
* If not provided, `sendMessage` is called instead.
|
||||
*
|
||||
* @returns {Promise<void>} - A promise that resolves when the image generation and processing are complete.
|
||||
*/
|
||||
async function generateExtrasImage(prompt, prefix, characterName, callback) {
|
||||
console.debug(extension_settings.sd);
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = '/api/image';
|
||||
|
@ -680,14 +699,28 @@ async function generateExtrasImage(prompt, prefix, callback) {
|
|||
|
||||
if (result.ok) {
|
||||
const data = await result.json();
|
||||
const base64Image = `data:image/jpeg;base64,${data.image}`;
|
||||
//filename should be character name + human readable timestamp + generation mode
|
||||
const filename = `${characterName}_${humanizedDateTime()}`;
|
||||
const base64Image = await saveBase64AsFile(data.image, characterName, filename, "jpg");
|
||||
callback ? callback(prompt, base64Image) : sendMessage(prompt, base64Image);
|
||||
} else {
|
||||
callPopup('Image generation has failed. Please try again.', 'text');
|
||||
}
|
||||
}
|
||||
|
||||
async function generateHordeImage(prompt, prefix, callback) {
|
||||
/**
|
||||
* Generates a "horde" image using the provided prompt and configuration settings,
|
||||
* then saves the generated image and either invokes a callback or sends a message with the image.
|
||||
*
|
||||
* @param {string} prompt - The main instruction used to guide the image generation.
|
||||
* @param {string} prefix - Additional context or prefix to guide the image generation.
|
||||
* @param {string} characterName - The name used to determine the sub-directory for saving.
|
||||
* @param {function} [callback] - Optional callback function invoked with the prompt and saved image.
|
||||
* If not provided, `sendMessage` is called instead.
|
||||
*
|
||||
* @returns {Promise<void>} - A promise that resolves when the image generation and processing are complete.
|
||||
*/
|
||||
async function generateHordeImage(prompt, prefix, characterName, callback) {
|
||||
const result = await fetch('/horde_generateimage', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
|
@ -709,7 +742,8 @@ async function generateHordeImage(prompt, prefix, callback) {
|
|||
|
||||
if (result.ok) {
|
||||
const data = await result.text();
|
||||
const base64Image = `data:image/webp;base64,${data}`;
|
||||
const filename = `${characterName}_${humanizedDateTime()}`;
|
||||
const base64Image = await saveBase64AsFile(data, characterName, filename, "webp");
|
||||
callback ? callback(prompt, base64Image) : sendMessage(prompt, base64Image);
|
||||
} else {
|
||||
toastr.error('Image generation has failed. Please try again.');
|
||||
|
@ -827,7 +861,7 @@ async function sdMessageButton(e) {
|
|||
const message_id = $mes.attr('mesid');
|
||||
const message = context.chat[message_id];
|
||||
const characterName = message?.name || context.name2;
|
||||
const messageText = substituteParams(message?.mes);
|
||||
const messageText = message?.mes;
|
||||
const hasSavedImage = message?.extra?.image && message?.extra?.title;
|
||||
|
||||
if ($icon.hasClass(busyClass)) {
|
||||
|
@ -842,7 +876,7 @@ async function sdMessageButton(e) {
|
|||
message.extra.title = prompt;
|
||||
|
||||
console.log('Regenerating an image, using existing prompt:', prompt);
|
||||
await sendGenerationRequest(generationMode.FREE, prompt, saveGeneratedImage);
|
||||
await sendGenerationRequest(generationMode.FREE, prompt, characterName, saveGeneratedImage);
|
||||
}
|
||||
else {
|
||||
console.log("doing /sd raw last");
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
isDataURL,
|
||||
createThumbnail,
|
||||
extractAllWords,
|
||||
saveBase64AsFile
|
||||
} from './utils.js';
|
||||
import { RA_CountCharTokens, humanizedDateTime, dragElement, favsToHotswap } from "./RossAscends-mods.js";
|
||||
import { loadMovingUIState, sortEntitiesList } from './power-user.js';
|
||||
|
@ -336,25 +337,25 @@ async function getGroups() {
|
|||
}
|
||||
|
||||
export function getGroupBlock(group) {
|
||||
const template = $("#group_list_template .group_select").clone();
|
||||
template.data("id", group.id);
|
||||
template.attr("grid", group.id);
|
||||
template.find(".ch_name").html(group.name);
|
||||
template.find('.group_fav_icon').css("display", 'none');
|
||||
template.addClass(group.fav ? 'is_fav' : '');
|
||||
template.find(".ch_fav").val(group.fav);
|
||||
const template = $("#group_list_template .group_select").clone();
|
||||
template.data("id", group.id);
|
||||
template.attr("grid", group.id);
|
||||
template.find(".ch_name").html(group.name);
|
||||
template.find('.group_fav_icon').css("display", 'none');
|
||||
template.addClass(group.fav ? 'is_fav' : '');
|
||||
template.find(".ch_fav").val(group.fav);
|
||||
|
||||
// Display inline tags
|
||||
const tags = getTagsList(group.id);
|
||||
const tagsElement = template.find('.tags');
|
||||
tags.forEach(tag => appendTagToList(tagsElement, tag, {}));
|
||||
// Display inline tags
|
||||
const tags = getTagsList(group.id);
|
||||
const tagsElement = template.find('.tags');
|
||||
tags.forEach(tag => appendTagToList(tagsElement, tag, {}));
|
||||
|
||||
const avatar = getGroupAvatar(group);
|
||||
if (avatar) {
|
||||
$(template).find(".avatar").replaceWith(avatar);
|
||||
}
|
||||
const avatar = getGroupAvatar(group);
|
||||
if (avatar) {
|
||||
$(template).find(".avatar").replaceWith(avatar);
|
||||
}
|
||||
|
||||
return template;
|
||||
return template;
|
||||
}
|
||||
|
||||
function updateGroupAvatar(group) {
|
||||
|
@ -362,17 +363,27 @@ function updateGroupAvatar(group) {
|
|||
|
||||
$(".group_select").each(function () {
|
||||
if ($(this).data("id") == group.id) {
|
||||
$(this).find(".avatar").replaceWith(getGroupAvatar(group));
|
||||
$(this).find(".avatar").replaceWith(getGroupAvatar(group));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// check if isDataURLor if it's a valid local file url
|
||||
function isValidImageUrl(url) {
|
||||
console.trace(url);
|
||||
// check if empty dict
|
||||
if (Object.keys(url).length === 0) {
|
||||
return false;
|
||||
}
|
||||
return isDataURL(url) || (url && url.startsWith("user"));
|
||||
}
|
||||
|
||||
function getGroupAvatar(group) {
|
||||
if (!group) {
|
||||
return $(`<div class="avatar"><img src="${default_avatar}"></div>`);
|
||||
}
|
||||
|
||||
if (isDataURL(group.avatar_url)) {
|
||||
// if isDataURL or if it's a valid local file url
|
||||
if (isValidImageUrl(group.avatar_url)) {
|
||||
return $(`<div class="avatar"><img src="${group.avatar_url}"></div>`);
|
||||
}
|
||||
|
||||
|
@ -1079,8 +1090,7 @@ function select_group_chats(groupId, skipAnimation) {
|
|||
|
||||
setMenuType(!!group ? 'group_edit' : 'group_create');
|
||||
$("#group_avatar_preview").empty().append(getGroupAvatar(group));
|
||||
$("#rm_group_restore_avatar").toggle(!!group && isDataURL(group.avatar_url));
|
||||
$("#rm_group_chat_name").val(groupName);
|
||||
$("#rm_group_restore_avatar").toggle(!!group && isValidImageUrl(group.avatar_url));
|
||||
$("#rm_group_filter").val("").trigger("input");
|
||||
$(`input[name="rm_group_activation_strategy"][value="${replyStrategy}"]`).prop('checked', true);
|
||||
|
||||
|
@ -1122,9 +1132,18 @@ function select_group_chats(groupId, skipAnimation) {
|
|||
$("#rm_group_automode_label").hide();
|
||||
}
|
||||
|
||||
eventSource.emit('groupSelected', {detail: {id: openGroupId, group: group}});
|
||||
eventSource.emit('groupSelected', { detail: { id: openGroupId, group: group } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the upload and processing of a group avatar.
|
||||
* The selected image is read, cropped using a popup, processed into a thumbnail,
|
||||
* and then uploaded to the server.
|
||||
*
|
||||
* @param {Event} event - The event triggered by selecting a file input, containing the image file to upload.
|
||||
*
|
||||
* @returns {Promise<void>} - A promise that resolves when the processing and upload is complete.
|
||||
*/
|
||||
async function uploadGroupAvatar(event) {
|
||||
const file = event.target.files[0];
|
||||
|
||||
|
@ -1147,16 +1166,22 @@ async function uploadGroupAvatar(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
const thumbnail = await createThumbnail(croppedImage, 96, 144);
|
||||
|
||||
let thumbnail = await createThumbnail(croppedImage, 96, 144);
|
||||
//remove data:image/whatever;base64
|
||||
thumbnail = thumbnail.replace(/^data:image\/[a-z]+;base64,/, "");
|
||||
let _thisGroup = groups.find((x) => x.id == openGroupId);
|
||||
// filename should be group id + human readable timestamp
|
||||
const filename = `${_thisGroup.id}_${humanizedDateTime()}`;
|
||||
let thumbnailUrl = await saveBase64AsFile(thumbnail, openGroupId.toString(), filename, 'jpg');
|
||||
if (!openGroupId) {
|
||||
$('#group_avatar_preview img').attr('src', thumbnail);
|
||||
$('#group_avatar_preview img').attr('src', thumbnailUrl);
|
||||
$('#rm_group_restore_avatar').show();
|
||||
return;
|
||||
}
|
||||
|
||||
let _thisGroup = groups.find((x) => x.id == openGroupId);
|
||||
_thisGroup.avatar_url = thumbnail;
|
||||
|
||||
|
||||
_thisGroup.avatar_url = thumbnailUrl;
|
||||
$("#group_avatar_preview").empty().append(getGroupAvatar(_thisGroup));
|
||||
$("#rm_group_restore_avatar").show();
|
||||
await editGroup(openGroupId, true, true);
|
||||
|
@ -1238,6 +1263,11 @@ function updateFavButtonState(state) {
|
|||
}
|
||||
|
||||
export async function openGroupById(groupId) {
|
||||
if (!groups.find(x => x.id === groupId)) {
|
||||
console.log('Group not found', groupId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_send_press && !is_group_generating) {
|
||||
if (selected_group !== groupId) {
|
||||
cancelTtsPlay();
|
||||
|
@ -1303,7 +1333,7 @@ async function createGroup() {
|
|||
body: JSON.stringify({
|
||||
name: name,
|
||||
members: members,
|
||||
avatar_url: isDataURL(avatar_url) ? avatar_url : default_avatar,
|
||||
avatar_url: isValidImageUrl(avatar_url) ? avatar_url : default_avatar,
|
||||
allow_self_responses: allow_self_responses,
|
||||
activation_strategy: activation_strategy,
|
||||
disabled_members: [],
|
||||
|
|
|
@ -578,7 +578,7 @@ function calculateLogitBias() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Transforms instruction into compatible format for Novel AI.
|
||||
* Transforms instruction into compatible format for Novel AI if Novel AI instruct format not already detected.
|
||||
* 1. Instruction must begin and end with curly braces followed and preceded by a space.
|
||||
* 2. Instruction must not contain square brackets as it serves different purpose in NAI.
|
||||
* @param {string} prompt Original instruction prompt
|
||||
|
@ -586,7 +586,10 @@ function calculateLogitBias() {
|
|||
*/
|
||||
export function adjustNovelInstructionPrompt(prompt) {
|
||||
const stripedPrompt = prompt.replace(/[\[\]]/g, '').trim();
|
||||
return `{ ${stripedPrompt} }`;
|
||||
if (!stripedPrompt.includes('{ ')) {
|
||||
return `{ ${stripedPrompt} }`;
|
||||
}
|
||||
return stripedPrompt;
|
||||
}
|
||||
|
||||
export async function generateNovelWithStreaming(generate_data, signal) {
|
||||
|
|
|
@ -479,9 +479,10 @@ function populateChatHistory(prompts, chatCompletion, type = null, cyclePrompt =
|
|||
// Chat History
|
||||
chatCompletion.add(new MessageCollection('chatHistory'), prompts.index('chatHistory'));
|
||||
|
||||
let names = (selected_group && groups.find(x => x.id === selected_group)?.members.map(member => characters.find(c => c.avatar === member)?.name).filter(Boolean).join(', ')) || '';
|
||||
// Reserve budget for new chat message
|
||||
const newChat = selected_group ? oai_settings.new_group_chat_prompt : oai_settings.new_chat_prompt;
|
||||
const newChatMessage = new Message('system', newChat, 'newMainChat');
|
||||
const newChatMessage = new Message('system', substituteParams(newChat, null, null, null, names), 'newMainChat');
|
||||
chatCompletion.reserveBudget(newChatMessage);
|
||||
|
||||
// Reserve budget for continue nudge
|
||||
|
@ -512,7 +513,8 @@ function populateChatHistory(prompts, chatCompletion, type = null, cyclePrompt =
|
|||
const chatMessage = Message.fromPrompt(promptManager.preparePrompt(prompt));
|
||||
|
||||
if (true === promptManager.serviceSettings.names_in_completion && prompt.name) {
|
||||
chatMessage.name = promptManager.isValidName(prompt.name) ? prompt.name : promptManager.sanitizeName(prompt.name);
|
||||
const messageName = promptManager.isValidName(prompt.name) ? prompt.name : promptManager.sanitizeName(prompt.name);
|
||||
chatMessage.setName(messageName);
|
||||
}
|
||||
|
||||
if (chatCompletion.canAfford(chatMessage)) chatCompletion.insertAtStart(chatMessage, 'chatHistory');
|
||||
|
@ -541,9 +543,8 @@ function populateDialogueExamples(prompts, chatCompletion) {
|
|||
chatCompletion.add(new MessageCollection('dialogueExamples'), prompts.index('dialogueExamples'));
|
||||
if (openai_msgs_example.length) {
|
||||
const newExampleChat = new Message('system', oai_settings.new_example_chat_prompt, 'newChat');
|
||||
chatCompletion.reserveBudget(newExampleChat);
|
||||
|
||||
[...openai_msgs_example].forEach((dialogue, dialogueIndex) => {
|
||||
chatCompletion.insert(newExampleChat, 'dialogueExamples');
|
||||
dialogue.forEach((prompt, promptIndex) => {
|
||||
const role = 'system';
|
||||
const content = prompt.content || '';
|
||||
|
@ -556,11 +557,6 @@ function populateDialogueExamples(prompts, chatCompletion) {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
chatCompletion.freeBudget(newExampleChat);
|
||||
|
||||
const chatExamples = chatCompletion.getMessages().getItemByIdentifier('dialogueExamples').getCollection();
|
||||
if (chatExamples.length) chatCompletion.insertAtStart(newExampleChat, 'dialogueExamples');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -769,6 +765,12 @@ function preparePromptsForChatCompletion(Scenario, charPersonality, name2, world
|
|||
prompts.set(jbReplacement, prompts.index('jailbreak'));
|
||||
}
|
||||
|
||||
// TODO: Integrate Group nudge into the prompt manager properly
|
||||
if(selected_group) {
|
||||
let group_nudge = {"role": "system", "content": `[Write the next reply only as ${name2}]`};
|
||||
openai_msgs.push(group_nudge);
|
||||
}
|
||||
|
||||
// Allow subscribers to manipulate the prompts object
|
||||
eventSource.emit(event_types.OAI_BEFORE_CHATCOMPLETION, prompts);
|
||||
|
||||
|
@ -1370,7 +1372,7 @@ function countTokens(messages, full = false) {
|
|||
|
||||
for (const message of messages) {
|
||||
const model = getTokenizerModel();
|
||||
const hash = getStringHash(message.content);
|
||||
const hash = getStringHash(JSON.stringify(message));
|
||||
const cacheKey = `${model}-${hash}`;
|
||||
const cachedCount = tokenCache[chatId][cacheKey];
|
||||
|
||||
|
@ -1442,8 +1444,8 @@ class Message {
|
|||
this.role = role;
|
||||
this.content = content;
|
||||
|
||||
if (this.content) {
|
||||
this.tokens = tokenHandler.count({ role: this.role, content: this.content })
|
||||
if (typeof this.content === 'string') {
|
||||
this.tokens = tokenHandler.count({ role: this.role, content: this.content });
|
||||
} else {
|
||||
this.tokens = 0;
|
||||
}
|
||||
|
@ -1451,6 +1453,7 @@ class Message {
|
|||
|
||||
setName(name) {
|
||||
this.name = name;
|
||||
this.tokens = tokenHandler.count({ role: this.role, content: this.content, name: this.name });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { getContext } from "./extensions.js";
|
||||
import { getRequestHeaders } from "../script.js";
|
||||
|
||||
export function onlyUnique(value, index, array) {
|
||||
return array.indexOf(value) === index;
|
||||
|
@ -554,6 +555,48 @@ export function extractDataFromPng(data, identifier = 'chara') {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a base64 encoded image to the backend to be saved as a file.
|
||||
*
|
||||
* @param {string} base64Data - The base64 encoded image data.
|
||||
* @param {string} characterName - The character name to determine the sub-directory for saving.
|
||||
* @param {string} ext - The file extension for the image (e.g., 'jpg', 'png', 'webp').
|
||||
*
|
||||
* @returns {Promise<string>} - Resolves to the saved image's path on the server.
|
||||
* Rejects with an error if the upload fails.
|
||||
*/
|
||||
export async function saveBase64AsFile(base64Data, characterName, filename = "", ext) {
|
||||
// Construct the full data URL
|
||||
const format = ext; // Extract the file extension (jpg, png, webp)
|
||||
const dataURL = `data:image/${format};base64,${base64Data}`;
|
||||
|
||||
// Prepare the request body
|
||||
const requestBody = {
|
||||
image: dataURL,
|
||||
ch_name: characterName,
|
||||
filename: filename
|
||||
};
|
||||
|
||||
// Send the data URL to your backend using fetch
|
||||
const response = await fetch('/uploadimage', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(requestBody),
|
||||
headers: {
|
||||
...getRequestHeaders(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
});
|
||||
|
||||
// If the response is successful, get the saved image path from the server's response
|
||||
if (response.ok) {
|
||||
const responseData = await response.json();
|
||||
return responseData.path;
|
||||
} else {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || 'Failed to upload the image to the server');
|
||||
}
|
||||
}
|
||||
|
||||
export function createThumbnail(dataUrl, maxWidth, maxHeight) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
|
|
|
@ -464,7 +464,7 @@ function appendWorldEntry(name, data, entry) {
|
|||
|
||||
const contentInput = template.find('textarea[name="content"]');
|
||||
contentInput.data("uid", entry.uid);
|
||||
contentInput.on("input", function () {
|
||||
contentInput.on("input", function (_, { skipCount }) {
|
||||
const uid = $(this).data("uid");
|
||||
const value = $(this).val();
|
||||
data.entries[uid].content = value;
|
||||
|
@ -472,12 +472,25 @@ function appendWorldEntry(name, data, entry) {
|
|||
setOriginalDataValue(data, uid, "content", data.entries[uid].content);
|
||||
saveWorldInfo(name, data);
|
||||
|
||||
if (skipCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// count tokens
|
||||
countTokensDebounced(this, value);
|
||||
});
|
||||
contentInput.val(entry.content).trigger("input");
|
||||
contentInput.val(entry.content).trigger("input", { skipCount: true });
|
||||
//initScrollHeight(contentInput);
|
||||
|
||||
template.find('.inline-drawer-toggle').on('click', function () {
|
||||
const counter = template.find(".world_entry_form_token_counter");
|
||||
|
||||
if (counter.data('first-run')) {
|
||||
counter.data('first-run', false);
|
||||
countTokensDebounced(contentInput, contentInput.val());
|
||||
}
|
||||
});
|
||||
|
||||
// selective
|
||||
const selectiveInput = template.find('input[name="selective"]');
|
||||
selectiveInput.data("uid", entry.uid);
|
||||
|
|
2192
public/style.css
2192
public/style.css
File diff suppressed because it is too large
Load Diff
75
server.js
75
server.js
|
@ -297,6 +297,8 @@ const baseRequestArgs = { headers: { "Content-Type": "application/json" } };
|
|||
const directories = {
|
||||
worlds: 'public/worlds/',
|
||||
avatars: 'public/User Avatars',
|
||||
images: 'public/img/',
|
||||
userImages: 'public/user/images/',
|
||||
groups: 'public/groups/',
|
||||
groupChats: 'public/group chats',
|
||||
chats: 'public/chats/',
|
||||
|
@ -600,7 +602,7 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
|
|||
});
|
||||
|
||||
async function* readWebsocket() {
|
||||
const streamingUrl = request.header('X-Streaming-URL');
|
||||
const streamingUrl = request.header('X-Streaming-URL').replace("localhost", "127.0.0.1");
|
||||
const websocket = new WebSocket(streamingUrl);
|
||||
|
||||
websocket.on('open', async function () {
|
||||
|
@ -2612,6 +2614,73 @@ app.post('/uploaduseravatar', urlencodedParser, async (request, response) => {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Ensure the directory for the provided file path exists.
|
||||
* If not, it will recursively create the directory.
|
||||
*
|
||||
* @param {string} filePath - The full path of the file for which the directory should be ensured.
|
||||
*/
|
||||
function ensureDirectoryExistence(filePath) {
|
||||
const dirname = path.dirname(filePath);
|
||||
if (fs.existsSync(dirname)) {
|
||||
return true;
|
||||
}
|
||||
ensureDirectoryExistence(dirname);
|
||||
fs.mkdirSync(dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint to handle image uploads.
|
||||
* The image should be provided in the request body in base64 format.
|
||||
* Optionally, a character name can be provided to save the image in a sub-folder.
|
||||
*
|
||||
* @route POST /uploadimage
|
||||
* @param {Object} request.body - The request payload.
|
||||
* @param {string} request.body.image - The base64 encoded image data.
|
||||
* @param {string} [request.body.ch_name] - Optional character name to determine the sub-directory.
|
||||
* @returns {Object} response - The response object containing the path where the image was saved.
|
||||
*/
|
||||
app.post('/uploadimage', jsonParser, async (request, response) => {
|
||||
// Check for image data
|
||||
if (!request.body || !request.body.image) {
|
||||
return response.status(400).send({ error: "No image data provided" });
|
||||
}
|
||||
|
||||
// Extracting the base64 data and the image format
|
||||
const match = request.body.image.match(/^data:image\/(png|jpg|webp);base64,(.+)$/);
|
||||
if (!match) {
|
||||
return response.status(400).send({ error: "Invalid image format" });
|
||||
}
|
||||
|
||||
const [, format, base64Data] = match;
|
||||
|
||||
// Constructing filename and path
|
||||
let filename = `${Date.now()}.${format}`;
|
||||
if (request.body.filename) {
|
||||
filename = `${request.body.filename}.${format}`;
|
||||
}
|
||||
|
||||
// if character is defined, save to a sub folder for that character
|
||||
let pathToNewFile = path.join(directories.userImages, filename);
|
||||
if (request.body.ch_name) {
|
||||
pathToNewFile = path.join(directories.userImages, request.body.ch_name, filename);
|
||||
}
|
||||
|
||||
try {
|
||||
ensureDirectoryExistence(pathToNewFile);
|
||||
const imageBuffer = Buffer.from(base64Data, 'base64');
|
||||
await fs.promises.writeFile(pathToNewFile, imageBuffer);
|
||||
// send the path to the image, relative to the client folder, which means removing the first folder from the path which is 'public'
|
||||
pathToNewFile = pathToNewFile.split(path.sep).slice(1).join(path.sep);
|
||||
response.send({ path: pathToNewFile });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
response.status(500).send({ error: "Failed to save the image" });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.post('/getgroups', jsonParser, (_, response) => {
|
||||
const groups = [];
|
||||
|
||||
|
@ -3392,7 +3461,7 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
|||
config.responseType = 'stream';
|
||||
}
|
||||
|
||||
async function makeRequest(config, response_generate_openai, request, retries = 5, timeout = 1000) {
|
||||
async function makeRequest(config, response_generate_openai, request, retries = 5, timeout = 5000) {
|
||||
try {
|
||||
const response = await axios(config);
|
||||
|
||||
|
@ -3414,7 +3483,7 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
|||
}
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === 429 && retries > 0) {
|
||||
console.log('Out of quota, retrying...');
|
||||
console.log(`Out of quota, retrying in ${Math.round(timeout / 1000)}s`);
|
||||
setTimeout(() => {
|
||||
makeRequest(config, response_generate_openai, request, retries - 1);
|
||||
}, timeout);
|
||||
|
|
Loading…
Reference in New Issue