"use strict"; // @FILE-SUBCLASS-01-EXCEPTION /** * Base class for JavaScript ORM models * * Provides core functionality for fetching records from backend PHP models. * All model stubs generated by the manifest extend this base class. * * Example usage: * // Fetch single record * const user = await User_Model.fetch(123); * * // Fetch multiple records * const users = await User_Model.fetch([1, 2, 3]); * * // Create instance with data * const user = new User_Model({id: 1, name: 'John'}); * * @Instantiatable */ class Rsx_Js_Model { /** * Constructor - Initialize model instance with data * * @param {Object} data - Key-value pairs to populate the model */ constructor() { let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; // __MODEL SYSTEM: Enables automatic ORM instantiation when fetching from PHP models. // PHP models add "__MODEL": "ClassName" to JSON, JavaScript uses it to create proper instances. // This provides typed model objects instead of plain JSON, with methods and type checking. // This constructor filters out the __MODEL marker that was used to identify which class // to instantiate, keeping only the actual data properties on the instance. const { __MODEL, ...modelData } = data; Object.assign(this, modelData); } /** * Fetch record(s) from the backend model * * This method mirrors the PHP Model::fetch() functionality. * The backend model must have a fetch() method with the * #[Ajax_Endpoint_Model_Fetch] annotation to be callable. * * @param {number|Array} id - Single ID or array of IDs to fetch * @returns {Promise} - Single model instance, array of instances, or false */ static async fetch(id) { const CurrentClass = this; // Get the model class name from the current class const modelName = CurrentClass.name; const response = await $.ajax({ url: `/_fetch/${modelName}`, method: 'POST', data: { id: id }, dataType: 'json' }); // Handle response based on type if (response === false) { return false; } // Use _instantiate_models_recursive to handle ORM instantiation // This will automatically detect __MODEL properties and create appropriate instances return Rsx_Js_Model._instantiate_models_recursive(response); } /** * Get the model class name * Used internally for API calls * * @returns {string} The class name */ static getModelName() { const CurrentClass = this; return CurrentClass.name; } /** * Refresh this instance with latest data from server * * @returns {Promise} Updated instance or false if not found */ async refresh() { const that = this; if (!that.id) { shouldnt_happen('Cannot refresh model without id property'); } const fresh = await that.constructor.fetch(that.id); if (fresh === false) { return false; } // Update this instance with fresh data Object.assign(that, fresh); return that; } /** * Convert model instance to plain object * Useful for serialization or sending to APIs * * @returns {Object} Plain object representation */ toObject() { const that = this; const obj = {}; for (const key in that) { if (that.hasOwnProperty(key) && typeof that[key] !== 'function') { obj[key] = that[key]; } } return obj; } /** * Convert model instance to JSON string * * @returns {string} JSON representation */ toJSON() { const that = this; return JSON.stringify(that.toObject()); } /** * Recursively instantiate ORM models in response data * * Looks for objects with __MODEL property and instantiates the appropriate * JavaScript model class if it exists in the global scope. * * @param {*} data - The data to process (can be any type) * @returns {*} The data with ORM objects instantiated */ static _instantiate_models_recursive(data) { // __MODEL SYSTEM: Enables automatic ORM instantiation when fetching from PHP models. // PHP models add "__MODEL": "ClassName" to JSON, JavaScript uses it to create proper instances. // This provides typed model objects instead of plain JSON, with methods and type checking. // This recursive processor scans all API response data looking for __MODEL markers. // When found, it attempts to instantiate the appropriate JavaScript model class, // converting {__MODEL: "User_Model", id: 1, name: "John"} into new User_Model({...}). // Works recursively through arrays and nested objects to handle complex data structures. // Handle null/undefined if (data === null || data === undefined) { return data; } // Handle arrays - recursively process each element if (Array.isArray(data)) { return data.map(item => Rsx_Js_Model._instantiate_models_recursive(item)); } // Handle objects if (typeof data === 'object') { // Check if this object has a __MODEL property if (data.__MODEL && typeof data.__MODEL === 'string') { // Try to find the model class in the global scope const ModelClass = window[data.__MODEL]; // If the model class exists and extends Rsx_Js_Model, instantiate it // Dynamic model resolution requires checking class existence - @JS-DEFENSIVE-01-EXCEPTION if (ModelClass && ModelClass.prototype instanceof Rsx_Js_Model) { return new ModelClass(data); } } // Recursively process all object properties const result = {}; for (const key in data) { if (data.hasOwnProperty(key)) { result[key] = Rsx_Js_Model._instantiate_models_recursive(data[key]); } } return result; } // Return primitive values as-is return data; } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSc3hfSnNfTW9kZWwiLCJjb25zdHJ1Y3RvciIsImRhdGEiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJfX01PREVMIiwibW9kZWxEYXRhIiwiT2JqZWN0IiwiYXNzaWduIiwiZmV0Y2giLCJpZCIsIkN1cnJlbnRDbGFzcyIsIm1vZGVsTmFtZSIsIm5hbWUiLCJyZXNwb25zZSIsIiQiLCJhamF4IiwidXJsIiwibWV0aG9kIiwiZGF0YVR5cGUiLCJfaW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZSIsImdldE1vZGVsTmFtZSIsInJlZnJlc2giLCJ0aGF0Iiwic2hvdWxkbnRfaGFwcGVuIiwiZnJlc2giLCJ0b09iamVjdCIsIm9iaiIsImtleSIsImhhc093blByb3BlcnR5IiwidG9KU09OIiwiSlNPTiIsInN0cmluZ2lmeSIsIkFycmF5IiwiaXNBcnJheSIsIm1hcCIsIml0ZW0iLCJNb2RlbENsYXNzIiwid2luZG93IiwicHJvdG90eXBlIiwicmVzdWx0Il0sInNvdXJjZXMiOlsiYXBwL1JTcGFkZS9Db3JlL0pzL1JzeF9Kc19Nb2RlbC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBARklMRS1TVUJDTEFTUy0wMS1FWENFUFRJT05cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBKYXZhU2NyaXB0IE9STSBtb2RlbHNcbiAqXG4gKiBQcm92aWRlcyBjb3JlIGZ1bmN0aW9uYWxpdHkgZm9yIGZldGNoaW5nIHJlY29yZHMgZnJvbSBiYWNrZW5kIFBIUCBtb2RlbHMuXG4gKiBBbGwgbW9kZWwgc3R1YnMgZ2VuZXJhdGVkIGJ5IHRoZSBtYW5pZmVzdCBleHRlbmQgdGhpcyBiYXNlIGNsYXNzLlxuICpcbiAqIEV4YW1wbGUgdXNhZ2U6XG4gKiAgIC8vIEZldGNoIHNpbmdsZSByZWNvcmRcbiAqICAgY29uc3QgdXNlciA9IGF3YWl0IFVzZXJfTW9kZWwuZmV0Y2goMTIzKTtcbiAqXG4gKiAgIC8vIEZldGNoIG11bHRpcGxlIHJlY29yZHNcbiAqICAgY29uc3QgdXNlcnMgPSBhd2FpdCBVc2VyX01vZGVsLmZldGNoKFsxLCAyLCAzXSk7XG4gKlxuICogICAvLyBDcmVhdGUgaW5zdGFuY2Ugd2l0aCBkYXRhXG4gKiAgIGNvbnN0IHVzZXIgPSBuZXcgVXNlcl9Nb2RlbCh7aWQ6IDEsIG5hbWU6ICdKb2huJ30pO1xuICpcbiAqICBASW5zdGFudGlhdGFibGVcbiAqL1xuY2xhc3MgUnN4X0pzX01vZGVsIHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RvciAtIEluaXRpYWxpemUgbW9kZWwgaW5zdGFuY2Ugd2l0aCBkYXRhXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YSAtIEtleS12YWx1ZSBwYWlycyB0byBwb3B1bGF0ZSB0aGUgbW9kZWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihkYXRhID0ge30pIHtcbiAgICAgICAgLy8gX19NT0RFTCBTWVNURU06IEVuYWJsZXMgYXV0b21hdGljIE9STSBpbnN0YW50aWF0aW9uIHdoZW4gZmV0Y2hpbmcgZnJvbSBQSFAgbW9kZWxzLlxuICAgICAgICAvLyBQSFAgbW9kZWxzIGFkZCBcIl9fTU9ERUxcIjogXCJDbGFzc05hbWVcIiB0byBKU09OLCBKYXZhU2NyaXB0IHVzZXMgaXQgdG8gY3JlYXRlIHByb3BlciBpbnN0YW5jZXMuXG4gICAgICAgIC8vIFRoaXMgcHJvdmlkZXMgdHlwZWQgbW9kZWwgb2JqZWN0cyBpbnN0ZWFkIG9mIHBsYWluIEpTT04sIHdpdGggbWV0aG9kcyBhbmQgdHlwZSBjaGVja2luZy5cblxuICAgICAgICAvLyBUaGlzIGNvbnN0cnVjdG9yIGZpbHRlcnMgb3V0IHRoZSBfX01PREVMIG1hcmtlciB0aGF0IHdhcyB1c2VkIHRvIGlkZW50aWZ5IHdoaWNoIGNsYXNzXG4gICAgICAgIC8vIHRvIGluc3RhbnRpYXRlLCBrZWVwaW5nIG9ubHkgdGhlIGFjdHVhbCBkYXRhIHByb3BlcnRpZXMgb24gdGhlIGluc3RhbmNlLlxuICAgICAgICBjb25zdCB7IF9fTU9ERUwsIC4uLm1vZGVsRGF0YSB9ID0gZGF0YTtcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBtb2RlbERhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIHJlY29yZChzKSBmcm9tIHRoZSBiYWNrZW5kIG1vZGVsXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBtaXJyb3JzIHRoZSBQSFAgTW9kZWw6OmZldGNoKCkgZnVuY3Rpb25hbGl0eS5cbiAgICAgKiBUaGUgYmFja2VuZCBtb2RlbCBtdXN0IGhhdmUgYSBmZXRjaCgpIG1ldGhvZCB3aXRoIHRoZVxuICAgICAqICNbQWpheF9FbmRwb2ludF9Nb2RlbF9GZXRjaF0gYW5ub3RhdGlvbiB0byBiZSBjYWxsYWJsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfEFycmF5fSBpZCAtIFNpbmdsZSBJRCBvciBhcnJheSBvZiBJRHMgdG8gZmV0Y2hcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gLSBTaW5nbGUgbW9kZWwgaW5zdGFuY2UsIGFycmF5IG9mIGluc3RhbmNlcywgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZmV0Y2goaWQpIHtcbiAgICAgICAgY29uc3QgQ3VycmVudENsYXNzID0gdGhpcztcbiAgICAgICAgLy8gR2V0IHRoZSBtb2RlbCBjbGFzcyBuYW1lIGZyb20gdGhlIGN1cnJlbnQgY2xhc3NcbiAgICAgICAgY29uc3QgbW9kZWxOYW1lID0gQ3VycmVudENsYXNzLm5hbWU7XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaC8ke21vZGVsTmFtZX1gLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiB7IGlkOiBpZCB9LFxuICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIHJlc3BvbnNlIGJhc2VkIG9uIHR5cGVcbiAgICAgICAgaWYgKHJlc3BvbnNlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXNlIF9pbnN0YW50aWF0ZV9tb2RlbHNfcmVjdXJzaXZlIHRvIGhhbmRsZSBPUk0gaW5zdGFudGlhdGlvblxuICAgICAgICAvLyBUaGlzIHdpbGwgYXV0b21hdGljYWxseSBkZXRlY3QgX19NT0RFTCBwcm9wZXJ0aWVzIGFuZCBjcmVhdGUgYXBwcm9wcmlhdGUgaW5zdGFuY2VzXG4gICAgICAgIHJldHVybiBSc3hfSnNfTW9kZWwuX2luc3RhbnRpYXRlX21vZGVsc19yZWN1cnNpdmUocmVzcG9uc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgbW9kZWwgY2xhc3MgbmFtZVxuICAgICAqIFVzZWQgaW50ZXJuYWxseSBmb3IgQVBJIGNhbGxzXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY2xhc3MgbmFtZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRNb2RlbE5hbWUoKSB7XG4gICAgICAgIGNvbnN0IEN1cnJlbnRDbGFzcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBDdXJyZW50Q2xhc3MubmFtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWZyZXNoIHRoaXMgaW5zdGFuY2Ugd2l0aCBsYXRlc3QgZGF0YSBmcm9tIHNlcnZlclxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFVwZGF0ZWQgaW5zdGFuY2Ugb3IgZmFsc2UgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgYXN5bmMgcmVmcmVzaCgpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIGlmICghdGhhdC5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgcmVmcmVzaCBtb2RlbCB3aXRob3V0IGlkIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmcmVzaCA9IGF3YWl0IHRoYXQuY29uc3RydWN0b3IuZmV0Y2godGhhdC5pZCk7XG5cbiAgICAgICAgaWYgKGZyZXNoID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBkYXRlIHRoaXMgaW5zdGFuY2Ugd2l0aCBmcmVzaCBkYXRhXG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhhdCwgZnJlc2gpO1xuICAgICAgICByZXR1cm4gdGhhdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IG1vZGVsIGluc3RhbmNlIHRvIHBsYWluIG9iamVjdFxuICAgICAqIFVzZWZ1bCBmb3Igc2VyaWFsaXphdGlvbiBvciBzZW5kaW5nIHRvIEFQSXNcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFBsYWluIG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgICAqL1xuICAgIHRvT2JqZWN0KCkge1xuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgY29uc3Qgb2JqID0ge307XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRoYXQpIHtcbiAgICAgICAgICAgIGlmICh0aGF0Lmhhc093blByb3BlcnR5KGtleSkgJiYgdHlwZW9mIHRoYXRba2V5XSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIG9ialtrZXldID0gdGhhdFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydCBtb2RlbCBpbnN0YW5jZSB0byBKU09OIHN0cmluZ1xuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gSlNPTiByZXByZXNlbnRhdGlvblxuICAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGF0LnRvT2JqZWN0KCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGluc3RhbnRpYXRlIE9STSBtb2RlbHMgaW4gcmVzcG9uc2UgZGF0YVxuICAgICAqXG4gICAgICogTG9va3MgZm9yIG9iamVjdHMgd2l0aCBfX01PREVMIHByb3BlcnR5IGFuZCBpbnN0YW50aWF0ZXMgdGhlIGFwcHJvcHJpYXRlXG4gICAgICogSmF2YVNjcmlwdCBtb2RlbCBjbGFzcyBpZiBpdCBleGlzdHMgaW4gdGhlIGdsb2JhbCBzY29wZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gZGF0YSAtIFRoZSBkYXRhIHRvIHByb2Nlc3MgKGNhbiBiZSBhbnkgdHlwZSlcbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGRhdGEgd2l0aCBPUk0gb2JqZWN0cyBpbnN0YW50aWF0ZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgX2luc3RhbnRpYXRlX21vZGVsc19yZWN1cnNpdmUoZGF0YSkge1xuICAgICAgICAvLyBfX01PREVMIFNZU1RFTTogRW5hYmxlcyBhdXRvbWF0aWMgT1JNIGluc3RhbnRpYXRpb24gd2hlbiBmZXRjaGluZyBmcm9tIFBIUCBtb2RlbHMuXG4gICAgICAgIC8vIFBIUCBtb2RlbHMgYWRkIFwiX19NT0RFTFwiOiBcIkNsYXNzTmFtZVwiIHRvIEpTT04sIEphdmFTY3JpcHQgdXNlcyBpdCB0byBjcmVhdGUgcHJvcGVyIGluc3RhbmNlcy5cbiAgICAgICAgLy8gVGhpcyBwcm92aWRlcyB0eXBlZCBtb2RlbCBvYmplY3RzIGluc3RlYWQgb2YgcGxhaW4gSlNPTiwgd2l0aCBtZXRob2RzIGFuZCB0eXBlIGNoZWNraW5nLlxuXG4gICAgICAgIC8vIFRoaXMgcmVjdXJzaXZlIHByb2Nlc3NvciBzY2FucyBhbGwgQVBJIHJlc3BvbnNlIGRhdGEgbG9va2luZyBmb3IgX19NT0RFTCBtYXJrZXJzLlxuICAgICAgICAvLyBXaGVuIGZvdW5kLCBpdCBhdHRlbXB0cyB0byBpbnN0YW50aWF0ZSB0aGUgYXBwcm9wcmlhdGUgSmF2YVNjcmlwdCBtb2RlbCBjbGFzcyxcbiAgICAgICAgLy8gY29udmVydGluZyB7X19NT0RFTDogXCJVc2VyX01vZGVsXCIsIGlkOiAxLCBuYW1lOiBcIkpvaG5cIn0gaW50byBuZXcgVXNlcl9Nb2RlbCh7Li4ufSkuXG4gICAgICAgIC8vIFdvcmtzIHJlY3Vyc2l2ZWx5IHRocm91Z2ggYXJyYXlzIGFuZCBuZXN0ZWQgb2JqZWN0cyB0byBoYW5kbGUgY29tcGxleCBkYXRhIHN0cnVjdHVyZXMuXG4gICAgICAgIC8vIEhhbmRsZSBudWxsL3VuZGVmaW5lZFxuICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCB8fCBkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIGFycmF5cyAtIHJlY3Vyc2l2ZWx5IHByb2Nlc3MgZWFjaCBlbGVtZW50XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YS5tYXAoKGl0ZW0pID0+IFJzeF9Kc19Nb2RlbC5faW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZShpdGVtKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgb2JqZWN0c1xuICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIG9iamVjdCBoYXMgYSBfX01PREVMIHByb3BlcnR5XG4gICAgICAgICAgICBpZiAoZGF0YS5fX01PREVMICYmIHR5cGVvZiBkYXRhLl9fTU9ERUwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIGZpbmQgdGhlIG1vZGVsIGNsYXNzIGluIHRoZSBnbG9iYWwgc2NvcGVcbiAgICAgICAgICAgICAgICBjb25zdCBNb2RlbENsYXNzID0gd2luZG93W2RhdGEuX19NT0RFTF07XG5cbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbW9kZWwgY2xhc3MgZXhpc3RzIGFuZCBleHRlbmRzIFJzeF9Kc19Nb2RlbCwgaW5zdGFudGlhdGUgaXRcbiAgICAgICAgICAgICAgICAvLyBEeW5hbWljIG1vZGVsIHJlc29sdXRpb24gcmVxdWlyZXMgY2hlY2tpbmcgY2xhc3MgZXhpc3RlbmNlIC0gQEpTLURFRkVOU0lWRS0wMS1FWENFUFRJT05cbiAgICAgICAgICAgICAgICBpZiAoTW9kZWxDbGFzcyAmJiBNb2RlbENsYXNzLnByb3RvdHlwZSBpbnN0YW5jZW9mIFJzeF9Kc19Nb2RlbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1vZGVsQ2xhc3MoZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBwcm9jZXNzIGFsbCBvYmplY3QgcHJvcGVydGllc1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRba2V5XSA9IFJzeF9Kc19Nb2RlbC5faW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZShkYXRhW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXR1cm4gcHJpbWl0aXZlIHZhbHVlcyBhcy1pc1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTUEsWUFBWSxDQUFDO0VBQ2Y7QUFDSjtB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