PATH: /home/hwyuvbry/www/kerbau/assets/vendor/libs/datatables-fixedheader
FILE_BARU
CREATE
FOLDER_BARU
MKDIR
UPLOAD_FILE
GO
[ .. KEMBALI ]
📄 datatables.fixedheader.js
↓
X
📄 datatables.fixedheader.js.LICENSE.txt
↓
X
SAVING...
BERHASIL DIUBAH!
EDITING: datatables.fixedheader.js
/* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ /******/ (function() { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./libs/datatables-fixedheader/datatables.fixedheader.js": /*!***************************************************************!*\ !*** ./libs/datatables-fixedheader/datatables.fixedheader.js ***! \***************************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var datatables_net_fixedheader_js_dataTables_fixedHeader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! datatables.net-fixedheader/js/dataTables.fixedHeader */ "./node_modules/datatables.net-fixedheader/js/dataTables.fixedHeader.js"); /* harmony import */ var datatables_net_fixedheader_js_dataTables_fixedHeader__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(datatables_net_fixedheader_js_dataTables_fixedHeader__WEBPACK_IMPORTED_MODULE_0__); /***/ }), /***/ "./node_modules/datatables.net-fixedheader/js/dataTables.fixedHeader.js": /*!******************************************************************************!*\ !*** ./node_modules/datatables.net-fixedheader/js/dataTables.fixedHeader.js ***! \******************************************************************************/ /***/ (function(module, exports, __webpack_require__) { eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! FixedHeader 3.2.4\n * ©2009-2022 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary FixedHeader\n * @description Fix a table's header or footer, so it is always visible while\n * scrolling\n * @version 3.2.4\n * @author SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact www.sprymedia.co.uk\n * @copyright SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n * MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n(function( factory ){\n\tif ( true ) {\n\t\t// AMD\n\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"jquery\"), __webpack_require__(/*! datatables.net */ \"datatables.net\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t}\n\telse {}\n}(function( $, window, document, undefined ) {\n'use strict';\nvar DataTable = $.fn.dataTable;\n\n\nvar _instCounter = 0;\n\nvar FixedHeader = function ( dt, config ) {\n\t// Sanity check - you just know it will happen\n\tif ( ! (this instanceof FixedHeader) ) {\n\t\tthrow \"FixedHeader must be initialised with the 'new' keyword.\";\n\t}\n\n\t// Allow a boolean true for defaults\n\tif ( config === true ) {\n\t\tconfig = {};\n\t}\n\n\tdt = new DataTable.Api( dt );\n\n\tthis.c = $.extend( true, {}, FixedHeader.defaults, config );\n\n\tthis.s = {\n\t\tdt: dt,\n\t\tposition: {\n\t\t\ttheadTop: 0,\n\t\t\ttbodyTop: 0,\n\t\t\ttfootTop: 0,\n\t\t\ttfootBottom: 0,\n\t\t\twidth: 0,\n\t\t\tleft: 0,\n\t\t\ttfootHeight: 0,\n\t\t\ttheadHeight: 0,\n\t\t\twindowHeight: $(window).height(),\n\t\t\tvisible: true\n\t\t},\n\t\theaderMode: null,\n\t\tfooterMode: null,\n\t\tautoWidth: dt.settings()[0].oFeatures.bAutoWidth,\n\t\tnamespace: '.dtfc'+(_instCounter++),\n\t\tscrollLeft: {\n\t\t\theader: -1,\n\t\t\tfooter: -1\n\t\t},\n\t\tenable: true\n\t};\n\n\tthis.dom = {\n\t\tfloatingHeader: null,\n\t\tthead: $(dt.table().header()),\n\t\ttbody: $(dt.table().body()),\n\t\ttfoot: $(dt.table().footer()),\n\t\theader: {\n\t\t\thost: null,\n\t\t\tfloating: null,\n\t\t\tfloatingParent: $('<div class=\"dtfh-floatingparent\">'),\n\t\t\tplaceholder: null\n\t\t},\n\t\tfooter: {\n\t\t\thost: null,\n\t\t\tfloating: null,\n\t\t\tfloatingParent: $('<div class=\"dtfh-floatingparent\">'),\n\t\t\tplaceholder: null\n\t\t}\n\t};\n\n\tthis.dom.header.host = this.dom.thead.parent();\n\tthis.dom.footer.host = this.dom.tfoot.parent();\n\n\tvar dtSettings = dt.settings()[0];\n\tif ( dtSettings._fixedHeader ) {\n\t\tthrow \"FixedHeader already initialised on table \"+dtSettings.nTable.id;\n\t}\n\n\tdtSettings._fixedHeader = this;\n\n\tthis._constructor();\n};\n\n\n/*\n * Variable: FixedHeader\n * Purpose: Prototype for FixedHeader\n * Scope: global\n */\n$.extend( FixedHeader.prototype, {\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * API methods\n\t */\n\n\t/**\n\t * Kill off FH and any events\n\t */\n\tdestroy: function () {\n\t\tvar dom = this.dom;\n\n\t\tthis.s.dt.off( '.dtfc' );\n\t\t$(window).off( this.s.namespace );\n\n\t\t// Remove clones of FC blockers\n\t\tif (dom.header.rightBlocker) {\n\t\t\tdom.header.rightBlocker.remove();\n\t\t}\n\t\tif (dom.header.leftBlocker) {\n\t\t\tdom.header.leftBlocker.remove();\n\t\t}\n\t\tif (dom.footer.rightBlocker) {\n\t\t\tdom.footer.rightBlocker.remove();\n\t\t}\n\t\tif (dom.footer.leftBlocker) {\n\t\t\tdom.footer.leftBlocker.remove();\n\t\t}\n\n\t\tif ( this.c.header ) {\n\t\t\tthis._modeChange( 'in-place', 'header', true );\n\t\t}\n\n\t\tif ( this.c.footer && dom.tfoot.length ) {\n\t\t\tthis._modeChange( 'in-place', 'footer', true );\n\t\t}\n\t},\n\n\t/**\n\t * Enable / disable the fixed elements\n\t *\n\t * @param {boolean} enable `true` to enable, `false` to disable\n\t */\n\tenable: function ( enable, update )\n\t{\n\t\tthis.s.enable = enable;\n\n\t\tif ( update || update === undefined ) {\n\t\t\tthis._positions();\n\t\t\tthis._scroll( true );\n\t\t}\n\t},\n\n\t/**\n\t * Get enabled status\n\t */\n\tenabled: function ()\n\t{\n\t\treturn this.s.enable;\n\t},\n\t\n\t/**\n\t * Set header offset \n\t *\n\t * @param {int} new value for headerOffset\n\t */\n\theaderOffset: function ( offset )\n\t{\n\t\tif ( offset !== undefined ) {\n\t\t\tthis.c.headerOffset = offset;\n\t\t\tthis.update();\n\t\t}\n\n\t\treturn this.c.headerOffset;\n\t},\n\t\n\t/**\n\t * Set footer offset\n\t *\n\t * @param {int} new value for footerOffset\n\t */\n\tfooterOffset: function ( offset )\n\t{\n\t\tif ( offset !== undefined ) {\n\t\t\tthis.c.footerOffset = offset;\n\t\t\tthis.update();\n\t\t}\n\n\t\treturn this.c.footerOffset;\n\t},\n\n\t\n\t/**\n\t * Recalculate the position of the fixed elements and force them into place\n\t */\n\tupdate: function (force)\n\t{\n\t\tif (! this.s.enable) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar table = this.s.dt.table().node();\n\n\t\tif ( $(table).is(':visible') ) {\n\t\t\tthis.enable( true, false );\n\t\t}\n\t\telse {\n\t\t\tthis.enable( false, false );\n\t\t}\n\n\t\t// Don't update if header is not in the document atm (due to\n\t\t// async events)\n\t\tif ($(table).children('thead').length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._positions();\n\t\tthis._scroll( force !== undefined ? force : true );\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Constructor\n\t */\n\t\n\t/**\n\t * FixedHeader constructor - adding the required event listeners and\n\t * simple initialisation\n\t *\n\t * @private\n\t */\n\t_constructor: function ()\n\t{\n\t\tvar that = this;\n\t\tvar dt = this.s.dt;\n\n\t\t$(window)\n\t\t\t.on( 'scroll'+this.s.namespace, function () {\n\t\t\t\tthat._scroll();\n\t\t\t} )\n\t\t\t.on( 'resize'+this.s.namespace, DataTable.util.throttle( function () {\n\t\t\t\tthat.s.position.windowHeight = $(window).height();\n\t\t\t\tthat.update();\n\t\t\t}, 50 ) );\n\n\t\tvar autoHeader = $('.fh-fixedHeader');\n\t\tif ( ! this.c.headerOffset && autoHeader.length ) {\n\t\t\tthis.c.headerOffset = autoHeader.outerHeight();\n\t\t}\n\n\t\tvar autoFooter = $('.fh-fixedFooter');\n\t\tif ( ! this.c.footerOffset && autoFooter.length ) {\n\t\t\tthis.c.footerOffset = autoFooter.outerHeight();\n\t\t}\n\n\t\tdt\n\t\t\t.on( 'column-reorder.dt.dtfc column-visibility.dt.dtfc column-sizing.dt.dtfc responsive-display.dt.dtfc', function (e, ctx) {\n\t\t\t\tthat.update();\n\t\t\t} )\n\t\t\t.on( 'draw.dt.dtfc', function (e, ctx) {\n\t\t\t\t// For updates from our own table, don't reclone, but for all others, do\n\t\t\t\tthat.update(ctx === dt.settings()[0] ? false : true);\n\t\t\t} );\n\n\t\tdt.on( 'destroy.dtfc', function () {\n\t\t\tthat.destroy();\n\t\t} );\n\n\t\tthis._positions();\n\t\tthis._scroll();\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods\n\t */\n\n\t/**\n\t * Clone a fixed item to act as a place holder for the original element\n\t * which is moved into a clone of the table element, and moved around the\n\t * document to give the fixed effect.\n\t *\n\t * @param {string} item 'header' or 'footer'\n\t * @param {boolean} force Force the clone to happen, or allow automatic\n\t * decision (reuse existing if available)\n\t * @private\n\t */\n\t_clone: function ( item, force )\n\t{\n\t\tvar that = this;\n\t\tvar dt = this.s.dt;\n\t\tvar itemDom = this.dom[ item ];\n\t\tvar itemElement = item === 'header' ?\n\t\t\tthis.dom.thead :\n\t\t\tthis.dom.tfoot;\n\n\t\t// If footer and scrolling is enabled then we don't clone\n\t\t// Instead the table's height is decreased accordingly - see `_scroll()`\n\t\tif (item === 'footer' && this._scrollEnabled()) {\n\t\t\treturn;\n\t\t}\t\n\n\t\tif ( ! force && itemDom.floating ) {\n\t\t\t// existing floating element - reuse it\n\t\t\titemDom.floating.removeClass( 'fixedHeader-floating fixedHeader-locked' );\n\t\t}\n\t\telse {\n\t\t\tvar docScrollLeft = $(document).scrollLeft();\n\t\t\tvar docScrollTop = $(document).scrollTop();\n\n\t\t\tif ( itemDom.floating ) {\n\t\t\t\tif(itemDom.placeholder !== null) {\n\t\t\t\t\titemDom.placeholder.remove();\n\t\t\t\t}\n\t\t\t\tthis._unsize( item );\n\t\t\t\titemDom.floating.children().detach();\n\t\t\t\titemDom.floating.remove();\n\t\t\t}\n\n\t\t\tvar tableNode = $(dt.table().node()); \n\t\t\tvar scrollBody = $(tableNode.parent());\n\t\t\tvar scrollEnabled = this._scrollEnabled();\n\n\t\t\titemDom.floating = $( dt.table().node().cloneNode( false ) )\n\t\t\t\t.attr( 'aria-hidden', 'true' )\n\t\t\t\t.css({\n\t\t\t\t\t'table-layout': 'fixed',\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0\n\t\t\t\t})\n\t\t\t\t.removeAttr( 'id' )\n\t\t\t\t.append( itemElement );\n\n\t\t\titemDom.floatingParent\n\t\t\t\t.css({\n\t\t\t\t\twidth: scrollBody.width(),\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\theight: 'fit-content',\n\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\tleft: scrollEnabled ? tableNode.offset().left + scrollBody.scrollLeft() : 0\n\t\t\t\t})\n\t\t\t\t.css(\n\t\t\t\t\titem === 'header' ?\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttop: this.c.headerOffset,\n\t\t\t\t\t\t\tbottom: ''\n\t\t\t\t\t\t} :\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttop: '',\n\t\t\t\t\t\t\tbottom: this.c.footerOffset\n\t\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\t.addClass(item === 'footer' ? 'dtfh-floatingparentfoot' : 'dtfh-floatingparenthead')\n\t\t\t\t.append(itemDom.floating)\n\t\t\t\t.appendTo( 'body' );\n\n\t\t\tthis._stickyPosition(itemDom.floating, '-');\n\n\t\t\tvar scrollLeftUpdate = function () {\n\t\t\t\tvar scrollLeft = scrollBody.scrollLeft()\n\t\t\t\tthat.s.scrollLeft = {footer: scrollLeft, header: scrollLeft};\n\t\t\t\titemDom.floatingParent.scrollLeft(that.s.scrollLeft.header);\n\t\t\t}\n\n\t\t\tscrollLeftUpdate();\n\t\t\tscrollBody\n\t\t\t\t.off('scroll.dtfh')\n\t\t\t\t.on('scroll.dtfh', scrollLeftUpdate);\n\n\t\t\t// Insert a fake thead/tfoot into the DataTable to stop it jumping around\n\t\t\titemDom.placeholder = itemElement.clone( false );\n\t\t\titemDom.placeholder\n\t\t\t\t.find( '*[id]' )\n\t\t\t\t.removeAttr( 'id' );\n\n\t\t\titemDom.host.prepend( itemDom.placeholder );\n\n\t\t\t// Clone widths\n\t\t\tthis._matchWidths( itemDom.placeholder, itemDom.floating );\n\n\t\t\t// The above action will remove the table header, potentially causing the table to\n\t\t\t// collapse to a smaller size, before it is then re-inserted (append). The result\n\t\t\t// can be that the document, if scrolling, can \"jump\".\n\t\t\t$(document)\n\t\t\t\t.scrollTop(docScrollTop)\n\t\t\t\t.scrollLeft(docScrollLeft);\n\t\t}\n\t},\n\n\t/**\n\t * This method sets the sticky position of the header elements to match fixed columns\n\t * @param {JQuery<HTMLElement>} el \n\t * @param {string} sign \n\t */\n\t_stickyPosition: function(el, sign) {\n\t\tif (this._scrollEnabled()) {\n\t\t\tvar that = this\n\t\t\tvar rtl = $(that.s.dt.table().node()).css('direction') === 'rtl';\n\n\t\t\tel.find('th').each(function() {\n\t\t\t\t// Find out if fixed header has previously set this column\n\t\t\t\tif ($(this).css('position') === 'sticky') {\n\t\t\t\t\tvar right = $(this).css('right');\n\t\t\t\t\tvar left = $(this).css('left');\n\t\t\t\t\tif (right !== 'auto' && !rtl) {\n\t\t\t\t\t\t// New position either adds or dismisses the barWidth\n\t\t\t\t\t\tvar potential = +right.replace(/px/g, '') + (sign === '-' ? -1 : 1) * that.s.dt.settings()[0].oBrowser.barWidth;\n\t\t\t\t\t\t$(this).css('right', potential > 0 ? potential : 0);\n\t\t\t\t\t}\n\t\t\t\t\telse if(left !== 'auto' && rtl) {\n\t\t\t\t\t\tvar potential = +left.replace(/px/g, '') + (sign === '-' ? -1 : 1) * that.s.dt.settings()[0].oBrowser.barWidth;\n\t\t\t\t\t\t$(this).css('left', potential > 0 ? potential : 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * Copy widths from the cells in one element to another. This is required\n\t * for the footer as the footer in the main table takes its sizes from the\n\t * header columns. That isn't present in the footer so to have it still\n\t * align correctly, the sizes need to be copied over. It is also required\n\t * for the header when auto width is not enabled\n\t *\n\t * @param {jQuery} from Copy widths from\n\t * @param {jQuery} to Copy widths to\n\t * @private\n\t */\n\t_matchWidths: function ( from, to ) {\n\t\tvar get = function ( name ) {\n\t\t\treturn $(name, from)\n\t\t\t\t.map( function () {\n\t\t\t\t\treturn $(this).css('width').replace(/[^\\d\\.]/g, '') * 1;\n\t\t\t\t} ).toArray();\n\t\t};\n\n\t\tvar set = function ( name, toWidths ) {\n\t\t\t$(name, to).each( function ( i ) {\n\t\t\t\t$(this).css( {\n\t\t\t\t\twidth: toWidths[i],\n\t\t\t\t\tminWidth: toWidths[i]\n\t\t\t\t} );\n\t\t\t} );\n\t\t};\n\n\t\tvar thWidths = get( 'th' );\n\t\tvar tdWidths = get( 'td' );\n\n\t\tset( 'th', thWidths );\n\t\tset( 'td', tdWidths );\n\t},\n\n\t/**\n\t * Remove assigned widths from the cells in an element. This is required\n\t * when inserting the footer back into the main table so the size is defined\n\t * by the header columns and also when auto width is disabled in the\n\t * DataTable.\n\t *\n\t * @param {string} item The `header` or `footer`\n\t * @private\n\t */\n\t_unsize: function ( item ) {\n\t\tvar el = this.dom[ item ].floating;\n\n\t\tif ( el && (item === 'footer' || (item === 'header' && ! this.s.autoWidth)) ) {\n\t\t\t$('th, td', el).css( {\n\t\t\t\twidth: '',\n\t\t\t\tminWidth: ''\n\t\t\t} );\n\t\t}\n\t\telse if ( el && item === 'header' ) {\n\t\t\t$('th, td', el).css( 'min-width', '' );\n\t\t}\n\t},\n\n\t/**\n\t * Reposition the floating elements to take account of horizontal page\n\t * scroll\n\t *\n\t * @param {string} item The `header` or `footer`\n\t * @param {int} scrollLeft Document scrollLeft\n\t * @private\n\t */\n\t_horizontal: function ( item, scrollLeft )\n\t{\n\t\tvar itemDom = this.dom[ item ];\n\t\tvar position = this.s.position;\n\t\tvar lastScrollLeft = this.s.scrollLeft;\n\n\t\tif ( itemDom.floating && lastScrollLeft[ item ] !== scrollLeft ) {\n\t\t\t// If scrolling is enabled we need to match the floating header to the body\n\t\t\tif (this._scrollEnabled()) {\n\t\t\t\tvar newScrollLeft = $($(this.s.dt.table().node()).parent()).scrollLeft()\n\t\t\t\titemDom.floating.scrollLeft(newScrollLeft);\n\t\t\t\titemDom.floatingParent.scrollLeft(newScrollLeft);\n\t\t\t}\n\n\t\t\tlastScrollLeft[ item ] = scrollLeft;\n\t\t}\n\t},\n\n\t/**\n\t * Change from one display mode to another. Each fixed item can be in one\n\t * of:\n\t *\n\t * * `in-place` - In the main DataTable\n\t * * `in` - Floating over the DataTable\n\t * * `below` - (Header only) Fixed to the bottom of the table body\n\t * * `above` - (Footer only) Fixed to the top of the table body\n\t * \n\t * @param {string} mode Mode that the item should be shown in\n\t * @param {string} item 'header' or 'footer'\n\t * @param {boolean} forceChange Force a redraw of the mode, even if already\n\t * in that mode.\n\t * @private\n\t */\n\t_modeChange: function ( mode, item, forceChange )\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar itemDom = this.dom[ item ];\n\t\tvar position = this.s.position;\n\n\t\t// Just determine if scroll is enabled once\n\t\tvar scrollEnabled = this._scrollEnabled();\n\n\t\t// If footer and scrolling is enabled then we don't clone\n\t\t// Instead the table's height is decreased accordingly - see `_scroll()`\n\t\tif (item === 'footer' && scrollEnabled) {\n\t\t\treturn;\n\t\t}\t\t\n\n\t\t// It isn't trivial to add a !important css attribute...\n\t\tvar importantWidth = function (w) {\n\t\t\titemDom.floating.attr('style', function(i,s) {\n\t\t\t\treturn (s || '') + 'width: '+w+'px !important;';\n\t\t\t});\n\n\t\t\t// If not scrolling also have to update the floatingParent\n\t\t\tif (!scrollEnabled) {\n\t\t\t\titemDom.floatingParent.attr('style', function(i,s) {\n\t\t\t\t\treturn (s || '') + 'width: '+w+'px !important;';\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\t// Record focus. Browser's will cause input elements to loose focus if\n\t\t// they are inserted else where in the doc\n\t\tvar tablePart = this.dom[ item==='footer' ? 'tfoot' : 'thead' ];\n\t\tvar focus = $.contains( tablePart[0], document.activeElement ) ?\n\t\t\tdocument.activeElement :\n\t\t\tnull;\n\t\tvar scrollBody = $($(this.s.dt.table().node()).parent());\n\n\t\tif ( mode === 'in-place' ) {\n\t\t\t// Insert the header back into the table's real header\n\t\t\tif ( itemDom.placeholder ) {\n\t\t\t\titemDom.placeholder.remove();\n\t\t\t\titemDom.placeholder = null;\n\t\t\t}\n\n\t\t\tthis._unsize( item );\n\n\t\t\tif ( item === 'header' ) {\n\t\t\t\titemDom.host.prepend( tablePart );\n\t\t\t}\n\t\t\telse {\n\t\t\t\titemDom.host.append( tablePart );\n\t\t\t}\n\n\t\t\tif ( itemDom.floating ) {\n\t\t\t\titemDom.floating.remove();\n\t\t\t\titemDom.floating = null;\n\t\t\t\tthis._stickyPosition(itemDom.host, '+');\n\t\t\t}\n\n\t\t\tif ( itemDom.floatingParent ) {\n\t\t\t\titemDom.floatingParent.remove();\n\t\t\t}\n\n\t\t\t$($(itemDom.host.parent()).parent()).scrollLeft(scrollBody.scrollLeft())\n\t\t}\n\t\telse if ( mode === 'in' ) {\n\t\t\t// Remove the header from the read header and insert into a fixed\n\t\t\t// positioned floating table clone\n\t\t\tthis._clone( item, forceChange );\n\n\t\t\t// Get useful position values\n\t\t\tvar scrollOffset = scrollBody.offset();\n\t\t\tvar windowTop = $(document).scrollTop();\n\t\t\tvar windowHeight = $(window).height();\n\t\t\tvar windowBottom = windowTop + windowHeight;\n\t\t\tvar bodyTop = scrollEnabled ? scrollOffset.top : position.tbodyTop;\n\t\t\tvar bodyBottom = scrollEnabled ? scrollOffset.top + scrollBody.outerHeight() : position.tfootTop\n\n\t\t\t// Calculate the amount that the footer or header needs to be shuffled\n\t\t\tvar shuffle = item === 'footer' ?\n\t\t\t\t// footer and top of body isn't on screen\n\t\t\t\tbodyTop > windowBottom ?\n\t\t\t\t\t// Yes - push the footer below\n\t\t\t\t\tposition.tfootHeight :\n\t\t\t\t\t// No - bottom set to the gap between the top of the body and the bottom of the window\n\t\t\t\t\tbodyTop + position.tfootHeight - windowBottom :\n\t\t\t\t// Otherwise must be a header so get the difference from the bottom of the\n\t\t\t\t// desired floating header and the bottom of the table body\n\t\t\t\twindowTop + this.c.headerOffset + position.theadHeight - bodyBottom\n\t\t\t\t\n\t\t\t// Set the top or bottom based off of the offset and the shuffle value\n\t\t\tvar prop = item === 'header' ? 'top' : 'bottom';\n\t\t\tvar val = this.c[item+'Offset'] - (shuffle > 0 ? shuffle : 0);\n\n\t\t\titemDom.floating.addClass( 'fixedHeader-floating' );\n\t\t\titemDom.floatingParent\n\t\t\t\t.css(prop, val)\n\t\t\t\t.css( {\n\t\t\t\t\t'left': position.left,\n\t\t\t\t\t'height': item === 'header' ? position.theadHeight : position.tfootHeight,\n\t\t\t\t\t'z-index': 2\n\t\t\t\t})\n\t\t\t\t.append(itemDom.floating);\n\n\t\t\timportantWidth(position.width);\n\n\t\t\tif ( item === 'footer' ) {\n\t\t\t\titemDom.floating.css( 'top', '' );\n\t\t\t}\n\t\t}\n\t\telse if ( mode === 'below' ) { // only used for the header\n\t\t\t// Fix the position of the floating header at base of the table body\n\t\t\tthis._clone( item, forceChange );\n\n\t\t\titemDom.floating.addClass( 'fixedHeader-locked' );\n\t\t\titemDom.floatingParent.css({\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: position.tfootTop - position.theadHeight,\n\t\t\t\tleft: position.left+'px'\n\t\t\t});\n\n\t\t\timportantWidth(position.width);\n\t\t}\n\t\telse if ( mode === 'above' ) { // only used for the footer\n\t\t\t// Fix the position of the floating footer at top of the table body\n\t\t\tthis._clone( item, forceChange );\n\n\t\t\titemDom.floating.addClass( 'fixedHeader-locked' );\n\t\t\titemDom.floatingParent.css({\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: position.tbodyTop,\n\t\t\t\tleft: position.left+'px'\n\t\t\t});\n\n\t\t\timportantWidth(position.width);\n\t\t}\n\n\t\t// Restore focus if it was lost\n\t\tif ( focus && focus !== document.activeElement ) {\n\t\t\tsetTimeout( function () {\n\t\t\t\tfocus.focus();\n\t\t\t}, 10 );\n\t\t}\n\n\t\tthis.s.scrollLeft.header = -1;\n\t\tthis.s.scrollLeft.footer = -1;\n\t\tthis.s[item+'Mode'] = mode;\n\t},\n\n\t/**\n\t * Cache the positional information that is required for the mode\n\t * calculations that FixedHeader performs.\n\t *\n\t * @private\n\t */\n\t_positions: function ()\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar table = dt.table();\n\t\tvar position = this.s.position;\n\t\tvar dom = this.dom;\n\t\tvar tableNode = $(table.node());\n\t\tvar scrollEnabled = this._scrollEnabled();\n\n\t\t// Need to use the header and footer that are in the main table,\n\t\t// regardless of if they are clones, since they hold the positions we\n\t\t// want to measure from\n\t\tvar thead = $(dt.table().header());\n\t\tvar tfoot = $(dt.table().footer());\n\t\tvar tbody = dom.tbody;\n\t\tvar scrollBody = tableNode.parent();\n\n\t\tposition.visible = tableNode.is(':visible');\n\t\tposition.width = tableNode.outerWidth();\n\t\tposition.left = tableNode.offset().left;\n\t\tposition.theadTop = thead.offset().top;\n\t\tposition.tbodyTop = scrollEnabled ? scrollBody.offset().top : tbody.offset().top;\n\t\tposition.tbodyHeight = scrollEnabled ? scrollBody.outerHeight() : tbody.outerHeight();\n\t\tposition.theadHeight = thead.outerHeight();\n\t\tposition.theadBottom = position.theadTop + position.theadHeight;\n\n\t\tif ( tfoot.length ) {\n\t\t\tposition.tfootTop = position.tbodyTop + position.tbodyHeight; //tfoot.offset().top;\n\t\t\tposition.tfootBottom = position.tfootTop + tfoot.outerHeight();\n\t\t\tposition.tfootHeight = tfoot.outerHeight();\n\t\t}\n\t\telse {\n\t\t\tposition.tfootTop = position.tbodyTop + tbody.outerHeight();\n\t\t\tposition.tfootBottom = position.tfootTop;\n\t\t\tposition.tfootHeight = position.tfootTop;\n\t\t}\n\t},\n\n\n\t/**\n\t * Mode calculation - determine what mode the fixed items should be placed\n\t * into.\n\t *\n\t * @param {boolean} forceChange Force a redraw of the mode, even if already\n\t * in that mode.\n\t * @private\n\t */\n\t_scroll: function ( forceChange )\n\t{\n\t\tif (this.s.dt.settings()[0].bDestroying) {\n\t\t\treturn;\n\t\t}\n\n\t\t// ScrollBody details\n\t\tvar scrollEnabled = this._scrollEnabled();\n\t\tvar scrollBody = $(this.s.dt.table().node()).parent();\n\t\tvar scrollOffset = scrollBody.offset();\n\t\tvar scrollHeight = scrollBody.outerHeight();\n\n\t\t// Window details\n\t\tvar windowLeft = $(document).scrollLeft();\n\t\tvar windowTop = $(document).scrollTop();\n\t\tvar windowHeight = $(window).height();\n\t\tvar windowBottom = windowHeight + windowTop\n\n\n\t\tvar position = this.s.position;\n\t\tvar headerMode, footerMode;\n\n\t\t// Body Details\n\t\tvar bodyTop = (scrollEnabled ? scrollOffset.top : position.tbodyTop);\n\t\tvar bodyLeft = (scrollEnabled ? scrollOffset.left : position.left);\n\t\tvar bodyBottom = (scrollEnabled ? scrollOffset.top + scrollHeight : position.tfootTop);\n\t\tvar bodyWidth = (scrollEnabled ? scrollBody.outerWidth() : position.tbodyWidth);\n\n\t\tvar windowBottom = windowTop + windowHeight;\n\n\t\tif ( this.c.header ) {\n\t\t\tif ( ! this.s.enable ) {\n\t\t\t\theaderMode = 'in-place';\n\t\t\t}\n\t\t\t// The header is in it's normal place if the body top is lower than\n\t\t\t// the scroll of the window plus the headerOffset and the height of the header\n\t\t\telse if ( ! position.visible || windowTop + this.c.headerOffset + position.theadHeight <= bodyTop) {\n\t\t\t\theaderMode = 'in-place';\n\t\t\t}\n\t\t\t// The header should be floated if\n\t\t\telse if (\n\t\t\t\t// The scrolling plus the header offset plus the height of the header is lower than the top of the body\n\t\t\t\twindowTop + this.c.headerOffset + position.theadHeight > bodyTop &&\n\t\t\t\t// And the scrolling at the top plus the header offset is above the bottom of the body\n\t\t\t\twindowTop + this.c.headerOffset + position.theadHeight < bodyBottom\n\t\t\t) {\n\t\t\t\theaderMode = 'in';\n\t\t\t\tvar scrollBody = $($(this.s.dt.table().node()).parent());\n\n\t\t\t\t// Further to the above, If the scrolling plus the header offset plus the header height is lower\n\t\t\t\t// than the bottom of the table a shuffle is required so have to force the calculation\n\t\t\t\tif(windowTop + this.c.headerOffset + position.theadHeight > bodyBottom || this.dom.header.floatingParent === undefined){\n\t\t\t\t\tforceChange = true;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.dom.header.floatingParent\n\t\t\t\t\t\t.css({\n\t\t\t\t\t\t\t'top': this.c.headerOffset,\n\t\t\t\t\t\t\t'position': 'fixed'\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.append(this.dom.header.floating);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Anything else and the view is below the table\n\t\t\telse {\n\t\t\t\theaderMode = 'below';\n\t\t\t}\n\n\t\t\tif ( forceChange || headerMode !== this.s.headerMode ) {\n\t\t\t\tthis._modeChange( headerMode, 'header', forceChange );\n\t\t\t}\n\n\t\t\tthis._horizontal( 'header', windowLeft );\n\t\t}\n\n\t\tvar header = {\n\t\t\toffset: {top: 0, left: 0},\n\t\t\theight: 0\n\t\t}\n\t\tvar footer = {\n\t\t\toffset: {top: 0, left: 0},\n\t\t\theight: 0\n\t\t}\n\n\t\tif ( this.c.footer && this.dom.tfoot.length ) {\n\t\t\tif ( ! this.s.enable ) {\n\t\t\t\tfooterMode = 'in-place';\n\t\t\t}\n\t\t\telse if ( ! position.visible || position.tfootBottom + this.c.footerOffset <= windowBottom ) {\n\t\t\t\tfooterMode = 'in-place';\n\t\t\t}\n\t\t\telse if (\n\t\t\t\tbodyBottom + position.tfootHeight + this.c.footerOffset > windowBottom &&\n\t\t\t\tbodyTop + this.c.footerOffset < windowBottom\n\t\t\t) {\n\t\t\t\tfooterMode = 'in';\n\t\t\t\tforceChange = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfooterMode = 'above';\n\t\t\t}\n\t\t\t\n\t\t\tif ( forceChange || footerMode !== this.s.footerMode ) {\n\t\t\t\tthis._modeChange( footerMode, 'footer', forceChange );\n\t\t\t}\n\n\t\t\tthis._horizontal( 'footer', windowLeft );\n\t\t\t\n\t\t\tvar getOffsetHeight = function (el) {\n\t\t\t\treturn {\n\t\t\t\t\toffset: el.offset(),\n\t\t\t\t\theight: el.outerHeight()\n\t\t\t\t};\n\t\t\t};\n\t\t\n\t\t\theader = this.dom.header.floating ? getOffsetHeight(this.dom.header.floating) : getOffsetHeight(this.dom.thead);\n\t\t\tfooter = this.dom.footer.floating ? getOffsetHeight(this.dom.footer.floating) : getOffsetHeight(this.dom.tfoot);\n\n\t\t\t// If scrolling is enabled and the footer is off the screen\n\t\t\tif (scrollEnabled && footer.offset.top > windowTop){// && footer.offset.top >= windowBottom) {\n\t\t\t\t// Calculate the gap between the top of the scrollBody and the top of the window\n\t\t\t\tvar overlap = windowTop - scrollOffset.top;\n\t\t\t\t// The new height is the bottom of the window\n\t\t\t\tvar newHeight = windowBottom +\n\t\t\t\t\t// If the gap between the top of the scrollbody and the window is more than\n\t\t\t\t\t// the height of the header then the top of the table is still visible so add that gap\n\t\t\t\t\t// Doing this has effectively calculated the height from the top of the table to the bottom of the current page\n\t\t\t\t\t(overlap > -header.height ? overlap : 0) -\n\t\t\t\t\t// Take from that\n\t\t\t\t\t(\n\t\t\t\t\t\t// The top of the header plus\n\t\t\t\t\t\theader.offset.top +\n\t\t\t\t\t\t// The header height if the standard header is present\n\t\t\t\t\t\t(overlap < -header.height ? header.height : 0) +\n\t\t\t\t\t\t// And the height of the footer\n\t\t\t\t\t\tfooter.height\n\t\t\t\t\t)\n\n\t\t\t\t\t// Don't want a negative height\n\t\t\t\tif (newHeight < 0) {\n\t\t\t\t\tnewHeight = 0;\n\t\t\t\t}\n\n\t\t\t\t// At the end of the above calculation the space between the header (top of the page if floating)\n\t\t\t\t// and the point just above the footer should be the new value for the height of the table.\n\t\t\t\tscrollBody.outerHeight(newHeight);\n\t\t\t\t\n\t\t\t\t// Need some rounding here as sometimes very small decimal places are encountered\n\t\t\t\t// If the actual height is bigger or equal to the height we just applied then the footer is \"Floating\"\n\t\t\t\tif(Math.round(scrollBody.outerHeight()) >= Math.round(newHeight)) {\n\t\t\t\t\t$(this.dom.tfoot.parent()).addClass(\"fixedHeader-floating\");\n\t\t\t\t}\n\t\t\t\t// Otherwise max-width has kicked in so it is not floating\n\t\t\t\telse {\n\t\t\t\t\t$(this.dom.tfoot.parent()).removeClass(\"fixedHeader-floating\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(this.dom.header.floating){\n\t\t\tthis.dom.header.floatingParent.css('left', bodyLeft-windowLeft);\n\t\t}\n\t\tif(this.dom.footer.floating){\n\t\t\tthis.dom.footer.floatingParent.css('left', bodyLeft-windowLeft);\n\t\t}\n\n\t\t// If fixed columns is being used on this table then the blockers need to be copied across\n\t\t// Cloning these is cleaner than creating as our own as it will keep consistency with fixedColumns automatically\n\t\t// ASSUMING that the class remains the same\n\t\tif (this.s.dt.settings()[0]._fixedColumns !== undefined) {\n\t\t\tvar adjustBlocker = function (side, end, el) {\n\t\t\t\tif (el === undefined) {\n\t\t\t\t\tvar blocker = $('div.dtfc-'+side+'-'+end+'-blocker');\n\n\t\t\t\t\tel = blocker.length === 0 ?\n\t\t\t\t\t\tnull :\n\t\t\t\t\t\tblocker.clone().appendTo('body').css('z-index', 1);\n\t\t\t\t}\n\n\t\t\t\tif(el !== null) {\n\t\t\t\t\tel.css({\n\t\t\t\t\t\ttop: end === 'top' ? header.offset.top : footer.offset.top,\n\t\t\t\t\t\tleft: side === 'right' ? bodyLeft + bodyWidth - el.width() : bodyLeft\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn el;\n\t\t\t}\n\n\t\t\t// Adjust all blockers\n\t\t\tthis.dom.header.rightBlocker = adjustBlocker('right', 'top', this.dom.header.rightBlocker);\n\t\t\tthis.dom.header.leftBlocker = adjustBlocker('left', 'top', this.dom.header.leftBlocker);\n\t\t\tthis.dom.footer.rightBlocker = adjustBlocker('right', 'bottom', this.dom.footer.rightBlocker);\n\t\t\tthis.dom.footer.leftBlocker = adjustBlocker('left', 'bottom', this.dom.footer.leftBlocker);\n\t\t}\n\t},\n\n\t/**\n\t * Function to check if scrolling is enabled on the table or not\n\t * @returns Boolean value indicating if scrolling on the table is enabled or not\n\t */\n\t_scrollEnabled: function() {\n\t\tvar oScroll = this.s.dt.settings()[0].oScroll;\n\t\tif(oScroll.sY !== \"\" || oScroll.sX !== \"\") {\n\t\t\treturn true;\n\t\t}\n\t\treturn false\n\t}\n} );\n\n\n/**\n * Version\n * @type {String}\n * @static\n */\nFixedHeader.version = \"3.2.4\";\n\n/**\n * Defaults\n * @type {Object}\n * @static\n */\nFixedHeader.defaults = {\n\theader: true,\n\tfooter: false,\n\theaderOffset: 0,\n\tfooterOffset: 0\n};\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * DataTables interfaces\n */\n\n// Attach for constructor access\n$.fn.dataTable.FixedHeader = FixedHeader;\n$.fn.DataTable.FixedHeader = FixedHeader;\n\n\n// DataTables creation - check if the FixedHeader option has been defined on the\n// table and if so, initialise\n$(document).on( 'init.dt.dtfh', function (e, settings, json) {\n\tif ( e.namespace !== 'dt' ) {\n\t\treturn;\n\t}\n\n\tvar init = settings.oInit.fixedHeader;\n\tvar defaults = DataTable.defaults.fixedHeader;\n\n\tif ( (init || defaults) && ! settings._fixedHeader ) {\n\t\tvar opts = $.extend( {}, defaults, init );\n\n\t\tif ( init !== false ) {\n\t\t\tnew FixedHeader( settings, opts );\n\t\t}\n\t}\n} );\n\n// DataTables API methods\nDataTable.Api.register( 'fixedHeader()', function () {} );\n\nDataTable.Api.register( 'fixedHeader.adjust()', function () {\n\treturn this.iterator( 'table', function ( ctx ) {\n\t\tvar fh = ctx._fixedHeader;\n\n\t\tif ( fh ) {\n\t\t\tfh.update();\n\t\t}\n\t} );\n} );\n\nDataTable.Api.register( 'fixedHeader.enable()', function ( flag ) {\n\treturn this.iterator( 'table', function ( ctx ) {\n\t\tvar fh = ctx._fixedHeader;\n\n\t\tflag = ( flag !== undefined ? flag : true );\n\t\tif ( fh && flag !== fh.enabled() ) {\n\t\t\tfh.enable( flag );\n\t\t}\n\t} );\n} );\n\nDataTable.Api.register( 'fixedHeader.enabled()', function () {\n\tif ( this.context.length ) {\n\t\tvar fh = this.context[0]._fixedHeader;\n\n\t\tif ( fh ) {\n\t\t\treturn fh.enabled();\n\t\t}\n\t}\n\n\treturn false;\n} );\n\nDataTable.Api.register( 'fixedHeader.disable()', function ( ) {\n\treturn this.iterator( 'table', function ( ctx ) {\n\t\tvar fh = ctx._fixedHeader;\n\n\t\tif ( fh && fh.enabled() ) {\n\t\t\tfh.enable( false );\n\t\t}\n\t} );\n} );\n\n$.each( ['header', 'footer'], function ( i, el ) {\n\tDataTable.Api.register( 'fixedHeader.'+el+'Offset()', function ( offset ) {\n\t\tvar ctx = this.context;\n\n\t\tif ( offset === undefined ) {\n\t\t\treturn ctx.length && ctx[0]._fixedHeader ?\n\t\t\t\tctx[0]._fixedHeader[el +'Offset']() :\n\t\t\t\tundefined;\n\t\t}\n\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\tvar fh = ctx._fixedHeader;\n\n\t\t\tif ( fh ) {\n\t\t\t\tfh[ el +'Offset' ]( offset );\n\t\t\t}\n\t\t} );\n\t} );\n} );\n\n\nreturn FixedHeader;\n}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZGF0YXRhYmxlcy5uZXQtZml4ZWRoZWFkZXIvanMvZGF0YVRhYmxlcy5maXhlZEhlYWRlci5qcy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNLElBQTBDO0FBQ2hEO0FBQ0EsRUFBRSxpQ0FBUSxDQUFDLDJDQUFRLEVBQUUsMkRBQWdCLENBQUMsbUNBQUU7QUFDeEM7QUFDQSxHQUFHO0FBQUEsa0dBQUU7QUFDTDtBQUNBLE1BQU0sRUFpQko7QUFDRixDQUFDO0FBQ0Q7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSw0QkFBNEI7O0FBRTVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7OztBQUdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBLEVBQUU7OztBQUdGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxZQUFZLHFCQUFxQjtBQUNqQyxZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsU0FBUztBQUN0QixhQUFhLFNBQVM7QUFDdEIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRDtBQUNsRCxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRCxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlFQUFpRTtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxZQUFZLGdCQUFnQjtBQUM1QjtBQUNBO0FBQ0E7QUFDQSxZQUFZLGdCQUFnQjtBQUM1QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdURBQXVEO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7OztBQUdGO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBeUI7O0FBRXpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBLHdEQUF3RDs7QUFFeEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSCxFQUFFOzs7QUFHRjtBQUNBLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9WdWV4eS8uL25vZGVfbW9kdWxlcy9kYXRhdGFibGVzLm5ldC1maXhlZGhlYWRlci9qcy9kYXRhVGFibGVzLmZpeGVkSGVhZGVyLmpzPzhkNjgiXSwic291cmNlc0NvbnRlbnQiOlsiLyohIEZpeGVkSGVhZGVyIDMuMi40XG4gKiDCqTIwMDktMjAyMiBTcHJ5TWVkaWEgTHRkIC0gZGF0YXRhYmxlcy5uZXQvbGljZW5zZVxuICovXG5cbi8qKlxuICogQHN1bW1hcnkgICAgIEZpeGVkSGVhZGVyXG4gKiBAZGVzY3JpcHRpb24gRml4IGEgdGFibGUncyBoZWFkZXIgb3IgZm9vdGVyLCBzbyBpdCBpcyBhbHdheXMgdmlzaWJsZSB3aGlsZVxuICogICAgICAgICAgICAgIHNjcm9sbGluZ1xuICogQHZlcnNpb24gICAgIDMuMi40XG4gKiBAYXV0aG9yICAgICAgU3ByeU1lZGlhIEx0ZCAod3d3LnNwcnltZWRpYS5jby51aylcbiAqIEBjb250YWN0ICAgICB3d3cuc3ByeW1lZGlhLmNvLnVrXG4gKiBAY29weXJpZ2h0ICAgU3ByeU1lZGlhIEx0ZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBmaWxlIGlzIGZyZWUgc29mdHdhcmUsIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIGxpY2Vuc2U6XG4gKiAgIE1JVCBsaWNlbnNlIC0gaHR0cDovL2RhdGF0YWJsZXMubmV0L2xpY2Vuc2UvbWl0XG4gKlxuICogVGhpcyBzb3VyY2UgZmlsZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXRcbiAqIFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZXG4gKiBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBsaWNlbnNlIGZpbGVzIGZvciBkZXRhaWxzLlxuICpcbiAqIEZvciBkZXRhaWxzIHBsZWFzZSByZWZlciB0bzogaHR0cDovL3d3dy5kYXRhdGFibGVzLm5ldFxuICovXG5cbihmdW5jdGlvbiggZmFjdG9yeSApe1xuXHRpZiAoIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCApIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoIFsnanF1ZXJ5JywgJ2RhdGF0YWJsZXMubmV0J10sIGZ1bmN0aW9uICggJCApIHtcblx0XHRcdHJldHVybiBmYWN0b3J5KCAkLCB3aW5kb3csIGRvY3VtZW50ICk7XG5cdFx0fSApO1xuXHR9XG5cdGVsc2UgaWYgKCB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChyb290LCAkKSB7XG5cdFx0XHRpZiAoICEgcm9vdCApIHtcblx0XHRcdFx0cm9vdCA9IHdpbmRvdztcblx0XHRcdH1cblxuXHRcdFx0aWYgKCAhICQgfHwgISAkLmZuLmRhdGFUYWJsZSApIHtcblx0XHRcdFx0JCA9IHJlcXVpcmUoJ2RhdGF0YWJsZXMubmV0Jykocm9vdCwgJCkuJDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZhY3RvcnkoICQsIHJvb3QsIHJvb3QuZG9jdW1lbnQgKTtcblx0XHR9O1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEJyb3dzZXJcblx0XHRmYWN0b3J5KCBqUXVlcnksIHdpbmRvdywgZG9jdW1lbnQgKTtcblx0fVxufShmdW5jdGlvbiggJCwgd2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkICkge1xuJ3VzZSBzdHJpY3QnO1xudmFyIERhdGFUYWJsZSA9ICQuZm4uZGF0YVRhYmxlO1xuXG5cbnZhciBfaW5zdENvdW50ZXIgPSAwO1xuXG52YXIgRml4ZWRIZWFkZXIgPSBmdW5jdGlvbiAoIGR0LCBjb25maWcgKSB7XG5cdC8vIFNhbml0eSBjaGVjayAtIHlvdSBqdXN0IGtub3cgaXQgd2lsbCBoYXBwZW5cblx0aWYgKCAhICh0aGlzIGluc3RhbmNlb2YgRml4ZWRIZWFkZXIpICkge1xuXHRcdHRocm93IFwiRml4ZWRIZWFkZXIgbXVzdCBiZSBpbml0aWFsaXNlZCB3aXRoIHRoZSAnbmV3JyBrZXl3b3JkLlwiO1xuXHR9XG5cblx0Ly8gQWxsb3cgYSBib29sZWFuIHRydWUgZm9yIGRlZmF1bHRzXG5cdGlmICggY29uZmlnID09PSB0cnVlICkge1xuXHRcdGNvbmZpZyA9IHt9O1xuXHR9XG5cblx0ZHQgPSBuZXcgRGF0YVRhYmxlLkFwaSggZHQgKTtcblxuXHR0aGlzLmMgPSAkLmV4dGVuZCggdHJ1ZSwge30sIEZpeGVkSGVhZGVyLmRlZmF1bHRzLCBjb25maWcgKTtcblxuXHR0aGlzLnMgPSB7XG5cdFx0ZHQ6IGR0LFxuXHRcdHBvc2l0aW9uOiB7XG5cdFx0XHR0aGVhZFRvcDogMCxcblx0XHRcdHRib2R5VG9wOiAwLFxuXHRcdFx0dGZvb3RUb3A6IDAsXG5cdFx0XHR0Zm9vdEJvdHRvbTogMCxcblx0XHRcdHdpZHRoOiAwLFxuXHRcdFx0bGVmdDogMCxcblx0XHRcdHRmb290SGVpZ2h0OiAwLFxuXHRcdFx0dGhlYWRIZWlnaHQ6IDAsXG5cdFx0XHR3aW5kb3dIZWlnaHQ6ICQod2luZG93KS5oZWlnaHQoKSxcblx0XHRcdHZpc2libGU6IHRydWVcblx0XHR9LFxuXHRcdGhlYWRlck1vZGU6IG51bGwsXG5cdFx0Zm9vdGVyTW9kZTogbnVsbCxcblx0XHRhdXRvV2lkdGg6IGR0LnNldHRpbmdzKClbMF0ub0ZlYXR1cmVzLmJBdXRvV2lkdGgsXG5cdFx0bmFtZXNwYWNlOiAnLmR0ZmMnKyhfaW5zdENvdW50ZXIrKyksXG5cdFx0c2Nyb2xsTGVmdDoge1xuXHRcdFx0aGVhZGVyOiAtMSxcblx0XHRcdGZvb3RlcjogLTFcblx0XHR9LFxuXHRcdGVuYWJsZTogdHJ1ZVxuXHR9O1xuXG5cdHRoaXMuZG9tID0ge1xuXHRcdGZsb2F0aW5nSGVhZGVyOiBudWxsLFxuXHRcdHRoZWFkOiAkKGR0LnRhYmxlKCkuaGVhZGVyKCkpLFxuXHRcdHRib2R5OiAkKGR0LnRhYmxlKCkuYm9keSgpKSxcblx0XHR0Zm9vdDogJChkdC50YWJsZSgpLmZvb3RlcigpKSxcblx0XHRoZWFkZXI6IHtcblx0XHRcdGhvc3Q6IG51bGwsXG5cdFx0XHRmbG9hdGluZzogbnVsbCxcblx0XHRcdGZsb2F0aW5nUGFyZW50OiAkKCc8ZGl2IGNsYXNzPVwiZHRmaC1mbG9hdGluZ3BhcmVudFwiPicpLFxuXHRcdFx0cGxhY2Vob2xkZXI6IG51bGxcblx0XHR9LFxuXHRcdGZvb3Rlcjoge1xuXHRcdFx0aG9zdDogbnVsbCxcblx0XHRcdGZsb2F0aW5nOiBudWxsLFxuXHRcdFx0ZmxvYXRpbmdQYXJlbnQ6ICQoJzxkaXYgY2xhc3M9XCJkdGZoLWZsb2F0aW5ncGFyZW50XCI+JyksXG5cdFx0XHRwbGFjZWhvbGRlcjogbnVsbFxuXHRcdH1cblx0fTtcblxuXHR0aGlzLmRvbS5oZWFkZXIuaG9zdCA9IHRoaXMuZG9tLnRoZWFkLnBhcmVudCgpO1xuXHR0aGlzLmRvbS5mb290ZXIuaG9zdCA9IHRoaXMuZG9tLnRmb290LnBhcmVudCgpO1xuXG5cdHZhciBkdFNldHRpbmdzID0gZHQuc2V0dGluZ3MoKVswXTtcblx0aWYgKCBkdFNldHRpbmdzLl9maXhlZEhlYWRlciApIHtcblx0XHR0aHJvdyBcIkZpeGVkSGVhZGVyIGFscmVhZHkgaW5pdGlhbGlzZWQgb24gdGFibGUgXCIrZHRTZXR0aW5ncy5uVGFibGUuaWQ7XG5cdH1cblxuXHRkdFNldHRpbmdzLl9maXhlZEhlYWRlciA9IHRoaXM7XG5cblx0dGhpcy5fY29uc3RydWN0b3IoKTtcbn07XG5cblxuLypcbiAqIFZhcmlhYmxlOiBGaXhlZEhlYWRlclxuICogUHVycG9zZTogIFByb3RvdHlwZSBmb3IgRml4ZWRIZWFkZXJcbiAqIFNjb3BlOiAgICBnbG9iYWxcbiAqL1xuJC5leHRlbmQoIEZpeGVkSGVhZGVyLnByb3RvdHlwZSwge1xuXHQvKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKlxuXHQgKiBBUEkgbWV0aG9kc1xuXHQgKi9cblxuXHQvKipcblx0ICogS2lsbCBvZmYgRkggYW5kIGFueSBldmVudHNcblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgZG9tID0gdGhpcy5kb207XG5cblx0XHR0aGlzLnMuZHQub2ZmKCAnLmR0ZmMnICk7XG5cdFx0JCh3aW5kb3cpLm9mZiggdGhpcy5zLm5hbWVzcGFjZSApO1xuXG5cdFx0Ly8gUmVtb3ZlIGNsb25lcyBvZiBGQyBibG9ja2Vyc1xuXHRcdGlmIChkb20uaGVhZGVyLnJpZ2h0QmxvY2tlcikge1xuXHRcdFx0ZG9tLmhlYWRlci5yaWdodEJsb2NrZXIucmVtb3ZlKCk7XG5cdFx0fVxuXHRcdGlmIChkb20uaGVhZGVyLmxlZnRCbG9ja2VyKSB7XG5cdFx0XHRkb20uaGVhZGVyLmxlZnRCbG9ja2VyLnJlbW92ZSgpO1xuXHRcdH1cblx0XHRpZiAoZG9tLmZvb3Rlci5yaWdodEJsb2NrZXIpIHtcblx0XHRcdGRvbS5mb290ZXIucmlnaHRCbG9ja2VyLnJlbW92ZSgpO1xuXHRcdH1cblx0XHRpZiAoZG9tLmZvb3Rlci5sZWZ0QmxvY2tlcikge1xuXHRcdFx0ZG9tLmZvb3Rlci5sZWZ0QmxvY2tlci5yZW1vdmUoKTtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuYy5oZWFkZXIgKSB7XG5cdFx0XHR0aGlzLl9tb2RlQ2hhbmdlKCAnaW4tcGxhY2UnLCAnaGVhZGVyJywgdHJ1ZSApO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5jLmZvb3RlciAmJiBkb20udGZvb3QubGVuZ3RoICkge1xuXHRcdFx0dGhpcy5fbW9kZUNoYW5nZSggJ2luLXBsYWNlJywgJ2Zvb3RlcicsIHRydWUgKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEVuYWJsZSAvIGRpc2FibGUgdGhlIGZpeGVkIGVsZW1lbnRzXG5cdCAqXG5cdCAqIEBwYXJhbSAge2Jvb2xlYW59IGVuYWJsZSBgdHJ1ZWAgdG8gZW5hYmxlLCBgZmFsc2VgIHRvIGRpc2FibGVcblx0ICovXG5cdGVuYWJsZTogZnVuY3Rpb24gKCBlbmFibGUsIHVwZGF0ZSApXG5cdHtcblx0XHR0aGlzLnMuZW5hYmxlID0gZW5hYmxlO1xuXG5cdFx0aWYgKCB1cGRhdGUgfHwgdXBkYXRlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR0aGlzLl9wb3NpdGlvbnMoKTtcblx0XHRcdHRoaXMuX3Njcm9sbCggdHJ1ZSApO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogR2V0IGVuYWJsZWQgc3RhdHVzXG5cdCAqL1xuXHRlbmFibGVkOiBmdW5jdGlvbiAoKVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMucy5lbmFibGU7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogU2V0IGhlYWRlciBvZmZzZXQgXG5cdCAqXG5cdCAqIEBwYXJhbSAge2ludH0gbmV3IHZhbHVlIGZvciBoZWFkZXJPZmZzZXRcblx0ICovXG5cdGhlYWRlck9mZnNldDogZnVuY3Rpb24gKCBvZmZzZXQgKVxuXHR7XG5cdFx0aWYgKCBvZmZzZXQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHRoaXMuYy5oZWFkZXJPZmZzZXQgPSBvZmZzZXQ7XG5cdFx0XHR0aGlzLnVwZGF0ZSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmMuaGVhZGVyT2Zmc2V0O1xuXHR9LFxuXHRcblx0LyoqXG5cdCAqIFNldCBmb290ZXIgb2Zmc2V0XG5cdCAqXG5cdCAqIEBwYXJhbSAge2ludH0gbmV3IHZhbHVlIGZvciBmb290ZXJPZmZzZXRcblx0ICovXG5cdGZvb3Rlck9mZnNldDogZnVuY3Rpb24gKCBvZmZzZXQgKVxuXHR7XG5cdFx0aWYgKCBvZmZzZXQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHRoaXMuYy5mb290ZXJPZmZzZXQgPSBvZmZzZXQ7XG5cdFx0XHR0aGlzLnVwZGF0ZSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmMuZm9vdGVyT2Zmc2V0O1xuXHR9LFxuXG5cdFxuXHQvKipcblx0ICogUmVjYWxjdWxhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBmaXhlZCBlbGVtZW50cyBhbmQgZm9yY2UgdGhlbSBpbnRvIHBsYWNlXG5cdCAqL1xuXHR1cGRhdGU6IGZ1bmN0aW9uIChmb3JjZSlcblx0e1xuXHRcdGlmICghIHRoaXMucy5lbmFibGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgdGFibGUgPSB0aGlzLnMuZHQudGFibGUoKS5ub2RlKCk7XG5cblx0XHRpZiAoICQodGFibGUpLmlzKCc6dmlzaWJsZScpICkge1xuXHRcdFx0dGhpcy5lbmFibGUoIHRydWUsIGZhbHNlICk7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0dGhpcy5lbmFibGUoIGZhbHNlLCBmYWxzZSApO1xuXHRcdH1cblxuXHRcdC8vIERvbid0IHVwZGF0ZSBpZiBoZWFkZXIgaXMgbm90IGluIHRoZSBkb2N1bWVudCBhdG0gKGR1ZSB0b1xuXHRcdC8vIGFzeW5jIGV2ZW50cylcblx0XHRpZiAoJCh0YWJsZSkuY2hpbGRyZW4oJ3RoZWFkJykubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy5fcG9zaXRpb25zKCk7XG5cdFx0dGhpcy5fc2Nyb2xsKCBmb3JjZSAhPT0gdW5kZWZpbmVkID8gZm9yY2UgOiB0cnVlICk7XG5cdH0sXG5cblxuXHQvKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKlxuXHQgKiBDb25zdHJ1Y3RvclxuXHQgKi9cblx0XG5cdC8qKlxuXHQgKiBGaXhlZEhlYWRlciBjb25zdHJ1Y3RvciAtIGFkZGluZyB0aGUgcmVxdWlyZWQgZXZlbnQgbGlzdGVuZXJzIGFuZFxuXHQgKiBzaW1wbGUgaW5pdGlhbGlzYXRpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICovXG5cdF9jb25zdHJ1Y3RvcjogZnVuY3Rpb24gKClcblx0e1xuXHRcdHZhciB0aGF0ID0gdGhpcztcblx0XHR2YXIgZHQgPSB0aGlzLnMuZHQ7XG5cblx0XHQkKHdpbmRvdylcblx0XHRcdC5vbiggJ3Njcm9sbCcrdGhpcy5zLm5hbWVzcGFjZSwgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHR0aGF0Ll9zY3JvbGwoKTtcblx0XHRcdH0gKVxuXHRcdFx0Lm9uKCAncmVzaXplJyt0aGlzLnMubmFtZXNwYWNlLCBEYXRhVGFibGUudXRpbC50aHJvdHRsZSggZnVuY3Rpb24gKCkge1xuXHRcdFx0XHR0aGF0LnMucG9zaXRpb24ud2luZG93SGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xuXHRcdFx0XHR0aGF0LnVwZGF0ZSgpO1xuXHRcdFx0fSwgNTAgKSApO1xuXG5cdFx0dmFyIGF1dG9IZWFkZXIgPSAkKCcuZmgtZml4ZWRIZWFkZXInKTtcblx0XHRpZiAoICEgdGhpcy5jLmhlYWRlck9mZnNldCAmJiBhdXRvSGVhZGVyLmxlbmd0aCApIHtcblx0XHRcdHRoaXMuYy5oZWFkZXJPZmZzZXQgPSBhdXRvSGVhZGVyLm91dGVySGVpZ2h0KCk7XG5cdFx0fVxuXG5cdFx0dmFyIGF1dG9Gb290ZXIgPSAkKCcuZmgtZml4ZWRGb290ZXInKTtcblx0XHRpZiAoICEgdGhpcy5jLmZvb3Rlck9mZnNldCAmJiBhdXRvRm9vdGVyLmxlbmd0aCApIHtcblx0XHRcdHRoaXMuYy5mb290ZXJPZmZzZXQgPSBhdXRvRm9vdGVyLm91dGVySGVpZ2h0KCk7XG5cdFx0fVxuXG5cdFx0ZHRcblx0XHRcdC5vbiggJ2NvbHVtbi1yZW9yZGVyLmR0LmR0ZmMgY29sdW1uLXZpc2liaWxpdHkuZHQuZHRmYyBjb2x1bW4tc2l6aW5nLmR0LmR0ZmMgcmVzcG9uc2l2ZS1kaXNwbGF5LmR0LmR0ZmMnLCBmdW5jdGlvbiAoZSwgY3R4KSB7XG5cdFx0XHRcdHRoYXQudXBkYXRlKCk7XG5cdFx0XHR9IClcblx0XHRcdC5vbiggJ2RyYXcuZHQuZHRmYycsIGZ1bmN0aW9uIChlLCBjdHgpIHtcblx0XHRcdFx0Ly8gRm9yIHVwZGF0ZXMgZnJvbSBvdXIgb3duIHRhYmxlLCBkb24ndCByZWNsb25lLCBidXQgZm9yIGFsbCBvdGhlcnMsIGRvXG5cdFx0XHRcdHRoYXQudXBkYXRlKGN0eCA9PT0gZHQuc2V0dGluZ3MoKVswXSA/IGZhbHNlIDogdHJ1ZSk7XG5cdFx0XHR9ICk7XG5cblx0XHRkdC5vbiggJ2Rlc3Ryb3kuZHRmYycsIGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoYXQuZGVzdHJveSgpO1xuXHRcdH0gKTtcblxuXHRcdHRoaXMuX3Bvc2l0aW9ucygpO1xuXHRcdHRoaXMuX3Njcm9sbCgpO1xuXHR9LFxuXG5cblx0LyogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICpcblx0ICogUHJpdmF0ZSBtZXRob2RzXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBDbG9uZSBhIGZpeGVkIGl0ZW0gdG8gYWN0IGFzIGEgcGxhY2UgaG9sZGVyIGZvciB0aGUgb3JpZ2luYWwgZWxlbWVudFxuXHQgKiB3aGljaCBpcyBtb3ZlZCBpbnRvIGEgY2xvbmUgb2YgdGhlIHRhYmxlIGVsZW1lbnQsIGFuZCBtb3ZlZCBhcm91bmQgdGhlXG5cdCAqIGRvY3VtZW50IHRvIGdpdmUgdGhlIGZpeGVkIGVmZmVjdC5cblx0ICpcblx0ICogQHBhcmFtICB7c3RyaW5nfSAgaXRlbSAgJ2hlYWRlcicgb3IgJ2Zvb3Rlcidcblx0ICogQHBhcmFtICB7Ym9vbGVhbn0gZm9yY2UgRm9yY2UgdGhlIGNsb25lIHRvIGhhcHBlbiwgb3IgYWxsb3cgYXV0b21hdGljXG5cdCAqICAgZGVjaXNpb24gKHJldXNlIGV4aXN0aW5nIGlmIGF2YWlsYWJsZSlcblx0ICogQHByaXZhdGVcblx0ICovXG5cdF9jbG9uZTogZnVuY3Rpb24gKCBpdGVtLCBmb3JjZSApXG5cdHtcblx0XHR2YXIgdGhhdCA9IHRoaXM7XG5cdFx0dmFyIGR0ID0gdGhpcy5zLmR0O1xuXHRcdHZhciBpdGVtRG9tID0gdGhpcy5kb21bIGl0ZW0gXTtcblx0XHR2YXIgaXRlbUVsZW1lbnQgPSBpdGVtID09PSAnaGVhZGVyJyA/XG5cdFx0XHR0aGlzLmRvbS50aGVhZCA6XG5cdFx0XHR0aGlzLmRvbS50Zm9vdDtcblxuXHRcdC8vIElmIGZvb3RlciBhbmQgc2Nyb2xsaW5nIGlzIGVuYWJsZWQgdGhlbiB3ZSBkb24ndCBjbG9uZVxuXHRcdC8vIEluc3RlYWQgdGhlIHRhYmxlJ3MgaGVpZ2h0IGlzIGRlY3JlYXNlZCBhY2NvcmRpbmdseSAtIHNlZSBgX3Njcm9sbCgpYFxuXHRcdGlmIChpdGVtID09PSAnZm9vdGVyJyAmJiB0aGlzLl9zY3JvbGxFbmFibGVkKCkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XHRcblxuXHRcdGlmICggISBmb3JjZSAmJiBpdGVtRG9tLmZsb2F0aW5nICkge1xuXHRcdFx0Ly8gZXhpc3RpbmcgZmxvYXRpbmcgZWxlbWVudCAtIHJldXNlIGl0XG5cdFx0XHRpdGVtRG9tLmZsb2F0aW5nLnJlbW92ZUNsYXNzKCAnZml4ZWRIZWFkZXItZmxvYXRpbmcgZml4ZWRIZWFkZXItbG9ja2VkJyApO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdHZhciBkb2NTY3JvbGxMZWZ0ID0gJChkb2N1bWVudCkuc2Nyb2xsTGVmdCgpO1xuXHRcdFx0dmFyIGRvY1Njcm9sbFRvcCA9ICQoZG9jdW1lbnQpLnNjcm9sbFRvcCgpO1xuXG5cdFx0XHRpZiAoIGl0ZW1Eb20uZmxvYXRpbmcgKSB7XG5cdFx0XHRcdGlmKGl0ZW1Eb20ucGxhY2Vob2xkZXIgIT09IG51bGwpIHtcblx0XHRcdFx0XHRpdGVtRG9tLnBsYWNlaG9sZGVyLnJlbW92ZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuX3Vuc2l6ZSggaXRlbSApO1xuXHRcdFx0XHRpdGVtRG9tLmZsb2F0aW5nLmNoaWxkcmVuKCkuZGV0YWNoKCk7XG5cdFx0XHRcdGl0ZW1Eb20uZmxvYXRpbmcucmVtb3ZlKCk7XG5cdFx0XHR9XG5cblx0XHRcdHZhciB0YWJsZU5vZGUgPSAkKGR0LnRhYmxlKCkubm9kZSgpKTsgXG5cdFx0XHR2YXIgc2Nyb2xsQm9keSA9ICQodGFibGVOb2RlLnBhcmVudCgpKTtcblx0XHRcdHZhciBzY3JvbGxFbmFibGVkID0gdGhpcy5fc2Nyb2xsRW5hYmxlZCgpO1xuXG5cdFx0XHRpdGVtRG9tLmZsb2F0aW5nID0gJCggZHQudGFibGUoKS5ub2RlKCkuY2xvbmVOb2RlKCBmYWxzZSApIClcblx0XHRcdFx0LmF0dHIoICdhcmlhLWhpZGRlbicsICd0cnVlJyApXG5cdFx0XHRcdC5jc3Moe1xuXHRcdFx0XHRcdCd0YWJsZS1sYXlvdXQnOiAnZml4ZWQnLFxuXHRcdFx0XHRcdHRvcDogMCxcblx0XHRcdFx0XHRsZWZ0OiAwXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5yZW1vdmVBdHRyKCAnaWQnIClcblx0XHRcdFx0LmFwcGVuZCggaXRlbUVsZW1lbnQgKTtcblxuXHRcdFx0aXRlbURvbS5mbG9hdGluZ1BhcmVudFxuXHRcdFx0XHQuY3NzKHtcblx0XHRcdFx0XHR3aWR0aDogc2Nyb2xsQm9keS53aWR0aCgpLFxuXHRcdFx0XHRcdG92ZXJmbG93OiAnaGlkZGVuJyxcblx0XHRcdFx0XHRoZWlnaHQ6ICdmaXQtY29udGVudCcsXG5cdFx0XHRcdFx0cG9zaXRpb246ICdmaXhlZCcsXG5cdFx0XHRcdFx0bGVmdDogc2Nyb2xsRW5hYmxlZCA/IHRhYmxlTm9kZS5vZmZzZXQoKS5sZWZ0ICsgc2Nyb2xsQm9keS5zY3JvbGxMZWZ0KCkgOiAwXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jc3MoXG5cdFx0XHRcdFx0aXRlbSA9PT0gJ2hlYWRlcicgP1xuXHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHR0b3A6IHRoaXMuYy5oZWFkZXJPZmZzZXQsXG5cdFx0XHRcdFx0XHRcdGJvdHRvbTogJydcblx0XHRcdFx0XHRcdH0gOlxuXHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHR0b3A6ICcnLFxuXHRcdFx0XHRcdFx0XHRib3R0b206IHRoaXMuYy5mb290ZXJPZmZzZXRcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0KVxuXHRcdFx0XHQuYWRkQ2xhc3MoaXRlbSA9PT0gJ2Zvb3RlcicgPyAnZHRmaC1mbG9hdGluZ3BhcmVudGZvb3QnIDogJ2R0ZmgtZmxvYXRpbmdwYXJlbnRoZWFkJylcblx0XHRcdFx0LmFwcGVuZChpdGVtRG9tLmZsb2F0aW5nKVxuXHRcdFx0XHQuYXBwZW5kVG8oICdib2R5JyApO1xuXG5cdFx0XHR0aGlzLl9zdGlja3lQb3NpdGlvbihpdGVtRG9tLmZsb2F0aW5nLCAnLScpO1xuXG5cdFx0XHR2YXIgc2Nyb2xsTGVmdFVwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dmFyIHNjcm9sbExlZnQgPSBzY3JvbGxCb2R5LnNjcm9sbExlZnQoKVxuXHRcdFx0XHR0aGF0LnMuc2Nyb2xsTGVmdCA9IHtmb290ZXI6IHNjcm9sbExlZnQsIGhlYWRlcjogc2Nyb2xsTGVmdH07XG5cdFx0XHRcdGl0ZW1Eb20uZmxvYXRpbmdQYXJlbnQuc2Nyb2xsTGVmdCh0aGF0LnMuc2Nyb2xsTGVmdC5oZWFkZXIpO1xuXHRcdFx0fVxuXG5cdFx0XHRzY3JvbGxMZWZ0VXBkYXRlKCk7XG5cdFx0XHRzY3JvbGxCb2R5XG5cdFx0XHRcdC5vZmYoJ3Njcm9sbC5kdGZoJylcblx0XHRcdFx0Lm9uKCdzY3JvbGwuZHRmaCcsIHNjcm9sbExlZnRVcGRhdGUpO1xuXG5cdFx0XHQvLyBJbnNlcnQgYSBmYWtlIHRoZWFkL3Rmb290IGludG8gdGhlIERhdGFUYWJsZSB0byBzdG9wIGl0IGp1bXBpbmcgYXJvdW5kXG5cdFx0XHRpdGVtRG9tLnBsYWNlaG9sZGVyID0gaXRlbUVsZW1lbnQuY2xvbmUoIGZhbHNlICk7XG5cdFx0XHRpdGVtRG9tLnBsYWNlaG9sZGVyXG5cdFx0XHRcdC5maW5kKCAnKltpZF0nIClcblx0XHRcdFx0LnJlbW92ZUF0dHIoICdpZCcgKTtcblxuXHRcdFx0aXRlbURvbS5ob3N0LnByZXBlbmQoIGl0ZW1Eb20ucGxhY2Vob2xkZXIgKTtcblxuXHRcdFx0Ly8gQ2xvbmUgd2lkdGhzXG5cdFx0XHR0aGlzLl9tYXRjaFdpZHRocyggaXRlbURvbS5wbGFjZWhvbGRlciwgaXRlbURvbS5mbG9hdGluZyApO1xuXG5cdFx0XHQvLyBUaGUgYWJvdmUgYWN0aW9uIHdpbGwgcmVtb3ZlIHRoZSB0YWJsZSBoZWFkZXIsIHBvdGVudGlhbGx5IGNhdXNpbmcgdGhlIHRhYmxlIHRvXG5cdFx0XHQvLyBjb2xsYXBzZSB0byBhIHNtYWxsZXIgc2l6ZSwgYmVmb3JlIGl0IGlzIHRoZW4gcmUtaW5zZXJ0ZWQgKGFwcGVuZCkuIFRoZSByZXN1bHRcblx0XHRcdC8vIGNhbiBiZSB0aGF0IHRoZSBkb2N1bWVudCwgaWYgc2Nyb2xsaW5nLCBjYW4gXCJqdW1wXCIuXG5cdFx0XHQkKGRvY3VtZW50KVxuXHRcdFx0XHQuc2Nyb2xsVG9wKGRvY1Njcm9sbFRvcClcblx0XHRcdFx0LnNjcm9sbExlZnQoZG9jU2Nyb2xsTGVmdCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBUaGlzIG1ldGhvZCBzZXRzIHRoZSBzdGlja3kgcG9zaXRpb24gb2YgdGhlIGhlYWRlciBlbGVtZW50cyB0byBtYXRjaCBmaXhlZCBjb2x1bW5zXG5cdCAqIEBwYXJhbSB7SlF1ZXJ5PEhUTUxFbGVtZW50Pn0gZWwgXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzaWduIFxuXHQgKi9cblx0X3N0aWNreVBvc2l0aW9uOiBmdW5jdGlvbihlbCwgc2lnbikge1xuXHRcdGlmICh0aGlzLl9zY3JvbGxFbmFibGVkKCkpIHtcblx0XHRcdHZhciB0aGF0ID0gdGhpc1xuXHRcdFx0dmFyIHJ0bCA9ICQodGhhdC5zLmR0LnRhYmxlKCkubm9kZSgpKS5jc3MoJ2RpcmVjdGlvbicpID09PSAncnRsJztcblxuXHRcdFx0ZWwuZmluZCgndGgnKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBGaW5kIG91dCBpZiBmaXhlZCBoZWFkZXIgaGFzIHByZXZpb3VzbHkgc2V0IHRoaXMgY29sdW1uXG5cdFx0XHRcdGlmICgkKHRoaXMpLmNzcygncG9zaXRpb24nKSA9PT0gJ3N0aWNreScpIHtcblx0XHRcdFx0XHR2YXIgcmlnaHQgPSAkKHRoaXMpLmNzcygncmlnaHQnKTtcblx0XHRcdFx0XHR2YXIgbGVmdCA9ICQodGhpcykuY3NzKCdsZWZ0Jyk7XG5cdFx0XHRcdFx0aWYgKHJpZ2h0ICE9PSAnYXV0bycgJiYgIXJ0bCkge1xuXHRcdFx0XHRcdFx0Ly8gTmV3IHBvc2l0aW9uIGVpdGhlciBhZGRzIG9yIGRpc21pc3NlcyB0aGUgYmFyV2lkdGhcblx0XHRcdFx0XHRcdHZhciBwb3RlbnRpYWwgPSArcmlnaHQucmVwbGFjZSgvcHgvZywgJycpICsgKHNpZ24gPT09ICctJyA/IC0xIDogMSkgKiB0aGF0LnMuZHQuc2V0dGluZ3MoKVswXS5vQnJvd3Nlci5iYXJXaWR0aDtcblx0XHRcdFx0XHRcdCQodGhpcykuY3NzKCdyaWdodCcsIHBvdGVudGlhbCA+IDAgPyBwb3RlbnRpYWwgOiAwKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSBpZihsZWZ0ICE9PSAnYXV0bycgJiYgcnRsKSB7XG5cdFx0XHRcdFx0XHR2YXIgcG90ZW50aWFsID0gK2xlZnQucmVwbGFjZSgvcHgvZywgJycpICsgKHNpZ24gPT09ICctJyA/IC0xIDogMSkgKiB0aGF0LnMuZHQuc2V0dGluZ3MoKVswXS5vQnJvd3Nlci5iYXJXaWR0aDtcblx0XHRcdFx0XHRcdCQodGhpcykuY3NzKCdsZWZ0JywgcG90ZW50aWFsID4gMCA/IHBvdGVudGlhbCA6IDApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBDb3B5IHdpZHRocyBmcm9tIHRoZSBjZWxscyBpbiBvbmUgZWxlbWVudCB0byBhbm90aGVyLiBUaGlzIGlzIHJlcXVpcmVkXG5cdCAqIGZvciB0aGUgZm9vdGVyIGFzIHRoZSBmb290ZXIgaW4gdGhlIG1haW4gdGFibGUgdGFrZXMgaXRzIHNpemVzIGZyb20gdGhlXG5cdCAqIGhlYWRlciBjb2x1bW5zLiBUaGF0IGlzbid0IHByZXNlbnQgaW4gdGhlIGZvb3RlciBzbyB0byBoYXZlIGl0IHN0aWxsXG5cdCAqIGFsaWduIGNvcnJlY3RseSwgdGhlIHNpemVzIG5lZWQgdG8gYmUgY29waWVkIG92ZXIuIEl0IGlzIGFsc28gcmVxdWlyZWRcblx0ICogZm9yIHRoZSBoZWFkZXIgd2hlbiBhdXRvIHdpZHRoIGlzIG5vdCBlbmFibGVkXG5cdCAqXG5cdCAqIEBwYXJhbSAge2pRdWVyeX0gZnJvbSBDb3B5IHdpZHRocyBmcm9tXG5cdCAqIEBwYXJhbSAge2pRdWVyeX0gdG8gICBDb3B5IHdpZHRocyB0b1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0X21hdGNoV2lkdGhzOiBmdW5jdGlvbiAoIGZyb20sIHRvICkge1xuXHRcdHZhciBnZXQgPSBmdW5jdGlvbiAoIG5hbWUgKSB7XG5cdFx0XHRyZXR1cm4gJChuYW1lLCBmcm9tKVxuXHRcdFx0XHQubWFwKCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0cmV0dXJuICQodGhpcykuY3NzKCd3aWR0aCcpLnJlcGxhY2UoL1teXFxkXFwuXS9nLCAnJykgKiAxO1xuXHRcdFx0XHR9ICkudG9BcnJheSgpO1xuXHRcdH07XG5cblx0XHR2YXIgc2V0ID0gZnVuY3Rpb24gKCBuYW1lLCB0b1dpZHRocyApIHtcblx0XHRcdCQobmFtZSwgdG8pLmVhY2goIGZ1bmN0aW9uICggaSApIHtcblx0XHRcdFx0JCh0aGlzKS5jc3MoIHtcblx0XHRcdFx0XHR3aWR0aDogdG9XaWR0aHNbaV0sXG5cdFx0XHRcdFx0bWluV2lkdGg6IHRvV2lkdGhzW2ldXG5cdFx0XHRcdH0gKTtcblx0XHRcdH0gKTtcblx0XHR9O1xuXG5cdFx0dmFyIHRoV2lkdGhzID0gZ2V0KCAndGgnICk7XG5cdFx0dmFyIHRkV2lkdGhzID0gZ2V0KCAndGQnICk7XG5cblx0XHRzZXQoICd0aCcsIHRoV2lkdGhzICk7XG5cdFx0c2V0KCAndGQnLCB0ZFdpZHRocyApO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgYXNzaWduZWQgd2lkdGhzIGZyb20gdGhlIGNlbGxzIGluIGFuIGVsZW1lbnQuIFRoaXMgaXMgcmVxdWlyZWRcblx0ICogd2hlbiBpbnNlcnRpbmcgdGhlIGZvb3RlciBiYWNrIGludG8gdGhlIG1haW4gdGFibGUgc28gdGhlIHNpemUgaXMgZGVmaW5lZFxuXHQgKiBieSB0aGUgaGVhZGVyIGNvbHVtbnMgYW5kIGFsc28gd2hlbiBhdXRvIHdpZHRoIGlzIGRpc2FibGVkIGluIHRoZVxuXHQgKiBEYXRhVGFibGUuXG5cdCAqXG5cdCAqIEBwYXJhbSAge3N0cmluZ30gaXRlbSBUaGUgYGhlYWRlcmAgb3IgYGZvb3RlcmBcblx0ICogQHByaXZhdGVcblx0ICovXG5cdF91bnNpemU6IGZ1bmN0aW9uICggaXRlbSApIHtcblx0XHR2YXIgZWwgPSB0aGlzLmRvbVsgaXRlbSBdLmZsb2F0aW5nO1xuXG5cdFx0aWYgKCBlbCAmJiAoaXRlbSA9PT0gJ2Zvb3RlcicgfHwgKGl0ZW0gPT09ICdoZWFkZXInICYmICEgdGhpcy5zLmF1dG9XaWR0aCkpICkge1xuXHRcdFx0JCgndGgsIHRkJywgZWwpLmNzcygge1xuXHRcdFx0XHR3aWR0aDogJycsXG5cdFx0XHRcdG1pbldpZHRoOiAnJ1xuXHRcdFx0fSApO1xuXHRcdH1cblx0XHRlbHNlIGlmICggZWwgJiYgaXRlbSA9PT0gJ2hlYWRlcicgKSB7XG5cdFx0XHQkKCd0aCwgdGQnLCBlbCkuY3NzKCAnbWluLXdpZHRoJywgJycgKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlcG9zaXRpb24gdGhlIGZsb2F0aW5nIGVsZW1lbnRzIHRvIHRha2UgYWNjb3VudCBvZiBob3Jpem9udGFsIHBhZ2Vcblx0ICogc2Nyb2xsXG5cdCAqXG5cdCAqIEBwYXJhbSAge3N0cmluZ30gaXRlbSAgICAgICBUaGUgYGhlYWRlcmAgb3IgYGZvb3RlcmBcblx0ICogQHBhcmFtICB7aW50fSAgICBzY3JvbGxMZWZ0IERvY3VtZW50IHNjcm9sbExlZnRcblx0ICogQHByaXZhdGVcblx0ICovXG5cdF9ob3Jpem9udGFsOiBmdW5jdGlvbiAoIGl0ZW0sIHNjcm9sbExlZnQgKVxuXHR7XG5cdFx0dmFyIGl0ZW1Eb20gPSB0aGlzLmRvbVsgaXRlbSBdO1xuXHRcdHZhciBwb3NpdGlvbiA9IHRoaXMucy5wb3NpdGlvbjtcblx0XHR2YXIgbGFzdFNjcm9sbExlZnQgPSB0aGlzLnMuc2Nyb2xsTGVmdDtcblxuXHRcdGlmICggaXRlbURvbS5mbG9hdGluZyAmJiBsYXN0U2Nyb2xsTGVmdFsgaXRlbSBdICE9PSBzY3JvbGxMZWZ0ICkge1xuXHRcdFx0Ly8gSWYgc2Nyb2xsaW5nIGlzIGVuYWJsZWQgd2UgbmVlZCB0byBtYXRjaCB0aGUgZmxvYXRpbmcgaGVhZGVyIHRvIHRoZSBib2R5XG5cdFx0XHRpZiAodGhpcy5fc2Nyb2xsRW5hYmxlZCgpKSB7XG5cdFx0XHRcdHZhciBuZXdTY3JvbGxMZWZ0ID0gJCgkKHRoaXMucy5kdC50YWJsZSgpLm5vZGUoKSkucGFyZW50KCkpLnNjcm9sbExlZnQoKVxuXHRcdFx0XHRpdGVtRG9tLmZsb2F0aW5nLnNjcm9sbExlZnQobmV3U2Nyb2xsTGVmdCk7XG5cdFx0XHRcdGl0ZW1Eb20uZmxvYXRpbmdQYXJlbnQuc2Nyb2xsTGVmdChuZXdTY3JvbGxMZWZ0KTtcblx0XHRcdH1cblxuXHRcdFx0bGFzdFNjcm9sbExlZnRbIGl0ZW0gXSA9IHNjcm9sbExlZnQ7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBDaGFuZ2UgZnJvbSBvbmUgZGlzcGxheSBtb2RlIHRvIGFub3RoZXIuIEVhY2ggZml4ZWQgaXRlbSBjYW4gYmUgaW4gb25lXG5cdCAqIG9mOlxuXHQgKlxuXHQgKiAqIGBpbi1wbGFjZWAgLSBJbiB0aGUgbWFpbiBEYXRhVGFibGVcblx0ICogKiBgaW5gIC0gRmxvYXRpbmcgb3ZlciB0aGUgRGF0YVRhYmxlXG5cdCAqICogYGJlbG93YCAtIChIZWFkZXIgb25seSkgRml4ZWQgdG8gdGhlIGJvdHRvbSBvZiB0aGUgdGFibGUgYm9keVxuXHQgKiAqIGBhYm92ZWAgLSAoRm9vdGVyIG9ubHkpIEZpeGVkIHRvIHRoZSB0b3Agb2YgdGhlIHRhYmxlIGJvZHlcblx0ICogXG5cdCAqIEBwYXJhbSAge3N0cmluZ30gIG1vZGUgICAgICAgIE1vZGUgdGhhdCB0aGUgaXRlbSBzaG91bGQgYmUgc2hvd24gaW5cblx0ICogQHBhcmFtICB7c3RyaW5nfSAgaXRlbSAgICAgICAgJ2hlYWRlcicgb3IgJ2Zvb3Rlcidcblx0ICogQHBhcmFtICB7Ym9vbGVhbn0gZm9yY2VDaGFuZ2UgRm9yY2UgYSByZWRyYXcgb2YgdGhlIG1vZGUsIGV2ZW4gaWYgYWxyZWFkeVxuXHQgKiAgICAgaW4gdGhhdCBtb2RlLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0X21vZGVDaGFuZ2U6IGZ1bmN0aW9uICggbW9kZSwgaXRlbSwgZm9yY2VDaGFuZ2UgKVxuXHR7XG5cdFx0dmFyIGR0ID0gdGhpcy5zLmR0O1xuXHRcdHZhciBpdGVtRG9tID0gdGhpcy5kb21bIGl0ZW0gXTtcblx0XHR2YXIgcG9zaXRpb24gPSB0aGlzLnMucG9zaXRpb247XG5cblx0XHQvLyBKdXN0IGRldGVybWluZSBpZiBzY3JvbGwgaXMgZW5hYmxlZCBvbmNlXG5cdFx0dmFyIHNjcm9sbEVuYWJsZWQgPSB0aGlzLl9zY3JvbGxFbmFibGVkKCk7XG5cblx0XHQvLyBJZiBmb290ZXIgYW5kIHNjcm9sbGluZyBpcyBlbmFibGVkIHRoZW4gd2UgZG9uJ3QgY2xvbmVcblx0XHQvLyBJbnN0ZWFkIHRoZSB0YWJsZSdzIGhlaWdodCBpcyBkZWNyZWFzZWQgYWNjb3JkaW5nbHkgLSBzZWUgYF9zY3JvbGwoKWBcblx0XHRpZiAoaXRlbSA9PT0gJ2Zvb3RlcicgJiYgc2Nyb2xsRW5hYmxlZCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cdFx0XG5cblx0XHQvLyBJdCBpc24ndCB0cml2aWFsIHRvIGFkZCBhICFpbXBvcnRhbnQgY3NzIGF0dHJpYnV0ZS4uLlxuXHRcdHZhciBpbXBvcnRhbnRXaWR0aCA9IGZ1bmN0aW9uICh3KSB7XG5cdFx0XHRpdGVtRG9tLmZsb2F0aW5nLmF0dHIoJ3N0eWxlJywgZnVuY3Rpb24oaSxzKSB7XG5cdFx0XHRcdHJldHVybiAocyB8fCAnJykgKyAnd2lkdGg6ICcrdysncHggIWltcG9ydGFudDsnO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIElmIG5vdCBzY3JvbGxpbmcgYWxzbyBoYXZlIHRvIHVwZGF0ZSB0aGUgZmxvYXRpbmdQYXJlbnRcblx0XHRcdGlmICghc2Nyb2xsRW5hYmxlZCkge1xuXHRcdFx0XHRpdGVtRG9tLmZsb2F0aW5nUGFyZW50LmF0dHIoJ3N0eWxlJywgZnVuY3Rpb24oaSxzKSB7XG5cdFx0XHRcdFx0cmV0dXJuIChzIHx8ICcnKSArICd3aWR0aDogJyt3KydweCAhaW1wb3J0YW50Oyc7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHQvLyBSZWNvcmQgZm9jdXMuIEJyb3dzZXIncyB3aWxsIGNhdXNlIGlucHV0IGVsZW1lbnRzIHRvIGxvb3NlIGZvY3VzIGlmXG5cdFx0Ly8gdGhleSBhcmUgaW5zZXJ0ZWQgZWxzZSB3aGVyZSBpbiB0aGUgZG9jXG5cdFx0dmFyIHRhYmxlUGFydCA9IHRoaXMuZG9tWyBpdGVtPT09J2Zvb3RlcicgPyAndGZvb3QnIDogJ3RoZWFkJyBdO1xuXHRcdHZhciBmb2N1cyA9ICQuY29udGFpbnMoIHRhYmxlUGFydFswXSwgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCApID9cblx0XHRcdGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgOlxuXHRcdFx0bnVsbDtcblx0XHR2YXIgc2Nyb2xsQm9keSA9ICQoJCh0aGlzLnMuZHQudGFibGUoKS5ub2RlKCkpLnBhcmVudCgpKTtcblxuXHRcdGlmICggbW9kZSA9PT0gJ2luLXBsYWNlJyApIHtcblx0XHRcdC8vIEluc2VydCB0aGUgaGVhZGVyIGJhY2sgaW50byB0aGUgdGFibGUncyByZWFsIGhlYWRlclxuXHRcdFx0aWYgKCBpdGVtRG9tLnBsYWNlaG9sZGVyICkge1xuXHRcdFx0XHRpdGVtRG9tLnBsYWNlaG9sZGVyLnJlbW92ZSgpO1xuXHRcdFx0XHRpdGVtRG9tLnBsYWNlaG9sZGVyID0gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fdW5zaXplKCBpdGVtICk7XG5cblx0XHRcdGlmICggaXRlbSA9PT0gJ2hlYWRlcicgKSB7XG5cdFx0XHRcdGl0ZW1Eb20uaG9zdC5wcmVwZW5kKCB0YWJsZVBhcnQgKTtcblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRpdGVtRG9tLmhvc3QuYXBwZW5kKCB0YWJsZVBhcnQgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBpdGVtRG9tLmZsb2F0aW5nICkge1xuXHRcdFx0XHRpdGVtRG9tLmZsb2F0aW5nLnJlbW92ZSgpO1xuXHRcdFx0XHRpdGVtRG9tLmZsb2F0aW5nID0gbnVsbDtcblx0XHRcdFx0dGhpcy5fc3RpY2t5UG9zaXRpb24oaXRlbURvbS5ob3N0LCAnKycpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGl0ZW1Eb20uZmxvYXRpbmdQYXJlbnQgKSB7XG5cdFx0XHRcdGl0ZW1Eb20uZmxvYXRpbmdQYXJlbnQucmVtb3ZlKCk7XG5cdFx0XHR9XG5cblx0XHRcdCQoJChpdGVtRG9tLmhvc3QucGFyZW50KCkpLnBhcmVudCgpKS5zY3JvbGxMZWZ0KHNjcm9sbEJvZHkuc2Nyb2xsTGVmdCgpKVxuXHRcdH1cblx0XHRlbHNlIGlmICggbW9kZSA9PT0gJ2luJyApIHtcblx0XHRcdC8vIFJlbW92ZSB0aGUgaGVhZGVyIGZyb20gdGhlIHJlYWQgaGVhZGVyIGFuZCBpbnNlcnQgaW50byBhIGZpeGVkXG5cdFx0XHQvLyBwb3NpdGlvbmVkIGZsb2F0aW5nIHRhYmxlIGNsb25lXG5cdFx0XHR0aGlzLl9jbG9uZSggaXRlbSwgZm9yY2VDaGFuZ2UgKTtcblxuXHRcdFx0Ly8gR2V0IHVzZWZ1bCBwb3NpdGlvbiB2YWx1ZXNcblx0XHRcdHZhciBzY3JvbGxPZmZzZXQgPSBzY3JvbGxCb2R5Lm9mZnNldCgpO1xuXHRcdFx0dmFyIHdpbmRvd1RvcCA9ICQoZG9jdW1lbnQpLnNjcm9sbFRvcCgpO1xuXHRcdFx0dmFyIHdpbmRvd0hlaWdodCA9ICQod2luZG93KS5oZWlnaHQoKTtcblx0XHRcdHZhciB3aW5kb3dCb3R0b20gPSB3aW5kb3dUb3AgKyB3aW5kb3dIZWlnaHQ7XG5cdFx0XHR2YXIgYm9keVRvcCA9IHNjcm9sbEVuYWJsZWQgPyBzY3JvbGxPZmZzZXQudG9wIDogcG9zaXRpb24udGJvZHlUb3A7XG5cdFx0XHR2YXIgYm9keUJvdHRvbSA9IHNjcm9sbEVuYWJsZWQgPyBzY3JvbGxPZmZzZXQudG9wICsgc2Nyb2xsQm9keS5vdXRlckhlaWdodCgpIDogcG9zaXRpb24udGZvb3RUb3BcblxuXHRcdFx0Ly8gQ2FsY3VsYXRlIHRoZSBhbW91bnQgdGhhdCB0aGUgZm9vdGVyIG9yIGhlYWRlciBuZWVkcyB0byBiZSBzaHVmZmxlZFxuXHRcdFx0dmFyIHNodWZmbGUgPSBpdGVtID09PSAnZm9vdGVyJyA/XG5cdFx0XHRcdC8vIGZvb3RlciBhbmQgdG9wIG9mIGJvZHkgaXNuJ3Qgb24gc2NyZWVuXG5cdFx0XHRcdGJvZHlUb3AgPiB3aW5kb3dCb3R0b20gP1xuXHRcdFx0XHRcdC8vIFllcyAtIHB1c2ggdGhlIGZvb3RlciBiZWxvd1xuXHRcdFx0XHRcdHBvc2l0aW9uLnRmb290SGVpZ2h0IDpcblx0XHRcdFx0XHQvLyBObyAtIGJvdHRvbSBzZXQgdG8gdGhlIGdhcCBiZXR3ZWVuIHRoZSB0b3Agb2YgdGhlIGJvZHkgYW5kIHRoZSBib3R0b20gb2YgdGhlIHdpbmRvd1xuXHRcdFx0XHRcdGJvZHlUb3AgKyBwb3NpdGlvbi50Zm9vdEhlaWdodCAtIHdpbmRvd0JvdHRvbSA6XG5cdFx0XHRcdC8vIE90aGVyd2lzZSBtdXN0IGJlIGEgaGVhZGVyIHNvIGdldCB0aGUgZGlmZmVyZW5jZSBmcm9tIHRoZSBib3R0b20gb2YgdGhlXG5cdFx0XHRcdC8vICBkZXNpcmVkIGZsb2F0aW5nIGhlYWRlciBhbmQgdGhlIGJvdHRvbSBvZiB0aGUgdGFibGUgYm9keVxuXHRcdFx0XHR3aW5kb3dUb3AgKyB0aGlzLmMuaGVhZGVyT2Zmc2V0ICsgcG9zaXRpb24udGhlYWRIZWlnaHQgLSBib2R5Qm90dG9tXG5cdFx0XHRcdFxuXHRcdFx0Ly8gU2V0IHRoZSB0b3Agb3IgYm90dG9tIGJhc2VkIG9mZiBvZiB0aGUgb2Zmc2V0IGFuZCB0aGUgc2h1ZmZsZSB2YWx1ZVxuXHRcdFx0dmFyIHByb3AgPSBpdGVtID09PSAnaGVhZGVyJyA/ICd0b3AnIDogJ2JvdHRvbSc7XG5cdFx0XHR2YXIgdmFsID0gdGhpcy5jW2l0ZW0rJ09mZnNldCddIC0gKHNodWZmbGUgPiAwID8gc2h1ZmZsZSA6IDApO1xuXG5cdFx0XHRpdGVtRG9tLmZsb2F0aW5nLmFkZENsYXNzKCAnZml4ZWRIZWFkZXItZmxvYXRpbmcnICk7XG5cdFx0XHRpdGVtRG9tLmZsb2F0aW5nUGFyZW50XG5cdFx0XHRcdC5jc3MocHJvcCwgdmFsKVxuXHRcdFx0XHQuY3NzKCB7XG5cdFx0XHRcdFx0J2xlZnQnOiBwb3NpdGlvbi5sZWZ0LFxuXHRcdFx0XHRcdCdoZWlnaHQnOiBpdGVtID09PSAnaGVhZGVyJyA/IHBvc2l0aW9uLnRoZWFkSGVpZ2h0IDogcG9zaXRpb24udGZvb3RIZWlnaHQsXG5cdFx0XHRcdFx0J3otaW5kZXgnOiAyXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5hcHBlbmQoaXRlbURvbS5mbG9hdGluZyk7XG5cblx0XHRcdGltcG9ydGFudFdpZHRoKHBvc2l0aW9uLndpZHRoKTtcblxuXHRcdFx0aWYgKCBpdGVtID09PSAnZm9vdGVyJyApIHtcblx0XHRcdFx0aXRlbURvbS5mbG9hdGluZy5jc3MoICd0b3AnLCAnJyApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRlbHNlIGlmICggbW9kZSA9PT0gJ2JlbG93JyApIHsgLy8gb25seSB1c2VkIGZvciB0aGUgaGVhZGVyXG5cdFx0XHQvLyBGaXggdGhlIHBvc2l0aW9uIG9mIHRoZSBmbG9hdGluZyBoZWFkZXIgYXQgYmFzZSBvZiB0aGUgdGFibGUgYm9keVxuXHRcdFx0dGhpcy5fY2xvbmUoIGl0ZW0sIGZvcmNlQ2hhbmdlICk7XG5cblx0XHRcdGl0ZW1Eb20uZmxvYXRpbmcuYWRkQ2xhc3MoICdmaXhlZEhlYWRlci1sb2NrZWQnICk7XG5cdFx0XHRpdGVtRG9tLmZsb2F0aW5nUGFyZW50LmNzcyh7XG5cdFx0XHRcdHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuXHRcdFx0XHR0b3A6IHBvc2l0aW9uLnRmb290VG9wIC0gcG9zaXRpb24udGhlYWRIZWlnaHQsXG5cdFx0XHRcdGxlZnQ6IHBvc2l0aW9uLmxlZnQrJ3B4J1xuXHRcdFx0fSk7XG5cblx0XHRcdGltcG9ydGFudFdpZHRoKHBvc2l0aW9uLndpZHRoKTtcblx0XHR9XG5cdFx0ZWxzZSBpZiAoIG1vZGUgPT09ICdhYm92ZScgKSB7IC8vIG9ubHkgdXNlZCBmb3IgdGhlIGZvb3RlclxuXHRcdFx0Ly8gRml4IHRoZSBwb3NpdGlvbiBvZiB0aGUgZmxvYXRpbmcgZm9vdGVyIGF0IHRvcCBvZiB0aGUgdGFibGUgYm9keVxuXHRcdFx0dGhpcy5fY2xvbmUoIGl0ZW0sIGZvcmNlQ2hhbmdlICk7XG5cblx0XHRcdGl0ZW1Eb20uZmxvYXRpbmcuYWRkQ2xhc3MoICdmaXhlZEhlYWRlci1sb2NrZWQnICk7XG5cdFx0XHRpdGVtRG9tLmZsb2F0aW5nUGFyZW50LmNzcyh7XG5cdFx0XHRcdHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuXHRcdFx0XHR0b3A6IHBvc2l0aW9uLnRib2R5VG9wLFxuXHRcdFx0XHRsZWZ0OiBwb3NpdGlvbi5sZWZ0KydweCdcblx0XHRcdH0pO1xuXG5cdFx0XHRpbXBvcnRhbnRXaWR0aChwb3NpdGlvbi53aWR0aCk7XG5cdFx0fVxuXG5cdFx0Ly8gUmVzdG9yZSBmb2N1cyBpZiBpdCB3YXMgbG9zdFxuXHRcdGlmICggZm9jdXMgJiYgZm9jdXMgIT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgKSB7XG5cdFx0XHRzZXRUaW1lb3V0KCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGZvY3VzLmZvY3VzKCk7XG5cdFx0XHR9LCAxMCApO1xuXHRcdH1cblxuXHRcdHRoaXMucy5zY3JvbGxMZWZ0LmhlYWRlciA9IC0xO1xuXHRcdHRoaXMucy5zY3JvbGxMZWZ0LmZvb3RlciA9IC0xO1xuXHRcdHRoaXMuc1tpdGVtKydNb2RlJ10gPSBtb2RlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDYWNoZSB0aGUgcG9zaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IGlzIHJlcXVpcmVkIGZvciB0aGUgbW9kZVxuXHQgKiBjYWxjdWxhdGlvbnMgdGhhdCBGaXhlZEhlYWRlciBwZXJmb3Jtcy5cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICovXG5cdF9wb3NpdGlvbnM6IGZ1bmN0aW9uICgpXG5cdHtcblx0XHR2YXIgZHQgPSB0aGlzLnMuZHQ7XG5cdFx0dmFyIHRhYmxlID0gZHQudGFibGUoKTtcblx0XHR2YXIgcG9zaXRpb24gPSB0aGlzLnMucG9zaXRpb247XG5cdFx0dmFyIGRvbSA9IHRoaXMuZG9tO1xuXHRcdHZhciB0YWJsZU5vZGUgPSAkKHRhYmxlLm5vZGUoKSk7XG5cdFx0dmFyIHNjcm9sbEVuYWJsZWQgPSB0aGlzLl9zY3JvbGxFbmFibGVkKCk7XG5cblx0XHQvLyBOZWVkIHRvIHVzZSB0aGUgaGVhZGVyIGFuZCBmb290ZXIgdGhhdCBhcmUgaW4gdGhlIG1haW4gdGFibGUsXG5cdFx0Ly8gcmVnYXJkbGVzcyBvZiBpZiB0aGV5IGFyZSBjbG9uZXMsIHNpbmNlIHRoZXkgaG9sZCB0aGUgcG9zaXRpb25zIHdlXG5cdFx0Ly8gd2FudCB0byBtZWFzdXJlIGZyb21cblx0XHR2YXIgdGhlYWQgPSAkKGR0LnRhYmxlKCkuaGVhZGVyKCkpO1xuXHRcdHZhciB0Zm9vdCA9ICQoZHQudGFibGUoKS5mb290ZXIoKSk7XG5cdFx0dmFyIHRib2R5ID0gZG9tLnRib2R5O1xuXHRcdHZhciBzY3JvbGxCb2R5ID0gdGFibGVOb2RlLnBhcmVudCgpO1xuXG5cdFx0cG9zaXRpb24udmlzaWJsZSA9IHRhYmxlTm9kZS5pcygnOnZpc2libGUnKTtcblx0XHRwb3NpdGlvbi53aWR0aCA9IHRhYmxlTm9kZS5vdXRlcldpZHRoKCk7XG5cdFx0cG9zaXRpb24ubGVmdCA9IHRhYmxlTm9kZS5vZmZzZXQoKS5sZWZ0O1xuXHRcdHBvc2l0aW9uLnRoZWFkVG9wID0gdGhlYWQub2Zmc2V0KCkudG9wO1xuXHRcdHBvc2l0aW9uLnRib2R5VG9wID0gc2Nyb2xsRW5hYmxlZCA/IHNjcm9sbEJvZHkub2Zmc2V0KCkudG9wIDogdGJvZHkub2Zmc2V0KCkudG9wO1xuXHRcdHBvc2l0aW9uLnRib2R5SGVpZ2h0ID0gc2Nyb2xsRW5hYmxlZCA/IHNjcm9sbEJvZHkub3V0ZXJIZWlnaHQoKSA6IHRib2R5Lm91dGVySGVpZ2h0KCk7XG5cdFx0cG9zaXRpb24udGhlYWRIZWlnaHQgPSB0aGVhZC5vdXRlckhlaWdodCgpO1xuXHRcdHBvc2l0aW9uLnRoZWFkQm90dG9tID0gcG9zaXRpb24udGhlYWRUb3AgKyBwb3NpdGlvbi50aGVhZEhlaWdodDtcblxuXHRcdGlmICggdGZvb3QubGVuZ3RoICkge1xuXHRcdFx0cG9zaXRpb24udGZvb3RUb3AgPSBwb3NpdGlvbi50Ym9keVRvcCArIHBvc2l0aW9uLnRib2R5SGVpZ2h0OyAvL3Rmb290Lm9mZnNldCgpLnRvcDtcblx0XHRcdHBvc2l0aW9uLnRmb290Qm90dG9tID0gcG9zaXRpb24udGZvb3RUb3AgKyB0Zm9vdC5vdXRlckhlaWdodCgpO1xuXHRcdFx0cG9zaXRpb24udGZvb3RIZWlnaHQgPSB0Zm9vdC5vdXRlckhlaWdodCgpO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdHBvc2l0aW9uLnRmb290VG9wID0gcG9zaXRpb24udGJvZHlUb3AgKyB0Ym9keS5vdXRlckhlaWdodCgpO1xuXHRcdFx0cG9zaXRpb24udGZvb3RCb3R0b20gPSBwb3NpdGlvbi50Zm9vdFRvcDtcblx0XHRcdHBvc2l0aW9uLnRmb290SGVpZ2h0ID0gcG9zaXRpb24udGZvb3RUb3A7XG5cdFx0fVxuXHR9LFxuXG5cblx0LyoqXG5cdCAqIE1vZGUgY2FsY3VsYXRpb24gLSBkZXRlcm1pbmUgd2hhdCBtb2RlIHRoZSBmaXhlZCBpdGVtcyBzaG91bGQgYmUgcGxhY2VkXG5cdCAqIGludG8uXG5cdCAqXG5cdCAqIEBwYXJhbSAge2Jvb2xlYW59IGZvcmNlQ2hhbmdlIEZvcmNlIGEgcmVkcmF3IG9mIHRoZSBtb2RlLCBldmVuIGlmIGFscmVhZHlcblx0ICogICAgIGluIHRoYXQgbW9kZS5cblx0ICogQHByaXZhdGVcblx0ICovXG5cdF9zY3JvbGw6IGZ1bmN0aW9uICggZm9yY2VDaGFuZ2UgKVxuXHR7XG5cdFx0aWYgKHRoaXMucy5kdC5zZXR0aW5ncygpWzBdLmJEZXN0cm95aW5nKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gU2Nyb2xsQm9keSBkZXRhaWxzXG5cdFx0dmFyIHNjcm9sbEVuYWJsZWQgPSB0aGlzLl9zY3JvbGxFbmFibGVkKCk7XG5cdFx0dmFyIHNjcm9sbEJvZHkgPSAkKHRoaXMucy5kdC50YWJsZSgpLm5vZGUoKSkucGFyZW50KCk7XG5cdFx0dmFyIHNjcm9sbE9mZnNldCA9ICBzY3JvbGxCb2R5Lm9mZnNldCgpO1xuXHRcdHZhciBzY3JvbGxIZWlnaHQgPSAgc2Nyb2xsQm9keS5vdXRlckhlaWdodCgpO1xuXG5cdFx0Ly8gV2luZG93IGRldGFpbHNcblx0XHR2YXIgd2luZG93TGVmdCA9ICQoZG9jdW1lbnQpLnNjcm9sbExlZnQoKTtcblx0XHR2YXIgd2luZG93VG9wID0gJChkb2N1bWVudCkuc2Nyb2xsVG9wKCk7XG5cdFx0dmFyIHdpbmRvd0hlaWdodCA9ICQod2luZG93KS5oZWlnaHQoKTtcblx0XHR2YXIgd2luZG93Qm90dG9tID0gd2luZG93SGVpZ2h0ICsgd2luZG93VG9wXG5cblxuXHRcdHZhciBwb3NpdGlvbiA9IHRoaXMucy5wb3NpdGlvbjtcblx0XHR2YXIgaGVhZGVyTW9kZSwgZm9vdGVyTW9kZTtcblxuXHRcdC8vIEJvZHkgRGV0YWlsc1xuXHRcdHZhciBib2R5VG9wID0gKHNjcm9sbEVuYWJsZWQgPyBzY3JvbGxPZmZzZXQudG9wIDogcG9zaXRpb24udGJvZHlUb3ApO1xuXHRcdHZhciBib2R5TGVmdCA9IChzY3JvbGxFbmFibGVkID8gc2Nyb2xsT2Zmc2V0LmxlZnQgOiBwb3NpdGlvbi5sZWZ0KTtcblx0XHR2YXIgYm9keUJvdHRvbSA9IChzY3JvbGxFbmFibGVkID8gc2Nyb2xsT2Zmc2V0LnRvcCArIHNjcm9sbEhlaWdodCA6IHBvc2l0aW9uLnRmb290VG9wKTtcblx0XHR2YXIgYm9keVdpZHRoID0gKHNjcm9sbEVuYWJsZWQgPyBzY3JvbGxCb2R5Lm91dGVyV2lkdGgoKSA6IHBvc2l0aW9uLnRib2R5V2lkdGgpO1xuXG5cdFx0dmFyIHdpbmRvd0JvdHRvbSA9IHdpbmRvd1RvcCArIHdpbmRvd0hlaWdodDtcblxuXHRcdGlmICggdGhpcy5jLmhlYWRlciApIHtcblx0XHRcdGlmICggISB0aGlzLnMuZW5hYmxlICkge1xuXHRcdFx0XHRoZWFkZXJNb2RlID0gJ2luLXBsYWNlJztcblx0XHRcdH1cblx0XHRcdC8vIFRoZSBoZWFkZXIgaXMgaW4gaXQncyBub3JtYWwgcGxhY2UgaWYgdGhlIGJvZHkgdG9wIGlzIGxvd2VyIHRoYW5cblx0XHRcdC8vICB0aGUgc2Nyb2xsIG9mIHRoZSB3aW5kb3cgcGx1cyB0aGUgaGVhZGVyT2Zmc2V0IGFuZCB0aGUgaGVpZ2h0IG9mIHRoZSBoZWFkZXJcblx0XHRcdGVsc2UgaWYgKCAhIHBvc2l0aW9uLnZpc2libGUgfHwgd2luZG93VG9wICsgdGhpcy5jLmhlYWRlck9mZnNldCArIHBvc2l0aW9uLnRoZWFkSGVpZ2h0IDw9IGJvZHlUb3ApIHtcblx0XHRcdFx0aGVhZGVyTW9kZSA9ICdpbi1wbGFjZSc7XG5cdFx0XHR9XG5cdFx0XHQvLyBUaGUgaGVhZGVyIHNob3VsZCBiZSBmbG9hdGVkIGlmXG5cdFx0XHRlbHNlIGlmIChcblx0XHRcdFx0Ly8gVGhlIHNjcm9sbGluZyBwbHVzIHRoZSBoZWFkZXIgb2Zmc2V0IHBsdXMgdGhlIGhlaWdodCBvZiB0aGUgaGVhZGVyIGlzIGxvd2VyIHRoYW4gdGhlIHRvcCBvZiB0aGUgYm9keVxuXHRcdFx0XHR3aW5kb3dUb3AgKyB0aGlzLmMuaGVhZGVyT2Zmc2V0ICsgcG9zaXRpb24udGhlYWRIZWlnaHQgPiBib2R5VG9wICYmXG5cdFx0XHRcdC8vIEFuZCB0aGUgc2Nyb2xsaW5nIGF0IHRoZSB0b3AgcGx1cyB0aGUgaGVhZGVyIG9mZnNldCBpcyBhYm92ZSB0aGUgYm90dG9tIG9mIHRoZSBib2R5XG5cdFx0XHRcdHdpbmRvd1RvcCArIHRoaXMuYy5oZWFkZXJPZmZzZXQgKyBwb3NpdGlvbi50aGVhZEhlaWdodCA8IGJvZHlCb3R0b21cblx0XHRcdCkge1xuXHRcdFx0XHRoZWFkZXJNb2RlID0gJ2luJztcblx0XHRcdFx0dmFyIHNjcm9sbEJvZHkgPSAkKCQodGhpcy5zLmR0LnRhYmxlKCkubm9kZSgpKS5wYXJlbnQoKSk7XG5cblx0XHRcdFx0Ly8gRnVydGhlciB0byB0aGUgYWJvdmUsIElmIHRoZSBzY3JvbGxpbmcgcGx1cyB0aGUgaGVhZGVyIG9mZnNldCBwbHVzIHRoZSBoZWFkZXIgaGVpZ2h0IGlzIGxvd2VyXG5cdFx0XHRcdC8vIHRoYW4gdGhlIGJvdHRvbSBvZiB0aGUgdGFibGUgYSBzaHVmZmxlIGlzIHJlcXVpcmVkIHNvIGhhdmUgdG8gZm9yY2UgdGhlIGNhbGN1bGF0aW9uXG5cdFx0XHRcdGlmKHdpbmRvd1RvcCArIHRoaXMuYy5oZWFkZXJPZmZzZXQgKyBwb3NpdGlvbi50aGVhZEhlaWdodCA+IGJvZHlCb3R0b20gfHwgdGhpcy5kb20uaGVhZGVyLmZsb2F0aW5nUGFyZW50ID09PSB1bmRlZmluZWQpe1xuXHRcdFx0XHRcdGZvcmNlQ2hhbmdlID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHR0aGlzLmRvbS5oZWFkZXIuZmxvYXRpbmdQYXJlbnRcblx0XHRcdFx0XHRcdC5jc3Moe1xuXHRcdFx0XHRcdFx0XHQndG9wJzogdGhpcy5jLmhlYWRlck9mZnNldCxcblx0XHRcdFx0XHRcdFx0J3Bvc2l0aW9uJzogJ2ZpeGVkJ1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5hcHBlbmQodGhpcy5kb20uaGVhZGVyLmZsb2F0aW5nKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gQW55dGhpbmcgZWxzZSBhbmQgdGhlIHZpZXcgaXMgYmVsb3cgdGhlIHRhYmxlXG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0aGVhZGVyTW9kZSA9ICdiZWxvdyc7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZm9yY2VDaGFuZ2UgfHwgaGVhZGVyTW9kZSAhPT0gdGhpcy5zLmhlYWRlck1vZGUgKSB7XG5cdFx0XHRcdHRoaXMuX21vZGVDaGFuZ2UoIGhlYWRlck1vZGUsICdoZWFkZXInLCBmb3JjZUNoYW5nZSApO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9ob3Jpem9udGFsKCAnaGVhZGVyJywgd2luZG93TGVmdCApO1xuXHRcdH1cblxuXHRcdHZhciBoZWFkZXIgPSB7XG5cdFx0XHRvZmZzZXQ6IHt0b3A6IDAsIGxlZnQ6IDB9LFxuXHRcdFx0aGVpZ2h0OiAwXG5cdFx0fVxuXHRcdHZhciBmb290ZXIgPSB7XG5cdFx0XHRvZmZzZXQ6IHt0b3A6IDAsIGxlZnQ6IDB9LFxuXHRcdFx0aGVpZ2h0OiAwXG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzLmMuZm9vdGVyICYmIHRoaXMuZG9tLnRmb290Lmxlbmd0aCApIHtcblx0XHRcdGlmICggISB0aGlzLnMuZW5hYmxlICkge1xuXHRcdFx0XHRmb290ZXJNb2RlID0gJ2luLXBsYWNlJztcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKCAhIHBvc2l0aW9uLnZpc2libGUgfHwgcG9zaXRpb24udGZvb3RCb3R0b20gKyB0aGlzLmMuZm9vdGVyT2Zmc2V0IDw9IHdpbmRvd0JvdHRvbSApIHtcblx0XHRcdFx0Zm9vdGVyTW9kZSA9ICdpbi1wbGFjZSc7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIGlmIChcblx0XHRcdFx0Ym9keUJvdHRvbSArIHBvc2l0aW9uLnRmb290SGVpZ2h0ICsgdGhpcy5jLmZvb3Rlck9mZnNldCA+IHdpbmRvd0JvdHRvbSAmJlxuXHRcdFx0XHRib2R5VG9wICsgdGhpcy5jLmZvb3Rlck9mZnNldCA8IHdpbmRvd0JvdHRvbVxuXHRcdFx0KSB7XG5cdFx0XHRcdGZvb3Rlck1vZGUgPSAnaW4nO1xuXHRcdFx0XHRmb3JjZUNoYW5nZSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0Zm9vdGVyTW9kZSA9ICdhYm92ZSc7XG5cdFx0XHR9XG5cdFx0XHRcblx0XHRcdGlmICggZm9yY2VDaGFuZ2UgfHwgZm9vdGVyTW9kZSAhPT0gdGhpcy5zLmZvb3Rlck1vZGUgKSB7XG5cdFx0XHRcdHRoaXMuX21vZGVDaGFuZ2UoIGZvb3Rlck1vZGUsICdmb290ZXInLCBmb3JjZUNoYW5nZSApO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9ob3Jpem9udGFsKCAnZm9vdGVyJywgd2luZG93TGVmdCApO1xuXHRcdFx0XG5cdFx0XHR2YXIgZ2V0T2Zmc2V0SGVpZ2h0ID0gZnVuY3Rpb24gKGVsKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0b2Zmc2V0OiBlbC5vZmZzZXQoKSxcblx0XHRcdFx0XHRoZWlnaHQ6IGVsLm91dGVySGVpZ2h0KClcblx0XHRcdFx0fTtcblx0XHRcdH07XG5cdFx0XG5cdFx0XHRoZWFkZXIgPSB0aGlzLmRvbS5oZWFkZXIuZmxvYXRpbmcgPyBnZXRPZmZzZXRIZWlnaHQodGhpcy5kb20uaGVhZGVyLmZsb2F0aW5nKSA6IGdldE9mZnNldEhlaWdodCh0aGlzLmRvbS50aGVhZCk7XG5cdFx0XHRmb290ZXIgPSB0aGlzLmRvbS5mb290ZXIuZmxvYXRpbmcgPyBnZXRPZmZzZXRIZWlnaHQodGhpcy5kb20uZm9vdGVyLmZsb2F0aW5nKSA6IGdldE9mZnNldEhlaWdodCh0aGlzLmRvbS50Zm9vdCk7XG5cblx0XHRcdC8vIElmIHNjcm9sbGluZyBpcyBlbmFibGVkIGFuZCB0aGUgZm9vdGVyIGlzIG9mZiB0aGUgc2NyZWVuXG5cdFx0XHRpZiAoc2Nyb2xsRW5hYmxlZCAmJiBmb290ZXIub2Zmc2V0LnRvcCA+IHdpbmRvd1RvcCl7Ly8gJiYgZm9vdGVyLm9mZnNldC50b3AgPj0gd2luZG93Qm90dG9tKSB7XG5cdFx0XHRcdC8vIENhbGN1bGF0ZSB0aGUgZ2FwIGJldHdlZW4gdGhlIHRvcCBvZiB0aGUgc2Nyb2xsQm9keSBhbmQgdGhlIHRvcCBvZiB0aGUgd2luZG93XG5cdFx0XHRcdHZhciBvdmVybGFwID0gd2luZG93VG9wIC0gc2Nyb2xsT2Zmc2V0LnRvcDtcblx0XHRcdFx0Ly8gVGhlIG5ldyBoZWlnaHQgaXMgdGhlIGJvdHRvbSBvZiB0aGUgd2luZG93XG5cdFx0XHRcdHZhciBuZXdIZWlnaHQgPSB3aW5kb3dCb3R0b20gK1xuXHRcdFx0XHRcdC8vIElmIHRoZSBnYXAgYmV0d2VlbiB0aGUgdG9wIG9mIHRoZSBzY3JvbGxib2R5IGFuZCB0aGUgd2luZG93IGlzIG1vcmUgdGhhblxuXHRcdFx0XHRcdC8vICB0aGUgaGVpZ2h0IG9mIHRoZSBoZWFkZXIgdGhlbiB0aGUgdG9wIG9mIHRoZSB0YWJsZSBpcyBzdGlsbCB2aXNpYmxlIHNvIGFkZCB0aGF0IGdhcFxuXHRcdFx0XHRcdC8vIERvaW5nIHRoaXMgaGFzIGVmZmVjdGl2ZWx5IGNhbGN1bGF0ZWQgdGhlIGhlaWdodCBmcm9tIHRoZSB0b3Agb2YgdGhlIHRhYmxlIHRvIHRoZSBib3R0b20gb2YgdGhlIGN1cnJlbnQgcGFnZVxuXHRcdFx0XHRcdChvdmVybGFwID4gLWhlYWRlci5oZWlnaHQgPyBvdmVybGFwIDogMCkgLVxuXHRcdFx0XHRcdC8vIFRha2UgZnJvbSB0aGF0XG5cdFx0XHRcdFx0KFxuXHRcdFx0XHRcdFx0Ly8gVGhlIHRvcCBvZiB0aGUgaGVhZGVyIHBsdXNcblx0XHRcdFx0XHRcdGhlYWRlci5vZmZzZXQudG9wICtcblx0XHRcdFx0XHRcdC8vIFRoZSBoZWFkZXIgaGVpZ2h0IGlmIHRoZSBzdGFuZGFyZCBoZWFkZXIgaXMgcHJlc2VudFxuXHRcdFx0XHRcdFx0KG92ZXJsYXAgPCAtaGVhZGVyLmhlaWdodCA/IGhlYWRlci5oZWlnaHQgOiAwKSArXG5cdFx0XHRcdFx0XHQvLyBBbmQgdGhlIGhlaWdodCBvZiB0aGUgZm9vdGVyXG5cdFx0XHRcdFx0XHRmb290ZXIuaGVpZ2h0XG5cdFx0XHRcdFx0KVxuXG5cdFx0XHRcdFx0Ly8gRG9uJ3Qgd2FudCBhIG5lZ2F0aXZlIGhlaWdodFxuXHRcdFx0XHRpZiAobmV3SGVpZ2h0IDwgMCkge1xuXHRcdFx0XHRcdG5ld0hlaWdodCA9IDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBdCB0aGUgZW5kIG9mIHRoZSBhYm92ZSBjYWxjdWxhdGlvbiB0aGUgc3BhY2UgYmV0d2VlbiB0aGUgaGVhZGVyICh0b3Agb2YgdGhlIHBhZ2UgaWYgZmxvYXRpbmcpXG5cdFx0XHRcdC8vIGFuZCB0aGUgcG9pbnQganVzdCBhYm92ZSB0aGUgZm9vdGVyIHNob3VsZCBiZSB0aGUgbmV3IHZhbHVlIGZvciB0aGUgaGVpZ2h0IG9mIHRoZSB0YWJsZS5cblx0XHRcdFx0c2Nyb2xsQm9keS5vdXRlckhlaWdodChuZXdIZWlnaHQpO1xuXHRcdFx0XHRcblx0XHRcdFx0Ly8gTmVlZCBzb21lIHJvdW5kaW5nIGhlcmUgYXMgc29tZXRpbWVzIHZlcnkgc21hbGwgZGVjaW1hbCBwbGFjZXMgYXJlIGVuY291bnRlcmVkXG5cdFx0XHRcdC8vIElmIHRoZSBhY3R1YWwgaGVpZ2h0IGlzIGJpZ2dlciBvciBlcXVhbCB0byB0aGUgaGVpZ2h0IHdlIGp1c3QgYXBwbGllZCB0aGVuIHRoZSBmb290ZXIgaXMgXCJGbG9hdGluZ1wiXG5cdFx0XHRcdGlmKE1hdGgucm91bmQoc2Nyb2xsQm9keS5vdXRlckhlaWdodCgpKSA+PSBNYXRoLnJvdW5kKG5ld0hlaWdodCkpIHtcblx0XHRcdFx0XHQkKHRoaXMuZG9tLnRmb290LnBhcmVudCgpKS5hZGRDbGFzcyhcImZpeGVkSGVhZGVyLWZsb2F0aW5nXCIpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIE90aGVyd2lzZSBtYXgtd2lkdGggaGFzIGtpY2tlZCBpbiBzbyBpdCBpcyBub3QgZmxvYXRpbmdcblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0JCh0aGlzLmRvbS50Zm9vdC5wYXJlbnQoKSkucmVtb3ZlQ2xhc3MoXCJmaXhlZEhlYWRlci1mbG9hdGluZ1wiKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmKHRoaXMuZG9tLmhlYWRlci5mbG9hdGluZyl7XG5cdFx0XHR0aGlzLmRvbS5oZWFkZXIuZmxvYXRpbmdQYXJlbnQuY3NzKCdsZWZ0JywgYm9keUxlZnQtd2luZG93TGVmdCk7XG5cdFx0fVxuXHRcdGlmKHRoaXMuZG9tLmZvb3Rlci5mbG9hdGluZyl7XG5cdFx0XHR0aGlzLmRvbS5mb290ZXIuZmxvYXRpbmdQYXJlbnQuY3NzKCdsZWZ0JywgYm9keUxlZnQtd2luZG93TGVmdCk7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgZml4ZWQgY29sdW1ucyBpcyBiZWluZyB1c2VkIG9uIHRoaXMgdGFibGUgdGhlbiB0aGUgYmxvY2tlcnMgbmVlZCB0byBiZSBjb3BpZWQgYWNyb3NzXG5cdFx0Ly8gQ2xvbmluZyB0aGVzZSBpcyBjbGVhbmVyIHRoYW4gY3JlYXRpbmcgYXMgb3VyIG93biBhcyBpdCB3aWxsIGtlZXAgY29uc2lzdGVuY3kgd2l0aCBmaXhlZENvbHVtbnMgYXV0b21hdGljYWxseVxuXHRcdC8vIEFTU1VNSU5HIHRoYXQgdGhlIGNsYXNzIHJlbWFpbnMgdGhlIHNhbWVcblx0XHRpZiAodGhpcy5zLmR0LnNldHRpbmdzKClbMF0uX2ZpeGVkQ29sdW1ucyAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR2YXIgYWRqdXN0QmxvY2tlciA9IGZ1bmN0aW9uIChzaWRlLCBlbmQsIGVsKSB7XG5cdFx0XHRcdGlmIChlbCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0dmFyIGJsb2NrZXIgPSAkKCdkaXYuZHRmYy0nK3NpZGUrJy0nK2VuZCsnLWJsb2NrZXInKTtcblxuXHRcdFx0XHRcdGVsID0gYmxvY2tlci5sZW5ndGggPT09IDAgP1xuXHRcdFx0XHRcdFx0bnVsbCA6XG5cdFx0XHRcdFx0XHRibG9ja2VyLmNsb25lKCkuYXBwZW5kVG8oJ2JvZHknKS5jc3MoJ3otaW5kZXgnLCAxKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmKGVsICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0ZWwuY3NzKHtcblx0XHRcdFx0XHRcdHRvcDogZW5kID09PSAndG9wJyA/IGhlYWRlci5vZmZzZXQudG9wIDogZm9vdGVyLm9mZnNldC50b3AsXG5cdFx0XHRcdFx0XHRsZWZ0OiBzaWRlID09PSAncmlnaHQnID8gYm9keUxlZnQgKyBib2R5V2lkdGggLSBlbC53aWR0aCgpIDogYm9keUxlZnRcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBlbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRqdXN0IGFsbCBibG9ja2Vyc1xuXHRcdFx0dGhpcy5kb20uaGVhZGVyLnJpZ2h0QmxvY2tlciA9IGFkanVzdEJsb2NrZXIoJ3JpZ2h0JywgJ3RvcCcsIHRoaXMuZG9tLmhlYWRlci5yaWdodEJsb2NrZXIpO1xuXHRcdFx0dGhpcy5kb20uaGVhZGVyLmxlZnRCbG9ja2VyID0gYWRqdXN0QmxvY2tlcignbGVmdCcsICd0b3AnLCB0aGlzLmRvbS5oZWFkZXIubGVmdEJsb2NrZXIpO1xuXHRcdFx0dGhpcy5kb20uZm9vdGVyLnJpZ2h0QmxvY2tlciA9IGFkanVzdEJsb2NrZXIoJ3JpZ2h0JywgJ2JvdHRvbScsIHRoaXMuZG9tLmZvb3Rlci5yaWdodEJsb2NrZXIpO1xuXHRcdFx0dGhpcy5kb20uZm9vdGVyLmxlZnRCbG9ja2VyID0gYWRqdXN0QmxvY2tlcignbGVmdCcsICdib3R0b20nLCB0aGlzLmRvbS5mb290ZXIubGVmdEJsb2NrZXIpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRnVuY3Rpb24gdG8gY2hlY2sgaWYgc2Nyb2xsaW5nIGlzIGVuYWJsZWQgb24gdGhlIHRhYmxlIG9yIG5vdFxuXHQgKiBAcmV0dXJucyBCb29sZWFuIHZhbHVlIGluZGljYXRpbmcgaWYgc2Nyb2xsaW5nIG9uIHRoZSB0YWJsZSBpcyBlbmFibGVkIG9yIG5vdFxuXHQgKi9cblx0X3Njcm9sbEVuYWJsZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBvU2Nyb2xsID0gdGhpcy5zLmR0LnNldHRpbmdzKClbMF0ub1Njcm9sbDtcblx0XHRpZihvU2Nyb2xsLnNZICE9PSBcIlwiIHx8IG9TY3JvbGwuc1ggIT09IFwiXCIpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2Vcblx0fVxufSApO1xuXG5cbi8qKlxuICogVmVyc2lvblxuICogQHR5cGUge1N0cmluZ31cbiAqIEBzdGF0aWNcbiAqL1xuRml4ZWRIZWFkZXIudmVyc2lvbiA9IFwiMy4yLjRcIjtcblxuLyoqXG4gKiBEZWZhdWx0c1xuICogQHR5cGUge09iamVjdH1cbiAqIEBzdGF0aWNcbiAqL1xuRml4ZWRIZWFkZXIuZGVmYXVsdHMgPSB7XG5cdGhlYWRlcjogdHJ1ZSxcblx0Zm9vdGVyOiBmYWxzZSxcblx0aGVhZGVyT2Zmc2V0OiAwLFxuXHRmb290ZXJPZmZzZXQ6IDBcbn07XG5cblxuLyogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICpcbiAqIERhdGFUYWJsZXMgaW50ZXJmYWNlc1xuICovXG5cbi8vIEF0dGFjaCBmb3IgY29uc3RydWN0b3IgYWNjZXNzXG4kLmZuLmRhdGFUYWJsZS5GaXhlZEhlYWRlciA9IEZpeGVkSGVhZGVyO1xuJC5mbi5EYXRhVGFibGUuRml4ZWRIZWFkZXIgPSBGaXhlZEhlYWRlcjtcblxuXG4vLyBEYXRhVGFibGVzIGNyZWF0aW9uIC0gY2hlY2sgaWYgdGhlIEZpeGVkSGVhZGVyIG9wdGlvbiBoYXMgYmVlbiBkZWZpbmVkIG9uIHRoZVxuLy8gdGFibGUgYW5kIGlmIHNvLCBpbml0aWFsaXNlXG4kKGRvY3VtZW50KS5vbiggJ2luaXQuZHQuZHRmaCcsIGZ1bmN0aW9uIChlLCBzZXR0aW5ncywganNvbikge1xuXHRpZiAoIGUubmFtZXNwYWNlICE9PSAnZHQnICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdHZhciBpbml0ID0gc2V0dGluZ3Mub0luaXQuZml4ZWRIZWFkZXI7XG5cdHZhciBkZWZhdWx0cyA9IERhdGFUYWJsZS5kZWZhdWx0cy5maXhlZEhlYWRlcjtcblxuXHRpZiAoIChpbml0IHx8IGRlZmF1bHRzKSAmJiAhIHNldHRpbmdzLl9maXhlZEhlYWRlciApIHtcblx0XHR2YXIgb3B0cyA9ICQuZXh0ZW5kKCB7fSwgZGVmYXVsdHMsIGluaXQgKTtcblxuXHRcdGlmICggaW5pdCAhPT0gZmFsc2UgKSB7XG5cdFx0XHRuZXcgRml4ZWRIZWFkZXIoIHNldHRpbmdzLCBvcHRzICk7XG5cdFx0fVxuXHR9XG59ICk7XG5cbi8vIERhdGFUYWJsZXMgQVBJIG1ldGhvZHNcbkRhdGFUYWJsZS5BcGkucmVnaXN0ZXIoICdmaXhlZEhlYWRlcigpJywgZnVuY3Rpb24gKCkge30gKTtcblxuRGF0YVRhYmxlLkFwaS5yZWdpc3RlciggJ2ZpeGVkSGVhZGVyLmFkanVzdCgpJywgZnVuY3Rpb24gKCkge1xuXHRyZXR1cm4gdGhpcy5pdGVyYXRvciggJ3RhYmxlJywgZnVuY3Rpb24gKCBjdHggKSB7XG5cdFx0dmFyIGZoID0gY3R4Ll9maXhlZEhlYWRlcjtcblxuXHRcdGlmICggZmggKSB7XG5cdFx0XHRmaC51cGRhdGUoKTtcblx0XHR9XG5cdH0gKTtcbn0gKTtcblxuRGF0YVRhYmxlLkFwaS5yZWdpc3RlciggJ2ZpeGVkSGVhZGVyLmVuYWJsZSgpJywgZnVuY3Rpb24gKCBmbGFnICkge1xuXHRyZXR1cm4gdGhpcy5pdGVyYXRvciggJ3RhYmxlJywgZnVuY3Rpb24gKCBjdHggKSB7XG5cdFx0dmFyIGZoID0gY3R4Ll9maXhlZEhlYWRlcjtcblxuXHRcdGZsYWcgPSAoIGZsYWcgIT09IHVuZGVmaW5lZCA/IGZsYWcgOiB0cnVlICk7XG5cdFx0aWYgKCBmaCAmJiBmbGFnICE9PSBmaC5lbmFibGVkKCkgKSB7XG5cdFx0XHRmaC5lbmFibGUoIGZsYWcgKTtcblx0XHR9XG5cdH0gKTtcbn0gKTtcblxuRGF0YVRhYmxlLkFwaS5yZWdpc3RlciggJ2ZpeGVkSGVhZGVyLmVuYWJsZWQoKScsIGZ1bmN0aW9uICgpIHtcblx0aWYgKCB0aGlzLmNvbnRleHQubGVuZ3RoICkge1xuXHRcdHZhciBmaCA9IHRoaXMuY29udGV4dFswXS5fZml4ZWRIZWFkZXI7XG5cblx0XHRpZiAoIGZoICkge1xuXHRcdFx0cmV0dXJuIGZoLmVuYWJsZWQoKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG59ICk7XG5cbkRhdGFUYWJsZS5BcGkucmVnaXN0ZXIoICdmaXhlZEhlYWRlci5kaXNhYmxlKCknLCBmdW5jdGlvbiAoICkge1xuXHRyZXR1cm4gdGhpcy5pdGVyYXRvciggJ3RhYmxlJywgZnVuY3Rpb24gKCBjdHggKSB7XG5cdFx0dmFyIGZoID0gY3R4Ll9maXhlZEhlYWRlcjtcblxuXHRcdGlmICggZmggJiYgZmguZW5hYmxlZCgpICkge1xuXHRcdFx0ZmguZW5hYmxlKCBmYWxzZSApO1xuXHRcdH1cblx0fSApO1xufSApO1xuXG4kLmVhY2goIFsnaGVhZGVyJywgJ2Zvb3RlciddLCBmdW5jdGlvbiAoIGksIGVsICkge1xuXHREYXRhVGFibGUuQXBpLnJlZ2lzdGVyKCAnZml4ZWRIZWFkZXIuJytlbCsnT2Zmc2V0KCknLCBmdW5jdGlvbiAoIG9mZnNldCApIHtcblx0XHR2YXIgY3R4ID0gdGhpcy5jb250ZXh0O1xuXG5cdFx0aWYgKCBvZmZzZXQgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybiBjdHgubGVuZ3RoICYmIGN0eFswXS5fZml4ZWRIZWFkZXIgP1xuXHRcdFx0XHRjdHhbMF0uX2ZpeGVkSGVhZGVyW2VsICsnT2Zmc2V0J10oKSA6XG5cdFx0XHRcdHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5pdGVyYXRvciggJ3RhYmxlJywgZnVuY3Rpb24gKCBjdHggKSB7XG5cdFx0XHR2YXIgZmggPSBjdHguX2ZpeGVkSGVhZGVyO1xuXG5cdFx0XHRpZiAoIGZoICkge1xuXHRcdFx0XHRmaFsgZWwgKydPZmZzZXQnIF0oIG9mZnNldCApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSApO1xufSApO1xuXG5cbnJldHVybiBGaXhlZEhlYWRlcjtcbn0pKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/datatables.net-fixedheader/js/dataTables.fixedHeader.js\n"); /***/ }), /***/ "datatables.net": /*!*********************************!*\ !*** external "$.fn.dataTable" ***! \*********************************/ /***/ (function(module) { "use strict"; module.exports = window["$.fn.dataTable"]; /***/ }), /***/ "jquery": /*!*************************!*\ !*** external "jQuery" ***! \*************************/ /***/ (function(module) { "use strict"; module.exports = window["jQuery"]; /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ !function() { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function() { return module['default']; } : /******/ function() { return module; }; /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ !function() { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = function(exports, definition) { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ !function() { /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } /******/ }(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ !function() { /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ }(); /******/ /************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module can't be inlined because the eval-source-map devtool is used. /******/ var __webpack_exports__ = __webpack_require__("./libs/datatables-fixedheader/datatables.fixedheader.js"); /******/ var __webpack_export_target__ = window; /******/ for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i]; /******/ if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true }); /******/ /******/ })() ;
SIMPAN PERUBAHAN