UNPKG

browserfs

Version:

A filesystem in your browser!

760 lines 130 kB
"use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var file_system = require('../core/file_system'); var api_error_1 = require('../core/api_error'); var node_fs_stats_1 = require('../core/node_fs_stats'); var path = require('path'); var Inode = require('../generic/inode'); var preload_file = require('../generic/preload_file'); var ROOT_NODE_ID = "/"; function GenerateRandomID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } function noError(e, cb) { if (e) { cb(e); return false; } return true; } function noErrorTx(e, tx, cb) { if (e) { tx.abort(function () { cb(e); }); return false; } return true; } var SimpleSyncRWTransaction = (function () { function SimpleSyncRWTransaction(store) { this.store = store; this.originalData = {}; this.modifiedKeys = []; } SimpleSyncRWTransaction.prototype.stashOldValue = function (key, value) { if (!this.originalData.hasOwnProperty(key)) { this.originalData[key] = value; } }; SimpleSyncRWTransaction.prototype.markModified = function (key) { if (this.modifiedKeys.indexOf(key) === -1) { this.modifiedKeys.push(key); if (!this.originalData.hasOwnProperty(key)) { this.originalData[key] = this.store.get(key); } } }; SimpleSyncRWTransaction.prototype.get = function (key) { var val = this.store.get(key); this.stashOldValue(key, val); return val; }; SimpleSyncRWTransaction.prototype.put = function (key, data, overwrite) { this.markModified(key); return this.store.put(key, data, overwrite); }; SimpleSyncRWTransaction.prototype.del = function (key) { this.markModified(key); this.store.del(key); }; SimpleSyncRWTransaction.prototype.commit = function () { }; SimpleSyncRWTransaction.prototype.abort = function () { var i, key, value; for (i = 0; i < this.modifiedKeys.length; i++) { key = this.modifiedKeys[i]; value = this.originalData[key]; if (value === null) { this.store.del(key); } else { this.store.put(key, value, true); } } }; return SimpleSyncRWTransaction; }()); exports.SimpleSyncRWTransaction = SimpleSyncRWTransaction; var SyncKeyValueFile = (function (_super) { __extends(SyncKeyValueFile, _super); function SyncKeyValueFile(_fs, _path, _flag, _stat, contents) { _super.call(this, _fs, _path, _flag, _stat, contents); } SyncKeyValueFile.prototype.syncSync = function () { if (this.isDirty()) { this._fs._syncSync(this.getPath(), this.getBuffer(), this.getStats()); this.resetDirty(); } }; SyncKeyValueFile.prototype.closeSync = function () { this.syncSync(); }; return SyncKeyValueFile; }(preload_file.PreloadFile)); exports.SyncKeyValueFile = SyncKeyValueFile; var SyncKeyValueFileSystem = (function (_super) { __extends(SyncKeyValueFileSystem, _super); function SyncKeyValueFileSystem(options) { _super.call(this); this.store = options.store; this.makeRootDirectory(); } SyncKeyValueFileSystem.isAvailable = function () { return true; }; SyncKeyValueFileSystem.prototype.getName = function () { return this.store.name(); }; SyncKeyValueFileSystem.prototype.isReadOnly = function () { return false; }; SyncKeyValueFileSystem.prototype.supportsSymlinks = function () { return false; }; SyncKeyValueFileSystem.prototype.supportsProps = function () { return false; }; SyncKeyValueFileSystem.prototype.supportsSynch = function () { return true; }; SyncKeyValueFileSystem.prototype.makeRootDirectory = function () { var tx = this.store.beginTransaction('readwrite'); if (tx.get(ROOT_NODE_ID) === undefined) { var currTime = (new Date()).getTime(), dirInode = new Inode(GenerateRandomID(), 4096, 511 | node_fs_stats_1.FileType.DIRECTORY, currTime, currTime, currTime); tx.put(dirInode.id, new Buffer("{}"), false); tx.put(ROOT_NODE_ID, dirInode.toBuffer(), false); tx.commit(); } }; SyncKeyValueFileSystem.prototype._findINode = function (tx, parent, filename) { var _this = this; var read_directory = function (inode) { var dirList = _this.getDirListing(tx, parent, inode); if (dirList[filename]) { return dirList[filename]; } else { throw api_error_1.ApiError.ENOENT(path.resolve(parent, filename)); } }; if (parent === '/') { if (filename === '') { return ROOT_NODE_ID; } else { return read_directory(this.getINode(tx, parent, ROOT_NODE_ID)); } } else { return read_directory(this.getINode(tx, parent + path.sep + filename, this._findINode(tx, path.dirname(parent), path.basename(parent)))); } }; SyncKeyValueFileSystem.prototype.findINode = function (tx, p) { return this.getINode(tx, p, this._findINode(tx, path.dirname(p), path.basename(p))); }; SyncKeyValueFileSystem.prototype.getINode = function (tx, p, id) { var inode = tx.get(id); if (inode === undefined) { throw api_error_1.ApiError.ENOENT(p); } return Inode.fromBuffer(inode); }; SyncKeyValueFileSystem.prototype.getDirListing = function (tx, p, inode) { if (!inode.isDirectory()) { throw api_error_1.ApiError.ENOTDIR(p); } var data = tx.get(inode.id); if (data === undefined) { throw api_error_1.ApiError.ENOENT(p); } return JSON.parse(data.toString()); }; SyncKeyValueFileSystem.prototype.addNewNode = function (tx, data) { var retries = 0, currId; while (retries < 5) { try { currId = GenerateRandomID(); tx.put(currId, data, false); return currId; } catch (e) { } } throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, 'Unable to commit data to key-value store.'); }; SyncKeyValueFileSystem.prototype.commitNewFile = function (tx, p, type, mode, data) { var parentDir = path.dirname(p), fname = path.basename(p), parentNode = this.findINode(tx, parentDir), dirListing = this.getDirListing(tx, parentDir, parentNode), currTime = (new Date()).getTime(); if (p === '/') { throw api_error_1.ApiError.EEXIST(p); } if (dirListing[fname]) { throw api_error_1.ApiError.EEXIST(p); } try { var dataId = this.addNewNode(tx, data), fileNode = new Inode(dataId, data.length, mode | type, currTime, currTime, currTime), fileNodeId = this.addNewNode(tx, fileNode.toBuffer()); dirListing[fname] = fileNodeId; tx.put(parentNode.id, new Buffer(JSON.stringify(dirListing)), true); } catch (e) { tx.abort(); throw e; } tx.commit(); return fileNode; }; SyncKeyValueFileSystem.prototype.empty = function () { this.store.clear(); this.makeRootDirectory(); }; SyncKeyValueFileSystem.prototype.renameSync = function (oldPath, newPath) { var tx = this.store.beginTransaction('readwrite'), oldParent = path.dirname(oldPath), oldName = path.basename(oldPath), newParent = path.dirname(newPath), newName = path.basename(newPath), oldDirNode = this.findINode(tx, oldParent), oldDirList = this.getDirListing(tx, oldParent, oldDirNode); if (!oldDirList[oldName]) { throw api_error_1.ApiError.ENOENT(oldPath); } var nodeId = oldDirList[oldName]; delete oldDirList[oldName]; if ((newParent + '/').indexOf(oldPath + '/') === 0) { throw new api_error_1.ApiError(api_error_1.ErrorCode.EBUSY, oldParent); } var newDirNode, newDirList; if (newParent === oldParent) { newDirNode = oldDirNode; newDirList = oldDirList; } else { newDirNode = this.findINode(tx, newParent); newDirList = this.getDirListing(tx, newParent, newDirNode); } if (newDirList[newName]) { var newNameNode = this.getINode(tx, newPath, newDirList[newName]); if (newNameNode.isFile()) { try { tx.del(newNameNode.id); tx.del(newDirList[newName]); } catch (e) { tx.abort(); throw e; } } else { throw api_error_1.ApiError.EPERM(newPath); } } newDirList[newName] = nodeId; try { tx.put(oldDirNode.id, new Buffer(JSON.stringify(oldDirList)), true); tx.put(newDirNode.id, new Buffer(JSON.stringify(newDirList)), true); } catch (e) { tx.abort(); throw e; } tx.commit(); }; SyncKeyValueFileSystem.prototype.statSync = function (p, isLstat) { return this.findINode(this.store.beginTransaction('readonly'), p).toStats(); }; SyncKeyValueFileSystem.prototype.createFileSync = function (p, flag, mode) { var tx = this.store.beginTransaction('readwrite'), data = new Buffer(0), newFile = this.commitNewFile(tx, p, node_fs_stats_1.FileType.FILE, mode, data); return new SyncKeyValueFile(this, p, flag, newFile.toStats(), data); }; SyncKeyValueFileSystem.prototype.openFileSync = function (p, flag) { var tx = this.store.beginTransaction('readonly'), node = this.findINode(tx, p), data = tx.get(node.id); if (data === undefined) { throw api_error_1.ApiError.ENOENT(p); } return new SyncKeyValueFile(this, p, flag, node.toStats(), data); }; SyncKeyValueFileSystem.prototype.removeEntry = function (p, isDir) { var tx = this.store.beginTransaction('readwrite'), parent = path.dirname(p), parentNode = this.findINode(tx, parent), parentListing = this.getDirListing(tx, parent, parentNode), fileName = path.basename(p); if (!parentListing[fileName]) { throw api_error_1.ApiError.ENOENT(p); } var fileNodeId = parentListing[fileName]; delete parentListing[fileName]; var fileNode = this.getINode(tx, p, fileNodeId); if (!isDir && fileNode.isDirectory()) { throw api_error_1.ApiError.EISDIR(p); } else if (isDir && !fileNode.isDirectory()) { throw api_error_1.ApiError.ENOTDIR(p); } try { tx.del(fileNode.id); tx.del(fileNodeId); tx.put(parentNode.id, new Buffer(JSON.stringify(parentListing)), true); } catch (e) { tx.abort(); throw e; } tx.commit(); }; SyncKeyValueFileSystem.prototype.unlinkSync = function (p) { this.removeEntry(p, false); }; SyncKeyValueFileSystem.prototype.rmdirSync = function (p) { if (this.readdirSync(p).length > 0) { throw api_error_1.ApiError.ENOTEMPTY(p); } else { this.removeEntry(p, true); } }; SyncKeyValueFileSystem.prototype.mkdirSync = function (p, mode) { var tx = this.store.beginTransaction('readwrite'), data = new Buffer('{}'); this.commitNewFile(tx, p, node_fs_stats_1.FileType.DIRECTORY, mode, data); }; SyncKeyValueFileSystem.prototype.readdirSync = function (p) { var tx = this.store.beginTransaction('readonly'); return Object.keys(this.getDirListing(tx, p, this.findINode(tx, p))); }; SyncKeyValueFileSystem.prototype._syncSync = function (p, data, stats) { var tx = this.store.beginTransaction('readwrite'), fileInodeId = this._findINode(tx, path.dirname(p), path.basename(p)), fileInode = this.getINode(tx, p, fileInodeId), inodeChanged = fileInode.update(stats); try { tx.put(fileInode.id, data, true); if (inodeChanged) { tx.put(fileInodeId, fileInode.toBuffer(), true); } } catch (e) { tx.abort(); throw e; } tx.commit(); }; return SyncKeyValueFileSystem; }(file_system.SynchronousFileSystem)); exports.SyncKeyValueFileSystem = SyncKeyValueFileSystem; var AsyncKeyValueFile = (function (_super) { __extends(AsyncKeyValueFile, _super); function AsyncKeyValueFile(_fs, _path, _flag, _stat, contents) { _super.call(this, _fs, _path, _flag, _stat, contents); } AsyncKeyValueFile.prototype.sync = function (cb) { var _this = this; if (this.isDirty()) { this._fs._sync(this.getPath(), this.getBuffer(), this.getStats(), function (e) { if (!e) { _this.resetDirty(); } cb(e); }); } else { cb(); } }; AsyncKeyValueFile.prototype.close = function (cb) { this.sync(cb); }; return AsyncKeyValueFile; }(preload_file.PreloadFile)); exports.AsyncKeyValueFile = AsyncKeyValueFile; var AsyncKeyValueFileSystem = (function (_super) { __extends(AsyncKeyValueFileSystem, _super); function AsyncKeyValueFileSystem() { _super.apply(this, arguments); } AsyncKeyValueFileSystem.prototype.init = function (store, cb) { this.store = store; this.makeRootDirectory(cb); }; AsyncKeyValueFileSystem.isAvailable = function () { return true; }; AsyncKeyValueFileSystem.prototype.getName = function () { return this.store.name(); }; AsyncKeyValueFileSystem.prototype.isReadOnly = function () { return false; }; AsyncKeyValueFileSystem.prototype.supportsSymlinks = function () { return false; }; AsyncKeyValueFileSystem.prototype.supportsProps = function () { return false; }; AsyncKeyValueFileSystem.prototype.supportsSynch = function () { return false; }; AsyncKeyValueFileSystem.prototype.makeRootDirectory = function (cb) { var tx = this.store.beginTransaction('readwrite'); tx.get(ROOT_NODE_ID, function (e, data) { if (e || data === undefined) { var currTime = (new Date()).getTime(), dirInode = new Inode(GenerateRandomID(), 4096, 511 | node_fs_stats_1.FileType.DIRECTORY, currTime, currTime, currTime); tx.put(dirInode.id, new Buffer("{}"), false, function (e) { if (noErrorTx(e, tx, cb)) { tx.put(ROOT_NODE_ID, dirInode.toBuffer(), false, function (e) { if (e) { tx.abort(function () { cb(e); }); } else { tx.commit(cb); } }); } }); } else { tx.commit(cb); } }); }; AsyncKeyValueFileSystem.prototype._findINode = function (tx, parent, filename, cb) { var _this = this; var handle_directory_listings = function (e, inode, dirList) { if (e) { cb(e); } else if (dirList[filename]) { cb(null, dirList[filename]); } else { cb(api_error_1.ApiError.ENOENT(path.resolve(parent, filename))); } }; if (parent === '/') { if (filename === '') { cb(null, ROOT_NODE_ID); } else { this.getINode(tx, parent, ROOT_NODE_ID, function (e, inode) { if (noError(e, cb)) { _this.getDirListing(tx, parent, inode, function (e, dirList) { handle_directory_listings(e, inode, dirList); }); } }); } } else { this.findINodeAndDirListing(tx, parent, handle_directory_listings); } }; AsyncKeyValueFileSystem.prototype.findINode = function (tx, p, cb) { var _this = this; this._findINode(tx, path.dirname(p), path.basename(p), function (e, id) { if (noError(e, cb)) { _this.getINode(tx, p, id, cb); } }); }; AsyncKeyValueFileSystem.prototype.getINode = function (tx, p, id, cb) { tx.get(id, function (e, data) { if (noError(e, cb)) { if (data === undefined) { cb(api_error_1.ApiError.ENOENT(p)); } else { cb(null, Inode.fromBuffer(data)); } } }); }; AsyncKeyValueFileSystem.prototype.getDirListing = function (tx, p, inode, cb) { if (!inode.isDirectory()) { cb(api_error_1.ApiError.ENOTDIR(p)); } else { tx.get(inode.id, function (e, data) { if (noError(e, cb)) { try { cb(null, JSON.parse(data.toString())); } catch (e) { cb(api_error_1.ApiError.ENOENT(p)); } } }); } }; AsyncKeyValueFileSystem.prototype.findINodeAndDirListing = function (tx, p, cb) { var _this = this; this.findINode(tx, p, function (e, inode) { if (noError(e, cb)) { _this.getDirListing(tx, p, inode, function (e, listing) { if (noError(e, cb)) { cb(null, inode, listing); } }); } }); }; AsyncKeyValueFileSystem.prototype.addNewNode = function (tx, data, cb) { var retries = 0, currId, reroll = function () { if (++retries === 5) { cb(new api_error_1.ApiError(api_error_1.ErrorCode.EIO, 'Unable to commit data to key-value store.')); } else { currId = GenerateRandomID(); tx.put(currId, data, false, function (e, committed) { if (e || !committed) { reroll(); } else { cb(null, currId); } }); } }; reroll(); }; AsyncKeyValueFileSystem.prototype.commitNewFile = function (tx, p, type, mode, data, cb) { var _this = this; var parentDir = path.dirname(p), fname = path.basename(p), currTime = (new Date()).getTime(); if (p === '/') { return cb(api_error_1.ApiError.EEXIST(p)); } this.findINodeAndDirListing(tx, parentDir, function (e, parentNode, dirListing) { if (noErrorTx(e, tx, cb)) { if (dirListing[fname]) { tx.abort(function () { cb(api_error_1.ApiError.EEXIST(p)); }); } else { _this.addNewNode(tx, data, function (e, dataId) { if (noErrorTx(e, tx, cb)) { var fileInode = new Inode(dataId, data.length, mode | type, currTime, currTime, currTime); _this.addNewNode(tx, fileInode.toBuffer(), function (e, fileInodeId) { if (noErrorTx(e, tx, cb)) { dirListing[fname] = fileInodeId; tx.put(parentNode.id, new Buffer(JSON.stringify(dirListing)), true, function (e) { if (noErrorTx(e, tx, cb)) { tx.commit(function (e) { if (noErrorTx(e, tx, cb)) { cb(null, fileInode); } }); } }); } }); } }); } } }); }; AsyncKeyValueFileSystem.prototype.empty = function (cb) { var _this = this; this.store.clear(function (e) { if (noError(e, cb)) { _this.makeRootDirectory(cb); } }); }; AsyncKeyValueFileSystem.prototype.rename = function (oldPath, newPath, cb) { var _this = this; var tx = this.store.beginTransaction('readwrite'), oldParent = path.dirname(oldPath), oldName = path.basename(oldPath), newParent = path.dirname(newPath), newName = path.basename(newPath), inodes = {}, lists = {}, errorOccurred = false; if ((newParent + '/').indexOf(oldPath + '/') === 0) { return cb(new api_error_1.ApiError(api_error_1.ErrorCode.EBUSY, oldParent)); } var theOleSwitcharoo = function () { if (errorOccurred || !lists.hasOwnProperty(oldParent) || !lists.hasOwnProperty(newParent)) { return; } var oldParentList = lists[oldParent], oldParentINode = inodes[oldParent], newParentList = lists[newParent], newParentINode = inodes[newParent]; if (!oldParentList[oldName]) { cb(api_error_1.ApiError.ENOENT(oldPath)); } else { var fileId = oldParentList[oldName]; delete oldParentList[oldName]; var completeRename = function () { newParentList[newName] = fileId; tx.put(oldParentINode.id, new Buffer(JSON.stringify(oldParentList)), true, function (e) { if (noErrorTx(e, tx, cb)) { if (oldParent === newParent) { tx.commit(cb); } else { tx.put(newParentINode.id, new Buffer(JSON.stringify(newParentList)), true, function (e) { if (noErrorTx(e, tx, cb)) { tx.commit(cb); } }); } } }); }; if (newParentList[newName]) { _this.getINode(tx, newPath, newParentList[newName], function (e, inode) { if (noErrorTx(e, tx, cb)) { if (inode.isFile()) { tx.del(inode.id, function (e) { if (noErrorTx(e, tx, cb)) { tx.del(newParentList[newName], function (e) { if (noErrorTx(e, tx, cb)) { completeRename(); } }); } }); } else { tx.abort(function (e) { cb(api_error_1.ApiError.EPERM(newPath)); }); } } }); } else { completeRename(); } } }; var processInodeAndListings = function (p) { _this.findINodeAndDirListing(tx, p, function (e, node, dirList) { if (e) { if (!errorOccurred) { errorOccurred = true; tx.abort(function () { cb(e); }); } } else { inodes[p] = node; lists[p] = dirList; theOleSwitcharoo(); } }); }; processInodeAndListings(oldParent); if (oldParent !== newParent) { processInodeAndListings(newParent); } }; AsyncKeyValueFileSystem.prototype.stat = function (p, isLstat, cb) { var tx = this.store.beginTransaction('readonly'); this.findINode(tx, p, function (e, inode) { if (noError(e, cb)) { cb(null, inode.toStats()); } }); }; AsyncKeyValueFileSystem.prototype.createFile = function (p, flag, mode, cb) { var _this = this; var tx = this.store.beginTransaction('readwrite'), data = new Buffer(0); this.commitNewFile(tx, p, node_fs_stats_1.FileType.FILE, mode, data, function (e, newFile) { if (noError(e, cb)) { cb(null, new AsyncKeyValueFile(_this, p, flag, newFile.toStats(), data)); } }); }; AsyncKeyValueFileSystem.prototype.openFile = function (p, flag, cb) { var _this = this; var tx = this.store.beginTransaction('readonly'); this.findINode(tx, p, function (e, inode) { if (noError(e, cb)) { tx.get(inode.id, function (e, data) { if (noError(e, cb)) { if (data === undefined) { cb(api_error_1.ApiError.ENOENT(p)); } else { cb(null, new AsyncKeyValueFile(_this, p, flag, inode.toStats(), data)); } } }); } }); }; AsyncKeyValueFileSystem.prototype.removeEntry = function (p, isDir, cb) { var _this = this; var tx = this.store.beginTransaction('readwrite'), parent = path.dirname(p), fileName = path.basename(p); this.findINodeAndDirListing(tx, parent, function (e, parentNode, parentListing) { if (noErrorTx(e, tx, cb)) { if (!parentListing[fileName]) { tx.abort(function () { cb(api_error_1.ApiError.ENOENT(p)); }); } else { var fileNodeId = parentListing[fileName]; delete parentListing[fileName]; _this.getINode(tx, p, fileNodeId, function (e, fileNode) { if (noErrorTx(e, tx, cb)) { if (!isDir && fileNode.isDirectory()) { tx.abort(function () { cb(api_error_1.ApiError.EISDIR(p)); }); } else if (isDir && !fileNode.isDirectory()) { tx.abort(function () { cb(api_error_1.ApiError.ENOTDIR(p)); }); } else { tx.del(fileNode.id, function (e) { if (noErrorTx(e, tx, cb)) { tx.del(fileNodeId, function (e) { if (noErrorTx(e, tx, cb)) { tx.put(parentNode.id, new Buffer(JSON.stringify(parentListing)), true, function (e) { if (noErrorTx(e, tx, cb)) { tx.commit(cb); } }); } }); } }); } } }); } } }); }; AsyncKeyValueFileSystem.prototype.unlink = function (p, cb) { this.removeEntry(p, false, cb); }; AsyncKeyValueFileSystem.prototype.rmdir = function (p, cb) { var _this = this; this.readdir(p, function (err, files) { if (err) { cb(err); } else if (files.length > 0) { cb(api_error_1.ApiError.ENOTEMPTY(p)); } else { _this.removeEntry(p, true, cb); } }); }; AsyncKeyValueFileSystem.prototype.mkdir = function (p, mode, cb) { var tx = this.store.beginTransaction('readwrite'), data = new Buffer('{}'); this.commitNewFile(tx, p, node_fs_stats_1.FileType.DIRECTORY, mode, data, cb); }; AsyncKeyValueFileSystem.prototype.readdir = function (p, cb) { var _this = this; var tx = this.store.beginTransaction('readonly'); this.findINode(tx, p, function (e, inode) { if (noError(e, cb)) { _this.getDirListing(tx, p, inode, function (e, dirListing) { if (noError(e, cb)) { cb(null, Object.keys(dirListing)); } }); } }); }; AsyncKeyValueFileSystem.prototype._sync = function (p, data, stats, cb) { var _this = this; var tx = this.store.beginTransaction('readwrite'); this._findINode(tx, path.dirname(p), path.basename(p), function (e, fileInodeId) { if (noErrorTx(e, tx, cb)) { _this.getINode(tx, p, fileInodeId, function (e, fileInode) { if (noErrorTx(e, tx, cb)) { var inodeChanged = fileInode.update(stats); tx.put(fileInode.id, data, true, function (e) { if (noErrorTx(e, tx, cb)) { if (inodeChanged) { tx.put(fileInodeId, fileInode.toBuffer(), true, function (e) { if (noErrorTx(e, tx, cb)) { tx.commit(cb); } }); } else { tx.commit(cb); } } }); } }); } }); }; return AsyncKeyValueFileSystem; }(file_system.BaseFileSystem)); exports.AsyncKeyValueFileSystem = AsyncKeyValueFileSystem; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5X3ZhbHVlX2ZpbGVzeXN0ZW0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZ2VuZXJpYy9rZXlfdmFsdWVfZmlsZXN5c3RlbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFPLFdBQVcsV0FBVyxxQkFBcUIsQ0FBQyxDQUFDO0FBQ3BELDBCQUFrQyxtQkFBbUIsQ0FBQyxDQUFBO0FBQ3RELDhCQUF5Qyx1QkFBdUIsQ0FBQyxDQUFBO0FBR2pFLElBQU8sSUFBSSxXQUFXLE1BQU0sQ0FBQyxDQUFDO0FBQzlCLElBQU8sS0FBSyxXQUFXLGtCQUFrQixDQUFDLENBQUM7QUFDM0MsSUFBTyxZQUFZLFdBQVcseUJBQXlCLENBQUMsQ0FBQztBQUN6RCxJQUFJLFlBQVksR0FBVyxHQUFHLENBQUM7QUFLL0I7SUFFRSxNQUFNLENBQUMsc0NBQXNDLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUM7UUFDeEUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNuRSxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4QixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFNRCxpQkFBaUIsQ0FBVyxFQUFFLEVBQXlCO0lBQ3JELEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDTixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDTixNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBTUQsbUJBQW1CLENBQVcsRUFBRSxFQUE4QixFQUFFLEVBQXlCO0lBQ3ZGLEVBQUUs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