diff --git a/public/index.html b/public/index.html
index 24bf7c48b..eb622fd90 100644
--- a/public/index.html
+++ b/public/index.html
@@ -35,6 +35,7 @@
+
diff --git a/public/script.js b/public/script.js
index ebf095771..7b91763a3 100644
--- a/public/script.js
+++ b/public/script.js
@@ -1399,6 +1399,20 @@ function getStoppingStrings(isImpersonate, addSpace) {
return addSpace ? result.map(x => `${x} `) : result;
}
+
+// Background prompt generation
+export async function generateQuietPrompt(quiet_prompt) {
+ return await new Promise(
+ async function promptPromise(resolve, reject) {
+ try {
+ await Generate('quiet', { resolve, reject, quiet_prompt, force_name2: true, });
+ }
+ catch {
+ reject();
+ }
+ });
+}
+
function processCommands(message, type) {
if (type == "regenerate" || type == "swipe" || type == 'quiet') {
return null;
diff --git a/public/scripts/extensions/backgrounds/index.js b/public/scripts/extensions/backgrounds/index.js
index 3c7dbfafb..e5d224d1d 100644
--- a/public/scripts/extensions/backgrounds/index.js
+++ b/public/scripts/extensions/backgrounds/index.js
@@ -1,4 +1,7 @@
+import { generateQuietPrompt } from "../../../script.js";
import { getContext, saveMetadataDebounced } from "../../extensions.js";
+import { registerSlashCommand } from "../../slash-commands.js";
+import { stringFormat } from "../../utils.js";
export { MODULE_NAME };
const MODULE_NAME = 'backgrounds';
@@ -87,6 +90,30 @@ function onSelectBackgroundClick() {
}
}
+const autoBgPrompt = `Pause your roleplay and choose a location ONLY from the provided list that is the most suitable for the current scene. Do not output any other text:\n{0}`;
+
+async function autoBackgroundCommand() {
+ const options = Array.from(document.querySelectorAll('.BGSampleTitle')).map(x => ({ element: x, text: x.innerText.trim() })).filter(x => x.text.length > 0);
+ if (options.length == 0) {
+ toastr.warning('No backgrounds to choose from. Please upload some images to the "backgrounds" folder.');
+ return;
+ }
+
+ const list = options.map(option => `- ${option.text}`).join('\n');
+ const prompt = stringFormat(autoBgPrompt, list);
+ const reply = await generateQuietPrompt(prompt);
+ const fuse = new Fuse(options, { keys: ['text'] });
+ const bestMatch = fuse.search(reply, { limit: 1 });
+
+ if (bestMatch.length == 0) {
+ toastr.warning('No match found. Please try again.');
+ return;
+ }
+
+ console.debug('Automatically choosing background:', bestMatch);
+ bestMatch[0].item.element.click();
+}
+
$(document).ready(function () {
function addSettings() {
const html = `
@@ -111,6 +138,16 @@ $(document).ready(function () {
Any background image selected while lock is engaged will be saved automatically.
+
-
You are in offline mode. Click on the image below to set the expression.
+
+ You are in offline mode. Click on the image below to set the expression.
+
diff --git a/public/scripts/extensions/expressions/style.css b/public/scripts/extensions/expressions/style.css
index 81b39408a..de1eb9fd2 100644
--- a/public/scripts/extensions/expressions/style.css
+++ b/public/scripts/extensions/expressions/style.css
@@ -143,11 +143,6 @@ img.expression.default {
color: red;
}
-.expression_settings p {
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
-}
-
.expression_settings label {
display: flex;
align-items: center;
@@ -171,4 +166,4 @@ img.expression.default {
div.expression {
display: none;
}
-}
\ No newline at end of file
+}
diff --git a/public/scripts/extensions/objective/index.js b/public/scripts/extensions/objective/index.js
index d2d675e71..3485da1ec 100644
--- a/public/scripts/extensions/objective/index.js
+++ b/public/scripts/extensions/objective/index.js
@@ -4,7 +4,9 @@ import {
substituteParams,
eventSource,
event_types,
+ generateQuietPrompt,
} from "../../../script.js";
+import { registerSlashCommand } from "../../slash-commands.js";
const MODULE_NAME = "Objective"
@@ -40,18 +42,6 @@ const objectivePrompts = {
const extensionPrompt = "Your current task is [{{task}}]. Balance existing roleplay with completing this task."
-// Background prompt generation
-async function generateQuietPrompt(quiet_prompt) {
- return await new Promise(
- async function promptPromise(resolve, reject) {
- try {
- await getContext().generate('quiet', { resolve, reject, quiet_prompt, force_name2: true, });
- }
- catch {
- reject();
- }
- });
-}
//###############################//
//# Task Management #//
@@ -112,7 +102,7 @@ async function generateTasks() {
// Call Quiet Generate to check if a task is completed
async function checkTaskCompleted() {
- // Make sure there are tasks
+ // Make sure there are tasks
if (jQuery.isEmptyObject(currentTask)) {
return
}
@@ -146,7 +136,7 @@ function setCurrentTask(taskId = null) {
currentTask = globalTasks[index];
}
- // Get the task description and add to extension prompt
+ // Get the task description and add to extension prompt
const description = currentTask.description || null;
// Now update the extension prompt
@@ -201,7 +191,7 @@ class ObjectiveTask {
this.id=id
}
}
-
+
// Complete the current task, setting next task to next incomplete task
completeTask() {
@@ -221,10 +211,10 @@ class ObjectiveTask {
`;
-
+
// Add the filled out template
$('#objective-tasks').append(template);
-
+
this.completedCheckbox = $(`#objective-task-complete-${this.id}`);
this.descriptionSpan = $(`#objective-task-description-${this.id}`);
this.addButton = $(`#objective-task-add-${this.id}`);
@@ -250,7 +240,7 @@ class ObjectiveTask {
onDescriptionFocusout(){
setCurrentTask();
}
-
+
onDeleteClick(){
deleteTask(this.id);
}
@@ -437,16 +427,16 @@ jQuery(() => {
-
+
-
+
@@ -486,4 +476,6 @@ jQuery(() => {
setCurrentTask();
$('#objective-counter').text(checkCounter)
});
+
+ registerSlashCommand('taskcheck', checkTaskCompleted, [], ' – checks if the current task is completed', true, true);
});
diff --git a/public/scripts/fuse.js b/public/scripts/fuse.js
new file mode 100644
index 000000000..42e7d3b7f
--- /dev/null
+++ b/public/scripts/fuse.js
@@ -0,0 +1,2240 @@
+/**
+ * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io)
+ *
+ * Copyright (c) 2022 Kiro Risk (http://kiro.me)
+ * All Rights Reserved. Apache Software License 2.0
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Fuse = factory());
+})(this, (function () { 'use strict';
+
+ function ownKeys(object, enumerableOnly) {
+ var keys = Object.keys(object);
+
+ if (Object.getOwnPropertySymbols) {
+ var symbols = Object.getOwnPropertySymbols(object);
+ enumerableOnly && (symbols = symbols.filter(function (sym) {
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
+ })), keys.push.apply(keys, symbols);
+ }
+
+ return keys;
+ }
+
+ function _objectSpread2(target) {
+ for (var i = 1; i < arguments.length; i++) {
+ var source = null != arguments[i] ? arguments[i] : {};
+ i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
+ _defineProperty(target, key, source[key]);
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
+ });
+ }
+
+ return target;
+ }
+
+ function _typeof(obj) {
+ "@babel/helpers - typeof";
+
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
+ return typeof obj;
+ } : function (obj) {
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+ }, _typeof(obj);
+ }
+
+ function _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+ }
+
+ function _defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+
+ function _createClass(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ Object.defineProperty(Constructor, "prototype", {
+ writable: false
+ });
+ return Constructor;
+ }
+
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
+ function _inherits(subClass, superClass) {
+ if (typeof superClass !== "function" && superClass !== null) {
+ throw new TypeError("Super expression must either be null or a function");
+ }
+
+ Object.defineProperty(subClass, "prototype", {
+ value: Object.create(superClass && superClass.prototype, {
+ constructor: {
+ value: subClass,
+ writable: true,
+ configurable: true
+ }
+ }),
+ writable: false
+ });
+ if (superClass) _setPrototypeOf(subClass, superClass);
+ }
+
+ function _getPrototypeOf(o) {
+ _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
+ return o.__proto__ || Object.getPrototypeOf(o);
+ };
+ return _getPrototypeOf(o);
+ }
+
+ function _setPrototypeOf(o, p) {
+ _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
+ o.__proto__ = p;
+ return o;
+ };
+
+ return _setPrototypeOf(o, p);
+ }
+
+ function _isNativeReflectConstruct() {
+ if (typeof Reflect === "undefined" || !Reflect.construct) return false;
+ if (Reflect.construct.sham) return false;
+ if (typeof Proxy === "function") return true;
+
+ try {
+ Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ function _assertThisInitialized(self) {
+ if (self === void 0) {
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ }
+
+ return self;
+ }
+
+ function _possibleConstructorReturn(self, call) {
+ if (call && (typeof call === "object" || typeof call === "function")) {
+ return call;
+ } else if (call !== void 0) {
+ throw new TypeError("Derived constructors may only return object or undefined");
+ }
+
+ return _assertThisInitialized(self);
+ }
+
+ function _createSuper(Derived) {
+ var hasNativeReflectConstruct = _isNativeReflectConstruct();
+
+ return function _createSuperInternal() {
+ var Super = _getPrototypeOf(Derived),
+ result;
+
+ if (hasNativeReflectConstruct) {
+ var NewTarget = _getPrototypeOf(this).constructor;
+
+ result = Reflect.construct(Super, arguments, NewTarget);
+ } else {
+ result = Super.apply(this, arguments);
+ }
+
+ return _possibleConstructorReturn(this, result);
+ };
+ }
+
+ function _toConsumableArray(arr) {
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
+ }
+
+ function _arrayWithoutHoles(arr) {
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+ }
+
+ function _iterableToArray(iter) {
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
+ }
+
+ function _unsupportedIterableToArray(o, minLen) {
+ if (!o) return;
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+ var n = Object.prototype.toString.call(o).slice(8, -1);
+ if (n === "Object" && o.constructor) n = o.constructor.name;
+ if (n === "Map" || n === "Set") return Array.from(o);
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
+ }
+
+ function _arrayLikeToArray(arr, len) {
+ if (len == null || len > arr.length) len = arr.length;
+
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+
+ return arr2;
+ }
+
+ function _nonIterableSpread() {
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+
+ function isArray(value) {
+ return !Array.isArray ? getTag(value) === '[object Array]' : Array.isArray(value);
+ } // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js
+
+ var INFINITY = 1 / 0;
+ function baseToString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
+ }
+
+ var result = value + '';
+ return result == '0' && 1 / value == -INFINITY ? '-0' : result;
+ }
+ function toString(value) {
+ return value == null ? '' : baseToString(value);
+ }
+ function isString(value) {
+ return typeof value === 'string';
+ }
+ function isNumber(value) {
+ return typeof value === 'number';
+ } // Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js
+
+ function isBoolean(value) {
+ return value === true || value === false || isObjectLike(value) && getTag(value) == '[object Boolean]';
+ }
+ function isObject(value) {
+ return _typeof(value) === 'object';
+ } // Checks if `value` is object-like.
+
+ function isObjectLike(value) {
+ return isObject(value) && value !== null;
+ }
+ function isDefined(value) {
+ return value !== undefined && value !== null;
+ }
+ function isBlank(value) {
+ return !value.trim().length;
+ } // Gets the `toStringTag` of `value`.
+ // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js
+
+ function getTag(value) {
+ return value == null ? value === undefined ? '[object Undefined]' : '[object Null]' : Object.prototype.toString.call(value);
+ }
+
+ var EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available';
+ var INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
+ var LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = function LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key) {
+ return "Invalid value for key ".concat(key);
+ };
+ var PATTERN_LENGTH_TOO_LARGE = function PATTERN_LENGTH_TOO_LARGE(max) {
+ return "Pattern length exceeds max of ".concat(max, ".");
+ };
+ var MISSING_KEY_PROPERTY = function MISSING_KEY_PROPERTY(name) {
+ return "Missing ".concat(name, " property in key");
+ };
+ var INVALID_KEY_WEIGHT_VALUE = function INVALID_KEY_WEIGHT_VALUE(key) {
+ return "Property 'weight' in key '".concat(key, "' must be a positive integer");
+ };
+
+ var hasOwn = Object.prototype.hasOwnProperty;
+
+ var KeyStore = /*#__PURE__*/function () {
+ function KeyStore(keys) {
+ var _this = this;
+
+ _classCallCheck(this, KeyStore);
+
+ this._keys = [];
+ this._keyMap = {};
+ var totalWeight = 0;
+ keys.forEach(function (key) {
+ var obj = createKey(key);
+ totalWeight += obj.weight;
+
+ _this._keys.push(obj);
+
+ _this._keyMap[obj.id] = obj;
+ totalWeight += obj.weight;
+ }); // Normalize weights so that their sum is equal to 1
+
+ this._keys.forEach(function (key) {
+ key.weight /= totalWeight;
+ });
+ }
+
+ _createClass(KeyStore, [{
+ key: "get",
+ value: function get(keyId) {
+ return this._keyMap[keyId];
+ }
+ }, {
+ key: "keys",
+ value: function keys() {
+ return this._keys;
+ }
+ }, {
+ key: "toJSON",
+ value: function toJSON() {
+ return JSON.stringify(this._keys);
+ }
+ }]);
+
+ return KeyStore;
+ }();
+ function createKey(key) {
+ var path = null;
+ var id = null;
+ var src = null;
+ var weight = 1;
+ var getFn = null;
+
+ if (isString(key) || isArray(key)) {
+ src = key;
+ path = createKeyPath(key);
+ id = createKeyId(key);
+ } else {
+ if (!hasOwn.call(key, 'name')) {
+ throw new Error(MISSING_KEY_PROPERTY('name'));
+ }
+
+ var name = key.name;
+ src = name;
+
+ if (hasOwn.call(key, 'weight')) {
+ weight = key.weight;
+
+ if (weight <= 0) {
+ throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
+ }
+ }
+
+ path = createKeyPath(name);
+ id = createKeyId(name);
+ getFn = key.getFn;
+ }
+
+ return {
+ path: path,
+ id: id,
+ weight: weight,
+ src: src,
+ getFn: getFn
+ };
+ }
+ function createKeyPath(key) {
+ return isArray(key) ? key : key.split('.');
+ }
+ function createKeyId(key) {
+ return isArray(key) ? key.join('.') : key;
+ }
+
+ function get(obj, path) {
+ var list = [];
+ var arr = false;
+
+ var deepGet = function deepGet(obj, path, index) {
+ if (!isDefined(obj)) {
+ return;
+ }
+
+ if (!path[index]) {
+ // If there's no path left, we've arrived at the object we care about.
+ list.push(obj);
+ } else {
+ var key = path[index];
+ var value = obj[key];
+
+ if (!isDefined(value)) {
+ return;
+ } // If we're at the last value in the path, and if it's a string/number/bool,
+ // add it to the list
+
+
+ if (index === path.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) {
+ list.push(toString(value));
+ } else if (isArray(value)) {
+ arr = true; // Search each item in the array.
+
+ for (var i = 0, len = value.length; i < len; i += 1) {
+ deepGet(value[i], path, index + 1);
+ }
+ } else if (path.length) {
+ // An object. Recurse further.
+ deepGet(value, path, index + 1);
+ }
+ }
+ }; // Backwards compatibility (since path used to be a string)
+
+
+ deepGet(obj, isString(path) ? path.split('.') : path, 0);
+ return arr ? list : list[0];
+ }
+
+ var MatchOptions = {
+ // Whether the matches should be included in the result set. When `true`, each record in the result
+ // set will include the indices of the matched characters.
+ // These can consequently be used for highlighting purposes.
+ includeMatches: false,
+ // When `true`, the matching function will continue to the end of a search pattern even if
+ // a perfect match has already been located in the string.
+ findAllMatches: false,
+ // Minimum number of characters that must be matched before a result is considered a match
+ minMatchCharLength: 1
+ };
+ var BasicOptions = {
+ // When `true`, the algorithm continues searching to the end of the input even if a perfect
+ // match is found before the end of the same input.
+ isCaseSensitive: false,
+ // When true, the matching function will continue to the end of a search pattern even if
+ includeScore: false,
+ // List of properties that will be searched. This also supports nested properties.
+ keys: [],
+ // Whether to sort the result list, by score
+ shouldSort: true,
+ // Default sort function: sort by ascending score, ascending index
+ sortFn: function sortFn(a, b) {
+ return a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1;
+ }
+ };
+ var FuzzyOptions = {
+ // Approximately where in the text is the pattern expected to be found?
+ location: 0,
+ // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match
+ // (of both letters and location), a threshold of '1.0' would match anything.
+ threshold: 0.6,
+ // Determines how close the match must be to the fuzzy location (specified above).
+ // An exact letter match which is 'distance' characters away from the fuzzy location
+ // would score as a complete mismatch. A distance of '0' requires the match be at
+ // the exact location specified, a threshold of '1000' would require a perfect match
+ // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.
+ distance: 100
+ };
+ var AdvancedOptions = {
+ // When `true`, it enables the use of unix-like search commands
+ useExtendedSearch: false,
+ // The get function to use when fetching an object's properties.
+ // The default will search nested paths *ie foo.bar.baz*
+ getFn: get,
+ // When `true`, search will ignore `location` and `distance`, so it won't matter
+ // where in the string the pattern appears.
+ // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score
+ ignoreLocation: false,
+ // When `true`, the calculation for the relevance score (used for sorting) will
+ // ignore the field-length norm.
+ // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm
+ ignoreFieldNorm: false,
+ // The weight to determine how much field length norm effects scoring.
+ fieldNormWeight: 1
+ };
+ var Config = _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, BasicOptions), MatchOptions), FuzzyOptions), AdvancedOptions);
+
+ var SPACE = /[^ ]+/g; // Field-length norm: the shorter the field, the higher the weight.
+ // Set to 3 decimals to reduce index size.
+
+ function norm() {
+ var weight = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
+ var mantissa = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
+ var cache = new Map();
+ var m = Math.pow(10, mantissa);
+ return {
+ get: function get(value) {
+ var numTokens = value.match(SPACE).length;
+
+ if (cache.has(numTokens)) {
+ return cache.get(numTokens);
+ } // Default function is 1/sqrt(x), weight makes that variable
+
+
+ var norm = 1 / Math.pow(numTokens, 0.5 * weight); // In place of `toFixed(mantissa)`, for faster computation
+
+ var n = parseFloat(Math.round(norm * m) / m);
+ cache.set(numTokens, n);
+ return n;
+ },
+ clear: function clear() {
+ cache.clear();
+ }
+ };
+ }
+
+ var FuseIndex = /*#__PURE__*/function () {
+ function FuseIndex() {
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
+ _ref$getFn = _ref.getFn,
+ getFn = _ref$getFn === void 0 ? Config.getFn : _ref$getFn,
+ _ref$fieldNormWeight = _ref.fieldNormWeight,
+ fieldNormWeight = _ref$fieldNormWeight === void 0 ? Config.fieldNormWeight : _ref$fieldNormWeight;
+
+ _classCallCheck(this, FuseIndex);
+
+ this.norm = norm(fieldNormWeight, 3);
+ this.getFn = getFn;
+ this.isCreated = false;
+ this.setIndexRecords();
+ }
+
+ _createClass(FuseIndex, [{
+ key: "setSources",
+ value: function setSources() {
+ var docs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
+ this.docs = docs;
+ }
+ }, {
+ key: "setIndexRecords",
+ value: function setIndexRecords() {
+ var records = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
+ this.records = records;
+ }
+ }, {
+ key: "setKeys",
+ value: function setKeys() {
+ var _this = this;
+
+ var keys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
+ this.keys = keys;
+ this._keysMap = {};
+ keys.forEach(function (key, idx) {
+ _this._keysMap[key.id] = idx;
+ });
+ }
+ }, {
+ key: "create",
+ value: function create() {
+ var _this2 = this;
+
+ if (this.isCreated || !this.docs.length) {
+ return;
+ }
+
+ this.isCreated = true; // List is Array
+
+ if (isString(this.docs[0])) {
+ this.docs.forEach(function (doc, docIndex) {
+ _this2._addString(doc, docIndex);
+ });
+ } else {
+ // List is Array