/** * @author KyMAN * @version 20241105 */ /** * @callback anyanka_keys_default_callback * @returns {void} */ /** * @callback anyanka_keys_convert_callback * @param {!number} value * @returns {void} */ /** * @callback anyanka_keys_data_callback * @param {!string} data * @param {!number} length * @returns {void} */ /** * @callback anyanka_keys_value_callback * @param {!number} value * @param {!number} i * @returns {void} */ /** * @class * @constructor * @param {Object.} [inputs = {}] * @returns {void} * @access public */ export const AnyankaKeys = (function(){ /** * @constructs AnyankaKeys * @param {Object.} [inputs = {}] * @returns {void} * @access private */ const AnyankaKeys = function(inputs = {}){ /** @type {AnyankaKeys} */ const self = this, /** @type {Array.} */ public_key = [], /** @type {Array.} */ private_key = [], /** @type {AnyankaKeys.Options} */ options = new AnyankaKeys.Options(inputs); /** @type {string} */ let alphabet = AnyankaKeys.SETTINGS.alpahbet, /** @type {number} */ base_from = AnyankaKeys.SETTINGS.base_from, /** @type {number} */ base_to = AnyankaKeys.SETTINGS.base_to, /** @type {number} */ divisor = AnyankaKeys.SETTINGS.divisor, /** @type {number} */ public_key_length = AnyankaKeys.SETTINGS.public_key_length, /** @type {number} */ private_key_length = AnyankaKeys.SETTINGS.private_key_length, /** @type {number} */ segments_key_length = AnyankaKeys.SETTINGS.segments_key_length, /** @type {number|boolean|null} */ summatory_value = AnyankaKeys.SETTINGS.summatory, /** @type {boolean} */ has_incremental = AnyankaKeys.SETTINGS.incremental, /** @type {boolean|number|null} */ random_private_start = AnyankaKeys.SETTINGS.random_private_start, /** @type {number} */ hash_length = AnyankaKeys.SETTINGS.hash_length, /** @type {number} */ hash_power = AnyankaKeys.SETTINGS.hash_power; /** * @returns {void} * @access private */ const constructor = () => { if(inputs){ if(typeof inputs == "string") inputs = {alphabet : inputs}; else if(!AnyankaKeys.is_dictionary(inputs)) inputs = {}; }else inputs = {}; inputs.alphabet !== undefined && (alphabet = inputs.alphabet); inputs.base_from !== undefined && (base_from = inputs.base_from); inputs.base_to !== undefined && (base_to = inputs.base_to); inputs.public_key_length !== undefined && (public_key_length = inputs.public_key_length); inputs.private_key_length !== undefined && (private_key_length = inputs.private_key_length); inputs.segments_key_length !== undefined && (segments_key_length = inputs.segments_key_length); inputs.summatory !== undefined && (summatory_value = inputs.summatory); inputs.incremental !== undefined && (has_incremental = inputs.incremental); inputs.random_private_start !== undefined && (random_private_start = inputs.random_private_start); inputs.hash_length !== undefined && (hash_length = inputs.hash_length); inputs.hash_power !== undefined && (hash_power = inputs.hash_power); ( typeof (alphabet = inputs.alphabet) != "string" || (alphabet = [...alphabet].filter((character, index) => alphabet.indexOf(character) == index)).length < 1 ) && (alphabet = AnyankaKeys.SETTINGS.alphabet); ( typeof (base_from = inputs.base_from) != "number" || base_from != base_from >> 0 || base_from < 2 ) && (base_from = AnyankaKeys.SETTINGS.base_from); ( typeof (base_to = inputs.base_to) != "number" || base_to != base_to >> 0 || base_to < 2 || base_to >= alphabet.length ) && (base_to = AnyankaKeys.SETTINGS.base_to); self.set_public_key(true); typeof summatory_value != "number" && summatory_value !== true && summatory_value !== null && (summatory_value = AnyankaKeys.SETTINGS.summatory); typeof has_incremental != "boolean" && (has_incremental = AnyankaKeys.SETTINGS.incremental); typeof random_private_start != "number" && random_private_start !== true && random_private_start !== null && (random_private_start = AnyankaKeys.SETTINGS.random_private_start); typeof hash_length != "number" && (hash_length = AnyankaKeys.SETTINGS.hash_length); typeof hash_power != "number" && (hash_power = AnyankaKeys.SETTINGS.hash_power); }; /** * @returns {string|null} * @access public */ this.get_public_key = () => public_key.length ? public_key.map(key => alphabet[key]).join("") : null; /** * @param {!number} x * @returns {number} * @access private */ const next = x => { x += 1 + divisor; while(x >= 2) x --; return x; }; /** * @param {string|boolean|null} [new_key = null] * @returns {number} * @access public */ this.set_public_key = (new_key = null) => { /** @type {number} */ let error = 0; if(new_key === undefined) error |= 1 << 1; else{ if(new_key === null){ AnyankaKeys.reset_array_with(public_key); AnyankaKeys.reset_array_with(private_key, [0]); }else{ /** @type {Array.|null} */ let new_public_key = null; switch(typeof new_key){ case "boolean": if(new_key) new_public_key = Array.from({ length : public_key_length }, () => Math.random() * base_to >> 0); else error |= 1 << 4; break; case "string": new_public_key = [...new_key].map(character => alphabet.indexOf(character)); if(Math.min(new_public_key) == -1) error |= 1 << 5; break; default: error |= 1 << 3; break; }; if(!error){ AnyankaKeys.reset_array_with(public_key, new_public_key); /** @type {number} */ const segment = public_key.length / segments_key_length >> 0, /** @type {number} */ start = Number(("" + divisor).split(".")[1]) % base_to; /** @type {number} */ let x = 1; public_key.length && AnyankaKeys.reset_array_with(private_key, Array.from({ length : private_key_length }, (_, i) => (AnyankaKeys.summatory( segments_key_length, j => public_key[(j * segment + i) % public_key_length], start, base_to ) * (x = next(x)) >> 0) % base_to)); }; }; }; return error; }; /** * @param {!number} i * @param {!number} value * @returns {string} * @access private */ const set_key = (i, value) => alphabet[(value + private_key[i % private_key_length]) % base_to]; /** * @param {!(any|null)} data * @returns {string} * @access public */ this.encrypt = data => { /** @type {string} */ let header = "", /** @type {string} */ body = "", /** @type {number} */ pre_empties = 0, /** @type {number} */ i = 0; /** @type {AnyankaKeys.BaseChange.Parameters} */ const parameters = new AnyankaKeys.BaseChange.Parameters({ /** @type {number} */ from : base_from, /** @type {number} */ to : base_to }), /** @type {Array.} */ header_data = ( random_private_start === true ? Array.from({length : 2}, () => Math.random() * base_to >> 0) : typeof random_private_start == "number" ? Array.from([base_to, 1], i => (random_private_start / i >> 0) % base_to) : [0, 0]), /** @type {number} */ summatory = (summatory_value === true ? Math.random() * base_to >> 0 : summatory_value % 58) || 1; /** @type {number} */ private_start = (header_data[0] * base_to + header_data[1]) % private_key_length, /** @type {anyanka_keys_convert_callback} */ set = value => body = set_key(private_start + (has_incremental ? i ++ : 1) * summatory, value) + body, /** @type {AnyankaKeys.Type} */ type = AnyankaKeys.get_each_bytes(data, byte => AnyankaKeys.change_base_iteration(byte, set, parameters), options); if([5, 6, 7, 8].includes(type.code)) data.some(value => { if(value) return true; pre_empties ++; }); else if(type.code == 10) pre_empties = type.empties; parameters.end(set); header += alphabet[header_data[0]] + alphabet[header_data[1]] + set_key(private_start, summatory); [type.code, pre_empties].forEach((value, i) => header += set_key(private_start + (has_incremental ? i : 1) * summatory, value)); return header + body; }; /** * @param {!number} i * @param {!string} character * @returns {number} * @access private */ const get_key = (i, character) => { /** @type {number} */ let value = alphabet.indexOf(character) - private_key[i % private_key_length]; return value < 0 ? value + base_to : value; }; /** * @param {!string} data * @returns {any|null} * @access public */ this.decrypt = data => { /** @type {string} */ const header = data.substring(0, 5), /** @type {AnyankaKeys.BaseChange.Parameters} */ parameters = new AnyankaKeys.BaseChange.Parameters({ /** @type {number} */ from : base_to, /** @type {number} */ to : base_from }), /** @type {string} */ body = data.substring(5), /** @type {number} */ body_l = body.length - 1, /** @type {number} */ private_start = (alphabet.indexOf(header[0]) * base_to + alphabet.indexOf(header[1])) % private_key_length, /** @type {number} */ summatory = get_key(private_start, header[2]), /** @type {AnyankaKeys.Type} */ type = new AnyankaKeys.Type(get_key( private_start + (has_incremental ? 0 : summatory), header[3] ), body, parameters.get_size(body), options); /** @type {number} */ let pre_empties = get_key(private_start + summatory, header[4]); [...body].forEach((character, i) => AnyankaKeys.change_base_iteration(get_key( private_start + (has_incremental ? body_l - i : 1) * summatory, character ), type.set_value, parameters)); parameters.end(type.set_value); (pre_empties == type.length() ? -- pre_empties : pre_empties) > 0 && type.set_pre_empties(pre_empties); type.build(); return type.data; }; /** * @param {any|null} data * @returns {string} * @access public */ this.hash = data => { /** @type {number} */ let summatory = 1, /** @type {number} */ i = 0, /** @type {number} */ x = 1, /** @type {number} */ wise = 0; /** @type {Array.} */ const hash = Array.from({length : hash_length}, () => 0), /** @type {number} */ value_limit = base_to ** hash_power, /** @type {AnyankaKeys.Type} */ type = AnyankaKeys.get_each_bytes(data, byte => { /** @type {number} */ const k = i ++ % hash_length; summatory = (summatory + byte) % value_limit; hash[k] = (hash[k] + byte) % value_limit; }, new AnyankaKeys.Options()), /** @type {number} */ base = summatory ** divisor / ++ i ** divisor; hash[0] += type.code; return hash.map(value => { value = wise ** (x = next(x)) + (base * value) ** x + base ** x; while((value *= base_to) < value_limit); wise += (value = (value >> 0) % base_to); return alphabet[value]; }).join(""); }; constructor(); }; /** @type {Object.} */ AnyankaKeys.SETTINGS = { /** @type {string} */ alphabet : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", /** @type {number} */ base_to : 58, // Cast for unique alphabet characters. /** @type {number} */ base_from : 256, /** @type {boolean|string|null} */ public_key : true, // true = Random || null = No keys || String = Default key /** @type {number} */ public_key_length : 1 << 8, /** @type {number} */ private_key_length : 1 << 12, /** @type {number} */ segments_key_length : 13, /** @type {boolean|number|null} */ summatory : true, // true = Random || null = No summatory || number = Default summatory /** @type {boolean} */ incremental : true, /** @type {boolean|number|null} */ random_private_start : true, /** @type {number} */ divisor : .21417, /** @type {number} */ hash_length : 47, /** @type {number} */ hash_power : 1.89673, /** @type {number} */ scape_character : 92, // Character ["\\", 92] /** @type {number} */ scape_blocks : 2 // Bits: [UTF-8, UTF-16, URI, Force UTF-16] }; /** * @param {!number} length * @param {!anyanka_keys_convert_callback} item_callback * @returns {void} * @access public * @static */ AnyankaKeys.bucle = (length, item_callback) => { /** @type {number} */ let i = 0; while(i < length) item_callback(i ++); }; /** * @param {!number} length * @param {!anyanka_keys_convert_callback} callback * @param {!number} [start = 0] * @param {?number} [limit = null] * @returns {number} * @access public * @static */ AnyankaKeys.summatory = (length, callback, start = 0, limit = null) => { limit || (limit = ~-(1 << 31)); AnyankaKeys.bucle(length, i => start = (start + callback(i)) % limit); return start; }; /** * @param {!Array.} array * @param {Array.} [new_data = []] * @returns {void} * @access public * @static */ AnyankaKeys.reset_array_with = (array, new_data = []) => { array.splice(0, array.length, ...new_data); }; /** * @constructor * @param {!Object.} [inputs = {}] * @returns {void} * @access public * @static */ AnyankaKeys.Options = function(inputs = {}){ /** @type {number} */ this.scape_blocks = ( inputs.scape_blocks !== undefined && typeof inputs.scape_blocks == "number" && inputs.scape_blocks >= 0 && inputs.scape_blocks <= 4 ) ? inputs.scape_blocks : AnyankaKeys.SETTINGS.scape_blocks; /** @type {number} */ this.scape_character = ( inputs.scape_character !== undefined && typeof inputs.scape_character == "number" && inputs.scape_character & 0xFF == inputs.scape_character ) ? inputs.scape_character : AnyankaKeys.SETTINGS.scape_character; /** @type {boolean} */ this.scape_utf8 = !!(this.scape_blocks & (1 << 0)); /** @type {boolean} */ this.scape_utf16 = !!(this.scape_blocks & (1 << 1)); /** @type {boolean} */ this.scape_uri = !!(this.scape_blocks & (1 << 2)); /** @type {boolean} */ this.force_utf16 = !!(this.scape_blocks & (1 << 3)); /** @type {boolean} */ this.scape = this.scape_utf8 || this.scape_utf16; }; /** * @constructor * @param {string|number} [name = "unknown"] * @param {string|null} [data = null] * @param {number} [length = 0] * @param {?AnyankaKeys.Options} [options = null] * @returns {void} * @access public */ AnyankaKeys.Type = function(name = "unknown", data = null, length = 0, options = null){ /** @type {AnyankaKeys.Type} */ const self = this; /** @type {any|null} */ let cache = null, /** @type {Array.|null} */ string_cache = null; /** @type {number} */ this.code = 0; /** @type {string} */ this.name = name; /** @type {any|null} */ this.data = null; /** @type {number} */ this.empties = 0; /** * @returns {void} * @access private */ const constructor = () => { if(typeof name == "number") self.name = AnyankaKeys.Type.TYPES[self.code = name]; else if(name){ if(self.code = AnyankaKeys.Type.TYPES.indexOf(name = name.toLowerCase()) != -1) self.name = name; else self.code = 0; }; data !== null && self.start(data, length); options || (options = new AnyankaKeys.Options()); }; /** * @param {!number} code * @param {?name} [name = null] * @returns {void} * @access public */ this.set = (code, name = null) => { self.code = code; name && (self.name = name); }; /** * @param {!number} byte * @returns {string} * @access private */ const get_character_by_byte = (byte) => { /** @type {string} */ let character = "", /** @type {boolean} */ force_scape = false; if(options.scape){ if(string_cache === null){ if(byte == options.scape_character) string_cache = []; else character = String.fromCharCode(byte); }else if(byte == options.scape_character){ if(!string_cache.length) character = String.fromCharCode(byte); else{ /** @type {number} */ let code = 0; string_cache.forEach((byte, i) => code += byte << i * 8); character = String.fromCharCode(code); force_scape = true; string_cache = []; }; }else if(!string_cache.length){ if(options.scape_utf16) string_cache.push(byte); else character = String.fromCharCode(string_cache[0]); }else character = String.fromCharCode(string_cache[0] | (byte << 8)); }else character = String.fromCharCode(byte); string_cache !== null && !force_scape && character !== "" && (string_cache = null); return character; }; /** @type {Object.|Object.|Object.|Object.>} */ this.action = { /** @type {Object.} */ start : { unknown : (data, length) => {}, string : (data, length) => self.data = "", undefined : (data, length) => self.data = undefined, null : (data, length) => {}, json : (data, length) => cache = "", utf8 : (data, length) => cache = [], utf16 : (data, length) => cache = [], utf32 : (data, length) => cache = [], bytes : (data, length) => self.data = [], bool : (data, length) => {}, integer : (data, length) => self.data = 0, float : (data, length) => {}, custom : (data, length) => cache = [] }, /** @type {Object.} */ set_value : { unknown : (value, i) => {}, string : (value, i) => self.data = get_character_by_byte(value) + self.data, undefined : (value, i) => {}, null : (value, i) => {}, json : (value, i) => cache = get_character_by_byte(value) + cache, utf8 : (value, i) => cache.unshift(value), utf16 : (value, i) => { if(i % 2) cache[0] = (cache[0] << 8) | value; else cache.unshift(value); }, utf32 : (value, i) => { if(i % 4) cache[0] = (cache[0] << 8) | value; else cache.unshift(value); }, bytes : (value, i) => self.data.unshift(value), bool : (value, i) => self.data = ( i ? null : value === 1 ? true : value === 0 ? false : null), integer : (value, i) => self.data = (self.data << 8) | value, float : (value, i) => {}, custom : (value, i) => cache.push(value) }, /** @type {Object.} */ set_pre_empties : { unknown : empties => {}, string : empties => {}, undefined : empties => {}, null : empties => {}, json : empties => {}, utf8 : empties => AnyankaKeys.bucle(empties, () => cache.unshift(0)), utf16 : empties => AnyankaKeys.bucle(empties, () => cache.unshift(0)), utf32 : empties => AnyankaKeys.bucle(empties, () => cache.unshift(0)), bytes : empties => AnyankaKeys.bucle(empties, () => self.data.unshift(0)), bool : empties => {}, integer : empties => self.data <<= empties * 8, float : empties => {}, custom : empties => AnyankaKeys.bucle(empties, () => self.data.unshift(0)) }, /** @type {Object.} */ build : { unknown : () => {}, string : () => { string_cache !== null && (self.data = String.fromCharCode(0) + self.data); options.scape_uri && (self.data = decodeURIComponent(self.data)); }, undefined : () => {}, null : () => {}, json : () => { string_cache !== null && (cache = String.fromCharCode(0) + cache); self.data = JSON.parse(cache ? options.scape_uri ? decodeURIComponent(cache) : cache : "[]"); }, utf8 : () => self.data = new Uint8Array(cache), utf16 : () => self.data = new Uint16Array(cache), utf32 : () => self.data = new Uint32Array(cache), bytes : () => {}, bool : () => {}, integer : () => {}, float : () => {}, custom : () => {} } }; /** * @param {!string} data * @param {!number} length * @returns {void} * @access public */ this.start = (data, length) => { self.action.start[self.name](data, length); }; /** * @param {!number} value * @param {!number} i * @returns {void} * @access public */ this.set_value = (value, i) => { self.action.set_value[self.name](value, i); } /** * @param {!number} empties * @returns {void} * @access public */ this.set_pre_empties = empties => { self.action.set_pre_empties[self.name](empties); } /** * @returns {void} * @access public */ this.build = () => { self.action.build[self.name](); } /** * @returns {number} * @access public */ this.length = () => (cache || self.data || []).length; constructor(); }; /** @type {Array.} */ AnyankaKeys.Type.TYPES = [ "unknown", "string", "undefined", "null", "json", "utf8", "utf16", "utf32", "bytes", "bool", "integer", "float", "custom" ]; /** * @constructor * @param {?Object.} [inputs = null] * @returns {void} * @access public */ AnyankaKeys.BaseChange = function(inputs = null){ /** @type {number} */ this.FROM = (inputs || (inputs = {})).from || inputs.base_from || AnyankaKeys.SETTINGS.base_from; /** @type {number} */ this.TO = inputs.to || inputs.base_to || AnyankaKeys.SETTINGS.base_to; }; /** * @constructor * @param {?Object.} [inputs = null] * @returns {void} * @access public */ AnyankaKeys.BaseChange.Parameters = function(inputs){ /** @type {AnyankaKeys.BaseChange.Parameters} */ const self = this; /** @type {number} */ let i = 0; /** @type {AnyankaKeys.BaseChange} */ this.BASE = new AnyankaKeys.BaseChange(inputs); /** @type {number|null} */ this.summatory = null; /** * @returns {void} * @access public */ this.go_to_next = () => { self.summatory = (self.summatory || 0) / self.BASE.TO >> 0; i ++; }; /** * @param {!number} value * @returns {void} * @access public */ this.add = value => { self.summatory = (self.summatory || 0) * self.BASE.FROM + value; }; /** * @param {!anyanka_keys_convert_callback} callback * @returns {void} * @access public */ this.process = callback => { if(self.summatory !== null) while(self.summatory >= self.BASE.TO){ callback(self.summatory % self.BASE.TO, i); self.go_to_next(); }; }; /** * @param {!anyanka_keys_convert_callback} callback * @returns {void} * @access public */ this.end = callback => { self.process(callback); if(self.summatory !== null && (!i || self.summatory)){ callback(self.summatory, i); self.go_to_next(); }; }; /** * @param {!string} data * @returns {number} * @access public */ this.get_size = data => Math.round(data.length * Math.log2(self.BASE.FROM) / Math.log2(self.BASE.TO)); }; /** * @param {!(any|null)} value * @returns {boolean} * @access public * @static */ AnyankaKeys.is_dictionary = value => ( value !== undefined && value !== null && value.constructor == Object ); /** * @param {!string} string * @param {!anyanka_keys_convert_callback} set * @param {!AnyankaKeys.Options} options * @returns {void} * @access public */ AnyankaKeys.get_each_bytes_in_string = (string, set, options) => [...( options.scape_uri ? encodeURIComponent(string) : string )].forEach(character => { /** @type {number} */ const code = character.charCodeAt(0), /** @type {boolean} */ is_utf8 = (code & 0xFF) == code; if(options.force_utf16) [8, 0].forEach(wise => set((code >> wise) & 0xFF)); else if(options.scape){ if(code == options.scape_character) [null, null].forEach(() => set(code)); else if(is_utf8){ set(code); options.scape_utf8 && set(options.scape_character); }else{ [8, 0].forEach(wise => set((code >> wise) & 0xFF)); options.scape_utf16 && set(options.scape_character); }; }else set(code); }); /** * @param {!(any|null)} data * @param {!anyanka_keys_convert_callback} set * @param {!AnyankaKeys.Options} options * @returns {AnyankaKeys.Type} * @access public * @static */ AnyankaKeys.get_each_bytes = (data, set, options) => { /** @type {AnyankaKeys.Type} */ let type = new AnyankaKeys.Type(); if(data === undefined) type.set(2); else if(data === null) type.set(3); else switch(typeof data){ case "string": AnyankaKeys.get_each_bytes_in_string(data, set, options); type.set(1); break; case "boolean": set(data ? 1 : 0); type.set(9); break; case "number": if(data == data >> 0){ let empties_done = false; do{ set(data & 0xFF); if(!empties_done){ if(data & 0xFF) empties_done = true; else type.empties ++; }; }while(data >>= 8); type.set(10); }else{ [...("" + data)].forEach(character => set(character.charCodeAt(0))); type.set(11); }; break; case "object": if(data instanceof Uint8Array){ type.set(5); [...data].forEach(set); }else if(data instanceof Uint16Array){ [...data].forEach(smallint => [0, 1].forEach(i => set((smallint >> i * 8) & 0xFF))); type.set(6); }else if(data instanceof Uint32Array){ [...data].forEach(integer => [0, 1, 2, 3].forEach(i => set((integer >> i * 8) & 0xFF))); type.set(7); }else if(data instanceof Array && !data.some(value => typeof value != "number" || value < 0 || value > 0xFF)){ data.forEach(set); type.set(8); }else if(["Array", "Object"].includes(data.constructor.name)){ AnyankaKeys.get_each_bytes_in_string(JSON.stringify(data), set, options); // [...JSON.stringify(data)].forEach(character => set(character.charCodeAt(0))); type.set(4); }else{ type.set(12, data.constructor.name); try{ AnyankaKeys.get_each_bytes_in_string(JSON.stringify(data), set, options); // [...JSON.stringify(data)].forEach(character => set(character.charCodeAt(0))); }catch(exception){ type.set(0); }; }; break; }; return type; }; /** * @param {!(number|Array.)} data * @param {!anyanka_keys_convert_callback} set * @param {?(AnyankaKeys.BaseChange.Parameters|Object.)} [parameters = null] * @returns {void} * @access public * @static */ AnyankaKeys.change_base_iteration = (data, set, parameters = null) => { ( !parameters || !(parameters instanceof AnyankaKeys.BaseChange.Parameters) ) && (parameters = new AnyankaKeys.BaseChange.Parameters(inputs)); (data instanceof Array ? data : [data]).forEach(value => { parameters.add(value); parameters.process(set); }); }; /** * @param {!(string|Array.)} value * @param {!number} to * @param {?number} [from = null] * @param {string|null} [type = null] * @returns {string|Array.|null} * @access public * @static */ AnyankaKeys.change_base = (value, to, from = null, type = null) => { from || (from = AnyankaKeys.SETTINGS.base_from); type || (type = ( typeof value == "number" && value == value >> 0 ? "integer" : typeof value == "string" ? "string" : value instanceof Array ? "array" : "unknown")); /** @type {string|Array.|null} */ let response = null, /** @type {anyanka_keys_convert_callback|null} */ set = null, /** @type {anyanka_keys_default_callback|null} */ iterator = null; /** @type {AnyankaKeys.BaseChange.Parameters} */ const parameters = new AnyankaKeys.BaseChange.Parameters({ /** @type {number} */ from : from, /** @type {number} */ to : to }); switch(type){ case "string": response = ""; set = value => response = String.fromCharCode(value) + response; iterator = () => [...value].map(character => AnyankaKeys.change_base_iteration(character.charCodeAt(0), set, parameters)); break; case "array": response = []; set = value => response.unshift(value); iterator = () => AnyankaKeys.change_base_iteration(value, set, parameters); break; }; if(response !== null){ iterator(); parameters.end(set); }; return response; }; return AnyankaKeys; })();