WI: Split entry header and editor

9a82b688baf495ef42af5afbf4f2675dda5327f2

Cohee <18619528+Cohee1207@users.noreply.github.com>

3 files changed, +625 -587Ignore whitespace
public/css/world-info.css+4 -0
@@ -201,6 +201,10 @@
201201 transition: opacity 500ms;
202202}
203203
204+.world_entry_edit {
205+ display: contents;
206+}
207+
204208.disabledWIEntry {
205209 opacity: 0.4;
206210 filter: grayscale(1);
public/index.html+294 -291
@@ -6193,6 +6193,298 @@
61936193 </div>
61946194 </div>
61956195 <div id="entry_edit_template" class="template_element">
6196+ <div class="world_entry_edit">
6197+ <div class="flex-container wide100p alignitemscenter">
6198+ <div name="keywordsAndLogicBlock" class="flex-container wide100p alignitemscenter">
6199+ <div class="world_entry_form_control keyprimary flex1">
6200+ <small class="displayNone">
6201+ <span data-i18n="Comma separated (required)">
6202+ Comma separated (required)
6203+ </span>
6204+ </small>
6205+ <small class="textAlignCenter" data-i18n="Primary Keywords">Primary Keywords</small>
6206+ <select class="keyprimaryselect keyselect select2_multi_sameline" name="key" data-i18n="[placeholder]Keywords or Regexes" placeholder="Keywords or Regexes" multiple="multiple"></select>
6207+ <textarea class="text_pole keyprimarytextpole mobile" name="key" rows="1" data-i18n="[placeholder]Comma separated list" placeholder="Comma separated list" style="display: none;"></textarea>
6208+ <button type="button" class="switch_input_type_icon" tabindex="-1" title="Switch to plaintext mode" data-i18n="[title]Switch to plaintext mode" data-icon-on="✨" data-icon-off="⌨️" data-tooltip-on="Switch to fancy mode" data-tooltip-off="Switch to plaintext mode">
6209+ ⌨️
6210+ </button>
6211+ </div>
6212+ <div class="world_entry_form_control">
6213+ <small class="textAlignCenter" data-i18n="Logic">Logic</small>
6214+ <select name="entryLogicType" class="text_pole widthFitContent margin0">
6215+ <option value="0" data-i18n="AND ANY">AND ANY</option>
6216+ <option value="3" data-i18n="AND ALL">AND ALL</option>
6217+ <option value="1" data-i18n="NOT ALL">NOT ALL</option>
6218+ <option value="2" data-i18n="NOT ANY">NOT ANY</option>
6219+ </select>
6220+ </div>
6221+ <div class="world_entry_form_control keysecondary flex1">
6222+ <small class="displayNone">
6223+ <span data-i18n="(ignored if empty)">
6224+ (ignored if empty)
6225+ </span>
6226+ </small>
6227+ <small class="textAlignCenter" data-i18n="Optional Filter">Optional Filter</small>
6228+ <select class="keysecondaryselect keyselect select2_multi_sameline" name="keysecondary" data-i18n="[placeholder]Keywords or Regexes (ignored if empty)" placeholder="Keywords or Regexes (ignored if empty)" multiple="multiple"></select>
6229+ <textarea class="text_pole keysecondarytextpole mobile" name="keysecondary" rows="1" data-i18n="[placeholder]Comma separated list (ignored if empty)" placeholder="Comma separated list (ignored if empty)" style="display: none;"></textarea>
6230+ <button type="button" class="switch_input_type_icon" tabindex="-1" title="Switch to plaintext mode" data-i18n="[title]Switch to plaintext mode" data-icon-on="✨" data-icon-off="⌨️" data-tooltip-on="Switch to fancy mode" data-tooltip-off="Switch to plaintext mode">
6231+ ⌨️
6232+ </button>
6233+ </div>
6234+ </div>
6235+ <div name="perEntryOverridesBlock" class="flex-container wide100p alignitemscenter">
6236+ <div class="world_entry_form_control flex1">
6237+ <small class="textAlignCenter" data-i18n="Scan Depth">Scan Depth</small>
6238+ <input class="text_pole margin0" name="scanDepth" type="number" placeholder="Use global setting" data-i18n="[placeholder]Use global setting" max="1000">
6239+ </div>
6240+ <div class="world_entry_form_control flex1">
6241+ <small class="textAlignCenter" data-i18n="Case-Sensitive">Case-Sensitive</small>
6242+ <select name="caseSensitive" class="text_pole widthNatural margin0">
6243+ <option value="null" data-i18n="Use global">Use global</option>
6244+ <option value="true" data-i18n="Yes">Yes</option>
6245+ <option value="false" data-i18n="No">No</option>
6246+ </select>
6247+ </div>
6248+ <div class="world_entry_form_control flex1">
6249+ <small class="textAlignCenter" data-i18n="Whole Words">Whole Words</small>
6250+ <select name="matchWholeWords" class="text_pole widthNatural margin0">
6251+ <option value="null" data-i18n="Use global">Use global</option>
6252+ <option value="true" data-i18n="Yes">Yes</option>
6253+ <option value="false" data-i18n="No">No</option>
6254+ </select>
6255+ </div>
6256+ <div class="world_entry_form_control flex1">
6257+ <small class="textAlignCenter" data-i18n="Group Scoring">Group Scoring</small>
6258+ <select name="useGroupScoring" class="text_pole widthNatural margin0">
6259+ <option value="null" data-i18n="Use global">Use global</option>
6260+ <option value="true" data-i18n="Yes">Yes</option>
6261+ <option value="false" data-i18n="No">No</option>
6262+ </select>
6263+ </div>
6264+ <div class="world_entry_form_control flex1" title="Can be used to automatically activate Quick Replies" data-i18n="[title]Can be used to automatically activate Quick Replies">
6265+ <small class="textAlignCenter" data-i18n="Automation ID">Automation ID</small>
6266+ <input class="text_pole margin0" name="automationId" type="text" placeholder="( None )" data-i18n="[placeholder]( None )">
6267+ </div>
6268+ <div class="world_entry_form_control flex1" title="Defines delay levels for recursive scans.&#13;&#13;Initially, only the first level (smallest number) will match.&#13;Once no matches are found, the next level becomes eligible for matching.&#13;This repeats until all levels are checked.&#13;&#13;Tied to the &quot;Delay until recursion&quot; setting." data-i18n="[title]delay_until_recursion_level">
6269+ <small class="textAlignCenter">
6270+ <span data-i18n="Recursion Level">Recursion Level</span>
6271+ <div class="fa-solid fa-circle-info opacity50p"></div>
6272+ </small>
6273+ <input class="text_pole margin0" name="delayUntilRecursionLevel" type="text" placeholder="1">
6274+ </div>
6275+ </div>
6276+ <div name="contentAndCharFilterBlock" class="world_entry_thin_controls flex2">
6277+ <div class="world_entry_form_control flex1">
6278+ <label for="content ">
6279+ <small>
6280+ <span class="alignitemscenter flex-container flexnowrap wide100p justifySpaceBetween">
6281+ <span class="alignitemscenter flex-container">
6282+ <span data-i18n="Content" class="mdhotkey_location">
6283+ Content
6284+ </span>
6285+ <i class="editor_maximize fa-solid fa-maximize right_menu_button" title="Expand the editor" data-i18n="[title]Expand the editor"></i>
6286+ </span>
6287+ <span>
6288+ (<span data-i18n="extension_token_counter">Tokens:</span>&nbsp; <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>)&nbsp;
6289+ <span class="world_entry_form_uid_value" data-first-run="true"></span>
6290+ </span>
6291+ <div>
6292+ <label class="checkbox flex-container alignitemscenter flexNoGap">
6293+ <input type="checkbox" name="exclude_recursion" />
6294+ <span data-i18n="Non-recursable (will not be activated by another)">
6295+ Non-recursable (will not be activated by another)
6296+ </span>
6297+ </label>
6298+ <label class="checkbox flex-container alignitemscenter flexNoGap">
6299+ <input type="checkbox" name="prevent_recursion" />
6300+ <span data-i18n="Prevent further recursion (this entry will not activate others)">
6301+ Prevent further recursion (will not activate others)
6302+ </span>
6303+ </label>
6304+ <label class="checkbox flex-container alignitemscenter flexNoGap">
6305+ <input type="checkbox" name="delay_until_recursion" />
6306+ <span data-i18n="Delay until recursion (can only be activated on recursive checking)">
6307+ Delay until recursion (can only be activated on recursive checking)
6308+ </span>
6309+ </label>
6310+ </div>
6311+ </span>
6312+ </small>
6313+ <small class="displayNone">
6314+ <span data-i18n="What this keyword should mean to the AI, sent verbatim">
6315+ What this keyword should mean to the AI, sent verbatim
6316+ </span>
6317+ </small>
6318+ </label>
6319+ <textarea class="text_pole mdHotkeys" name="content" rows="8" data-i18n="[placeholder]What this keyword should mean to the AI, sent verbatim" placeholder="What this keyword should mean to the AI, sent verbatim"></textarea>
6320+ </div>
6321+ </div>
6322+ <div class="world_entry_thin_controls commentContainer">
6323+ </div>
6324+ </div>
6325+ <div class="flex-container wide100p flexGap10">
6326+ <div class="flex4 flex-container flexFlowColumn flexNoGap">
6327+ <div class="flex-container justifySpaceBetween">
6328+ <small for="group">
6329+ <span data-i18n="Inclusion Group">Inclusion Group</span>
6330+ <a href="https://docs.sillytavern.app/usage/core-concepts/worldinfo/#inclusion-group" class="notes-link" target="_blank" title="Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.&#13;Supports multiple comma-separated groups.&#13;&#13;Documentation: World Info - Inclusion Group" data-i18n="[title]Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group">
6331+ <span class="fa-solid fa-circle-question note-link-span"></span>
6332+ </a>
6333+ </small>
6334+ <label class="checkbox_label flexNoGap margin-r5" for="groupOverride">
6335+ <input type="checkbox" name="groupOverride" />
6336+ <span>
6337+ <small title="Prioritize this entry: When checked, this entry is prioritized out of all selections.&#13;If multiple are prioritized, the one with the highest 'Order' is chosen.&#13;" data-i18n="[title]Prioritize this entry: When checked, this entry is prioritized out of all selections.If multiple are prioritized, the one with the highest 'Order' is chosen.">
6338+ <span data-i18n="Prioritize">Prioritize</span>
6339+ <div class="fa-solid fa-circle-info opacity50p"></div>
6340+ </small>
6341+ </span>
6342+ </label>
6343+ </div>
6344+ <div class="range-block-range">
6345+ <input type="text" class="text_pole margin0" name="group" rows="1" data-i18n="[placeholder]Only one entry with the same label will be activated" placeholder="Only one entry with the same label will be activated">
6346+ </div>
6347+ </div>
6348+ <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]A relative likelihood of entry activation within the group" title="A relative likelihood of entry activation within the group">
6349+ <div class="flex-container justifySpaceBetween marginBot5">
6350+ <small for="groupWeight" data-i18n="Group Weight">
6351+ Group Weight
6352+ </small>
6353+ </div>
6354+ <div class="range-block-range">
6355+ <input type="number" class="text_pole margin0" name="groupWeight" rows="1" placeholder="100" min="1" max="999999">
6356+ </div>
6357+ </div>
6358+ <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Sticky entries will stay active for N messages after being triggered." title="Sticky entries will stay active for N messages after being triggered.">
6359+ <div class="flex-container justifySpaceBetween marginBot5">
6360+ <small class="flex-container alignItemsBaseline" for="sticky">
6361+ <span data-i18n="Sticky">
6362+ Sticky
6363+ </span>
6364+ <i class="fa-solid fa-comments fa-xs"></i>
6365+ </small>
6366+ </div>
6367+ <div class="range-block-range">
6368+ <input class="text_pole margin0" name="sticky" type="number" data-i18n="[placeholder]Non-sticky" placeholder="Non-sticky" min="0" max="999999">
6369+ </div>
6370+ </div>
6371+ <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Entries with a cooldown can't be activated N messages after being triggered." title="Entries with a cooldown can't be activated N messages after being triggered.">
6372+ <div class="flex-container justifySpaceBetween marginBot5">
6373+ <small class="flex-container alignItemsBaseline" for="cooldown">
6374+ <span data-i18n="Cooldown">
6375+ Cooldown
6376+ </span>
6377+ <i class="fa-solid fa-comments fa-xs"></i>
6378+ </small>
6379+ </div>
6380+ <div class="range-block-range">
6381+ <input class="text_pole margin0" name="cooldown" type="number" data-i18n="[placeholder]No cooldown" placeholder="No cooldown" min="0" max="999999">
6382+ </div>
6383+ </div>
6384+ <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Entries with a delay can't be activated until there are N messages present in the chat." title="Entries with a delay can't be activated until there are N messages present in the chat.">
6385+ <div class="flex-container justifySpaceBetween marginBot5">
6386+ <small class="flex-container alignItemsBaseline" for="delay">
6387+ <span data-i18n="Delay">
6388+ Delay
6389+ </span>
6390+ <i class="fa-solid fa-comments fa-xs"></i>
6391+ </small>
6392+ </div>
6393+ <div class="range-block-range">
6394+ <input class="text_pole margin0" name="delay" type="number" data-i18n="[placeholder]No delay" placeholder="No delay" min="0" max="999999">
6395+ </div>
6396+ </div>
6397+ </div>
6398+ <div class="flex-container wide100p flexGap10">
6399+ <div class="flex4 flex-container flexFlowColumn flexNoGap">
6400+ <div class="flex-container justifySpaceBetween">
6401+ <small for="characterFilter" data-i18n="Filter to Characters or Tags">
6402+ Filter to Characters or Tags
6403+ </small>
6404+ <label class="checkbox_label flexNoGap margin-r5" for="character_exclusion">
6405+ <input type="checkbox" name="character_exclusion" />
6406+ <span>
6407+ <small title="Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry" data-i18n="[title]Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry">
6408+ <span data-i18n="Exclude">Exclude</span>
6409+ <div class="fa-solid fa-circle-info opacity50p"></div>
6410+ </small>
6411+ </span>
6412+ </label>
6413+ </div>
6414+ <div class="range-block-range">
6415+ <select name="characterFilter" class="select2_multi_sameline" multiple>
6416+ <option value="" data-i18n="-- Characters not found --">
6417+ -- Characters not found --
6418+ </option>
6419+ </select>
6420+ </div>
6421+ </div>
6422+ </div>
6423+ <div name="WIEntryBottomControls" class="flex-container flex1 justifySpaceBetween world_entry_form_horizontal">
6424+ <div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text">
6425+ <label class="checkbox flex-container">
6426+ <input type="checkbox" name="selective" />
6427+ <span data-i18n="Selective">Selective</span>
6428+ </label>
6429+ <label class="checkbox flex-container">
6430+ <input type="checkbox" name="useProbability" />
6431+ <span data-i18n="Use Probability">Use Probability</span>
6432+ </label>
6433+ <label class="checkbox flex-container">
6434+ <input type="checkbox" name="addMemo">
6435+ <span data-i18n="Add Memo">Add Memo</span>
6436+ </label>
6437+ </div>
6438+ </div>
6439+ <div class="inline-drawer wide100p flexFlowColumn">
6440+ <div class="inline-drawer-toggle inline-drawer-header inline-drawer-header-pointer userSettingsInnerExpandable">
6441+ <strong data-i18n="Additional Matching Sources">Additional Matching Sources</strong>
6442+ <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
6443+ </div>
6444+ <div class="inline-drawer-content flex-container flexFlowRow flexGap10 paddingBottom5px">
6445+ <small class="flex-container flex1 flexFlowColumn">
6446+ <label class="checkbox flex-container alignItemsCenter flexNoGap">
6447+ <input type="checkbox" name="matchCharacterDescription" />
6448+ <span data-i18n="Character Description">
6449+ Character Description
6450+ </span>
6451+ </label>
6452+ <label class="checkbox flex-container alignItemsCenter flexNoGap">
6453+ <input type="checkbox" name="matchCharacterPersonality" />
6454+ <span data-i18n="Character Personality">
6455+ Character Personality
6456+ </span>
6457+ </label>
6458+ <label class="checkbox flex-container alignItemsCenter flexNoGap">
6459+ <input type="checkbox" name="matchScenario" />
6460+ <span data-i18n="Scenario">
6461+ Scenario
6462+ </span>
6463+ </label>
6464+ </small>
6465+ <small class="flex-container flex1 flexFlowColumn">
6466+ <label class="checkbox flex-container alignItemsCenter flexNoGap">
6467+ <input type="checkbox" name="matchPersonaDescription" />
6468+ <span data-i18n="Persona Description">
6469+ Persona Description
6470+ </span>
6471+ </label>
6472+ <label class="checkbox flex-container alignItemsCenter flexNoGap">
6473+ <input type="checkbox" name="matchCharacterDepthPrompt" />
6474+ <span data-i18n="Character's Note">
6475+ Character's Note
6476+ </span>
6477+ </label>
6478+ <label class="checkbox flex-container alignItemsCenter flexNoGap">
6479+ <input type="checkbox" name="matchCreatorNotes" />
6480+ <span data-i18n="Creator's Notes">
6481+ Creator's Notes
6482+ </span>
6483+ </label>
6484+ </small>
6485+ </div>
6486+ </div>
6487+ </div>
61966488 <div class="world_entry">
61976489 <form class="world_entry_form wi-card-entry">
61986490 <div class="inline-drawer wide100p">
@@ -6265,297 +6557,8 @@
62656557 <i class="menu_button duplicate_entry_button fa-solid fa-paste" title="Duplicate world info entry" data-i18n="[title]Duplicate world info entry" type="submit" value=""></i>
62666558 <i class="menu_button delete_entry_button fa-solid fa-trash-can" title="Delete world info entry" data-i18n="[title]Delete world info entry" type="submit" value=""></i>
62676559 </div>
62686560 <div class="inline-drawer-content inline-drawer-outlet flex-container paddingBottom5px wide100p ">
6269- <div class="flex-container wide100p alignitemscenter">
6561+ <!-- Outlet for world_entry_edit -->
6270- <div name="keywordsAndLogicBlock" class="flex-container wide100p alignitemscenter">
6271- <div class="world_entry_form_control keyprimary flex1">
6272- <small class="displayNone">
6273- <span data-i18n="Comma separated (required)">
6274- Comma separated (required)
6275- </span>
6276- </small>
6277- <small class="textAlignCenter" data-i18n="Primary Keywords">Primary Keywords</small>
6278- <select class="keyprimaryselect keyselect select2_multi_sameline" name="key" data-i18n="[placeholder]Keywords or Regexes" placeholder="Keywords or Regexes" multiple="multiple"></select>
6279- <textarea class="text_pole keyprimarytextpole mobile" name="key" rows="1" data-i18n="[placeholder]Comma separated list" placeholder="Comma separated list" style="display: none;"></textarea>
6280- <button type="button" class="switch_input_type_icon" tabindex="-1" title="Switch to plaintext mode" data-i18n="[title]Switch to plaintext mode" data-icon-on="✨" data-icon-off="⌨️" data-tooltip-on="Switch to fancy mode" data-tooltip-off="Switch to plaintext mode">
6281- ⌨️
6282- </button>
6283- </div>
6284- <div class="world_entry_form_control">
6285- <small class="textAlignCenter" data-i18n="Logic">Logic</small>
6286- <select name="entryLogicType" class="text_pole widthFitContent margin0">
6287- <option value="0" data-i18n="AND ANY">AND ANY</option>
6288- <option value="3" data-i18n="AND ALL">AND ALL</option>
6289- <option value="1" data-i18n="NOT ALL">NOT ALL</option>
6290- <option value="2" data-i18n="NOT ANY">NOT ANY</option>
6291- </select>
6292- </div>
6293- <div class="world_entry_form_control keysecondary flex1">
6294- <small class="displayNone">
6295- <span data-i18n="(ignored if empty)">
6296- (ignored if empty)
6297- </span>
6298- </small>
6299- <small class="textAlignCenter" data-i18n="Optional Filter">Optional Filter</small>
6300- <select class="keysecondaryselect keyselect select2_multi_sameline" name="keysecondary" data-i18n="[placeholder]Keywords or Regexes (ignored if empty)" placeholder="Keywords or Regexes (ignored if empty)" multiple="multiple"></select>
6301- <textarea class="text_pole keysecondarytextpole mobile" name="keysecondary" rows="1" data-i18n="[placeholder]Comma separated list (ignored if empty)" placeholder="Comma separated list (ignored if empty)" style="display: none;"></textarea>
6302- <button type="button" class="switch_input_type_icon" tabindex="-1" title="Switch to plaintext mode" data-i18n="[title]Switch to plaintext mode" data-icon-on="✨" data-icon-off="⌨️" data-tooltip-on="Switch to fancy mode" data-tooltip-off="Switch to plaintext mode">
6303- ⌨️
6304- </button>
6305- </div>
6306- </div>
6307- <div name="perEntryOverridesBlock" class="flex-container wide100p alignitemscenter">
6308- <div class="world_entry_form_control flex1">
6309- <small class="textAlignCenter" data-i18n="Scan Depth">Scan Depth</small>
6310- <input class="text_pole margin0" name="scanDepth" type="number" placeholder="Use global setting" data-i18n="[placeholder]Use global setting" max="1000">
6311- </div>
6312- <div class="world_entry_form_control flex1">
6313- <small class="textAlignCenter" data-i18n="Case-Sensitive">Case-Sensitive</small>
6314- <select name="caseSensitive" class="text_pole widthNatural margin0">
6315- <option value="null" data-i18n="Use global">Use global</option>
6316- <option value="true" data-i18n="Yes">Yes</option>
6317- <option value="false" data-i18n="No">No</option>
6318- </select>
6319- </div>
6320- <div class="world_entry_form_control flex1">
6321- <small class="textAlignCenter" data-i18n="Whole Words">Whole Words</small>
6322- <select name="matchWholeWords" class="text_pole widthNatural margin0">
6323- <option value="null" data-i18n="Use global">Use global</option>
6324- <option value="true" data-i18n="Yes">Yes</option>
6325- <option value="false" data-i18n="No">No</option>
6326- </select>
6327- </div>
6328- <div class="world_entry_form_control flex1">
6329- <small class="textAlignCenter" data-i18n="Group Scoring">Group Scoring</small>
6330- <select name="useGroupScoring" class="text_pole widthNatural margin0">
6331- <option value="null" data-i18n="Use global">Use global</option>
6332- <option value="true" data-i18n="Yes">Yes</option>
6333- <option value="false" data-i18n="No">No</option>
6334- </select>
6335- </div>
6336- <div class="world_entry_form_control flex1" title="Can be used to automatically activate Quick Replies" data-i18n="[title]Can be used to automatically activate Quick Replies">
6337- <small class="textAlignCenter" data-i18n="Automation ID">Automation ID</small>
6338- <input class="text_pole margin0" name="automationId" type="text" placeholder="( None )" data-i18n="[placeholder]( None )">
6339- </div>
6340- <div class="world_entry_form_control flex1" title="Defines delay levels for recursive scans.&#13;&#13;Initially, only the first level (smallest number) will match.&#13;Once no matches are found, the next level becomes eligible for matching.&#13;This repeats until all levels are checked.&#13;&#13;Tied to the &quot;Delay until recursion&quot; setting." data-i18n="[title]delay_until_recursion_level">
6341- <small class="textAlignCenter">
6342- <span data-i18n="Recursion Level">Recursion Level</span>
6343- <div class="fa-solid fa-circle-info opacity50p"></div>
6344- </small>
6345- <input class="text_pole margin0" name="delayUntilRecursionLevel" type="text" placeholder="1">
6346- </div>
6347- </div>
6348- <div name="contentAndCharFilterBlock" class="world_entry_thin_controls flex2">
6349- <div class="world_entry_form_control flex1">
6350- <label for="content ">
6351- <small>
6352- <span class="alignitemscenter flex-container flexnowrap wide100p justifySpaceBetween">
6353- <span class="alignitemscenter flex-container">
6354- <span data-i18n="Content" class="mdhotkey_location">
6355- Content
6356- </span>
6357- <i class="editor_maximize fa-solid fa-maximize right_menu_button" title="Expand the editor" data-i18n="[title]Expand the editor"></i>
6358- </span>
6359- <span>
6360- (<span data-i18n="extension_token_counter">Tokens:</span>&nbsp; <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>)&nbsp;
6361- <span class="world_entry_form_uid_value" data-first-run="true"></span>
6362- </span>
6363- <div>
6364- <label class="checkbox flex-container alignitemscenter flexNoGap">
6365- <input type="checkbox" name="exclude_recursion" />
6366- <span data-i18n="Non-recursable (will not be activated by another)">
6367- Non-recursable (will not be activated by another)
6368- </span>
6369- </label>
6370- <label class="checkbox flex-container alignitemscenter flexNoGap">
6371- <input type="checkbox" name="prevent_recursion" />
6372- <span data-i18n="Prevent further recursion (this entry will not activate others)">
6373- Prevent further recursion (will not activate others)
6374- </span>
6375- </label>
6376- <label class="checkbox flex-container alignitemscenter flexNoGap">
6377- <input type="checkbox" name="delay_until_recursion" />
6378- <span data-i18n="Delay until recursion (can only be activated on recursive checking)">
6379- Delay until recursion (can only be activated on recursive checking)
6380- </span>
6381- </label>
6382- </div>
6383- </span>
6384- </small>
6385- <small class="displayNone">
6386- <span data-i18n="What this keyword should mean to the AI, sent verbatim">
6387- What this keyword should mean to the AI, sent verbatim
6388- </span>
6389- </small>
6390- </label>
6391- <textarea class="text_pole mdHotkeys" name="content" rows="8" data-i18n="[placeholder]What this keyword should mean to the AI, sent verbatim" placeholder="What this keyword should mean to the AI, sent verbatim"></textarea>
6392- </div>
6393- </div>
6394- <div class="world_entry_thin_controls commentContainer">
6395- </div>
6396- </div>
6397- <div class="flex-container wide100p flexGap10">
6398- <div class="flex4 flex-container flexFlowColumn flexNoGap">
6399- <div class="flex-container justifySpaceBetween">
6400- <small for="group">
6401- <span data-i18n="Inclusion Group">Inclusion Group</span>
6402- <a href="https://docs.sillytavern.app/usage/core-concepts/worldinfo/#inclusion-group" class="notes-link" target="_blank" title="Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.&#13;Supports multiple comma-separated groups.&#13;&#13;Documentation: World Info - Inclusion Group" data-i18n="[title]Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group">
6403- <span class="fa-solid fa-circle-question note-link-span"></span>
6404- </a>
6405- </small>
6406- <label class="checkbox_label flexNoGap margin-r5" for="groupOverride">
6407- <input type="checkbox" name="groupOverride" />
6408- <span>
6409- <small title="Prioritize this entry: When checked, this entry is prioritized out of all selections.&#13;If multiple are prioritized, the one with the highest 'Order' is chosen.&#13;" data-i18n="[title]Prioritize this entry: When checked, this entry is prioritized out of all selections.If multiple are prioritized, the one with the highest 'Order' is chosen.">
6410- <span data-i18n="Prioritize">Prioritize</span>
6411- <div class="fa-solid fa-circle-info opacity50p"></div>
6412- </small>
6413- </span>
6414- </label>
6415- </div>
6416- <div class="range-block-range">
6417- <input type="text" class="text_pole margin0" name="group" rows="1" data-i18n="[placeholder]Only one entry with the same label will be activated" placeholder="Only one entry with the same label will be activated">
6418- </div>
6419- </div>
6420- <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]A relative likelihood of entry activation within the group" title="A relative likelihood of entry activation within the group">
6421- <div class="flex-container justifySpaceBetween marginBot5">
6422- <small for="groupWeight" data-i18n="Group Weight">
6423- Group Weight
6424- </small>
6425- </div>
6426- <div class="range-block-range">
6427- <input type="number" class="text_pole margin0" name="groupWeight" rows="1" placeholder="100" min="1" max="999999">
6428- </div>
6429- </div>
6430- <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Sticky entries will stay active for N messages after being triggered." title="Sticky entries will stay active for N messages after being triggered.">
6431- <div class="flex-container justifySpaceBetween marginBot5">
6432- <small class="flex-container alignItemsBaseline" for="sticky">
6433- <span data-i18n="Sticky">
6434- Sticky
6435- </span>
6436- <i class="fa-solid fa-comments fa-xs"></i>
6437- </small>
6438- </div>
6439- <div class="range-block-range">
6440- <input class="text_pole margin0" name="sticky" type="number" data-i18n="[placeholder]Non-sticky" placeholder="Non-sticky" min="0" max="999999">
6441- </div>
6442- </div>
6443- <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Entries with a cooldown can't be activated N messages after being triggered." title="Entries with a cooldown can't be activated N messages after being triggered.">
6444- <div class="flex-container justifySpaceBetween marginBot5">
6445- <small class="flex-container alignItemsBaseline" for="cooldown">
6446- <span data-i18n="Cooldown">
6447- Cooldown
6448- </span>
6449- <i class="fa-solid fa-comments fa-xs"></i>
6450- </small>
6451- </div>
6452- <div class="range-block-range">
6453- <input class="text_pole margin0" name="cooldown" type="number" data-i18n="[placeholder]No cooldown" placeholder="No cooldown" min="0" max="999999">
6454- </div>
6455- </div>
6456- <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Entries with a delay can't be activated until there are N messages present in the chat." title="Entries with a delay can't be activated until there are N messages present in the chat.">
6457- <div class="flex-container justifySpaceBetween marginBot5">
6458- <small class="flex-container alignItemsBaseline" for="delay">
6459- <span data-i18n="Delay">
6460- Delay
6461- </span>
6462- <i class="fa-solid fa-comments fa-xs"></i>
6463- </small>
6464- </div>
6465- <div class="range-block-range">
6466- <input class="text_pole margin0" name="delay" type="number" data-i18n="[placeholder]No delay" placeholder="No delay" min="0" max="999999">
6467- </div>
6468- </div>
6469- </div>
6470- <div class="flex-container wide100p flexGap10">
6471- <div class="flex4 flex-container flexFlowColumn flexNoGap">
6472- <div class="flex-container justifySpaceBetween">
6473- <small for="characterFilter" data-i18n="Filter to Characters or Tags">
6474- Filter to Characters or Tags
6475- </small>
6476- <label class="checkbox_label flexNoGap margin-r5" for="character_exclusion">
6477- <input type="checkbox" name="character_exclusion" />
6478- <span>
6479- <small title="Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry" data-i18n="[title]Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry">
6480- <span data-i18n="Exclude">Exclude</span>
6481- <div class="fa-solid fa-circle-info opacity50p"></div>
6482- </small>
6483- </span>
6484- </label>
6485- </div>
6486- <div class="range-block-range">
6487- <select name="characterFilter" class="select2_multi_sameline" multiple>
6488- <option value="" data-i18n="-- Characters not found --">
6489- -- Characters not found --
6490- </option>
6491- </select>
6492- </div>
6493- </div>
6494- </div>
6495- <div name="WIEntryBottomControls" class="flex-container flex1 justifySpaceBetween world_entry_form_horizontal">
6496- <div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
6497- <label class="checkbox flex-container">
6498- <input type="checkbox" name="selective" />
6499- <span data-i18n="Selective">Selective</span>
6500- </label>
6501- <label class="checkbox flex-container">
6502- <input type="checkbox" name="useProbability" />
6503- <span data-i18n="Use Probability">Use Probability</span>
6504- </label>
6505- <label class="checkbox flex-container">
6506- <input type="checkbox" name="addMemo">
6507- <span data-i18n="Add Memo">Add Memo</span>
6508- </label>
6509- </div>
6510- </div>
6511- <div class="inline-drawer wide100p flexFlowColumn">
6512- <div class="inline-drawer-toggle inline-drawer-header inline-drawer-header-pointer userSettingsInnerExpandable">
6513- <strong data-i18n="Additional Matching Sources">Additional Matching Sources</strong>
6514- <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
6515- </div>
6516- <div class="inline-drawer-content flex-container flexFlowRow flexGap10 paddingBottom5px">
6517- <small class="flex-container flex1 flexFlowColumn">
6518- <label class="checkbox flex-container alignItemsCenter flexNoGap">
6519- <input type="checkbox" name="matchCharacterDescription" />
6520- <span data-i18n="Character Description">
6521- Character Description
6522- </span>
6523- </label>
6524- <label class="checkbox flex-container alignItemsCenter flexNoGap">
6525- <input type="checkbox" name="matchCharacterPersonality" />
6526- <span data-i18n="Character Personality">
6527- Character Personality
6528- </span>
6529- </label>
6530- <label class="checkbox flex-container alignItemsCenter flexNoGap">
6531- <input type="checkbox" name="matchScenario" />
6532- <span data-i18n="Scenario">
6533- Scenario
6534- </span>
6535- </label>
6536- </small>
6537- <small class="flex-container flex1 flexFlowColumn">
6538- <label class="checkbox flex-container alignItemsCenter flexNoGap">
6539- <input type="checkbox" name="matchPersonaDescription" />
6540- <span data-i18n="Persona Description">
6541- Persona Description
6542- </span>
6543- </label>
6544- <label class="checkbox flex-container alignItemsCenter flexNoGap">
6545- <input type="checkbox" name="matchCharacterDepthPrompt" />
6546- <span data-i18n="Character's Note">
6547- Character's Note
6548- </span>
6549- </label>
6550- <label class="checkbox flex-container alignItemsCenter flexNoGap">
6551- <input type="checkbox" name="matchCreatorNotes" />
6552- <span data-i18n="Creator's Notes">
6553- Creator's Notes
6554- </span>
6555- </label>
6556- </small>
6557- </div>
6558- </div>
65596562 </div>
65606563 </div>
65616564 </form>
public/scripts/world-info.js+327 -296
@@ -58,7 +58,8 @@ export const scan_state = {
5858 MIN_ACTIVATIONS: 3,
5959};
6060
6161const WI_ENTRY_EDIT_TEMPLATEWI_ENTRY_HEADER_TEMPLATE = $('#entry_edit_template .world_entry');
62+const WI_ENTRY_EDIT_TEMPLATE = $('#entry_edit_template .world_entry_edit');
6263
6364export let world_info = {};
6465export let selected_world_info = [];
@@ -1939,9 +1940,8 @@ function updateWorldEntryKeyOptionsCache(keyOptions, { remove = false, reset = f
19391940 worldEntryKeyOptionsCache.sort((a, b) => b.count - a.count || a.text.localeCompare(b.text));
19401941}
19411942
19421943function clearEntryList($list) {
19431944 console.time('clearEntryList');
1944- const $list = $('#world_popup_entries_list');
19451945
19461946 if (!$list.children().length) {
19471947 console.debug('List already empty, skipping cleanup.');
@@ -2007,7 +2007,7 @@ async function displayWorldEntries(name, data, navigation = navigation_option.no
20072007
20082008 worldEntriesList.css({ 'opacity': 0, 'transition': 'opacity 250ms ease-in-out' });
20092009 await delay(250);
20102010 clearEntryList(worldEntriesList);
20112011 worldEntriesList.show();
20122012
20132013 if (!data || !('entries' in data)) {
@@ -2104,7 +2104,7 @@ async function displayWorldEntries(name, data, navigation = navigation_option.no
21042104 try {
21052105 // Prevent saveWorldInfo from firing timeouts while rendering the list
21062106 isSaveWorldInfoDisabled = true;
21072107 clearEntryList(worldEntriesList);
21082108
21092109 const keywordHeaders = await renderTemplateAsync('worldInfoKeywordHeaders');
21102110 const blocks = [];
@@ -2885,82 +2885,14 @@ function handleEntryKillSwitchHelper({ entryKillSwitch, entry, data, name, setWI
28852885export async function getWorldEntry(name, data, entry) {
28862886 if (!data.entries[entry.uid]) return;
28872887
28882888 const templateheaderTemplate = WI_ENTRY_EDIT_TEMPLATEWI_ENTRY_HEADER_TEMPLATE.clone();
28892889 templateheaderTemplate.data('uid', entry.uid);
28902890 templateheaderTemplate.attr('uid', entry.uid);
28912891
28922892 if (typeof power_user.wi_key_input_plaintext === 'undefined') power_user.wi_key_input_plaintext = true;
28932893
2894- // Key inputs
2895- const keyInput = enableKeysInputHelper({ template, entry, entryPropName: 'key', originalDataValueName: 'keys', name, data });
2896- const keySecondaryInput = enableKeysInputHelper({ template, entry, entryPropName: 'keysecondary', originalDataValueName: 'secondary_keys', name, data });
2897-
2898- // Key input switch
2899- template.find('.switch_input_type_icon').on('click', function () {
2900- power_user.wi_key_input_plaintext = !power_user.wi_key_input_plaintext;
2901- saveSettingsDebounced();
2902- const uid = ($(this).parents('.world_entry')).data('uid');
2903- updateEditor(uid, false);
2904- $(`.world_entry[uid="${uid}"] .inline-drawer-icon`).trigger('click');
2905- }).each((_, icon) => {
2906- $(icon).attr('title', $(icon).data(power_user.wi_key_input_plaintext ? 'tooltip-on' : 'tooltip-off'));
2907- $(icon).text($(icon).data(power_user.wi_key_input_plaintext ? 'icon-on' : 'icon-off'));
2908- });
2909-
2910- // Logic AND/NOT
2911- const selectiveLogicDropdown = template.find('select[name="entryLogicType"]');
2912- selectiveLogicDropdown.data('uid', entry.uid);
2913- selectiveLogicDropdown.on('click', e => e.stopPropagation());
2914- selectiveLogicDropdown.on('input', async function () {
2915- const uid = $(this).data('uid');
2916- const value = Number($(this).val());
2917- data.entries[uid].selectiveLogic = !isNaN(value) ? value : world_info_logic.AND_ANY;
2918- setWIOriginalDataValue(data, uid, 'selectiveLogic', data.entries[uid].selectiveLogic);
2919- await saveWorldInfo(name, data);
2920- });
2921- template.find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`).prop('selected', true).trigger('input');
2922-
2923- // Character filter
2924- const characterFilterLabel = template.find('label[for="characterFilter"] > small');
2925- characterFilterLabel.text(entry.characterFilter?.isExclude ? 'Exclude Character(s)' : 'Filter to Character(s)');
2926- const characterExclusionInput = template.find('input[name="character_exclusion"]');
2927- characterExclusionInput.data('uid', entry.uid);
2928- characterExclusionInput.on('input', async function () {
2929- const uid = $(this).data('uid');
2930- const value = $(this).prop('checked');
2931- characterFilterLabel.text(value ? 'Exclude Character(s)' : 'Filter to Character(s)');
2932- if (data.entries[uid].characterFilter) {
2933- if (!value && data.entries[uid].characterFilter.names.length === 0 && data.entries[uid].characterFilter.tags.length === 0) {
2934- delete data.entries[uid].characterFilter;
2935- } else {
2936- data.entries[uid].characterFilter.isExclude = value;
2937- }
2938- } else if (value) {
2939- Object.assign(data.entries[uid], { characterFilter: { isExclude: true, names: [], tags: [] } });
2940- }
2941- if (data.entries[uid]?.characterFilter?.names?.length > 0) {
2942- for (const name of [...data.entries[uid].characterFilter.names]) {
2943- if (!getContext().characters.find(x => x.avatar.replace(/\.[^/.]+$/, '') === name)) {
2944- data.entries[uid].characterFilter.names = data.entries[uid].characterFilter.names.filter(x => x !== name);
2945- }
2946- }
2947- }
2948- setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter);
2949- await saveWorldInfo(name, data);
2950- });
2951- characterExclusionInput.prop('checked', entry.characterFilter?.isExclude ?? false).trigger('input');
2952-
2953- const characterFilter = template.find('select[name="characterFilter"]');
2954- characterFilter.data('uid', entry.uid);
2955- initCharacterFilterSelect2Helper(characterFilter, t);
2956- fillCharacterAndTagOptionsHelper({ characterFilter, entry, getContext });
2957- handleCharacterFilterChangeHelper({
2958- characterFilter, data, entry, name, world_names, getContext, setWIOriginalDataValue, saveWorldInfo, t,
2959- });
2960-
29612894 // Comment
29622895 const commentInput = templateheaderTemplate.find('textarea[name="comment"]');
2963- const commentToggle = template.find('input[name="addMemo"]');
29642896 commentInput.data('uid', entry.uid);
29652897 commentInput.on('input', async function (_, { skipReset } = {}) {
29662898 const uid = $(this).data('uid');
@@ -2970,157 +2902,43 @@ export async function getWorldEntry(name, data, entry) {
29702902 setWIOriginalDataValue(data, uid, 'comment', data.entries[uid].comment);
29712903 await saveWorldInfo(name, data);
29722904 });
2973- commentToggle.data('uid', entry.uid);
2974- commentToggle.on('input', async function () {
2975- const uid = $(this).data('uid');
2976- const value = $(this).prop('checked');
2977- const commentContainer = $(this).closest('.world_entry').find('.commentContainer');
2978- data.entries[uid].addMemo = value;
2979- await saveWorldInfo(name, data);
2980- value ? commentContainer.show() : commentContainer.hide();
2981- });
29822905 commentInput.val(entry.comment).trigger('input', { skipReset: true });
2983- commentToggle.prop('checked', true).trigger('input');
2984- commentToggle.parent().hide();
2985-
2986- // Content
2987- const counter = template.find('.world_entry_form_token_counter');
2988- const countTokensDebounced = debounce(async function (counter, value) {
2989- const numberOfTokens = await getTokenCountAsync(value);
2990- $(counter).text(numberOfTokens);
2991- }, debounce_timeout.relaxed);
2992- const contentInputId = `world_entry_content_${entry.uid}`;
2993- const contentInput = template.find('textarea[name="content"]');
2994- contentInput.data('uid', entry.uid);
2995- contentInput.attr('id', contentInputId);
2996- contentInput.on('input', async function (_, { skipCount } = {}) {
2997- const uid = $(this).data('uid');
2998- const value = $(this).val();
2999- data.entries[uid].content = value;
3000- setWIOriginalDataValue(data, uid, 'content', data.entries[uid].content);
3001- await saveWorldInfo(name, data);
3002- if (!skipCount) countTokensDebounced(counter, value);
3003- });
3004- contentInput.val(entry.content).trigger('input', { skipCount: true });
3005- template.find('.editor_maximize').attr('data-for', contentInputId);
3006- template.find('.inline-drawer-toggle').on('click', function () {
3007- if (counter.data('first-run')) {
3008- counter.data('first-run', false);
3009- countTokensDebounced(counter, contentInput.val());
3010- if (!keyInput.isFancy) initScrollHeight(keyInput.control);
3011- if (!keySecondaryInput.isFancy) initScrollHeight(keySecondaryInput.control);
3012- }
3013- });
3014-
3015- // Selective
3016- const selectiveInput = template.find('input[name="selective"]');
3017- selectiveInput.data('uid', entry.uid);
3018- selectiveInput.on('input', async function () {
3019- const uid = $(this).data('uid');
3020- const value = $(this).prop('checked');
3021- data.entries[uid].selective = value;
3022- setWIOriginalDataValue(data, uid, 'selective', data.entries[uid].selective);
3023- await saveWorldInfo(name, data);
3024- const keysecondary = $(this).closest('.world_entry').find('.keysecondary');
3025- const keysecondarytextpole = $(this).closest('.world_entry').find('.keysecondarytextpole');
3026- const keyprimaryselect = $(this).closest('.world_entry').find('.keyprimaryselect');
3027- const keyprimaryHeight = keyprimaryselect.outerHeight();
3028- keysecondarytextpole.css('height', keyprimaryHeight + 'px');
3029- value ? keysecondary.show() : keysecondary.hide();
3030- });
3031- selectiveInput.prop('checked', true).trigger('input');
3032- selectiveInput.parent().hide();
30332906
30342907 // Order
30352908 const orderInput = templateheaderTemplate.find('input[name="order"]');
30362909 orderInput.data('uid', entry.uid);
30372910 orderInput.on('input', async function () {
30382911 const uid = $(this).data('uid');
30392912 const value = Number($(this).val());
30402913 data.entries[uid].order = !isNaN(value) ? value : 0;
30412914 updatePosOrdDisplayHelper({ template: headerTemplate, data, uid });
30422915 setWIOriginalDataValue(data, uid, 'insertion_order', data.entries[uid].order);
30432916 await saveWorldInfo(name, data);
30442917 });
30452918 orderInput.val(entry.order).trigger('input');
30462919 orderInput.css('width', 'calc(3em + 15px)');
30472920
3048- // Group
3049- const groupInput = template.find('input[name="group"]');
3050- groupInput.data('uid', entry.uid);
3051- groupInput.on('input', async function () {
3052- const uid = $(this).data('uid');
3053- const value = String($(this).val()).trim();
3054- data.entries[uid].group = value;
3055- setWIOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group);
3056- await saveWorldInfo(name, data);
3057- });
3058- groupInput.val(entry.group ?? '').trigger('input');
3059- setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data), { allowMultiple: true }), 1);
3060-
3061- // Inclusion priority
3062- const groupOverrideInput = template.find('input[name="groupOverride"]');
3063- groupOverrideInput.data('uid', entry.uid);
3064- groupOverrideInput.on('input', async function () {
3065- const uid = $(this).data('uid');
3066- const value = $(this).prop('checked');
3067- data.entries[uid].groupOverride = value;
3068- setWIOriginalDataValue(data, uid, 'extensions.group_override', data.entries[uid].groupOverride);
3069- await saveWorldInfo(name, data);
3070- });
3071- groupOverrideInput.prop('checked', entry.groupOverride).trigger('input');
3072-
3073- // Group weight
3074- handleNumberInputHelper({
3075- inputElem: template.find('input[name="groupWeight"]'),
3076- entry, entryKey: 'groupWeight', data, name, setWIOriginalDataValue, saveWorldInfo,
3077- min: 1, max: 10000, clamp: true,
3078- });
3079-
3080- // Sticky, cooldown, delay
3081- handleNumberInputHelper({
3082- inputElem: template.find('input[name="sticky"]'),
3083- entry, entryKey: 'sticky', data, name, setWIOriginalDataValue, saveWorldInfo,
3084- min: 1, max: 10000, clamp: false,
3085- });
3086- handleNumberInputHelper({
3087- inputElem: template.find('input[name="cooldown"]'),
3088- entry, entryKey: 'cooldown', data, name, setWIOriginalDataValue, saveWorldInfo,
3089- min: 1, max: 10000, clamp: false,
3090- });
3091- handleNumberInputHelper({
3092- inputElem: template.find('input[name="delay"]'),
3093- entry, entryKey: 'delay', data, name, setWIOriginalDataValue, saveWorldInfo,
3094- min: 1, max: 10000, clamp: false,
3095- });
3096-
30972921 // Probability
30982922 handleProbabilityInputHelper({ probabilityInput: templateheaderTemplate.find('input[name="probability"]'), data, entry, name, setWIOriginalDataValue, saveWorldInfo });
3099- handleProbabilityToggleHelper({
3100- probabilityToggle: template.find('input[name="useProbability"]'),
3101- data, entry, name,
3102- probabilityInput: template.find('input[name="probability"]'),
3103- setWIOriginalDataValue, saveWorldInfo,
3104- });
31052923
31062924 // Depth
31072925 handleNumberInputHelper({
31082926 inputElem: templateheaderTemplate.find('input[name="depth"]'),
31092927 entry, entryKey: 'depth', data, name, setWIOriginalDataValue, saveWorldInfo,
31102928 min: 0, max: MAX_SCAN_DEPTH, clamp: false,
31112929 });
31122930 templateheaderTemplate.find('input[name="depth"]').css('width', 'calc(3em + 15px)');
31132931
31142932 // Position
31152933 if (entry.position === undefined) entry.position = 0;
31162934 const positionInput = templateheaderTemplate.find('select[name="position"]');
31172935 positionInput.data('uid', entry.uid);
31182936 positionInput.on('click', e => e.stopPropagation());
31192937 positionInput.on('input', async function () {
31202938 const uid = $(this).data('uid');
31212939 const value = Number($(this).val());
31222940 data.entries[uid].position = !isNaN(value) ? value : 0;
31232941 const depthInput = templateheaderTemplate.find('input[name="depth"]');
31242942 if (value === world_info_position.atDepth) {
31252943 depthInput.prop('disabled', false);
31262944 depthInput.css('visibility', 'visible');
@@ -3131,64 +2949,29 @@ export async function getWorldEntry(name, data, entry) {
31312949 depthInput.css('visibility', 'hidden');
31322950 data.entries[uid].role = null;
31332951 }
31342952 updatePosOrdDisplayHelper({ template: headerTemplate, data, uid });
31352953 setWIOriginalDataValue(data, uid, 'position', data.entries[uid].position == 0 ? 'before_char' : 'after_char');
31362954 setWIOriginalDataValue(data, uid, 'extensions.position', data.entries[uid].position);
31372955 setWIOriginalDataValue(data, uid, 'extensions.role', data.entries[uid].role);
31382956 await saveWorldInfo(name, data);
31392957 });
31402958 const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : '';
31412959 templateheaderTemplate.find(`select[name="position"] option[value="${entry.position}"][data-role="${roleValue}"]`).prop('selected', true).trigger('input');
3142-
3143- // UID display
3144- template.find('.world_entry_form_uid_value').text(`(UID: ${entry.uid})`);
31452960
31462961 // Tri-state selector
31472962 handleEntryStateSelectorHelper({
31482963 entryStateSelector: templateheaderTemplate.find('select[name="entryStateSelector"]'),
31492964 entry, data, name, setWIOriginalDataValue, saveWorldInfo,
31502965 });
31512966
31522967 // Kill switch
31532968 handleEntryKillSwitchHelper({
31542969 entryKillSwitch: templateheaderTemplate.find('div[name="entryKillSwitch"]'),
31552970 entry, data, name, setWIOriginalDataValue, saveWorldInfo, template: headerTemplate,
3156- });
3157-
3158- // Exclude/prevent recursion
3159- handleMatchCheckboxHelper({ template, entry, fieldName: 'excludeRecursion', data, name });
3160- handleMatchCheckboxHelper({ template, entry, fieldName: 'preventRecursion', data, name });
3161-
3162- // Delay until recursion
3163- const delayUntilRecursionInput = template.find('input[name="delay_until_recursion"]');
3164- delayUntilRecursionInput.data('uid', entry.uid);
3165- const delayUntilRecursionLevelInput = template.find('input[name="delayUntilRecursionLevel"]');
3166- delayUntilRecursionLevelInput.data('uid', entry.uid);
3167- delayUntilRecursionInput.on('input', async function () {
3168- const uid = $(this).data('uid');
3169- const toggled = $(this).prop('checked');
3170- const value = toggled ? data.entries[uid].delayUntilRecursion || true : false;
3171- if (!toggled) delayUntilRecursionLevelInput.val('');
3172- data.entries[uid].delayUntilRecursion = value;
3173- setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion);
3174- await saveWorldInfo(name, data);
3175- });
3176- delayUntilRecursionInput.prop('checked', entry.delayUntilRecursion).trigger('input');
3177- delayUntilRecursionLevelInput.on('input', async function () {
3178- const uid = $(this).data('uid');
3179- const content = $(this).val();
3180- const value = content === '' ? (typeof data.entries[uid].delayUntilRecursion === 'boolean' ? data.entries[uid].delayUntilRecursion : true)
3181- : content === 1 ? true
3182- : !isNaN(Number(content)) ? Number(content)
3183- : false;
3184- data.entries[uid].delayUntilRecursion = value;
3185- setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion);
3186- await saveWorldInfo(name, data);
31872971 });
3188- delayUntilRecursionLevelInput.val(['number', 'string'].includes(typeof entry.delayUntilRecursion) ? entry.delayUntilRecursion : '').trigger('input');
31892972
31902973 // Duplicate/delete/move buttons
31912974 templateheaderTemplate.find('.duplicate_entry_button').data('uid', entry.uid).on('click', async function () {
31922975 const uid = $(this).data('uid');
31932976 const entryDup = duplicateWorldInfoEntry(data, uid);
31942977 if (entryDup) {
@@ -3196,7 +2979,7 @@ export async function getWorldEntry(name, data, entry) {
31962979 updateEditor(entryDup.uid);
31972980 }
31982981 });
31992982 templateheaderTemplate.find('.delete_entry_button').data('uid', entry.uid).on('click', async function (e) {
32002983 e.stopPropagation();
32012984 const uid = $(this).data('uid');
32022985 const deleted = await deleteWorldInfoEntry(data, uid);
@@ -3205,7 +2988,7 @@ export async function getWorldEntry(name, data, entry) {
32052988 await saveWorldInfo(name, data);
32062989 updateEditor(navigation_option.previous);
32072990 });
32082991 templateheaderTemplate.find('.move_entry_button').attr('data-uid', entry.uid).attr('data-current-world', name).on('click', async function (e) {
32092992 e.stopPropagation();
32102993 const sourceUid = $(this).attr('data-uid');
32112994 const sourceWorld = $(this).attr('data-current-world');
@@ -3257,67 +3040,315 @@ export async function getWorldEntry(name, data, entry) {
32573040 await moveWorldInfoEntry(sourceWorld, selectedValue, sourceUid);
32583041 });
32593042
3260- // Scan depth
3043+ let drawerInitialized = false;
3261- const scanDepthInput = template.find('input[name="scanDepth"]');
3044+ let drawerDestroyTimeout = null;
3262- scanDepthInput.data('uid', entry.uid);
3045+ headerTemplate.find('.inline-drawer-toggle').on('click', function () {
3263- scanDepthInput.on('input', async function () {
3046+ if (drawerDestroyTimeout) {
3264- const uid = $(this).data('uid');
3047+ clearTimeout(drawerDestroyTimeout);
3265- const isEmpty = $(this).val() === '';
3048+ drawerDestroyTimeout = null;
3266- const value = Number($(this).val());
3049+ }
32673050 if (value < 0drawerInitialized) {
3268- $(this).val(0).trigger('input');
3051+ drawerDestroyTimeout = setTimeout(() => {
3269- toastr.warning('Scan depth cannot be negative');
3052+ // Drawer was reopened, so we don't destroy it
3270- return;
3053+ if (editOutlet.is(':visible')) {
3271- }
3054+ return;
3272- if (value > MAX_SCAN_DEPTH) {
3055+ }
3273- $(this).val(MAX_SCAN_DEPTH).trigger('input');
3056+ drawerInitialized = false;
3274- toastr.warning(`Scan depth cannot exceed ${MAX_SCAN_DEPTH}`);
3057+ clearEntryList(editOutlet);
3275- return;
3058+ }, debounce_timeout.relaxed);
3059+ } else {
3060+ drawerInitialized = true;
3061+ addEditorDrawerContent();
32763062 }
3277- data.entries[uid].scanDepth = !isEmpty && !isNaN(value) && value >= 0 && value <= MAX_SCAN_DEPTH ? Math.floor(value) : null;
3278- setWIOriginalDataValue(data, uid, 'extensions.scan_depth', data.entries[uid].scanDepth);
3279- await saveWorldInfo(name, data);
32803063 });
3281- scanDepthInput.val(entry.scanDepth ?? null).trigger('input');
32823064
3283- // Boolean selects
3065+ const editOutlet = headerTemplate.find('.inline-drawer-outlet');
3284- handleBooleanSelectHelper({
3285- selectElem: template.find('select[name="caseSensitive"]'),
3286- entry, entryKey: 'caseSensitive', data, name, setWIOriginalDataValue, saveWorldInfo,
3287- });
3288- handleBooleanSelectHelper({
3289- selectElem: template.find('select[name="matchWholeWords"]'),
3290- entry, entryKey: 'matchWholeWords', data, name, setWIOriginalDataValue, saveWorldInfo,
3291- });
3292- handleBooleanSelectHelper({
3293- selectElem: template.find('select[name="useGroupScoring"]'),
3294- entry, entryKey: 'useGroupScoring', data, name, setWIOriginalDataValue, saveWorldInfo,
3295- });
32963066
3297- // Match checkboxes
3067+ function addEditorDrawerContent() {
3298- handleMatchCheckboxHelper({ template, entry, fieldName: 'matchPersonaDescription', data, name });
3068+ const editTemplate = WI_ENTRY_EDIT_TEMPLATE.clone();
3299- handleMatchCheckboxHelper({ template, entry, fieldName: 'matchCharacterDescription', data, name });
3069+
3300- handleMatchCheckboxHelper({ template, entry, fieldName: 'matchCharacterPersonality', data, name });
3070+ // UID display
3301- handleMatchCheckboxHelper({ template, entry, fieldName: 'matchCharacterDepthPrompt', data, name });
3071+ editTemplate.find('.world_entry_form_uid_value').text(`(UID: ${entry.uid})`);
3302- handleMatchCheckboxHelper({ template, entry, fieldName: 'matchScenario', data, name });
3072+
3303- handleMatchCheckboxHelper({ template, entry, fieldName: 'matchCreatorNotes', data, name });
3073+ // Key inputs
3304-
3074+ const keyInput = enableKeysInputHelper({ template: editTemplate, entry, entryPropName: 'key', originalDataValueName: 'keys', name, data });
3305- // Automation ID
3075+ const keySecondaryInput = enableKeysInputHelper({ template: editTemplate, entry, entryPropName: 'keysecondary', originalDataValueName: 'secondary_keys', name, data });
3306- const automationIdInput = template.find('input[name="automationId"]');
3076+
3307- automationIdInput.data('uid', entry.uid);
3077+ // Key input switch
33083078 automationIdInput editTemplate.find('.switch_input_type_icon').on('inputclick', async function () {
3309- const uid = $(this).data('uid');
3079+ power_user.wi_key_input_plaintext = !power_user.wi_key_input_plaintext;
3310- const value = $(this).val();
3080+ saveSettingsDebounced();
3311- data.entries[uid].automationId = value;
3081+ const uid = ($(this).parents('.world_entry')).data('uid');
3312- setWIOriginalDataValue(data, uid, 'extensions.automation_id', data.entries[uid].automationId);
3082+ updateEditor(uid, false);
3313- await saveWorldInfo(name, data);
3083+ $(`.world_entry[uid="${uid}"] .inline-drawer-icon`).trigger('click');
3314- });
3084+ }).each((_, icon) => {
3315- automationIdInput.val(entry.automationId ?? '').trigger('input');
3085+ $(icon).attr('title', $(icon).data(power_user.wi_key_input_plaintext ? 'tooltip-on' : 'tooltip-off'));
3316- setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1);
3086+ $(icon).text($(icon).data(power_user.wi_key_input_plaintext ? 'icon-on' : 'icon-off'));
3087+ });
3088+
3089+ // Probability toggle
3090+ handleProbabilityToggleHelper({
3091+ probabilityToggle: editTemplate.find('input[name="useProbability"]'),
3092+ data, entry, name,
3093+ probabilityInput: headerTemplate.find('input[name="probability"]'),
3094+ setWIOriginalDataValue, saveWorldInfo,
3095+ });
3096+
3097+ // Comment toggle
3098+ const commentToggle = editTemplate.find('input[name="addMemo"]');
3099+ commentToggle.data('uid', entry.uid);
3100+ commentToggle.on('input', async function () {
3101+ const uid = $(this).data('uid');
3102+ const value = $(this).prop('checked');
3103+ const commentContainer = $(this).closest('.world_entry').find('.commentContainer');
3104+ data.entries[uid].addMemo = value;
3105+ await saveWorldInfo(name, data);
3106+ value ? commentContainer.show() : commentContainer.hide();
3107+ });
3108+ commentToggle.prop('checked', true).trigger('input');
3109+ commentToggle.parent().hide();
3110+
3111+ // Logic AND/NOT
3112+ const selectiveLogicDropdown = editTemplate.find('select[name="entryLogicType"]');
3113+ selectiveLogicDropdown.data('uid', entry.uid);
3114+ selectiveLogicDropdown.on('click', e => e.stopPropagation());
3115+ selectiveLogicDropdown.on('input', async function () {
3116+ const uid = $(this).data('uid');
3117+ const value = Number($(this).val());
3118+ data.entries[uid].selectiveLogic = !isNaN(value) ? value : world_info_logic.AND_ANY;
3119+ setWIOriginalDataValue(data, uid, 'selectiveLogic', data.entries[uid].selectiveLogic);
3120+ await saveWorldInfo(name, data);
3121+ });
3122+ editTemplate.find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`).prop('selected', true).trigger('input');
3123+
3124+ // Selective
3125+ const selectiveInput = editTemplate.find('input[name="selective"]');
3126+ selectiveInput.data('uid', entry.uid);
3127+ selectiveInput.on('input', async function () {
3128+ const uid = $(this).data('uid');
3129+ const value = $(this).prop('checked');
3130+ data.entries[uid].selective = value;
3131+ setWIOriginalDataValue(data, uid, 'selective', data.entries[uid].selective);
3132+ await saveWorldInfo(name, data);
3133+ const keysecondary = $(this).closest('.world_entry').find('.keysecondary');
3134+ const keysecondarytextpole = $(this).closest('.world_entry').find('.keysecondarytextpole');
3135+ const keyprimaryselect = $(this).closest('.world_entry').find('.keyprimaryselect');
3136+ const keyprimaryHeight = keyprimaryselect.outerHeight();
3137+ keysecondarytextpole.css('height', keyprimaryHeight + 'px');
3138+ value ? keysecondary.show() : keysecondary.hide();
3139+ });
3140+ selectiveInput.prop('checked', true).trigger('input');
3141+ selectiveInput.parent().hide();
3142+
3143+ // Character filter
3144+ const characterFilterLabel = editTemplate.find('label[for="characterFilter"] > small');
3145+ characterFilterLabel.text(entry.characterFilter?.isExclude ? 'Exclude Character(s)' : 'Filter to Character(s)');
3146+ const characterExclusionInput = editTemplate.find('input[name="character_exclusion"]');
3147+ characterExclusionInput.data('uid', entry.uid);
3148+ characterExclusionInput.on('input', async function () {
3149+ const uid = $(this).data('uid');
3150+ const value = $(this).prop('checked');
3151+ characterFilterLabel.text(value ? 'Exclude Character(s)' : 'Filter to Character(s)');
3152+ if (data.entries[uid].characterFilter) {
3153+ if (!value && data.entries[uid].characterFilter.names.length === 0 && data.entries[uid].characterFilter.tags.length === 0) {
3154+ delete data.entries[uid].characterFilter;
3155+ } else {
3156+ data.entries[uid].characterFilter.isExclude = value;
3157+ }
3158+ } else if (value) {
3159+ Object.assign(data.entries[uid], { characterFilter: { isExclude: true, names: [], tags: [] } });
3160+ }
3161+ if (data.entries[uid]?.characterFilter?.names?.length > 0) {
3162+ for (const name of [...data.entries[uid].characterFilter.names]) {
3163+ if (!getContext().characters.find(x => x.avatar.replace(/\.[^/.]+$/, '') === name)) {
3164+ data.entries[uid].characterFilter.names = data.entries[uid].characterFilter.names.filter(x => x !== name);
3165+ }
3166+ }
3167+ }
3168+ setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter);
3169+ await saveWorldInfo(name, data);
3170+ });
3171+ characterExclusionInput.prop('checked', entry.characterFilter?.isExclude ?? false).trigger('input');
3172+
3173+ const characterFilter = editTemplate.find('select[name="characterFilter"]');
3174+ characterFilter.data('uid', entry.uid);
3175+ initCharacterFilterSelect2Helper(characterFilter, t);
3176+ fillCharacterAndTagOptionsHelper({ characterFilter, entry, getContext });
3177+ handleCharacterFilterChangeHelper({
3178+ characterFilter, data, entry, name, world_names, getContext, setWIOriginalDataValue, saveWorldInfo, t,
3179+ });
3180+
3181+ // Content
3182+ const counter = editTemplate.find('.world_entry_form_token_counter');
3183+ const countTokensDebounced = debounce(async function (counter, value) {
3184+ const numberOfTokens = await getTokenCountAsync(value);
3185+ $(counter).text(numberOfTokens);
3186+ }, debounce_timeout.relaxed);
3187+ const contentInputId = `world_entry_content_${entry.uid}`;
3188+ const contentInput = editTemplate.find('textarea[name="content"]');
3189+ contentInput.data('uid', entry.uid);
3190+ contentInput.attr('id', contentInputId);
3191+ contentInput.on('input', async function (_, { skipCount } = {}) {
3192+ const uid = $(this).data('uid');
3193+ const value = $(this).val();
3194+ data.entries[uid].content = value;
3195+ setWIOriginalDataValue(data, uid, 'content', data.entries[uid].content);
3196+ await saveWorldInfo(name, data);
3197+ if (!skipCount) countTokensDebounced(counter, value);
3198+ });
3199+ contentInput.val(entry.content).trigger('input', { skipCount: true });
3200+ editTemplate.find('.editor_maximize').attr('data-for', contentInputId);
3201+
3202+ // Scan depth
3203+ const scanDepthInput = editTemplate.find('input[name="scanDepth"]');
3204+ scanDepthInput.data('uid', entry.uid);
3205+ scanDepthInput.on('input', async function () {
3206+ const uid = $(this).data('uid');
3207+ const isEmpty = $(this).val() === '';
3208+ const value = Number($(this).val());
3209+ if (value < 0) {
3210+ $(this).val(0).trigger('input');
3211+ toastr.warning('Scan depth cannot be negative');
3212+ return;
3213+ }
3214+ if (value > MAX_SCAN_DEPTH) {
3215+ $(this).val(MAX_SCAN_DEPTH).trigger('input');
3216+ toastr.warning(`Scan depth cannot exceed ${MAX_SCAN_DEPTH}`);
3217+ return;
3218+ }
3219+ data.entries[uid].scanDepth = !isEmpty && !isNaN(value) && value >= 0 && value <= MAX_SCAN_DEPTH ? Math.floor(value) : null;
3220+ setWIOriginalDataValue(data, uid, 'extensions.scan_depth', data.entries[uid].scanDepth);
3221+ await saveWorldInfo(name, data);
3222+ });
3223+ scanDepthInput.val(entry.scanDepth ?? null).trigger('input');
3224+
3225+ // Group
3226+ const groupInput = editTemplate.find('input[name="group"]');
3227+ groupInput.data('uid', entry.uid);
3228+ groupInput.on('input', async function () {
3229+ const uid = $(this).data('uid');
3230+ const value = String($(this).val()).trim();
3231+ data.entries[uid].group = value;
3232+ setWIOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group);
3233+ await saveWorldInfo(name, data);
3234+ });
3235+ groupInput.val(entry.group ?? '').trigger('input');
3236+ setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data), { allowMultiple: true }), 1);
3237+
3238+ // Inclusion priority
3239+ const groupOverrideInput = editTemplate.find('input[name="groupOverride"]');
3240+ groupOverrideInput.data('uid', entry.uid);
3241+ groupOverrideInput.on('input', async function () {
3242+ const uid = $(this).data('uid');
3243+ const value = $(this).prop('checked');
3244+ data.entries[uid].groupOverride = value;
3245+ setWIOriginalDataValue(data, uid, 'extensions.group_override', data.entries[uid].groupOverride);
3246+ await saveWorldInfo(name, data);
3247+ });
3248+ groupOverrideInput.prop('checked', entry.groupOverride).trigger('input');
3249+
3250+ // Group weight
3251+ handleNumberInputHelper({
3252+ inputElem: editTemplate.find('input[name="groupWeight"]'),
3253+ entry, entryKey: 'groupWeight', data, name, setWIOriginalDataValue, saveWorldInfo,
3254+ min: 1, max: 10000, clamp: true,
3255+ });
3256+
3257+ // Sticky, cooldown, delay
3258+ handleNumberInputHelper({
3259+ inputElem: editTemplate.find('input[name="sticky"]'),
3260+ entry, entryKey: 'sticky', data, name, setWIOriginalDataValue, saveWorldInfo,
3261+ min: 1, max: 10000, clamp: false,
3262+ });
3263+ handleNumberInputHelper({
3264+ inputElem: editTemplate.find('input[name="cooldown"]'),
3265+ entry, entryKey: 'cooldown', data, name, setWIOriginalDataValue, saveWorldInfo,
3266+ min: 1, max: 10000, clamp: false,
3267+ });
3268+ handleNumberInputHelper({
3269+ inputElem: editTemplate.find('input[name="delay"]'),
3270+ entry, entryKey: 'delay', data, name, setWIOriginalDataValue, saveWorldInfo,
3271+ min: 1, max: 10000, clamp: false,
3272+ });
3273+
3274+ // Exclude/prevent recursion
3275+ handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'excludeRecursion', data, name });
3276+ handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'preventRecursion', data, name });
3277+
3278+ // Delay until recursion
3279+ const delayUntilRecursionInput = editTemplate.find('input[name="delay_until_recursion"]');
3280+ delayUntilRecursionInput.data('uid', entry.uid);
3281+ const delayUntilRecursionLevelInput = editTemplate.find('input[name="delayUntilRecursionLevel"]');
3282+ delayUntilRecursionLevelInput.data('uid', entry.uid);
3283+ delayUntilRecursionInput.on('input', async function () {
3284+ const uid = $(this).data('uid');
3285+ const toggled = $(this).prop('checked');
3286+ const value = toggled ? data.entries[uid].delayUntilRecursion || true : false;
3287+ if (!toggled) delayUntilRecursionLevelInput.val('');
3288+ data.entries[uid].delayUntilRecursion = value;
3289+ setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion);
3290+ await saveWorldInfo(name, data);
3291+ });
3292+ delayUntilRecursionInput.prop('checked', entry.delayUntilRecursion).trigger('input');
3293+ delayUntilRecursionLevelInput.on('input', async function () {
3294+ const uid = $(this).data('uid');
3295+ const content = $(this).val();
3296+ const value = content === '' ? (typeof data.entries[uid].delayUntilRecursion === 'boolean' ? data.entries[uid].delayUntilRecursion : true)
3297+ : content === 1 ? true
3298+ : !isNaN(Number(content)) ? Number(content)
3299+ : false;
3300+ data.entries[uid].delayUntilRecursion = value;
3301+ setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion);
3302+ await saveWorldInfo(name, data);
3303+ });
3304+ delayUntilRecursionLevelInput.val(['number', 'string'].includes(typeof entry.delayUntilRecursion) ? entry.delayUntilRecursion : '').trigger('input');
3305+
3306+ // Boolean selects
3307+ handleBooleanSelectHelper({
3308+ selectElem: editTemplate.find('select[name="caseSensitive"]'),
3309+ entry, entryKey: 'caseSensitive', data, name, setWIOriginalDataValue, saveWorldInfo,
3310+ });
3311+ handleBooleanSelectHelper({
3312+ selectElem: editTemplate.find('select[name="matchWholeWords"]'),
3313+ entry, entryKey: 'matchWholeWords', data, name, setWIOriginalDataValue, saveWorldInfo,
3314+ });
3315+ handleBooleanSelectHelper({
3316+ selectElem: editTemplate.find('select[name="useGroupScoring"]'),
3317+ entry, entryKey: 'useGroupScoring', data, name, setWIOriginalDataValue, saveWorldInfo,
3318+ });
3319+
3320+ // Match checkboxes
3321+ handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchPersonaDescription', data, name });
3322+ handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterDescription', data, name });
3323+ handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterPersonality', data, name });
3324+ handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterDepthPrompt', data, name });
3325+ handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchScenario', data, name });
3326+ handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCreatorNotes', data, name });
3327+
3328+ // Automation ID
3329+ const automationIdInput = editTemplate.find('input[name="automationId"]');
3330+ automationIdInput.data('uid', entry.uid);
3331+ automationIdInput.on('input', async function () {
3332+ const uid = $(this).data('uid');
3333+ const value = $(this).val();
3334+ data.entries[uid].automationId = value;
3335+ setWIOriginalDataValue(data, uid, 'extensions.automation_id', data.entries[uid].automationId);
3336+ await saveWorldInfo(name, data);
3337+ });
3338+ automationIdInput.val(entry.automationId ?? '').trigger('input');
3339+ setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1);
3340+
3341+ countTokensDebounced(counter, contentInput.val());
3342+ if (!keyInput.isFancy) initScrollHeight(keyInput.control);
3343+ if (!keySecondaryInput.isFancy) initScrollHeight(keySecondaryInput.control);
3344+
3345+ editTemplate.find('.inline-drawer-content').css('display', 'none');
3346+ editOutlet.append(editTemplate);
3347+ }
33173348
33183349 templateheaderTemplate.find('.inline-drawer-content').css('display', 'none');
33193350
33203351 return templateheaderTemplate;
33213352}
33223353
33233354/**