From 4f92dd1017ca9d637ab6bcfded0149e8e8053b5b Mon Sep 17 00:00:00 2001 From: DrunkLeen Date: Sun, 10 Mar 2024 16:56:31 +0100 Subject: [PATCH] page navigation fixed --- core/views.py | 1 - .../apps/user-management/roles/list/add.js | 150 +++------------- .../js/custom/pages/user-profile/general.js | 2 +- static/panel/js/scripts.bundle.js | 18 +- static/panel/js/widgets.bundle.js | 4 +- .../custom/datatables/datatables.bundle.js | 166 +++++++++--------- static/panel/plugins/global/plugins.bundle.js | 46 ++--- templates/main.html | 19 +- 8 files changed, 165 insertions(+), 241 deletions(-) diff --git a/core/views.py b/core/views.py index 47c24b6..7b670cf 100644 --- a/core/views.py +++ b/core/views.py @@ -241,7 +241,6 @@ def panel_admin(request) -> HttpResponse: context["cpu_percent"] = psutil.cpu_percent(interval=1) context["ram_percent"] = psutil.virtual_memory().percent - print(context) return render(request, 'panel/pages/overview.html', context) return redirect('panel-user', username=request.user.username) diff --git a/static/panel/js/custom/apps/user-management/roles/list/add.js b/static/panel/js/custom/apps/user-management/roles/list/add.js index 7b86b8f..9608cac 100644 --- a/static/panel/js/custom/apps/user-management/roles/list/add.js +++ b/static/panel/js/custom/apps/user-management/roles/list/add.js @@ -1,51 +1,26 @@ "use strict"; // Class definition -var KTUsersAddRole = function () { +var KTUsersAddUser = function () { // Shared variables - const element = document.getElementById('kt_modal_add_role'); - const form = element.querySelector('#kt_modal_add_role_form'); + const element = document.getElementById('kt_modal_add_user'); + const form = element.querySelector('#kt_modal_add_user_form'); const modal = new bootstrap.Modal(element); // Init add schedule modal - var initAddRole = () => { + var initAddUser = () => { - // Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/ - var validator = FormValidation.formValidation( - form, - { - fields: { - 'role_name': { - validators: { - notEmpty: { - message: 'Role name is required' - } - } - }, - }, - - plugins: { - trigger: new FormValidation.plugins.Trigger(), - bootstrap: new FormValidation.plugins.Bootstrap5({ - rowSelector: '.fv-row', - eleInvalidClass: '', - eleValidClass: '' - }) - } - } - ); - - // Close button handler - const closeButton = element.querySelector('[data-kt-roles-modal-action="close"]'); - closeButton.addEventListener('click', e => { + // Cancel button handler + const cancelButton = element.querySelector('[data-kt-users-modal-action="cancel"]'); + cancelButton.addEventListener('click', e => { e.preventDefault(); Swal.fire({ - text: "Are you sure you would like to close?", + text: "Are you sure you would like to cancel?", icon: "warning", showCancelButton: true, buttonsStyling: false, - confirmButtonText: "Yes, close it!", + confirmButtonText: "Yes, cancel it!", cancelButtonText: "No, return", customClass: { confirmButton: "btn btn-primary", @@ -53,14 +28,25 @@ var KTUsersAddRole = function () { } }).then(function (result) { if (result.value) { - modal.hide(); // Hide modal - } + form.reset(); // Reset form + modal.hide(); + } else if (result.dismiss === 'cancel') { + Swal.fire({ + text: "Your form has not been cancelled!.", + icon: "error", + buttonsStyling: false, + confirmButtonText: "Ok, got it!", + customClass: { + confirmButton: "btn btn-primary", + } + }); + } }); }); - // Cancel button handler - const cancelButton = element.querySelector('[data-kt-roles-modal-action="cancel"]'); - cancelButton.addEventListener('click', e => { + // Close button handler + const closeButton = element.querySelector('[data-kt-users-modal-action="close"]'); + closeButton.addEventListener('click', e => { e.preventDefault(); Swal.fire({ @@ -76,8 +62,8 @@ var KTUsersAddRole = function () { } }).then(function (result) { if (result.value) { - form.reset(); // Reset form - modal.hide(); // Hide modal + form.reset(); // Reset form + modal.hide(); } else if (result.dismiss === 'cancel') { Swal.fire({ text: "Your form has not been cancelled!.", @@ -91,95 +77,17 @@ var KTUsersAddRole = function () { } }); }); - - // Submit button handler - const submitButton = element.querySelector('[data-kt-roles-modal-action="submit"]'); - submitButton.addEventListener('click', function (e) { - // Prevent default button action - e.preventDefault(); - - // Validate form before submit - if (validator) { - validator.validate().then(function (status) { - console.log('validated!'); - - if (status == 'Valid') { - // Show loading indication - submitButton.setAttribute('data-kt-indicator', 'on'); - - // Disable button to avoid multiple click - submitButton.disabled = true; - - // Simulate form submission. For more info check the plugin's official documentation: https://sweetalert2.github.io/ - setTimeout(function () { - // Remove loading indication - submitButton.removeAttribute('data-kt-indicator'); - - // Enable button - submitButton.disabled = false; - - // Show popup confirmation - Swal.fire({ - text: "Form has been successfully submitted!", - icon: "success", - buttonsStyling: false, - confirmButtonText: "Ok, got it!", - customClass: { - confirmButton: "btn btn-primary" - } - }).then(function (result) { - if (result.isConfirmed) { - modal.hide(); - } - }); - - //form.submit(); // Submit form - }, 2000); - } else { - // Show popup warning. For more info check the plugin's official documentation: https://sweetalert2.github.io/ - Swal.fire({ - text: "Sorry, looks like there are some errors detected, please try again.", - icon: "error", - buttonsStyling: false, - confirmButtonText: "Ok, got it!", - customClass: { - confirmButton: "btn btn-primary" - } - }); - } - }); - } - }); - - - } - - // Select all handler - const handleSelectAll = () =>{ - // Define variables - const selectAll = form.querySelector('#kt_roles_select_all'); - const allCheckboxes = form.querySelectorAll('[type="checkbox"]'); - - // Handle check state - selectAll.addEventListener('change', e => { - - // Apply check state to all checkboxes - allCheckboxes.forEach(c => { - c.checked = e.target.checked; - }); - }); } return { // Public functions init: function () { - initAddRole(); - handleSelectAll(); + initAddUser(); } }; }(); // On document ready KTUtil.onDOMContentLoaded(function () { - KTUsersAddRole.init(); + KTUsersAddUser.init(); }); \ No newline at end of file diff --git a/static/panel/js/custom/pages/user-profile/general.js b/static/panel/js/custom/pages/user-profile/general.js index 957fafb..3b248aa 100644 --- a/static/panel/js/custom/pages/user-profile/general.js +++ b/static/panel/js/custom/pages/user-profile/general.js @@ -122,7 +122,7 @@ var KTProfileGeneral = function () { if ( localStorage.getItem('nav-initialized') === "1") { window.scroll({ - top: parseInt(profileNav.getAttribute("data-kt-pages-scroll-position")), + top: parseInt(profileNav.getAttribute("data-kt-page-scroll-position")), behavior: 'smooth' }); } diff --git a/static/panel/js/scripts.bundle.js b/static/panel/js/scripts.bundle.js index 4257fc0..1a1d89e 100644 --- a/static/panel/js/scripts.bundle.js +++ b/static/panel/js/scripts.bundle.js @@ -31,7 +31,7 @@ if (document.readyState === "loading") { KTComponents.init(); } - // Init pages loader + // Init page loader window.addEventListener("load", function() { KTApp.hidePageLoading(); }); @@ -649,14 +649,14 @@ var KTApp = function () { } var showPageLoading = function() { - document.body.classList.add('pages-loading'); - document.body.setAttribute('data-kt-app-pages-loading', "on"); + document.body.classList.add('page-loading'); + document.body.setAttribute('data-kt-app-page-loading', "on"); } var hidePageLoading = function() { - // CSS3 Transitions only after pages load(.pages-loading or .app-pages-loading class added to body tag and remove with JS on pages load) - document.body.classList.remove('pages-loading'); - document.body.removeAttribute('data-kt-app-pages-loading'); + // CSS3 Transitions only after page load(.page-loading or .app-page-loading class added to body tag and remove with JS on page load) + document.body.classList.remove('page-loading'); + document.body.removeAttribute('data-kt-app-page-loading'); } return { @@ -7443,7 +7443,7 @@ var KTAppLayoutBuilder = function() { ); setTimeout(function() { - location.reload(); // reload pages + location.reload(); // reload page }, 1500); }, error: function(response) { @@ -7537,13 +7537,13 @@ var KTAppLayoutBuilder = function() { return; toastr.success( - "Preview has been successfully reset and the pages will be reloaded.", + "Preview has been successfully reset and the page will be reloaded.", "Reset Preview!", {timeOut: 0, extendedTimeOut: 0, closeButton: true, closeDuration: 0} ); setTimeout(function() { - location.reload(); // reload pages + location.reload(); // reload page }, 1500); }, error: function(response) { diff --git a/static/panel/js/widgets.bundle.js b/static/panel/js/widgets.bundle.js index 9ccde0a..ab8c5c1 100644 --- a/static/panel/js/widgets.bundle.js +++ b/static/panel/js/widgets.bundle.js @@ -17976,7 +17976,7 @@ var KTTimelineWidget1 = function () { group: 'ui', start: moment(now).add(30, 'minutes'), end: moment(now).add(2.5, 'hours'), - content: 'Landing pages', + content: 'Landing page', progress: "55%", color: 'danger', users: [ @@ -18637,7 +18637,7 @@ var KTTimelineWidget4 = function () { group: 'ui', start: moment(now).add(30, 'minutes'), end: moment(now).add(2.5, 'hours'), - content: 'Landing pages', + content: 'Landing page', progress: "55%", color: 'danger', users: [ diff --git a/static/panel/plugins/custom/datatables/datatables.bundle.js b/static/panel/plugins/custom/datatables/datatables.bundle.js index f8f991b..010d4ed 100644 --- a/static/panel/plugins/custom/datatables/datatables.bundle.js +++ b/static/panel/plugins/custom/datatables/datatables.bundle.js @@ -93,7 +93,7 @@ * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. * Can be either 'current', whereby the current sorting of the table is used, or * 'original' whereby the original order the data was read into the table is used. - * @param {string} [oOpts.pages=all] Limit the selection to the currently displayed pages + * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page * ("current") or not ("all"). If 'current' is given, then order is assumed to be * 'current' and filter is 'applied', regardless of what they might be given as. * @returns {object} jQuery object, filtered by the given selector. @@ -141,7 +141,7 @@ * @param {string} [oOpts.order=current] Order of the data in the processed array. * Can be either 'current', whereby the current sorting of the table is used, or * 'original' whereby the original order the data was read into the table is used. - * @param {string} [oOpts.pages=all] Limit the selection to the currently displayed pages + * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page * ("current") or not ("all"). If 'current' is given, then order is assumed to be * 'current' and filter is 'applied', regardless of what they might be given as. * @returns {array} Data for the matched elements. If any elements, as a result of the @@ -620,7 +620,7 @@ /** * This function will place a new row directly after a row which is currently - * on display on the pages, with the HTML contents that is passed into the + * on display on the page, with the HTML contents that is passed into the * function. This can be used, for example, to ask for confirmation that a * particular record should be deleted. * @param {node} nTr The table row to 'open' @@ -663,7 +663,7 @@ * function. With this function you can have a DataTables table go to the next, * previous, first or last pages. * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" - * or pages number to jump to (integer), note that pages 0 is the first pages. + * or page number to jump to (integer), note that page 0 is the first page. * @param {bool} [bRedraw=true] Redraw the table or not * @dtopt API * @deprecated Since v1.10 @@ -1274,7 +1274,7 @@ } } else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) { - /* Grab the data from the pages - only do this when deferred loading or no Ajax + /* Grab the data from the page - only do this when deferred loading or no Ajax * source since there is no point in reading the DOM data if we are then going * to replace it with Ajax data */ @@ -3586,7 +3586,7 @@ * Redraw the table - taking account of the various features which are enabled * @param {object} oSettings dataTables settings object * @param {boolean} [holdPosition] Keep the current paging position. By default - * the paging is reset to the first pages + * the paging is reset to the first page * @memberof DataTable#oApi */ function _fnReDraw( settings, holdPosition ) @@ -3623,7 +3623,7 @@ /** - * Add the options to the pages HTML for the table + * Add the options to the page HTML for the table * @param {object} oSettings dataTables settings object * @memberof DataTable#oApi */ @@ -4188,7 +4188,7 @@ * @param {string} json.sEcho Tracking flag for DataTables to match requests * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering - * @param {array} json.aaData The data to display on this pages + * @param {array} json.aaData The data to display on this page * @param {string} [json.sColumns] Column ordering (sName, comma separated) * @memberof DataTable#oApi */ @@ -5032,12 +5032,12 @@ /** - * Alter the display settings to change the pages + * Alter the display settings to change the page * @param {object} settings DataTables settings object * @param {string|int} action Paging action to take: "first", "previous", - * "next" or "last" or pages number to jump to (integer) + * "next" or "last" or page number to jump to (integer) * @param [bool] redraw Automatically draw the update or not - * @returns {bool} true pages has changed, false - no change + * @returns {bool} true page has changed, false - no change * @memberof DataTable#oApi */ function _fnPageChange ( settings, action, redraw ) @@ -5103,7 +5103,7 @@ } else { // No change event - paging was called, but no change - _fnCallbackFire( settings, null, 'pages-nc', [settings] ); + _fnCallbackFire( settings, null, 'page-nc', [settings] ); } return changed; @@ -5836,7 +5836,7 @@ } ) ); }; - // IE6/7 will crash if we bind a resize event handler on pages load. + // IE6/7 will crash if we bind a resize event handler on page load. // To be removed in 1.11 which drops IE6/7 support if ( ie67 ) { setTimeout( bindResize, 1000 ); @@ -6827,7 +6827,7 @@ start = end - len; } - // Keep the start record on the current pages + // Keep the start record on the current page start -= (start % len); if ( len === -1 || start < 0 ) @@ -6998,7 +6998,7 @@ * The API class is heavily based on jQuery, presenting a chainable interface * that you can use to interact with tables. Each instance of the API class has * a "context" - i.e. the tables that it will operate on. This could be a single - * table, all tables on a pages or a sub-set thereof. + * table, all tables on a page or a sub-set thereof. * * Additionally the API is designed to allow you to easily work with the data in * the tables, retrieving and manipulating it as required. This is done by @@ -7629,25 +7629,25 @@ /** - * Get the current pages index. + * Get the current page index. * - * @return {integer} Current pages index (zero based) + * @return {integer} Current page index (zero based) *//** - * Set the current pages. + * Set the current page. * - * Note that if you attempt to show a pages which does not exist, DataTables will + * Note that if you attempt to show a page which does not exist, DataTables will * not throw an error, but rather reset the paging. * * @param {integer|string} action The paging action to take. This can be one of: - * * `integer` - The pages index to jump to + * * `integer` - The page index to jump to * * `string` - An action to take: - * * `first` - Jump to first pages. - * * `next` - Jump to the next pages - * * `previous` - Jump to previous pages - * * `last` - Jump to the last pages. + * * `first` - Jump to first page. + * * `next` - Jump to the next page + * * `previous` - Jump to previous page + * * `last` - Jump to the last page. * @returns {DataTables.Api} this */ - _api_register( 'pages()', function ( action ) { + _api_register( 'page()', function ( action ) { if ( action === undefined ) { return this.page.info().page; // not an expensive call } @@ -7666,18 +7666,18 @@ * with a suitable selector. * * @return {object} Object with the following properties set: - * * `pages` - Current pages index (zero based - i.e. the first pages is `0`) + * * `page` - Current page index (zero based - i.e. the first page is `0`) * * `pages` - Total number of pages - * * `start` - Display index for the first record shown on the current pages - * * `end` - Display index for the last record shown on the current pages + * * `start` - Display index for the first record shown on the current page + * * `end` - Display index for the last record shown on the current page * * `length` - Display length (number of records). Note that generally `start * + length = end`, but this is not always true, for example if there are - * only 2 records to show on the final pages, with a length of 10. + * only 2 records to show on the final page, with a length of 10. * * `recordsTotal` - Full data set length * * `recordsDisplay` - Data set length once the current filtering criterion * are applied. */ - _api_register( 'pages.info()', function ( action ) { + _api_register( 'page.info()', function ( action ) { if ( this.context.length === 0 ) { return undefined; } @@ -7703,17 +7703,17 @@ /** - * Get the current pages length. + * Get the current page length. * - * @return {integer} Current pages length. Note `-1` indicates that all records + * @return {integer} Current page length. Note `-1` indicates that all records * are to be shown. *//** - * Set the current pages length. + * Set the current page length. * * @param {integer} Page length to set. Use `-1` to show all records. * @returns {DataTables.Api} this */ - _api_register( 'pages.len()', function ( len ) { + _api_register( 'page.len()', function ( len ) { // Note that we can't call this function 'length()' because `length` // is a Javascript property of functions which defines how many arguments // the function expects. @@ -7723,7 +7723,7 @@ undefined; } - // else, set the pages length + // else, set the page length return this.iterator( 'table', function ( settings ) { _fnLengthChange( settings, len ); } ); @@ -7985,7 +7985,7 @@ _range( 0, displayMaster.length ); } else if ( page == 'current' ) { - // Current pages implies that order=current and filter=applied, since it is + // Current page implies that order=current and filter=applied, since it is // fairly senseless otherwise, regardless of what order and search actually // are for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i").addClass(this.c.dom.container.className)},this._constructor()}v.extend(k.prototype,{action:function(t,n){t=this._nodeToButton(t);return n===x?t.conf.action:(t.conf.action=n,this)},active:function(t,n){var t=this._nodeToButton(t),e=this.c.dom.button.active,t=v(t.node);return n===x?t.hasClass(e):(t.toggleClass(e,n===x||n),this)},add:function(t,n,e){var o=this.s.buttons;if("string"==typeof n){for(var i=n.split("-"),s=this.s,r=0,a=i.length-1;r"),p.conf._collection=p.collection,p.conf.split)for(var h=0;h'+this.c.dom.splitDropdown.text+""));this._expandButton(p.buttons,p.conf.buttons,p.conf.split,!l,l,s,p.conf)}p.conf.parent=r,f.init&&f.init.call(a.button(p.node),a,v(p.node),f),0}}}},_buildButton:function(n,t,e,o){function i(t){return"function"==typeof t?t(h,l,n):t}var s,r,a,l,c=this.c.dom.button,u=this.c.dom.buttonLiner,d=this.c.dom.collection,f=(this.c.dom.split,this.c.dom.splitCollection),p=this.c.dom.splitDropdownButton,h=this.s.dt;if(n.spacer)return r=v("").addClass("dt-button-spacer "+n.style+" "+c.spacerClass).html(i(n.text)),{conf:n,node:r,inserter:r,buttons:[],inCollection:t,isSplit:e,inSplit:o,collection:null};if(!e&&o&&f?c=p:!e&&t&&d.button&&(c=d.button),!e&&o&&f.buttonLiner?u=f.buttonLiner:!e&&t&&d.buttonLiner&&(u=d.buttonLiner),n.available&&!n.available(h,n)&&!n.hasOwnProperty("html"))return!1;n.hasOwnProperty("html")?l=v(n.html):(s=function(t,n,e,o){o.action.call(n.button(e),t,n,e,o),v(n.table().node()).triggerHandler("buttons-action.dt",[n.button(e),n,e,o])},r=n.tag||c.tag,a=n.clickBlurs===x||n.clickBlurs,l=v("<"+r+"/>").addClass(c.className).addClass(o?this.c.dom.splitDropdownButton.className:"").attr("tabindex",this.s.dt.settings()[0].iTabIndex).attr("aria-controls",this.s.dt.table().node().id).on("click.dtb",function(t){t.preventDefault(),!l.hasClass(c.disabled)&&n.action&&s(t,h,l,n),a&&l.trigger("blur")}).on("keypress.dtb",function(t){13===t.keyCode&&(t.preventDefault(),!l.hasClass(c.disabled)&&n.action&&s(t,h,l,n))}),"a"===r.toLowerCase()&&l.attr("href","#"),"button"===r.toLowerCase()&&l.attr("type","button"),u.tag?(p=v("<"+u.tag+"/>").html(i(n.text)).addClass(u.className),"a"===u.tag.toLowerCase()&&p.attr("href","#"),l.append(p)):l.html(i(n.text)),!1===n.enabled&&l.addClass(c.disabled),n.className&&l.addClass(n.className),n.titleAttr&&l.attr("title",i(n.titleAttr)),n.attr&&l.attr(n.attr),n.namespace||(n.namespace=".dt-button-"+w++),n.config!==x&&n.config.split&&(n.split=n.config.split));var b,g,m,y,f=this.c.dom.buttonContainer,d=f&&f.tag?v("<"+f.tag+"/>").addClass(f.className).append(l):l;return this._addKey(n),this.c.buttonCreated&&(d=this.c.buttonCreated(n,d)),e&&((b=v("
").addClass(this.c.dom.splitWrapper.className)).append(l),g=v.extend(n,{text:this.c.dom.splitDropdown.text,className:this.c.dom.splitDropdown.className,closeButton:!1,attr:{"aria-haspopup":"dialog","aria-expanded":!1},align:this.c.dom.splitDropdown.align,splitAlignClass:this.c.dom.splitDropdown.splitAlignClass}),this._addKey(g),m=function(t,n,e,o){C.split.action.call(n.button(b),t,n,e,o),v(n.table().node()).triggerHandler("buttons-action.dt",[n.button(e),n,e,o]),e.attr("aria-expanded",!0)},y=v('").on("click.dtb",function(t){t.preventDefault(),t.stopPropagation(),y.hasClass(c.disabled)||m(t,h,y,g),a&&y.trigger("blur")}).on("keypress.dtb",function(t){13===t.keyCode&&(t.preventDefault(),y.hasClass(c.disabled)||m(t,h,y,g))}),0===n.split.length&&y.addClass("dtb-hide-drop"),b.append(y).attr(g.attr)),{conf:n,node:(e?b:l).get(0),inserter:e?b:d,buttons:[],inCollection:t,isSplit:e,inSplit:o,collection:null}},_nodeToButton:function(t,n){for(var e=0,o=(n=n||this.s.buttons).length;e").addClass("dt-button-collection").addClass(b.collectionLayout).addClass(b.splitAlignClass).addClass(p).css("display","none").attr({"aria-modal":!0,role:"dialog"}),o=v(o).addClass(b.contentClassName).attr("role","menu").appendTo(s),g.attr("aria-expanded","true"),g.parents("body")[0]!==y.body&&(g=y.body.lastChild),b.popoverTitle?s.prepend('
'+b.popoverTitle+"
"):b.collectionTitle&&s.prepend('
'+b.collectionTitle+"
"),b.closeButton&&s.prepend('
x
').addClass("dtb-collection-closeable"),_(s.insertAfter(g),b.fade),n=v(t.table().container()),d=s.css("position"),"container"!==b.span&&"dt-container"!==b.align||(g=g.parent(),s.css("width",n.width())),"absolute"===d?(p=v(g[0].offsetParent),t=g.position(),n=g.offset(),r=p.offset(),a=p.position(),l=m.getComputedStyle(p[0]),r.height=p.outerHeight(),r.width=p.width()+parseFloat(l.paddingLeft),r.right=r.left+r.width,r.bottom=r.top+r.height,p=t.top+g.outerHeight(),c=t.left,s.css({top:p,left:c}),l=m.getComputedStyle(s[0]),(u=s.offset()).height=s.outerHeight(),u.width=s.outerWidth(),u.right=u.left+u.width,u.bottom=u.top+u.height,u.marginTop=parseFloat(l.marginTop),u.marginBottom=parseFloat(l.marginBottom),b.dropup&&(p=t.top-u.height-u.marginTop-u.marginBottom),"button-right"!==b.align&&!s.hasClass(b.rightAlignClassName)||(c=t.left-u.width+g.outerWidth()),"dt-container"!==b.align&&"container"!==b.align||(c=cr.width&&(c=r.width-u.width),a.left+c+u.width>v(m).width()&&(c=v(m).width()-u.width-a.left),n.left+c<0&&(c=-n.left),a.top+p+u.height>v(m).height()+v(m).scrollTop()&&(p=t.top-u.height-u.marginTop-u.marginBottom),a.top+p").addClass(n).css("display","none").insertAfter(o),e):A(v("div."+n),e,function(){v(this).removeClass(n).remove()})},k.instanceSelector=function(t,i){var s,r,a;return t===x||null===t?v.map(i,function(t){return t.inst}):(s=[],r=v.map(i,function(t){return t.name}),(a=function(t){var n;if(Array.isArray(t))for(var e=0,o=t.length;e)<[^<]*)*<\/script>/gi,"")).replace(//g,""),n&&!n.stripHtml||(t=t.replace(/<[^>]*>/g,"")),n&&!n.trim||(t=t.replace(/^\s+|\s+$/g,"")),n&&!n.stripNewlines||(t=t.replace(/\n/g," ")),n&&!n.decodeEntities||(l.innerHTML=t,t=l.value)),t},k.defaults={buttons:["copy","excel","csv","pdf","print"],name:"main",tabIndex:0,dom:{container:{tag:"div",className:"dt-buttons"},collection:{tag:"div",className:""},button:{tag:"button",className:"dt-button",active:"active",disabled:"disabled",spacerClass:""},buttonLiner:{tag:"span",className:""},split:{tag:"div",className:"dt-button-split"},splitWrapper:{tag:"div",className:"dt-btn-split-wrapper"},splitDropdown:{tag:"button",text:"▼",className:"dt-btn-split-drop",align:"split-right",splitAlignClass:"dt-button-split-left"},splitDropdownButton:{tag:"button",className:"dt-btn-split-drop-button dt-button"},splitCollection:{tag:"div",className:"dt-button-split-collection"}}},v.extend(C,{collection:{text:function(t){return t.i18n("buttons.collection","Collection")},className:"buttons-collection",closeButton:!(k.version="2.3.6"),init:function(t,n,e){n.attr("aria-expanded",!1)},action:function(t,n,e,o){o._collection.parents("body").length?this.popover(!1,o):this.popover(o._collection,o),"keypress"===t.type&&v("a, button",o._collection).eq(0).focus()},attr:{"aria-haspopup":"dialog"}},split:{text:function(t){return t.i18n("buttons.split","Split")},className:"buttons-split",closeButton:!1,init:function(t,n,e){return n.attr("aria-expanded",!1)},action:function(t,n,e,o){this.popover(o._collection,o)},attr:{"aria-haspopup":"dialog"}},copy:function(t,n){if(C.copyHtml5)return"copyHtml5"},csv:function(t,n){if(C.csvHtml5&&C.csvHtml5.available(t,n))return"csvHtml5"},excel:function(t,n){if(C.excelHtml5&&C.excelHtml5.available(t,n))return"excelHtml5"},pdf:function(t,n){if(C.pdfHtml5&&C.pdfHtml5.available(t,n))return"pdfHtml5"},pageLength:function(t){var n=t.settings()[0].aLengthMenu,e=[],o=[];if(Array.isArray(n[0]))e=n[0],o=n[1];else for(var i=0;i"+t+"":"",_(v('
').html(t).append(v("
")["string"==typeof n?"html":"append"](n)).css("display","none").appendTo("body")),e!==x&&0!==e&&(i=setTimeout(function(){o.buttons.info(!1)},e)),this.on("destroy.btn-info",function(){o.buttons.info(!1)})),this}),e.Api.register("buttons.exportData()",function(t){if(this.context.length)return c(new e.Api(this.context[0]),t)}),e.Api.register("buttons.exportInfo()",function(t){return{filename:n(t=t||{}),title:r(t),messageTop:a(this,t.message||t.messageTop,"top"),messageBottom:a(this,t.messageBottom,"bottom")}});var i,n=function(t){var n;return(n="function"==typeof(n="*"===t.filename&&"*"!==t.title&&t.title!==x&&null!==t.title&&""!==t.title?t.title:t.filename)?n():n)===x||null===n?null:(n=(n=-1!==n.indexOf("*")?n.replace("*",v("head > title").text()).trim():n).replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g,""))+(s(t.extension)||"")},s=function(t){return null===t||t===x?null:"function"==typeof t?t():t},r=function(t){t=s(t.title);return null===t?null:-1!==t.indexOf("*")?t.replace("*",v("head > title").text()||"Exported data"):t},a=function(t,n,e){n=s(n);return null===n?null:(t=v("caption",t.table().container()).eq(0),"*"===n?t.css("caption-side")!==e?null:t.length?t.text():"":n)},l=v("