@@ -0,0 +1,610 @@
+/*!
+ * bootstrap-fileinput vh.1.0.0 from v5.5.2
+ * http://plugins.krajee.com/file-input
+ *
+ * Krajee default styling for bootstrap-fileinput.
+ * Author: Kartik Visweswaran
+ * Copyright: 2014 - 2022, Kartik Visweswaran, Krajee.com
+ * Licensed under the BSD-3-Clause
+ * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
+ */
+input[type=file].file-loading, .file-loading input[type=file] {
+ width: 0;
+ height: 0;
+}
+
+.file-input-ajax-new .no-browse .input-group-btn, .file-input-ajax-new .fileinput-upload-button, .file-input-ajax-new .fileinput-remove-button, .file-input-new .no-browse .input-group-btn, .file-input-new .fileinput-upload-button, .file-input-new .fileinput-remove-button, .file-input-new .glyphicon-file, .file-input-new .close, .file-input-new .file-preview, .file-zoom-dialog .modal-header:after, .file-zoom-dialog .modal-header:before, .file-caption-icon, .hide-content .kv-file-content, .kv-hidden {
+ display: none;
+.file-zoom-dialog .floating-buttons, .file-zoom-dialog .btn-navigate, .krajee-default .file-thumb-progress, .file-preview .fileinput-remove, .file-caption-icon, .btn-file input[type=file], .file-no-browse {
+ position: absolute;
+.file-zoom-dialog .modal-dialog, .krajee-default .file-thumbnail-footer, .krajee-default.file-preview-frame, .file-preview, .file-caption, .btn-file, .file-loading:before, .file-input {
+ position: relative;
+.krajee-default .file-other-error, .krajee-default .file-actions, .file-error-message ul, .file-error-message pre {
+ text-align: left;
+.file-error-message ul, .file-error-message pre {
+ margin: 0;
+.krajee-default .file-upload-indicator, .krajee-default .file-drag-handle {
+ float: left;
+ margin-top: 10px;
+ width: 16px;
+ height: 16px;
+.krajee-default .file-thumb-progress .progress-bar, .krajee-default .file-thumb-progress .progress {
+ height: 11px;
+ font-size: 9px;
+.krajee-default .file-size-info, .krajee-default .file-caption-info {
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 160px;
+ height: 15px;
+ margin: auto;
+.file-zoom-content > .file-object.type-image, .file-zoom-content > .file-object.type-flash, .file-zoom-content > .file-object.type-video {
+ max-width: 100%;
+ max-height: 100%;
+ width: auto;
+.file-zoom-content > .file-object.type-flash, .file-zoom-content > .file-object.type-video {
+ height: 100%;
+.file-zoom-content > .file-object.type-default, .file-zoom-content > .file-object.type-text, .file-zoom-content > .file-object.type-html, .file-zoom-content > .file-object.type-pdf {
+ width: 100%;
+.file-no-browse {
+ left: 50%;
+ bottom: 20%;
+ width: 1px;
+ height: 1px;
+ font-size: 0;
+ opacity: 0;
+ border: none;
+ background: none;
+ outline: none;
+ box-shadow: none;
+.file-loading:before {
+ content: " Loading...";
+ display: inline-block;
+ padding-left: 20px;
+ line-height: 16px;
+ font-size: 13px;
+ font-variant: small-caps;
+ color: #999;
+ background: transparent url(../img/loading.gif) top left no-repeat;
+.file-object {
+ margin: 0 0 -5px 0;
+ padding: 0;
+.btn-file {
+.btn-file input[type=file] {
+ top: 0;
+ left: 0;
+ min-width: 100%;
+ min-height: 100%;
+ text-align: right;
+ background: none repeat scroll 0 0 transparent;
+ cursor: inherit;
+.btn-file ::-ms-browse {
+ font-size: 10000px;
+.file-caption .input-group {
+ align-items: center;
+.file-caption.icon-visible .file-caption-icon {
+.file-caption.icon-visible .file-caption-name {
+ padding-left: 25px;
+.file-caption.icon-visible > .input-group-lg .file-caption-name {
+ padding-left: 30px;
+.file-caption.icon-visible > .input-group-sm .file-caption-name {
+ padding-left: 22px;
+.file-caption-icon {
+ left: 4px;
+ padding: 7px 5px;
+.input-group-lg .file-caption-icon {
+ font-size: 1.25rem;
+.input-group-sm .file-caption-icon {
+ font-size: 0.875rem;
+ padding: 0.25rem;
+.file-error-message {
+ color: #a94442;
+ background-color: #f2dede;
+ margin: 5px;
+ border: 1px solid #ebccd1;
+ border-radius: 4px;
+ padding: 15px;
+.file-error-message pre {
+ margin: 5px 0;
+.file-caption-disabled {
+ background-color: #eee;
+ cursor: not-allowed;
+ opacity: 1;
+.file-preview {
+ border-radius: 5px;
+ border: 1px solid #ddd;
+ padding: 8px;
+ margin-bottom: 5px;
+.file-preview .btn-xs {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+.file-preview .fileinput-remove {
+ top: 1px;
+ right: 1px;
+ line-height: 10px;
+.file-preview .clickable {
+ cursor: pointer;
+.file-preview .kv-zoom-cache {
+.file-preview-image {
+ font: 40px Impact, Charcoal, sans-serif;
+ color: #008000;
+ height: auto;
+.krajee-default.file-preview-frame {
+ margin: 8px;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
+ padding: 6px;
+ text-align: center;
+ height: 244px;
+.krajee-default.file-preview-frame .kv-file-content {
+ width: 213px;
+ height: 140px;
+.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
+ width: 400px;
+.krajee-default.file-preview-frame .file-thumbnail-footer {
+ height: 70px;
+.krajee-default.file-preview-frame:not(.file-preview-error):hover {
+ border: 1px solid rgba(0, 0, 0, 0.3);
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4);
+.krajee-default.file-preview-frame[data-template=audio] .kv-file-content {
+ width: 240px;
+ height: 55px;
+.krajee-default .file-preview-text {
+ color: #428bca;
+ resize: none;
+.krajee-default .file-preview-html {
+.krajee-default .file-other-icon {
+ font-size: 6em;
+ line-height: 1;
+.krajee-default .file-footer-buttons {
+ float: right;
+.krajee-default .file-footer-caption {
+ padding-top: 4px;
+ font-size: 11px;
+ margin-bottom: 30px;
+.krajee-default .file-preview-error {
+ opacity: 0.65;
+.krajee-default .file-thumb-progress {
+ top: 37px;
+ right: 0;
+.krajee-default .file-thumb-progress .progress {
+ color: #ccc;
+.krajee-default .file-thumb-progress .progress-bar {
+ font-family: Verdana, Helvetica, sans-serif;
+.krajee-default.kvsortable-ghost {
+ background: #e1edf7;
+ border: 2px solid #a1abff;
+.krajee-default .file-preview-other:hover {
+ opacity: 0.8;
+.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover {
+ color: #000;
+.file-upload-stats {
+ font-size: 10px;
+.kv-upload-progress .progress {
+ height: 20px;
+ line-height: 20px;
+ margin: 10px 0;
+.kv-upload-progress .progress-bar {
+.kv-upload-progress .file-upload-stats {
+ margin: -10px 0 5px;
+.file-thumb-progress .progress {
+ background-color: #ccc;
+.file-thumb-progress .progress-bar {
+ font-size: 0.7rem;
+.file-zoom-dialog .file-other-icon {
+ font-size: 22em;
+ font-size: 50vmin;
+.file-zoom-dialog .modal-dialog {
+.file-zoom-dialog .modal-header {
+ display: flex;
+ justify-content: space-between;
+.file-zoom-dialog .btn-navigate {
+ margin: 0 0.1rem;
+ font-size: 1.2rem;
+ width: 2.4rem;
+ height: 2.4rem;
+ top: 50%;
+ border-radius: 50%;
+.file-zoom-dialog .btn-navigate * {
+.file-zoom-dialog .floating-buttons {
+ top: 5px;
+ right: 10px;
+.file-zoom-dialog .btn-kv-prev {
+.file-zoom-dialog .btn-kv-next {
+.file-zoom-dialog .kv-zoom-header {
+ padding: 0.5rem;
+.file-zoom-dialog .kv-zoom-body {
+.file-zoom-dialog .kv-zoom-description {
+ font-size: 0.8rem;
+ background-color: #1a1a1a;
+ padding: 1rem;
+ border-radius: 0.5rem;
+ color: #fff;
+ left: 15%;
+ right: 15%;
+ bottom: 15%;
+.file-zoom-dialog .kv-desc-hide {
+ padding: 0 0.1rem;
+.file-zoom-dialog .kv-desc-hide:hover,
+.file-zoom-dialog .kv-desc-hide:focus {
+ opacity: 0.7;
+.file-input-new .no-browse .form-control {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+.file-input-ajax-new .no-browse .form-control {
+.file-thumb-loading:not(:has(.file-preview-thumbnails .file-preview-frame)) {
+ background: transparent url(../img/loading.gif) no-repeat scroll center center content-box !important;
+.file-thumb-loading .file-drop-zone:hover {
+ padding-bottom: 6px;
+.file-thumb-loading .file-drop-zone:hover .file-preview-status {
+ margin-top: -1px;
+.file-thumb-loading .file-drop-zone *:first-child:is(.file-preview-thumbnails):has(.file-preview-frame) + .file-preview-status {
+ background: rgba(255, 255, 255, 0.38) url(../img/loading.gif) no-repeat scroll center center content-box !important;
+ width: calc(100% - 60px);
+.file-drop-zone {
+ border: 1px dashed #aaa;
+ min-height: 272px;
+ vertical-align: middle;
+ margin: 12px 15px 12px 12px;
+ padding: 5px;
+ user-select: none;
+.file-drop-zone.clickable:hover {
+ border: 2px dashed #999;
+ margin-top: 11px;
+ margin-bottom: 11px;
+.file-drop-zone.clickable:hover .file-preview-frame {
+ margin-left: 7px;
+ margin-bottom: 7px;
+.file-drop-zone.clickable:has(.file-preview-frame):hover {
+.file-drop-zone.clickable .file-preview-thumbnails {
+.file-drop-zone:not(:has(input[type=file][multiple])), .file-drop-zone:not(:has(input[type=file][multiple=true])) {
+ justify-content: center;
+.file-drop-zone *:first-child:is(.file-preview-thumbnails):has(.file-preview-frame) + .file-preview-status {
+ top: 25px;
+ transform: translateX(-50%);
+.file-drop-zone .file-preview-status {
+ height: 260px;
+.file-drop-zone-title {
+ color: #aaa;
+ font-size: 1.6em;
+ padding: 85px 10px;
+ cursor: default;
+.file-highlighted {
+ border: 2px dashed #999 !important;
+.file-uploading {
+ background: url(../img/loading-sm.gif) no-repeat center bottom 10px;
+.file-zoom-fullscreen .modal-dialog {
+.file-zoom-fullscreen .modal-content {
+ border-radius: 0;
+ min-height: 100vh;
+.file-zoom-fullscreen .kv-zoom-body {
+ overflow-y: auto;
+.floating-buttons {
+ z-index: 3000;
+.floating-buttons .btn-kv {
+ margin-left: 3px;
+.kv-zoom-actions {
+ min-width: 140px;
+.kv-zoom-actions .btn-kv {
+.file-zoom-content {
+ min-height: 300px;
+.file-zoom-content .file-preview-image {
+.file-zoom-content .file-preview-video {
+.file-zoom-content > .file-object.type-image {
+ min-height: inherit;
+.file-zoom-content > .file-object.type-audio {
+ height: 30px;
+.file-zoom-content:hover {
+ background: transparent;
+@media (min-width: 576px) {
+ .file-zoom-dialog .modal-dialog {
+ max-width: 500px;
+ }
+@media (min-width: 992px) {
+ .file-zoom-dialog .modal-lg {
+ max-width: 800px;
+@media (max-width: 767px) {
+ .file-preview-thumbnails {
+ flex-direction: column;
+ .file-zoom-dialog .modal-header {
+@media (max-width: 350px) {
+ .krajee-default.file-preview-frame:not([data-template=audio]) .kv-file-content {
+@media (max-width: 420px) {
+ .krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
+.file-loading[dir=rtl]:before {
+ background: transparent url(../img/loading.gif) top right no-repeat;
+ padding-left: 0;
+ padding-right: 20px;
+.clickable .file-drop-zone-title {
+.file-sortable .file-drag-handle {
+ cursor: grab;
+.file-sortable .file-drag-handle:hover {
+.file-grabbing, .file-grabbing * {
+ cursor: not-allowed !important;
+.file-grabbing .file-preview-thumbnails * {
+ cursor: grabbing !important;
+.file-preview-initial.sortable-chosen {
+ background-color: #d9edf7;
+ border-color: #17a2b8;
+.file-preview-other-frame, .file-preview-object, .kv-file-content, .kv-zoom-body {
+.btn-kv-rotate {
+.kv-file-rotate {
+.rotatable:not(.hide-rotate) .btn-kv-rotate {
+.rotatable:not(.hide-rotate) .kv-file-rotate {
+.rotatable .file-zoom-detail {
+ transform-origin: center center;
+.rotatable .kv-file-content {
+.rotatable .kv-file-content > :first-child {
+.rotate-animate {
+ transition: transform 0.3s ease;
+.kv-overflow-hidden {
@@ -0,0 +1,6583 @@
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(window.jQuery);
+}(function ($) {
+ $.fn.fileinputLocales = {};
+ $.fn.fileinputThemes = {};
+ if (!$.fn.fileinputBsVersion) {
+ $.fn.fileinputBsVersion = (window.bootstrap && window.bootstrap.Alert && window.bootstrap.Alert.VERSION) ||
+ (window.Alert && window.Alert.VERSION) || '3.x.x';
+ String.prototype.setTokens = function (replacePairs) {
+ var str = this.toString(), key, re;
+ for (key in replacePairs) {
+ if (replacePairs.hasOwnProperty(key)) {
+ re = new RegExp('\{' + key + '\}', 'g');
+ str = str.replace(re, replacePairs[key]);
+ return str;
+ };
+ if (!Array.prototype.flatMap) { // polyfill flatMap
+ Array.prototype.flatMap = function (lambda) {
+ return [].concat(this.map(lambda));
+ var $h, FileInput;
+ // fileinput helper object for all global variables and internal helper methods
+ $h = {
+ FRAMES: '.kv-preview-thumb',
+ SORT_CSS: 'file-sortable',
+ INIT_FLAG: 'init-',
+ SCRIPT_SRC: document && document.currentScript && document.currentScript.src || null,
+ OBJECT_PARAMS: '<param name="controller" value="true" />\n' +
+ '<param name="allowFullScreen" value="true" />\n' +
+ '<param name="allowScriptAccess" value="always" />\n' +
+ '<param name="autoPlay" value="false" />\n' +
+ '<param name="autoStart" value="false" />\n' +
+ '<param name="quality" value="high" />\n',
+ DEFAULT_PREVIEW: '<div class="file-preview-other">\n' +
+ '<span class="{previewFileIconClass}">{previewFileIcon}</span>\n' +
+ '</div>',
+ MODAL_ID: 'kvFileinputModal',
+ MODAL_EVENTS: ['show', 'shown', 'hide', 'hidden', 'loaded'],
+ logMessages: {
+ ajaxError: '{status}: {error}. Error Details: {text}.',
+ badDroppedFiles: 'Error scanning dropped files!',
+ badExifParser: 'Error loading the piexif.js library. {details}',
+ badInputType: 'The input "type" must be set to "file" for initializing the "bootstrap-fileinput" plugin.',
+ exifWarning: 'To avoid this warning, either set "autoOrientImage" to "false" OR ensure you have loaded ' +
+ 'the "piexif.js" library correctly on your page before the "fileinput.js" script.',
+ invalidChunkSize: 'Invalid upload chunk size: "{chunkSize}". Resumable uploads are disabled.',
+ invalidThumb: 'Invalid thumb frame with id: "{id}".',
+ noResumableSupport: 'The browser does not support resumable or chunk uploads.',
+ noUploadUrl: 'The "uploadUrl" is not set. Ajax uploads and resumable uploads have been disabled.',
+ retryStatus: 'Retrying upload for chunk # {chunk} for {filename}... retry # {retry}.',
+ chunkQueueError: 'Could not push task to ajax pool for chunk index # {index}.',
+ resumableMaxRetriesReached: 'Maximum resumable ajax retries ({n}) reached.',
+ resumableRetryError: 'Could not retry the resumable request (try # {n})... aborting.',
+ resumableAborting: 'Aborting / cancelling the resumable request.',
+ resumableRequestError: 'Error processing resumable request. {msg}'
+ },
+ objUrl: window.URL || window.webkitURL,
+ getZoomPlaceholder: function () { // used to prevent 404 errors in URL parsing
+ var src = $h.SCRIPT_SRC, srcPath, zoomVar = '?kvTemp__2873389129__=';
+ if (!src) {
+ return zoomVar;
+ srcPath = src.substring(0, src.lastIndexOf("/"));
+ return srcPath.substring(0, srcPath.lastIndexOf("/") + 1) + 'img/loading.gif' + zoomVar;
+ isBs: function (ver) {
+ var chk = $.trim(($.fn.fileinputBsVersion || '') + '');
+ ver = parseInt(ver, 10);
+ if (!chk) {
+ return ver === 4;
+ return ver === parseInt(chk.charAt(0), 10);
+ defaultButtonCss: function (fill) {
+ return 'btn-default btn-' + (fill ? '' : 'outline-') + 'secondary';
+ now: function () {
+ return new Date().getTime();
+ round: function (num) {
+ num = parseFloat(num);
+ return isNaN(num) ? 0 : Math.floor(Math.round(num));
+ getArray: function (obj) {
+ var i, arr = [], len = obj && obj.length || 0;
+ for (i = 0; i < len; i++) {
+ arr.push(obj[i]);
+ return arr;
+ getFileRelativePath: function (file) {
+ /** @namespace file.relativePath */
+ /** @namespace file.webkitRelativePath */
+ return String(file.newPath || file.relativePath || file.webkitRelativePath || $h.getFileName(file) || null);
+ getFileId: function (file, generateFileId) {
+ var relativePath = $h.getFileRelativePath(file);
+ if (typeof generateFileId === 'function') {
+ return generateFileId(file);
+ if (!file) {
+ return null;
+ if (!relativePath) {
+ return (file.size + '_' + encodeURIComponent(relativePath).replace(/%/g, '_'));
+ getFrameSelector: function (id, selector) {
+ selector = selector || '';
+ return '[id="' + id + '"]' + selector;
+ getZoomSelector: function (id, selector) {
+ return $h.getFrameSelector('zoom-' + id, selector);
+ getFrameElement: function ($element, id, selector) {
+ return $element.find($h.getFrameSelector(id, selector));
+ getZoomElement: function ($element, id, selector) {
+ return $element.find($h.getZoomSelector(id, selector));
+ getElapsed: function (seconds) {
+ var delta = seconds, out = '', result = {}, structure = {
+ year: 31536000,
+ month: 2592000,
+ week: 604800, // uncomment row to ignore
+ day: 86400, // feel free to add your own row
+ hour: 3600,
+ minute: 60,
+ second: 1
+ $h.getObjectKeys(structure).forEach(function (key) {
+ result[key] = Math.floor(delta / structure[key]);
+ delta -= result[key] * structure[key];
+ });
+ $.each(result, function (key, value) {
+ if (value > 0) {
+ out += (out ? ' ' : '') + value + key.substring(0, 1);
+ return out;
+ debounce: function (func, delay) {
+ var inDebounce;
+ return function () {
+ var args = arguments, context = this;
+ clearTimeout(inDebounce);
+ inDebounce = setTimeout(function () {
+ func.apply(context, args);
+ }, delay);
+ stopEvent: function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ getFileName: function (file) {
+ /** @namespace file.fileName */
+ return file ? (file.fileName || file.name || '') : ''; // some confusion in different versions of Firefox
+ createObjectURL: function (data) {
+ if ($h.objUrl && $h.objUrl.createObjectURL && data) {
+ return $h.objUrl.createObjectURL(data);
+ return '';
+ revokeObjectURL: function (data) {
+ if ($h.objUrl && $h.objUrl.revokeObjectURL && data) {
+ $h.objUrl.revokeObjectURL(data);
+ compare: function (input, str, exact) {
+ return input !== undefined && (exact ? input === str : input.match(str));
+ isIE: function (ver) {
+ var div, status;
+ // check for IE versions < 11
+ if (navigator.appName !== 'Microsoft Internet Explorer') {
+ return false;
+ if (ver === 10) {
+ return new RegExp('msie\\s' + ver, 'i').test(navigator.userAgent);
+ div = document.createElement('div');
+ div.innerHTML = '<!--[if IE ' + ver + ']> <i></i> <![endif]-->';
+ status = div.getElementsByTagName('i').length;
+ document.body.appendChild(div);
+ div.parentNode.removeChild(div);
+ return status;
+ canOrientImage: function ($el) {
+ var $img = $(document.createElement('img')).css({width: '1px', height: '1px'}).insertAfter($el),
+ flag = $img.css('image-orientation');
+ $img.remove();
+ return !!flag;
+ canAssignFilesToInput: function () {
+ var input = document.createElement('input');
+ try {
+ input.type = 'file';
+ input.files = null;
+ return true;
+ } catch (err) {
+ getDragDropFolders: function (items) {
+ var i, item, len = items ? items.length : 0, folders = 0;
+ if (len > 0 && items[0].webkitGetAsEntry()) {
+ item = items[i].webkitGetAsEntry();
+ if (item && item.isDirectory) {
+ folders++;
+ return folders;
+ initModal: function ($modal) {
+ var $body = $('body');
+ if ($body.length) {
+ $modal.appendTo($body);
+ isFunction: function (v) {
+ return typeof v === 'function';
+ isEmpty: function (value, trim) {
+ if (value === undefined || value === null || value === '') {
+ if ($h.isString(value) && trim) {
+ return $.trim(value) === '';
+ if ($h.isArray(value)) {
+ return value.length === 0;
+ if ($.isPlainObject(value) && $.isEmptyObject(value)) {
+ isArray: function (a) {
+ return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]';
+ isString: function (a) {
+ return Object.prototype.toString.call(a) === '[object String]';
+ ifSet: function (needle, haystack, def) {
+ def = def || '';
+ return (haystack && typeof haystack === 'object' && needle in haystack) ? haystack[needle] : def;
+ cleanArray: function (arr) {
+ if (!(arr instanceof Array)) {
+ arr = [];
+ return arr.filter(function (e) {
+ return (e !== undefined && e !== null);
+ spliceArray: function (arr, index, reverseOrder) {
+ var i, j = 0, out = [], newArr;
+ return [];
+ newArr = $.extend(true, [], arr);
+ if (reverseOrder) {
+ newArr.reverse();
+ for (i = 0; i < newArr.length; i++) {
+ if (i !== index) {
+ out[j] = newArr[i];
+ j++;
+ out.reverse();
+ getNum: function (num, def) {
+ def = def || 0;
+ if (typeof num === 'number') {
+ return num;
+ if (typeof num === 'string') {
+ return isNaN(num) ? def : num;
+ hasFileAPISupport: function () {
+ return !!(window.File && window.FileReader);
+ hasDragDropSupport: function () {
+ var div = document.createElement('div');
+ /** @namespace div.draggable */
+ /** @namespace div.ondragstart */
+ /** @namespace div.ondrop */
+ return !$h.isIE(9) &&
+ (div.draggable !== undefined || (div.ondragstart !== undefined && div.ondrop !== undefined));
+ hasFileUploadSupport: function () {
+ return $h.hasFileAPISupport() && window.FormData;
+ hasBlobSupport: function () {
+ return !!window.Blob && Boolean(new Blob());
+ } catch (e) {
+ hasArrayBufferViewSupport: function () {
+ return new Blob([new Uint8Array(100)]).size === 100;
+ hasResumableUploadSupport: function () {
+ /** @namespace Blob.prototype.webkitSlice */
+ /** @namespace Blob.prototype.mozSlice */
+ return $h.hasFileUploadSupport() && $h.hasBlobSupport() && $h.hasArrayBufferViewSupport() &&
+ (!!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice || !!Blob.prototype.slice || false);
+ dataURI2Blob: function (dataURI) {
+ var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder ||
+ window.MSBlobBuilder, canBlob = $h.hasBlobSupport(), byteStr, arrayBuffer, intArray, i, mimeStr, bb,
+ canProceed = (canBlob || BlobBuilder) && window.atob && window.ArrayBuffer && window.Uint8Array;
+ if (!canProceed) {
+ if (dataURI.split(',')[0].indexOf('base64') >= 0) {
+ byteStr = atob(dataURI.split(',')[1]);
+ byteStr = decodeURIComponent(dataURI.split(',')[1]);
+ arrayBuffer = new ArrayBuffer(byteStr.length);
+ intArray = new Uint8Array(arrayBuffer);
+ for (i = 0; i < byteStr.length; i += 1) {
+ intArray[i] = byteStr.charCodeAt(i);
+ mimeStr = dataURI.split(',')[0].split(':')[1].split(';')[0];
+ if (canBlob) {
+ return new Blob([$h.hasArrayBufferViewSupport() ? intArray : arrayBuffer], {type: mimeStr});
+ bb = new BlobBuilder();
+ bb.append(arrayBuffer);
+ return bb.getBlob(mimeStr);
+ arrayBuffer2String: function (buffer) {
+ if (window.TextDecoder) {
+ return new TextDecoder('utf-8').decode(buffer);
+ var array = Array.prototype.slice.apply(new Uint8Array(buffer)), out = '', i = 0, len, c, char2, char3;
+ len = array.length;
+ while (i < len) {
+ c = array[i++];
+ switch (c >> 4) { // jshint ignore:line
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ // 0xxxxxxx
+ out += String.fromCharCode(c);
+ break;
+ case 12:
+ case 13:
+ // 110x xxxx 10xx xxxx
+ char2 = array[i++];
+ out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); // jshint ignore:line
+ case 14:
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ char3 = array[i++];
+ out += String.fromCharCode(((c & 0x0F) << 12) | // jshint ignore:line
+ ((char2 & 0x3F) << 6) | // jshint ignore:line
+ ((char3 & 0x3F) << 0)); // jshint ignore:line
+ isHtml: function (str) {
+ var a = document.createElement('div');
+ a.innerHTML = str;
+ for (var c = a.childNodes, i = c.length; i--;) {
+ if (c[i].nodeType === 1) {
+ isPdf: function (str) {
+ if ($h.isEmpty(str)) {
+ str = str.toString().trim().replace(/\n/g, ' ');
+ if (str.length === 0) {
+ isSvg: function (str) {
+ return str.match(/^\s*<\?xml/i) && (str.match(/<!DOCTYPE svg/i) || str.match(/<svg/i));
+ getMimeType: function (sign, contents, type) {
+ var signature = sign || "";
+ switch (signature) {
+ case 'ffd8ffe0':
+ case 'ffd8ffe1':
+ case 'ffd8ffe2':
+ return 'image/jpeg';
+ case '89504e47':
+ return 'image/png';
+ case '47494638':
+ return 'image/gif';
+ case '49492a00':
+ return 'image/tiff';
+ case '52494646':
+ return 'image/webp';
+ case '41433130':
+ return 'image/vnd.dwg';
+ case '66747970':
+ return 'video/3gp';
+ case '4f676753':
+ return 'video/ogg';
+ case '1a45dfa3':
+ return 'video/mkv';
+ case '000001ba':
+ case '000001b3':
+ return 'video/mpeg';
+ case '3026b275':
+ return 'video/wmv';
+ case '25504446':
+ return 'application/pdf';
+ case '25215053':
+ return 'application/ps';
+ case '504b0304':
+ case '504b0506':
+ case '504b0508':
+ return 'application/zip';
+ case '377abcaf':
+ return 'application/7z';
+ case '75737461':
+ return 'application/tar';
+ case '7801730d':
+ return 'application/dmg';
+ default:
+ switch (signature.substring(0, 6)) {
+ case '435753':
+ return 'application/x-shockwave-flash';
+ case '494433':
+ return 'audio/mp3';
+ case '425a68':
+ return 'application/bzip';
+ switch (signature.substring(0, 4)) {
+ case '424d':
+ return 'image/bmp';
+ case 'fffb':
+ case '4d5a':
+ return 'application/exe';
+ case '1f9d':
+ case '1fa0':
+ case '1f8b':
+ return 'application/gzip';
+ return contents && !contents.match(
+ /[^\u0000-\u007f]/) ? 'application/text-plain' : type;
+ addCss: function ($el, css) {
+ $el.removeClass(css).addClass(css);
+ getElement: function (options, param, value) {
+ return ($h.isEmpty(options) || $h.isEmpty(options[param])) ? value : $(options[param]);
+ createElement: function (str, tag) {
+ tag = tag || 'div';
+ return $($.parseHTML('<' + tag + '>' + str + '</' + tag + '>'));
+ uniqId: function () {
+ return (new Date().getTime() + Math.floor(Math.random() * Math.pow(10, 15))).toString(36);
+ cspBuffer: {
+ CSP_ATTRIB: 'data-csp-01928735', // a randomly named temporary attribute to store the CSP elem id
+ domElementsStyles: {},
+ stash: function (htmlString) {
+ var self = this, outerDom = $.parseHTML('<div>' + htmlString + '</div>'), $el = $(outerDom);
+ $el.find('[style]').each(function (key, elem) {
+ var $elem = $(elem), styleDeclaration = $elem[0].style, id = $h.uniqId(), styles = {};
+ if (styleDeclaration && styleDeclaration.length) {
+ $(styleDeclaration).each(function () {
+ styles[this] = styleDeclaration[this];
+ self.domElementsStyles[id] = styles;
+ $elem.removeAttr('style').attr(self.CSP_ATTRIB, id);
+ $el.filter('*').removeAttr('style'); // make sure all style attr are removed
+ var values = Object.values ? Object.values(outerDom) : Object.keys(outerDom).map(function (itm) {
+ return outerDom[itm];
+ return values.flatMap(function (elem) {
+ return elem.innerHTML;
+ }).join('');
+ apply: function (domElement) {
+ var self = this, $el = $(domElement);
+ $el.find('[' + self.CSP_ATTRIB + ']').each(function (key, elem) {
+ var $elem = $(elem), id = $elem.attr(self.CSP_ATTRIB), styles = self.domElementsStyles[id];
+ if (styles) {
+ $elem.css(styles);
+ $elem.removeAttr(self.CSP_ATTRIB);
+ self.domElementsStyles = {};
+ setHtml: function ($elem, htmlString) {
+ var buf = $h.cspBuffer;
+ $elem.html(buf.stash(htmlString));
+ buf.apply($elem);
+ return $elem;
+ htmlEncode: function (str, undefVal) {
+ if (str === undefined) {
+ return undefVal || null;
+ return str.replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+ replaceTags: function (str, tags) {
+ var out = str;
+ if (!tags) {
+ $.each(tags, function (key, value) {
+ if (typeof value === 'function') {
+ value = value();
+ out = out.split(key).join(value);
+ cleanMemory: function ($thumb) {
+ var data = $thumb.is('img') ? $thumb.attr('src') : $thumb.find('source').attr('src');
+ $h.revokeObjectURL(data);
+ findFileName: function (filePath) {
+ var sepIndex = filePath.lastIndexOf('/');
+ if (sepIndex === -1) {
+ sepIndex = filePath.lastIndexOf('\\');
+ return filePath.split(filePath.substring(sepIndex, sepIndex + 1)).pop();
+ checkFullScreen: function () {
+ return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement ||
+ document.msFullscreenElement;
+ toggleFullScreen: function (maximize) {
+ var doc = document, de = doc.documentElement, isFullScreen = $h.checkFullScreen();
+ if (de && maximize && !isFullScreen) {
+ if (de.requestFullscreen) {
+ de.requestFullscreen();
+ if (de.msRequestFullscreen) {
+ de.msRequestFullscreen();
+ if (de.mozRequestFullScreen) {
+ de.mozRequestFullScreen();
+ if (de.webkitRequestFullscreen) {
+ de.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+ if (isFullScreen) {
+ if (doc.exitFullscreen) {
+ doc.exitFullscreen();
+ if (doc.msExitFullscreen) {
+ doc.msExitFullscreen();
+ if (doc.mozCancelFullScreen) {
+ doc.mozCancelFullScreen();
+ if (doc.webkitExitFullscreen) {
+ doc.webkitExitFullscreen();
+ moveArray: function (arr, oldIndex, newIndex, reverseOrder) {
+ var newArr = $.extend(true, [], arr);
+ if (newIndex >= newArr.length) {
+ var k = newIndex - newArr.length;
+ while ((k--) + 1) {
+ newArr.push(undefined);
+ newArr.splice(newIndex, 0, newArr.splice(oldIndex, 1)[0]);
+ return newArr;
+ closeButton: function (css) {
+ css = ($h.isBs(5) ? 'btn-close' : 'close') + (css ? ' ' + css : '');
+ return '<button type="button" class="' + css + '" aria-label="Close">\n' +
+ ($h.isBs(5) ? '' : ' <span aria-hidden="true">×</span>\n') +
+ '</button>';
+ getRotation: function (value) {
+ switch (value) {
+ return 'rotateY(180deg)';
+ return 'rotate(180deg)';
+ return 'rotate(180deg) rotateY(180deg)';
+ return 'rotate(270deg) rotateY(180deg)';
+ return 'rotate(90deg)';
+ return 'rotate(90deg) rotateY(180deg)';
+ case 8:
+ return 'rotate(270deg)';
+ setTransform: function (el, val) {
+ if (!el) {
+ return;
+ el.style.transform = val;
+ el.style.webkitTransform = val;
+ el.style['-moz-transform'] = val;
+ el.style['-ms-transform'] = val;
+ el.style['-o-transform'] = val;
+ getObjectKeys: function (obj) {
+ var keys = [];
+ if (obj) {
+ $.each(obj, function (key) {
+ keys.push(key);
+ return keys;
+ getObjectSize: function (obj) {
+ return $h.getObjectKeys(obj).length;
+ /**
+ * Small dependency injection for the task manager
+ * https://gist.github.com/fearphage/4341799
+ whenAll: function (array) {
+ var s = [].slice, resolveValues = arguments.length === 1 && $h.isArray(array) ? array : s.call(arguments),
+ deferred = $.Deferred(), i, failed = 0, value, length = resolveValues.length,
+ remaining = length, rejectContexts, rejectValues, resolveContexts, updateFunc;
+ rejectContexts = rejectValues = resolveContexts = Array(length);
+ updateFunc = function (index, contexts, values) {
+ if (values !== resolveValues) {
+ failed++;
+ deferred.notifyWith(contexts[index] = this, values[index] = s.call(arguments));
+ if (!(--remaining)) {
+ deferred[(!failed ? 'resolve' : 'reject') + 'With'](contexts, values);
+ for (i = 0; i < length; i++) {
+ if ((value = resolveValues[i]) && $.isFunction(value.promise)) {
+ value.promise()
+ .done(updateFunc(i, resolveContexts, resolveValues))
+ .fail(updateFunc(i, rejectContexts, rejectValues));
+ deferred.notifyWith(this, value);
+ --remaining;
+ if (!remaining) {
+ deferred.resolveWith(resolveContexts, resolveValues);
+ return deferred.promise();
+ FileInput = function (element, options) {
+ var self = this;
+ self.$element = $(element);
+ self.$parent = self.$element.parent();
+ if (!self._validate()) {
+ self.isPreviewable = $h.hasFileAPISupport();
+ self.isIE9 = $h.isIE(9);
+ self.isIE10 = $h.isIE(10);
+ if (self.isPreviewable || self.isIE9) {
+ self._init(options);
+ self._listen();
+ self.$element.removeClass('file-loading');
+ FileInput.prototype = {
+ constructor: FileInput,
+ _cleanup: function () {
+ self.reader = null;
+ self.clearFileStack();
+ self.fileBatchCompleted = true;
+ self.isError = false;
+ self.isDuplicateError = false;
+ self.isPersistentError = false;
+ self.cancelling = false;
+ self.paused = false;
+ self.lastProgress = 0;
+ self._initAjax();
+ _isAborted: function () {
+ return self.cancelling || self.paused;
+ _initAjax: function () {
+ var self = this, tm = self.taskManager = {
+ pool: {},
+ addPool: function (id) {
+ return (tm.pool[id] = new tm.TasksPool(id));
+ getPool: function (id) {
+ return tm.pool[id];
+ addTask: function (id, logic) { // add standalone task directly from task manager
+ return new tm.Task(id, logic);
+ TasksPool: function (id) {
+ var tp = this;
+ tp.id = id;
+ tp.cancelled = false;
+ tp.cancelledDeferrer = $.Deferred();
+ tp.tasks = {};
+ tp.addTask = function (id, logic) {
+ return (tp.tasks[id] = new tm.Task(id, logic));
+ tp.size = function () {
+ return $h.getObjectSize(tp.tasks);
+ tp.run = function (maxThreads) {
+ var i = 0, failed = false, task, tasksList = $h.getObjectKeys(tp.tasks).map(function (key) {
+ return tp.tasks[key];
+ }), tasksDone = [], deferred = $.Deferred(), enqueue, callback;
+ if (tp.cancelled) {
+ tp.cancelledDeferrer.resolve();
+ return deferred.reject();
+ // if run all at once
+ if (!maxThreads) {
+ var tasksDeferredList = $h.getObjectKeys(tp.tasks).map(function (key) {
+ return tp.tasks[key].deferred;
+ // when all are done
+ $h.whenAll(tasksDeferredList).done(function () {
+ var argv = $h.getArray(arguments);
+ if (!tp.cancelled) {
+ deferred.resolve.apply(null, argv);
+ tp.cancelledDeferrer.reject();
+ deferred.reject.apply(null, argv);
+ }).fail(function () {
+ // run all tasks
+ $.each(tp.tasks, function (id) {
+ task = tp.tasks[id];
+ task.run();
+ return deferred;
+ enqueue = function (task) {
+ $.when(task.deferred)
+ .fail(function () {
+ failed = true;
+ callback.apply(null, arguments);
+ })
+ .always(callback);
+ callback = function () {
+ // notify a task just ended
+ deferred.notify(argv);
+ tasksDone.push(argv);
+ deferred.reject.apply(null, tasksDone);
+ if (tasksDone.length === tp.size()) {
+ if (failed) {
+ deferred.resolve.apply(null, tasksDone);
+ // if there are any tasks remaining
+ if (tasksList.length) {
+ task = tasksList.shift();
+ enqueue(task);
+ // run the first "maxThreads" tasks
+ while (tasksList.length && i++ < maxThreads) {
+ tp.cancel = function () {
+ tp.cancelled = true;
+ return tp.cancelledDeferrer;
+ Task: function (id, logic) {
+ var tk = this;
+ tk.id = id;
+ tk.deferred = $.Deferred();
+ tk.logic = logic;
+ tk.context = null;
+ tk.run = function () {
+ argv.unshift(tk.deferred); // add deferrer as first argument
+ logic.apply(tk.context, argv); // run task
+ return tk.deferred; // return deferrer
+ tk.runWithContext = function (context) {
+ tk.context = context;
+ return tk.run();
+ self.ajaxQueue = [];
+ self.ajaxRequests = [];
+ self.ajaxPool = null;
+ self.ajaxAborted = false;
+ _init: function (options, refreshMode) {
+ var self = this, f, $el = self.$element, $cont, t, tmp;
+ self.options = options;
+ self.zoomPlaceholder = $h.getZoomPlaceholder();
+ self.canOrientImage = $h.canOrientImage($el);
+ $.each(options, function (key, value) {
+ switch (key) {
+ case 'minFileCount':
+ case 'maxFileCount':
+ case 'maxTotalFileCount':
+ case 'minFileSize':
+ case 'maxFileSize':
+ case 'maxFilePreviewSize':
+ case 'resizeQuality':
+ case 'resizeIfSizeMoreThan':
+ case 'progressUploadThreshold':
+ case 'initialPreviewCount':
+ case 'zoomModalHeight':
+ case 'minImageHeight':
+ case 'maxImageHeight':
+ case 'minImageWidth':
+ case 'maxImageWidth':
+ case 'bytesToKB':
+ self[key] = $h.getNum(value);
+ self[key] = value;
+ if (!self.bytesToKB || self.bytesToKB <= 0) {
+ self.bytesToKB = 1024;
+ if (self.errorCloseButton === undefined) {
+ self.errorCloseButton = $h.closeButton('kv-error-close' + ($h.isBs(5) ? ' float-end' : ''));
+ if (self.maxTotalFileCount > 0 && self.maxTotalFileCount < self.maxFileCount) {
+ self.maxTotalFileCount = self.maxFileCount;
+ if (self.rtl) { // swap buttons for rtl
+ tmp = self.previewZoomButtonIcons.prev;
+ self.previewZoomButtonIcons.prev = self.previewZoomButtonIcons.next;
+ self.previewZoomButtonIcons.next = tmp;
+ // validate chunk threads to not exceed maxAjaxThreads
+ if (!isNaN(self.maxAjaxThreads) && self.maxAjaxThreads < self.resumableUploadOptions.maxThreads) {
+ self.resumableUploadOptions.maxThreads = self.maxAjaxThreads;
+ self._initFileManager();
+ if (typeof self.autoOrientImage === 'function') {
+ self.autoOrientImage = self.autoOrientImage();
+ if (typeof self.autoOrientImageInitial === 'function') {
+ self.autoOrientImageInitial = self.autoOrientImageInitial();
+ if (!refreshMode) {
+ self._cleanup();
+ self.duplicateErrors = [];
+ self.$form = $el.closest('form');
+ self._initTemplateDefaults();
+ self.uploadFileAttr = !$h.isEmpty($el.attr('name')) ? $el.attr('name') : 'file_data';
+ t = self._getLayoutTemplate('progress');
+ self.progressTemplate = t.replace('{class}', self.progressClass);
+ self.progressInfoTemplate = t.replace('{class}', self.progressInfoClass);
+ self.progressPauseTemplate = t.replace('{class}', self.progressPauseClass);
+ self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass);
+ self.progressErrorTemplate = t.replace('{class}', self.progressErrorClass);
+ self.isDisabled = $el.attr('disabled') || $el.attr('readonly');
+ if (self.isDisabled) {
+ $el.attr('disabled', true);
+ self.isClickable = self.browseOnZoneClick && self.showPreview &&
+ (self.dropZoneEnabled || !$h.isEmpty(self.defaultPreviewContent));
+ self.isAjaxUpload = $h.hasFileUploadSupport() && !$h.isEmpty(self.uploadUrl);
+ self.dropZoneEnabled = $h.hasDragDropSupport() && self.dropZoneEnabled;
+ if (!self.isAjaxUpload) {
+ self.dropZoneEnabled = self.dropZoneEnabled && $h.canAssignFilesToInput();
+ self.slug = typeof options.slugCallback === 'function' ? options.slugCallback : self._slugDefault;
+ self.mainTemplate = self.showCaption ? self._getLayoutTemplate('main1') : self._getLayoutTemplate('main2');
+ self.captionTemplate = self._getLayoutTemplate('caption');
+ self.previewGenericTemplate = self._getPreviewTemplate('generic');
+ if (!self.imageCanvas && self.resizeImage && (self.maxImageWidth || self.maxImageHeight)) {
+ self.imageCanvas = document.createElement('canvas');
+ self.imageCanvasContext = self.imageCanvas.getContext('2d');
+ if ($h.isEmpty($el.attr('id'))) {
+ $el.attr('id', $h.uniqId());
+ self.namespace = '.fileinput_' + $el.attr('id').replace(/-/g, '_');
+ if (self.$container === undefined) {
+ self.$container = self._createContainer();
+ self._refreshContainer();
+ $cont = self.$container;
+ self.$dropZone = $cont.find('.file-drop-zone');
+ self.$progress = $cont.find('.kv-upload-progress');
+ self.$btnUpload = $cont.find('.fileinput-upload');
+ self.$captionContainer = $h.getElement(options, 'elCaptionContainer', $cont.find('.file-caption'));
+ self.$caption = $h.getElement(options, 'elCaptionText', $cont.find('.file-caption-name'));
+ if (!$h.isEmpty(self.msgPlaceholder)) {
+ f = $el.attr('multiple') ? self.filePlural : self.fileSingle;
+ self.$caption.attr('placeholder', self.msgPlaceholder.replace('{files}', f));
+ self.$captionIcon = self.$captionContainer.find('.file-caption-icon');
+ self.$previewContainer = $h.getElement(options, 'elPreviewContainer', $cont.find('.file-preview'));
+ self.$preview = $h.getElement(options, 'elPreviewImage', $cont.find('.file-preview-thumbnails'));
+ self.$previewStatus = $h.getElement(options, 'elPreviewStatus', $cont.find('.file-preview-status'));
+ self.$errorContainer = $h.getElement(options, 'elErrorContainer',
+ self.$previewContainer.find('.kv-fileinput-error'));
+ self._validateDisabled();
+ if (!$h.isEmpty(self.msgErrorClass)) {
+ $h.addCss(self.$errorContainer, self.msgErrorClass);
+ self._resetErrors();
+ self.$errorContainer.hide();
+ self.previewInitId = 'thumb-' + $el.attr('id');
+ self._initPreviewCache();
+ self._initPreview(true);
+ self._initPreviewActions();
+ if (self.$parent.hasClass('file-loading')) {
+ self.$container.insertBefore(self.$parent);
+ self.$parent.remove();
+ if (!self._errorsExist()) {
+ self._setFileDropZoneTitle();
+ if ($el.attr('disabled')) {
+ self.disable();
+ self._initZoom();
+ if (self.hideThumbnailContent) {
+ $h.addCss(self.$preview, 'hide-content');
+ var fileSelectEle = $el[0];
+ fileSelectEle.onclick = function (e) {
+ window.addEventListener('focus', function () { setTimeout(afterSelected, 300); }, {once: true})
+ e.stopPropagation(); // stop Bubbling and Capture
+ function afterSelected() {
+ self._toggleLoading('hide');
+ (fileSelectEle.value.length == 0) && self._setFileDropZoneTitle();
+ $el[0].closest('.input-group').addEventListener('click', function (e) {
+ $el.click();
+ _initFileManager: function () {
+ self.uploadStartTime = $h.now();
+ self.fileManager = {
+ stack: {},
+ filesProcessed: [],
+ errors: [],
+ loadedImages: {},
+ totalImages: 0,
+ totalFiles: null,
+ totalSize: null,
+ uploadedSize: 0,
+ stats: {},
+ bpsLog: [],
+ bps: 0,
+ initStats: function (id) {
+ var data = {started: $h.now()};
+ if (id) {
+ self.fileManager.stats[id] = data;
+ self.fileManager.stats = data;
+ getUploadStats: function (id, loaded, total) {
+ var fm = self.fileManager,
+ started = id ? fm.stats[id] && fm.stats[id].started || $h.now() : self.uploadStartTime,
+ elapsed = ($h.now() - started) / 1000, bps = Math.ceil(elapsed ? loaded / elapsed : 0),
+ pendingBytes = total - loaded, out, delay = fm.bpsLog.length ? self.bitrateUpdateDelay : 0;
+ setTimeout(function () {
+ var i, j = 0, n = 0, len, beg;
+ fm.bpsLog.push(bps);
+ fm.bpsLog.sort(function (a, b) {
+ return a - b;
+ len = fm.bpsLog.length;
+ beg = len > 10 ? len - 10 : Math.ceil(len / 2);
+ for (i = len; i > beg; i--) {
+ n = parseFloat(fm.bpsLog[i]);
+ fm.bps = (j > 0 ? n / j : 0) * 64;
+ out = {
+ fileId: id,
+ started: started,
+ elapsed: elapsed,
+ loaded: loaded,
+ total: total,
+ bps: fm.bps,
+ bitrate: self._getSize(fm.bps, false, self.bitRateUnits),
+ pendingBytes: pendingBytes
+ fm.stats[id] = out;
+ fm.stats = out;
+ exists: function (id) {
+ return $.inArray(id, self.fileManager.getIdList()) !== -1;
+ count: function () {
+ return self.fileManager.getIdList().length;
+ total: function () {
+ var fm = self.fileManager;
+ if (!fm.totalFiles) {
+ fm.totalFiles = fm.count();
+ return fm.totalFiles;
+ getTotalSize: function () {
+ if (fm.totalSize) {
+ return fm.totalSize;
+ fm.totalSize = 0;
+ $.each(self.getFileStack(), function (id, f) {
+ var size = parseFloat(f.size);
+ fm.totalSize += isNaN(size) ? 0 : size;
+ add: function (file, id) {
+ if (!id) {
+ id = self.fileManager.getId(file);
+ self.fileManager.stack[id] = {
+ file: file,
+ name: $h.getFileName(file),
+ relativePath: $h.getFileRelativePath(file),
+ size: file.size,
+ nameFmt: self._getFileName(file, ''),
+ sizeFmt: self._getSize(file.size)
+ remove: function ($thumb) {
+ var id = self._getThumbFileId($thumb);
+ self.fileManager.removeFile(id);
+ removeFile: function (id) {
+ delete fm.stack[id];
+ delete fm.loadedImages[id];
+ move: function (idFrom, idTo) {
+ var result = {}, stack = self.fileManager.stack;
+ if (!idFrom && !idTo || idFrom === idTo) {
+ $.each(stack, function (k, v) {
+ if (k !== idFrom) {
+ result[k] = v;
+ if (k === idTo) {
+ result[idFrom] = stack[idFrom];
+ self.fileManager.stack = result;
+ list: function () {
+ var files = [];
+ $.each(self.getFileStack(), function (k, v) {
+ if (v && v.file) {
+ files.push(v.file);
+ return files;
+ isPending: function (id) {
+ return $.inArray(id, self.fileManager.filesProcessed) === -1 && self.fileManager.exists(id);
+ isProcessed: function () {
+ var filesProcessed = true, fm = self.fileManager;
+ $.each(self.getFileStack(), function (id) {
+ if (fm.isPending(id)) {
+ filesProcessed = false;
+ return filesProcessed;
+ clear: function () {
+ fm.totalFiles = null;
+ fm.totalSize = null;
+ fm.uploadedSize = 0;
+ fm.stack = {};
+ fm.errors = [];
+ fm.filesProcessed = [];
+ fm.stats = {};
+ fm.bpsLog = [];
+ fm.bps = 0;
+ fm.clearImages();
+ clearImages: function () {
+ self.fileManager.loadedImages = {};
+ self.fileManager.totalImages = 0;
+ addImage: function (id, config) {
+ self.fileManager.loadedImages[id] = config;
+ removeImage: function (id) {
+ delete self.fileManager.loadedImages[id];
+ getImageIdList: function () {
+ return $h.getObjectKeys(self.fileManager.loadedImages);
+ getImageCount: function () {
+ return self.fileManager.getImageIdList().length;
+ getId: function (file) {
+ return self._getFileId(file);
+ getIndex: function (id) {
+ return self.fileManager.getIdList().indexOf(id);
+ getThumb: function (id) {
+ var $thumb = null;
+ self._getThumbs().each(function () {
+ var $t = $(this);
+ if (self._getThumbFileId($t) === id) {
+ $thumb = $t;
+ return $thumb;
+ getThumbIndex: function ($thumb) {
+ return self.fileManager.getIndex(id);
+ getIdList: function () {
+ return $h.getObjectKeys(self.fileManager.stack);
+ getFile: function (id) {
+ return self.fileManager.stack[id] || null;
+ getFileName: function (id, fmt) {
+ var file = self.fileManager.getFile(id);
+ return fmt ? (file.nameFmt || '') : file.name || '';
+ getFirstFile: function () {
+ var ids = self.fileManager.getIdList(), id = ids && ids.length ? ids[0] : null;
+ return self.fileManager.getFile(id);
+ setFile: function (id, file) {
+ if (self.fileManager.getFile(id)) {
+ self.fileManager.stack[id].file = file;
+ self.fileManager.add(file, id);
+ setProcessed: function (id) {
+ self.fileManager.filesProcessed.push(id);
+ getProgress: function () {
+ var total = self.fileManager.total(), filesProcessed = self.fileManager.filesProcessed.length;
+ if (!total) {
+ return 0;
+ return Math.ceil(filesProcessed / total * 100);
+ setProgress: function (id, pct) {
+ var f = self.fileManager.getFile(id);
+ if (!isNaN(pct) && f) {
+ f.progress = pct;
+ _setUploadData: function (fd, config) {
+ $.each(config, function (key, value) {
+ var param = self.uploadParamNames[key] || key;
+ fd.append(param, value[0], value[1]);
+ fd.append(param, value);
+ _initResumableUpload: function () {
+ var self = this, opts = self.resumableUploadOptions, logs = $h.logMessages, rm, fm = self.fileManager;
+ if (!self.enableResumableUpload) {
+ if (opts.fallback !== false && typeof opts.fallback !== 'function') {
+ opts.fallback = function (s) {
+ s._log(logs.noResumableSupport);
+ s.enableResumableUpload = false;
+ if (!$h.hasResumableUploadSupport() && opts.fallback !== false) {
+ opts.fallback(self);
+ if (!self.uploadUrl && self.enableResumableUpload) {
+ self._log(logs.noUploadUrl);
+ self.enableResumableUpload = false;
+ opts.chunkSize = parseFloat(opts.chunkSize);
+ if (opts.chunkSize <= 0 || isNaN(opts.chunkSize)) {
+ self._log(logs.invalidChunkSize, {chunkSize: opts.chunkSize});
+ rm = self.resumableManager = {
+ init: function (id, f, index) {
+ rm.logs = [];
+ rm.stack = [];
+ rm.error = '';
+ rm.id = id;
+ rm.file = f.file;
+ rm.fileName = f.name;
+ rm.fileIndex = index;
+ rm.completed = false;
+ rm.lastProgress = 0;
+ if (self.showPreview) {
+ rm.$thumb = fm.getThumb(id) || null;
+ rm.$progress = rm.$btnDelete = null;
+ if (rm.$thumb && rm.$thumb.length) {
+ rm.$progress = rm.$thumb.find('.file-thumb-progress');
+ rm.$btnDelete = rm.$thumb.find('.kv-file-remove');
+ rm.chunkSize = opts.chunkSize * self.bytesToKB;
+ rm.chunkCount = rm.getTotalChunks();
+ setAjaxError: function (jqXHR, textStatus, errorThrown, isTest) {
+ if (jqXHR.responseJSON && jqXHR.responseJSON.error) {
+ errorThrown = jqXHR.responseJSON.error.toString();
+ if (!isTest) {
+ rm.error = errorThrown;
+ if (opts.showErrorLog) {
+ self._log(logs.ajaxError, {
+ status: jqXHR.status,
+ error: errorThrown,
+ text: jqXHR.responseText || ''
+ reset: function () {
+ rm.chunksProcessed = {};
+ setProcessed: function (status) {
+ var id = rm.id, msg, $thumb = rm.$thumb, $prog = rm.$progress, hasThumb = $thumb && $thumb.length,
+ params = {id: hasThumb ? $thumb.attr('id') : '', index: fm.getIndex(id), fileId: id}, tokens,
+ skipErrorsAndProceed = self.resumableUploadOptions.skipErrorsAndProceed;
+ rm.completed = true;
+ if (hasThumb) {
+ $thumb.removeClass('file-uploading');
+ if (status === 'success') {
+ fm.uploadedSize += rm.file.size;
+ self._setProgress(101, $prog);
+ self._setThumbStatus($thumb, 'Success');
+ self._initUploadSuccess(rm.chunksProcessed[id].data, $thumb);
+ fm.removeFile(id);
+ delete rm.chunksProcessed[id];
+ self._raise('fileuploaded', [params.id, params.index, params.fileId]);
+ if (fm.isProcessed()) {
+ self._setProgress(101);
+ if (status !== 'cancel') {
+ self._setThumbStatus($thumb, 'Error');
+ self._setPreviewError($thumb, true);
+ self._setProgress(101, $prog, self.msgProgressError);
+ self._setProgress(101, self.$progress, self.msgProgressError);
+ self.cancelling = !skipErrorsAndProceed;
+ if (!self.$errorContainer.find('li[data-file-id="' + params.fileId + '"]').length) {
+ tokens = {file: rm.fileName, max: opts.maxRetries, error: rm.error};
+ msg = self.msgResumableUploadRetriesExceeded.setTokens(tokens);
+ $.extend(params, tokens);
+ self._showFileError(msg, params, 'filemaxretries');
+ if (skipErrorsAndProceed) {
+ rm.reset();
+ check: function () {
+ var status = true;
+ $.each(rm.logs, function (index, value) {
+ if (!value) {
+ status = false;
+ processedResumables: function () {
+ var logs = rm.logs, i, count = 0;
+ if (!logs || !logs.length) {
+ for (i = 0; i < logs.length; i++) {
+ if (logs[i] === true) {
+ count++;
+ return count;
+ getUploadedSize: function () {
+ var size = rm.processedResumables() * rm.chunkSize;
+ return size > rm.file.size ? rm.file.size : size;
+ getTotalChunks: function () {
+ var chunkSize = parseFloat(rm.chunkSize);
+ if (!isNaN(chunkSize) && chunkSize > 0) {
+ return Math.ceil(rm.file.size / chunkSize);
+ var chunksProcessed = rm.processedResumables(), total = rm.chunkCount;
+ if (total === 0) {
+ return Math.ceil(chunksProcessed / total * 100);
+ checkAborted: function (intervalId) {
+ if (self._isAborted()) {
+ clearInterval(intervalId);
+ self.unlock();
+ upload: function () {
+ var ids = fm.getIdList(), flag = 'new', intervalId;
+ intervalId = setInterval(function () {
+ var id;
+ rm.checkAborted(intervalId);
+ if (flag === 'new') {
+ self.lock();
+ flag = 'processing';
+ id = ids.shift();
+ fm.initStats(id);
+ if (fm.stack[id]) {
+ rm.init(id, fm.stack[id], fm.getIndex(id));
+ rm.processUpload();
+ if (!fm.isPending(id) && rm.completed) {
+ flag = 'new';
+ var $initThumbs = self.$preview.find('.file-preview-initial');
+ if ($initThumbs.length) {
+ $h.addCss($initThumbs, $h.SORT_CSS);
+ self._initSortable();
+ self._clearFileInput();
+ var data = self.previewCache.data;
+ if (data) {
+ self.initialPreview = data.content;
+ self.initialPreviewConfig = data.config;
+ self.initialPreviewThumbTags = data.tags;
+ self._raise('filebatchuploadcomplete', [
+ self.initialPreview,
+ self.initialPreviewConfig,
+ self.initialPreviewThumbTags,
+ self._getExtraData()
+ ]);
+ }, self.processDelay);
+ uploadResumable: function () {
+ var i, pool, tm = self.taskManager, total = rm.chunkCount;
+ pool = tm.addPool(rm.id);
+ for (i = 0; i < total; i++) {
+ rm.logs[i] = !!(rm.chunksProcessed[rm.id] && rm.chunksProcessed[rm.id][i]);
+ if (!rm.logs[i]) {
+ rm.pushAjax(i, 0);
+ pool.run(opts.maxThreads)
+ .done(function () {
+ rm.setProcessed('success');
+ rm.setProcessed(pool.cancelled ? 'cancel' : 'error');
+ processUpload: function () {
+ var fd, f, id = rm.id, fnBefore, fnSuccess, fnError, fnComplete, outData;
+ if (!opts.testUrl) {
+ rm.uploadResumable();
+ fd = new FormData();
+ f = fm.stack[id];
+ self._setUploadData(fd, {
+ fileName: f.fileName,
+ fileSize: f.size,
+ fileRelativePath: f.relativePath,
+ chunkSize: rm.chunkSize,
+ chunkCount: rm.chunkCount
+ fnBefore = function (jqXHR) {
+ outData = self._getOutData(fd, jqXHR);
+ self._raise('filetestbeforesend', [id, fm, rm, outData]);
+ fnSuccess = function (data, textStatus, jqXHR) {
+ outData = self._getOutData(fd, jqXHR, data);
+ var pNames = self.uploadParamNames, chunksUploaded = pNames.chunksUploaded || 'chunksUploaded',
+ params = [id, fm, rm, outData];
+ if (!data[chunksUploaded] || !$h.isArray(data[chunksUploaded])) {
+ self._raise('filetesterror', params);
+ if (!rm.chunksProcessed[id]) {
+ rm.chunksProcessed[id] = {};
+ $.each(data[chunksUploaded], function (key, index) {
+ rm.logs[index] = true;
+ rm.chunksProcessed[id][index] = true;
+ rm.chunksProcessed[id].data = data;
+ self._raise('filetestsuccess', params);
+ fnError = function (jqXHR, textStatus, errorThrown) {
+ self._raise('filetestajaxerror', [id, fm, rm, outData]);
+ rm.setAjaxError(jqXHR, textStatus, errorThrown, true);
+ fnComplete = function () {
+ self._raise('filetestcomplete', [id, fm, rm, self._getOutData(fd)]);
+ self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, fd, id, rm.fileIndex, opts.testUrl);
+ pushAjax: function (index, retry) {
+ var tm = self.taskManager, pool = tm.getPool(rm.id);
+ pool.addTask(pool.size() + 1, function (deferrer) {
+ // use fifo chunk stack
+ var arr = rm.stack.shift(), index;
+ index = arr[0];
+ if (!rm.chunksProcessed[rm.id] || !rm.chunksProcessed[rm.id][index]) {
+ rm.sendAjax(index, arr[1], deferrer);
+ self._log(logs.chunkQueueError, {index: index});
+ rm.stack.push([index, retry]);
+ sendAjax: function (index, retry, deferrer) {
+ var f, chunkSize = rm.chunkSize, id = rm.id, file = rm.file, $thumb = rm.$thumb,
+ msgs = $h.logMessages, $btnDelete = rm.$btnDelete, logError = function (msg, tokens) {
+ if (tokens) {
+ msg = msg.setTokens(tokens);
+ msg = msgs.resumableRequestError.setTokens({msg: msg});
+ self._log(msg);
+ deferrer.reject(msg);
+ if (rm.chunksProcessed[id] && rm.chunksProcessed[id][index]) {
+ if (retry > opts.maxRetries) {
+ logError(msgs.resumableMaxRetriesReached, {n: opts.maxRetries});
+ rm.setProcessed('error');
+ var fd, outData, fnBefore, fnSuccess, fnError, fnComplete, slice = file.slice ? 'slice' :
+ (file.mozSlice ? 'mozSlice' : (file.webkitSlice ? 'webkitSlice' : 'slice')),
+ blob = file[slice](chunkSize * index, chunkSize * (index + 1));
+ chunkCount: rm.chunkCount,
+ chunkIndex: index,
+ chunkSize: chunkSize,
+ chunkSizeStart: chunkSize * index,
+ fileBlob: [blob, rm.fileName],
+ fileName: rm.fileName,
+ fileSize: file.size,
+ retryCount: retry
+ if (rm.$progress && rm.$progress.length) {
+ rm.$progress.show();
+ if (!$thumb.hasClass('file-preview-success')) {
+ self._setThumbStatus($thumb, 'Loading');
+ $h.addCss($thumb, 'file-uploading');
+ $btnDelete.attr('disabled', true);
+ self._raise('filechunkbeforesend', [id, index, retry, fm, rm, outData]);
+ logError(msgs.resumableAborting);
+ var paramNames = self.uploadParamNames, chunkIndex = paramNames.chunkIndex || 'chunkIndex',
+ params = [id, index, retry, fm, rm, outData];
+ if (data.error) {
+ self._log(logs.retryStatus, {
+ retry: retry + 1,
+ filename: rm.fileName,
+ chunk: index
+ self._raise('filechunkerror', params);
+ rm.pushAjax(index, retry + 1);
+ rm.error = data.error;
+ logError(data.error);
+ rm.logs[data[chunkIndex]] = true;
+ rm.chunksProcessed[id][data[chunkIndex]] = true;
+ deferrer.resolve.call(null, data);
+ self._raise('filechunksuccess', params);
+ rm.check();
+ rm.setAjaxError(jqXHR, textStatus, errorThrown);
+ self._raise('filechunkajaxerror', [id, index, retry, fm, rm, outData]);
+ rm.pushAjax(index, retry + 1); // push another task
+ logError(msgs.resumableRetryError, {n: retry - 1}); // resolve the current task
+ if (!self._isAborted()) {
+ self._raise('filechunkcomplete', [id, index, retry, fm, rm, self._getOutData(fd)]);
+ self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, fd, id, rm.fileIndex);
+ _initTemplateDefaults: function () {
+ var self = this, tMain1, tMain2, tPreview, tFileIcon, tClose, tCaption, tBtnDefault, tBtnLink, tBtnBrowse,
+ tModalMain, tModal, tProgress, tSize, tFooter, tActions, tActionDelete, tActionUpload, tActionDownload,
+ tActionZoom, tActionDrag, tIndicator, tTagBef, tTagBef1, tTagBef2, tTagAft, tGeneric, tHtml, tImage,
+ tText, tOffice, tGdocs, tVideo, tAudio, tFlash, tObject, tPdf, tOther, tStyle, tZoomCache, vDefaultDim,
+ tActionRotate, tStats, tModalLabel, tDescClose, renderObject = function (type, mime) {
+ return '<object class="kv-preview-data file-preview-' + type + '" title="{caption}" ' +
+ 'data="{data}" type="' + mime + '"' + tStyle + '>\n' + $h.DEFAULT_PREVIEW + '\n</object>\n';
+ }, defBtnCss1 = 'btn btn-sm btn-kv ' + $h.defaultButtonCss();
+ tMain1 = '{preview}\n' +
+ '<div class="kv-upload-progress kv-hidden"></div><div class="clearfix"></div>\n' +
+ '<div class="file-caption {class}">\n' +
+ ' <div class="input-group {inputGroupClass}">\n' +
+ ' {caption}\n<span class="file-caption-icon"></span>\n' +
+ ($h.isBs(5) ? '' : '<div class="input-group-btn input-group-append">\n') +
+ ' {remove}\n' +
+ ' {cancel}\n' +
+ ' {pause}\n' +
+ ' {upload}\n' +
+ ' {browse}\n' +
+ ($h.isBs(5) ? '' : ' </div>\n') +
+ ' </div>';
+ '</div>';
+ tMain2 = '{preview}\n<div class="kv-upload-progress kv-hidden"></div>\n<div class="clearfix"></div>\n' +
+ '<span class="{class}">{remove}\n{cancel}\n{upload}\n{browse}\n</span>';
+ tPreview = '<div class="file-preview {class}">\n' +
+ ' {close}' +
+ ' <div class="{dropClass} clearfix">\n' +
+ ' <div class="file-preview-thumbnails clearfix">\n' +
+ ' </div>\n' +
+ ' <div class="file-preview-status text-center text-success"></div>\n' +
+ ' <div class="kv-fileinput-error"></div>\n' +
+ tClose = $h.closeButton('fileinput-remove');
+ tFileIcon = '<i class="bi-file-earmark-arrow-up"></i>';
+ // noinspection HtmlUnknownAttribute
+ tCaption = '<input readonly class="file-caption-name form-control {class}">\n';
+ //noinspection HtmlUnknownAttribute
+ tBtnDefault = '<button type="{type}" title="{title}" class="{css}" ' +
+ '{status} {tabIndexConfig}>{icon} {label}</button>';
+ //noinspection HtmlUnknownTarget,HtmlUnknownAttribute
+ tBtnLink = '<a href="{href}" title="{title}" class="{css}" {status} {tabIndexConfig}>{icon} {label}</a>';
+ tBtnBrowse = '<div class="{css}" {status} {tabIndexConfig}>{icon} {label}</div>';
+ tModalLabel = $h.MODAL_ID + 'Label';
+ tModalMain = '<div id="' + $h.MODAL_ID + '" class="file-zoom-dialog modal fade" ' +
+ 'aria-labelledby="' + tModalLabel + '" {tabIndexConfig}></div>';
+ tModal = '<div class="modal-dialog modal-lg{rtl}" role="document">\n' +
+ ' <div class="modal-content">\n' +
+ ' <div class="modal-header kv-zoom-header">\n' +
+ ' <h6 class="modal-title kv-zoom-title" id="' + tModalLabel + '"><span class="kv-zoom-caption"></span> <span class="kv-zoom-size"></span></h6>\n' +
+ ' <div class="kv-zoom-actions">{rotate}{toggleheader}{fullscreen}{borderless}{close}</div>\n' +
+ ' <div class="floating-buttons"></div>\n' +
+ ' <div class="kv-zoom-body file-zoom-content {zoomFrameClass}"></div>\n' + '{prev} {next}\n' +
+ ' <div class="kv-zoom-description"></div>\n' +
+ '</div>\n';
+ tDescClose = '<button type="button" class="kv-desc-hide" aria-label="Close">{closeIcon}</button>';
+ tProgress = '<div class="progress">\n' +
+ ' <div class="{class}" role="progressbar"' +
+ ' aria-valuenow="{percent}" aria-valuemin="0" aria-valuemax="100" style="width:{percent}%;">\n' +
+ ' {status}\n' +
+ '</div>{stats}';
+ tStats = '<div class="text-primary file-upload-stats">' +
+ '<span class="pending-time">{pendingTime}</span> ' +
+ '<span class="upload-speed">{uploadSpeed}</span>' +
+ tSize = ' <samp>({sizeText})</samp>';
+ tFooter = '<div class="file-thumbnail-footer">\n' +
+ ' <div class="file-footer-caption" title="{caption}">\n' +
+ ' <div class="file-caption-info">{caption}</div>\n' +
+ ' <div class="file-size-info">{size}</div>\n' +
+ ' {progress}\n{indicator}\n{actions}\n' +
+ tActions = '<div class="file-actions">\n' +
+ ' <div class="file-footer-buttons">\n' +
+ ' {rotate} {download} {upload} {delete} {zoom} {other}' +
+ '</div>\n' +
+ '{drag}\n' +
+ '<div class="clearfix"></div>';
+ tActionDelete = '<button type="button" class="kv-file-remove {removeClass}" ' +
+ 'title="{removeTitle}" {dataUrl}{dataKey}>{removeIcon}</button>\n';
+ tActionUpload = '<button type="button" class="kv-file-upload {uploadClass}" title="{uploadTitle}">' +
+ '{uploadIcon}</button>';
+ tActionRotate = '<button type="button" class="kv-file-rotate {rotateClass}" title="{rotateTitle}">' +
+ '{rotateIcon}</button>';
+ tActionDownload = '<a class="kv-file-download {downloadClass}" title="{downloadTitle}" ' +
+ 'href="{downloadUrl}" download="{caption}" target="_blank">{downloadIcon}</a>';
+ tActionZoom = '<button type="button" class="kv-file-zoom {zoomClass}" ' +
+ 'title="{zoomTitle}">{zoomIcon}</button>';
+ tActionDrag = '<span class="file-drag-handle {dragClass}" title="{dragTitle}">{dragIcon}</span>';
+ tIndicator = '<div class="file-upload-indicator" title="{indicatorTitle}">{indicator}</div>';
+ tTagBef = '<div class="file-preview-frame {frameClass}" id="{previewId}" data-fileindex="{fileindex}"' +
+ ' data-fileid="{fileid}" data-filename="{filename}" data-template="{template}" data-zoom="{zoomData}"';
+ tTagBef1 = tTagBef + '><div class="kv-file-content">\n';
+ tTagBef2 = tTagBef + ' title="{caption}"><div class="kv-file-content">\n';
+ tTagAft = '</div>{footer}\n{zoomCache}</div>\n';
+ tGeneric = '{content}\n';
+ tStyle = ' {style}';
+ tHtml = renderObject('html', 'text/html');
+ tText = renderObject('text', 'text/plain;charset=UTF-8');
+ tPdf = renderObject('pdf', 'application/pdf');
+ tImage = '<img src="{data}" class="file-preview-image kv-preview-data" title="{title}" alt="{alt}"' +
+ tStyle + '>\n';
+ tOffice = '<iframe class="kv-preview-data file-preview-office" ' +
+ 'src="https://view.officeapps.live.com/op/embed.aspx?src={data}"' + tStyle + '></iframe>';
+ tGdocs = '<iframe class="kv-preview-data file-preview-gdocs" ' +
+ 'src="https://docs.google.com/gview?url={data}&embedded=true"' + tStyle + '></iframe>';
+ tVideo = '<video class="kv-preview-data file-preview-video" controls' + tStyle + '>\n' +
+ '<source src="{data}" type="{type}">\n' + $h.DEFAULT_PREVIEW + '\n</video>\n';
+ tAudio = '<!--suppress ALL --><audio class="kv-preview-data file-preview-audio" controls' + tStyle + '>\n<source src="{data}" ' +
+ 'type="{type}">\n' + $h.DEFAULT_PREVIEW + '\n</audio>\n';
+ tFlash = '<embed class="kv-preview-data file-preview-flash" src="{data}" type="application/x-shockwave-flash"' + tStyle + '>\n';
+ tObject = '<object class="kv-preview-data file-preview-object file-object {typeCss}" ' +
+ 'data="{data}" type="{type}"' + tStyle + '>\n' + '<param name="movie" value="{caption}" />\n' +
+ $h.OBJECT_PARAMS + ' ' + $h.DEFAULT_PREVIEW + '\n</object>\n';
+ tOther = '<div class="kv-preview-data file-preview-other-frame"' + tStyle + '>\n' + $h.DEFAULT_PREVIEW + '\n</div>\n';
+ tZoomCache = '<div class="kv-zoom-cache">{zoomContent}</div>';
+ vDefaultDim = {width: '100%', height: '100%', 'min-height': '480px'};
+ if (self._isPdfRendered()) {
+ tPdf = self.pdfRendererTemplate.replace('{renderer}', self._encodeURI(self.pdfRendererUrl));
+ self.defaults = {
+ layoutTemplates: {
+ main1: tMain1,
+ main2: tMain2,
+ preview: tPreview,
+ close: tClose,
+ fileIcon: tFileIcon,
+ caption: tCaption,
+ modalMain: tModalMain,
+ modal: tModal,
+ descriptionClose: tDescClose,
+ progress: tProgress,
+ stats: tStats,
+ size: tSize,
+ footer: tFooter,
+ indicator: tIndicator,
+ actions: tActions,
+ actionDelete: tActionDelete,
+ actionRotate: tActionRotate,
+ actionUpload: tActionUpload,
+ actionDownload: tActionDownload,
+ actionZoom: tActionZoom,
+ actionDrag: tActionDrag,
+ btnDefault: tBtnDefault,
+ btnLink: tBtnLink,
+ btnBrowse: tBtnBrowse,
+ zoomCache: tZoomCache
+ previewMarkupTags: {
+ tagBefore1: tTagBef1,
+ tagBefore2: tTagBef2,
+ tagAfter: tTagAft
+ previewContentTemplates: {
+ generic: tGeneric,
+ html: tHtml,
+ image: tImage,
+ text: tText,
+ office: tOffice,
+ gdocs: tGdocs,
+ video: tVideo,
+ audio: tAudio,
+ flash: tFlash,
+ object: tObject,
+ pdf: tPdf,
+ other: tOther
+ allowedPreviewTypes: ['image', 'html', 'text', 'video', 'audio', 'flash', 'pdf', 'object'],
+ previewTemplates: {},
+ previewSettings: {
+ image: {width: 'auto', height: 'auto', 'max-width': '100%', 'max-height': '100%'},
+ html: {width: '213px', height: '160px'},
+ text: {width: '213px', height: '160px'},
+ office: {width: '213px', height: '160px'},
+ gdocs: {width: '213px', height: '160px'},
+ video: {width: '213px', height: '160px'},
+ audio: {width: '100%', height: '30px'},
+ flash: {width: '213px', height: '160px'},
+ object: {width: '213px', height: '160px'},
+ pdf: {width: '100%', height: '160px', 'position': 'relative'},
+ other: {width: '213px', height: '160px'}
+ previewSettingsSmall: {
+ html: {width: '100%', height: '160px'},
+ text: {width: '100%', height: '160px'},
+ office: {width: '100%', height: '160px'},
+ gdocs: {width: '100%', height: '160px'},
+ video: {width: '100%', height: 'auto'},
+ flash: {width: '100%', height: 'auto'},
+ object: {width: '100%', height: 'auto'},
+ pdf: {width: '100%', height: '160px'},
+ other: {width: '100%', height: '160px'}
+ previewZoomSettings: {
+ html: vDefaultDim,
+ text: vDefaultDim,
+ office: {width: '100%', height: '100%', 'max-width': '100%', 'min-height': '480px'},
+ gdocs: {width: '100%', height: '100%', 'max-width': '100%', 'min-height': '480px'},
+ video: {width: 'auto', height: '100%', 'max-width': '100%'},
+ flash: {width: 'auto', height: '480px'},
+ object: {width: 'auto', height: '100%', 'max-width': '100%', 'min-height': '480px'},
+ pdf: vDefaultDim,
+ other: {width: 'auto', height: '100%', 'min-height': '480px'}
+ mimeTypeAliases: {
+ 'video/quicktime': 'video/mp4'
+ fileTypeSettings: {
+ image: function (vType, vName) {
+ return ($h.compare(vType, 'image.*') && !$h.compare(vType, /(tiff?|wmf)$/i) ||
+ $h.compare(vName, /\.(gif|png|jpe?g)$/i));
+ html: function (vType, vName) {
+ return $h.compare(vType, 'text/html') || $h.compare(vName, /\.(htm|html)$/i);
+ office: function (vType, vName) {
+ return $h.compare(vType, /(word|excel|powerpoint|office)$/i) ||
+ $h.compare(vName, /\.(docx?|xlsx?|pptx?|pps|potx?)$/i);
+ gdocs: function (vType, vName) {
+ return $h.compare(vType, /(word|excel|powerpoint|office|iwork-pages|tiff?)$/i) ||
+ $h.compare(vName,
+ /\.(docx?|xlsx?|pptx?|pps|potx?|rtf|ods|odt|pages|ai|dxf|ttf|tiff?|wmf|e?ps)$/i);
+ text: function (vType, vName) {
+ return $h.compare(vType, 'text.*') || $h.compare(vName, /\.(xml|javascript)$/i) ||
+ $h.compare(vName, /\.(txt|md|nfo|ini|json|php|js|css)$/i);
+ video: function (vType, vName) {
+ return $h.compare(vType, 'video.*') && ($h.compare(vType, /(ogg|mp4|mp?g|mov|webm|3gp)$/i) ||
+ $h.compare(vName, /\.(og?|mp4|webm|mp?g|mov|3gp)$/i));
+ audio: function (vType, vName) {
+ return $h.compare(vType, 'audio.*') && ($h.compare(vName, /(ogg|mp3|mp?g|wav)$/i) ||
+ $h.compare(vName, /\.(og?|mp3|mp?g|wav)$/i));
+ flash: function (vType, vName) {
+ return $h.compare(vType, 'application/x-shockwave-flash', true) || $h.compare(vName,
+ /\.(swf)$/i);
+ pdf: function (vType, vName) {
+ return $h.compare(vType, 'application/pdf', true) || $h.compare(vName, /\.(pdf)$/i);
+ object: function () {
+ other: function () {
+ fileActionSettings: {
+ showRemove: true,
+ showUpload: true,
+ showDownload: true,
+ showZoom: true,
+ showDrag: true,
+ showRotate: true,
+ removeIcon: '<i class="bi-trash"></i>',
+ removeClass: defBtnCss1,
+ removeErrorClass: 'btn btn-sm btn-kv btn-danger',
+ removeTitle: 'Remove file',
+ uploadIcon: '<i class="bi-upload"></i>',
+ uploadClass: defBtnCss1,
+ uploadTitle: 'Upload file',
+ uploadRetryIcon: '<i class="bi-cloud-arrow-up-fill"></i>',
+ uploadRetryTitle: 'Retry upload',
+ downloadIcon: '<i class="bi-download"></i>',
+ downloadClass: defBtnCss1,
+ downloadTitle: 'Download file',
+ rotateIcon: '<i class="bi-arrow-clockwise"></i>',
+ rotateClass: defBtnCss1,
+ rotateTitle: 'Rotate 90 deg. clockwise',
+ zoomIcon: '<i class="bi-zoom-in"></i>',
+ zoomClass: defBtnCss1,
+ zoomTitle: 'View Details',
+ dragIcon: '<i class="bi-arrows-move"></i>',
+ dragClass: 'text-primary',
+ dragTitle: 'Move / Rearrange',
+ dragSettings: {},
+ indicatorNew: '<i class="bi-plus-lg text-warning"></i>',
+ indicatorSuccess: '<i class="bi-check-lg text-success"></i>',
+ indicatorError: '<i class="bi-exclamation-lg text-danger"></i>',
+ indicatorLoading: '<i class="bi-hourglass-bottom text-muted"></i>',
+ indicatorPaused: '<i class="bi-pause-fill text-primary"></i>',
+ indicatorNewTitle: 'Not uploaded yet',
+ indicatorSuccessTitle: 'Uploaded',
+ indicatorErrorTitle: 'Upload Error',
+ indicatorLoadingTitle: 'Uploading …',
+ indicatorPausedTitle: 'Upload Paused'
+ $.each(self.defaults, function (key, setting) {
+ if (key === 'allowedPreviewTypes') {
+ if (self.allowedPreviewTypes === undefined) {
+ self.allowedPreviewTypes = setting;
+ self[key] = $.extend(true, {}, setting, self[key]);
+ self._initPreviewTemplates();
+ _initPreviewTemplates: function () {
+ var self = this, tags = self.previewMarkupTags, tagBef, tagAft = tags.tagAfter;
+ $.each(self.previewContentTemplates, function (key, value) {
+ if ($h.isEmpty(self.previewTemplates[key])) {
+ tagBef = tags.tagBefore2;
+ if (key === 'generic' || key === 'image') {
+ tagBef = tags.tagBefore1;
+ if (self._isPdfRendered() && key === 'pdf') {
+ tagBef = tagBef.replace('kv-file-content', 'kv-file-content kv-pdf-rendered');
+ self.previewTemplates[key] = tagBef + value + tagAft;
+ _initPreviewCache: function () {
+ self.previewCache = {
+ data: {},
+ init: function () {
+ var content = self.initialPreview;
+ if (content.length > 0 && !$h.isArray(content)) {
+ content = content.split(self.initialPreviewDelimiter);
+ self.previewCache.data = {
+ content: content,
+ config: self.initialPreviewConfig,
+ tags: self.initialPreviewThumbTags
+ count: function (skipNull) {
+ if (!self.previewCache.data || !self.previewCache.data.content) {
+ if (skipNull) {
+ var chk = self.previewCache.data.content.filter(function (n) {
+ return n !== null;
+ return chk.length;
+ return self.previewCache.data.content.length;
+ get: function (i, isDisabled) {
+ var ind = $h.INIT_FLAG + i, data = self.previewCache.data, config = data.config[i],
+ content = data.content[i], out, $tmp, cat, ftr,
+ fname, ftype, frameClass, asData = $h.ifSet('previewAsData', config, self.initialPreviewAsData),
+ a = config ? {title: config.title || null, alt: config.alt || null} : {title: null, alt: null},
+ parseTemplate = function (cat, dat, fname, ftype, ftr, ind, fclass, t) {
+ var fc = ' file-preview-initial ' + $h.SORT_CSS + (fclass ? ' ' + fclass : ''),
+ id = self.previewInitId + '-' + ind,
+ fileId = config && config.fileId || id;
+ /** @namespace config.zoomData */
+ return self._generatePreviewTemplate(cat, dat, fname, ftype, id, fileId, false, null, null, fc,
+ ftr, ind, t, a, config && config.zoomData || dat);
+ if (!content || !content.length) {
+ isDisabled = isDisabled === undefined ? true : isDisabled;
+ cat = $h.ifSet('type', config, self.initialPreviewFileType || 'generic');
+ fname = $h.ifSet('filename', config, $h.ifSet('caption', config));
+ ftype = $h.ifSet('filetype', config, cat);
+ ftr = self.previewCache.footer(i, isDisabled, (config && config.size || null));
+ frameClass = $h.ifSet('frameClass', config);
+ if (asData) {
+ out = parseTemplate(cat, content, fname, ftype, ftr, ind, frameClass);
+ out = parseTemplate('generic', content, fname, ftype, ftr, ind, frameClass, cat)
+ .setTokens({'content': data.content[i]});
+ if (data.tags.length && data.tags[i]) {
+ out = $h.replaceTags(out, data.tags[i]);
+ /** @namespace config.frameAttr */
+ if (!$h.isEmpty(config) && !$h.isEmpty(config.frameAttr)) {
+ $tmp = $h.createElement(out);
+ $tmp.find('.file-preview-initial').attr(config.frameAttr);
+ out = $tmp.html();
+ $tmp.remove();
+ clean: function (data) {
+ data.content = $h.cleanArray(data.content);
+ data.config = $h.cleanArray(data.config);
+ data.tags = $h.cleanArray(data.tags);
+ self.previewCache.data = data;
+ add: function (content, config, tags, append) {
+ var data = self.previewCache.data, index;
+ index = content.length - 1;
+ if (!$h.isArray(content)) {
+ if (append && data.content) {
+ index = data.content.push(content[0]) - 1;
+ data.config[index] = config;
+ data.tags[index] = tags;
+ data.content = content;
+ data.config = config;
+ data.tags = tags;
+ self.previewCache.clean(data);
+ return index;
+ set: function (content, config, tags, append) {
+ var data = self.previewCache.data, i, chk;
+ chk = content.filter(function (n) {
+ if (!chk.length) {
+ if (data.content === undefined) {
+ data.content = [];
+ if (data.config === undefined) {
+ data.config = [];
+ if (data.tags === undefined) {
+ data.tags = [];
+ if (append) {
+ for (i = 0; i < content.length; i++) {
+ if (content[i]) {
+ data.content.push(content[i]);
+ for (i = 0; i < config.length; i++) {
+ if (config[i]) {
+ data.config.push(config[i]);
+ for (i = 0; i < tags.length; i++) {
+ if (tags[i]) {
+ data.tags.push(tags[i]);
+ unset: function (index) {
+ var chk = self.previewCache.count(), rev = self.reversePreviewOrder;
+ if (chk === 1) {
+ self.previewCache.data.content = [];
+ self.previewCache.data.config = [];
+ self.previewCache.data.tags = [];
+ self.initialPreview = [];
+ self.initialPreviewConfig = [];
+ self.initialPreviewThumbTags = [];
+ self.previewCache.data.content = $h.spliceArray(self.previewCache.data.content, index, rev);
+ self.previewCache.data.config = $h.spliceArray(self.previewCache.data.config, index, rev);
+ self.previewCache.data.tags = $h.spliceArray(self.previewCache.data.tags, index, rev);
+ var data = $.extend(true, {}, self.previewCache.data);
+ out: function () {
+ var html = '', caption, len = self.previewCache.count(), i, content;
+ if (len === 0) {
+ return {content: '', caption: ''};
+ content = self.previewCache.get(i);
+ html = self.reversePreviewOrder ? (content + html) : (html + content);
+ caption = self._getMsgSelected(len);
+ return {content: html, caption: caption};
+ footer: function (i, isDisabled, size) {
+ var data = self.previewCache.data || {};
+ if ($h.isEmpty(data.content)) {
+ if ($h.isEmpty(data.config) || $h.isEmpty(data.config[i])) {
+ data.config[i] = {};
+ var config = data.config[i], caption = $h.ifSet('caption', config), a,
+ width = $h.ifSet('width', config, 'auto'), url = $h.ifSet('url', config, false),
+ key = $h.ifSet('key', config, null), fileId = $h.ifSet('fileId', config, null),
+ fs = self.fileActionSettings, initPreviewShowDel = self.initialPreviewShowDelete || false,
+ downloadInitialUrl = !self.initialPreviewDownloadUrl ? '' :
+ self.initialPreviewDownloadUrl + '?key=' + key + (fileId ? '&fileId=' + fileId : ''),
+ dUrl = config.downloadUrl || downloadInitialUrl,
+ dFil = config.filename || config.caption || '',
+ initPreviewShowDwl = !!(dUrl),
+ sDel = $h.ifSet('showRemove', config, initPreviewShowDel),
+ sRot = $h.ifSet('showRotate', config, $h.ifSet('showRotate', fs, true)),
+ sDwl = $h.ifSet('showDownload', config, $h.ifSet('showDownload', fs, initPreviewShowDwl)),
+ sZm = $h.ifSet('showZoom', config, $h.ifSet('showZoom', fs, true)),
+ sDrg = $h.ifSet('showDrag', config, $h.ifSet('showDrag', fs, true)),
+ dis = (url === false) && isDisabled;
+ sDwl = sDwl && config.downloadUrl !== false && !!dUrl;
+ a = self._renderFileActions(config, false, sDwl, sDel, sRot, sZm, sDrg, dis, url, key, true, dUrl, dFil);
+ return self._getLayoutTemplate('footer').setTokens({
+ 'progress': self._renderThumbProgress(),
+ 'actions': a,
+ 'caption': caption,
+ 'size': self._getSize(size),
+ 'width': width,
+ 'indicator': ''
+ self.previewCache.init();
+ _isPdfRendered: function () {
+ var self = this, useLib = self.usePdfRenderer,
+ flag = typeof useLib === 'function' ? useLib() : !!useLib;
+ return flag && self.pdfRendererUrl;
+ _handler: function ($el, event, callback) {
+ var self = this, ns = self.namespace, ev = event.split(' ').join(ns + ' ') + ns;
+ if (!$el || !$el.length) {
+ $el.off(ev).on(ev, callback);
+ _encodeURI: function (vUrl) {
+ return self.encodeUrl ? encodeURI(vUrl) : vUrl;
+ _log: function (msg, tokens) {
+ var self = this, id = self.$element.attr('id');
+ if (!self.showConsoleLogs) {
+ msg = '"' + id + '": ' + msg;
+ msg = 'bootstrap-fileinput: ' + msg;
+ if (typeof tokens === 'object') {
+ if (window.console && typeof window.console.log !== 'undefined') {
+ window.console.log(msg);
+ window.alert(msg);
+ _validate: function () {
+ var self = this, status = self.$element.attr('type') === 'file';
+ if (!status) {
+ self._log($h.logMessages.badInputType);
+ _errorsExist: function () {
+ var self = this, $err, $errList = self.$errorContainer.find('li');
+ if ($errList.length) {
+ $err = $h.createElement(self.$errorContainer.html());
+ $err.find('.kv-error-close').remove();
+ $err.find('ul').remove();
+ return !!$.trim($err.text()).length;
+ _errorHandler: function (evt, caption) {
+ var self = this, err = evt.target.error, showError = function (msg) {
+ self._showError(msg.replace('{name}', caption));
+ /** @namespace err.NOT_FOUND_ERR */
+ /** @namespace err.SECURITY_ERR */
+ /** @namespace err.NOT_READABLE_ERR */
+ if (err.code === err.NOT_FOUND_ERR) {
+ showError(self.msgFileNotFound);
+ if (err.code === err.SECURITY_ERR) {
+ showError(self.msgFileSecured);
+ if (err.code === err.NOT_READABLE_ERR) {
+ showError(self.msgFileNotReadable);
+ if (err.code === err.ABORT_ERR) {
+ showError(self.msgFilePreviewAborted);
+ showError(self.msgFilePreviewError);
+ _addError: function (msg) {
+ var self = this, $error = self.$errorContainer;
+ if (msg && $error.length) {
+ $h.setHtml($error, self.errorCloseButton + msg);
+ self._handler($error.find('.kv-error-close'), 'click', function () {
+ if (self.showPreview && !self.getFrames().length) {
+ self.clear();
+ $error.fadeOut('slow');
+ _setValidationError: function (css) {
+ css = (css ? css + ' ' : '') + 'has-error';
+ self.$container.removeClass(css).addClass('has-error');
+ $h.addCss(self.$caption, 'is-invalid');
+ _resetErrors: function (fade) {
+ var self = this, $error = self.$errorContainer, history = self.resumableUploadOptions.retainErrorHistory;
+ if (self.isPersistentError || (self.enableResumableUpload && history && !self.clearInput)) {
+ self.clearInput = false;
+ self.$container.removeClass('has-error');
+ self.$caption.removeClass('is-invalid is-valid file-processing');
+ $error.html('');
+ if (fade) {
+ $error.hide();
+ _showFolderError: function (folders) {
+ var self = this, $error = self.$errorContainer, msg;
+ if (!folders) {
+ msg = self.msgFoldersNotAllowed.replace('{n}', folders);
+ self._addError(msg);
+ self._setValidationError();
+ $error.fadeIn(self.fadeDelay);
+ self._raise('filefoldererror', [folders, msg]);
+ showUserError: function (msg, params, retainErrorHistory) {
+ var self = this, fileName;
+ if (!self.uploadInitiated) {
+ if (!params || !params.fileId) {
+ if (!retainErrorHistory) {
+ self.$errorContainer.html('');
+ self.$errorContainer.find('[data-file-id="' + params.fileId + '"]').remove();
+ fileName = self.fileManager.getFileName(params.fileId);
+ if (fileName) {
+ msg = '<b>' + fileName + ':</b> ' + msg;
+ self._showFileError(msg, params, 'fileusererror');
+ _showFileError: function (msg, params, event) {
+ var self = this, $error = self.$errorContainer, ev = event || 'fileuploaderror',
+ fId = params && params.fileId || '', e = params && params.id ?
+ '<li data-thumb-id="' + params.id + '" data-file-id="' + fId + '">' + msg + '</li>' :
+ '<li>' + msg + '</li>';
+ if ($error.find('ul').length === 0) {
+ self._addError('<ul>' + e + '</ul>');
+ $error.find('ul').append(e);
+ self._raise(ev, [params, msg]);
+ self._setValidationError('file-input-new');
+ _showError: function (msg, params, event) {
+ var self = this, $error = self.$errorContainer, ev = event || 'fileerror';
+ params = params || {};
+ params.reader = self.reader;
+ self.$btnUpload.attr('disabled', true);
+ _noFilesError: function (params) {
+ var self = this, label = self.minFileCount > 1 ? self.filePlural : self.fileSingle,
+ msg = self.msgFilesTooLess.replace('{n}', self.minFileCount).replace('{files}', label),
+ $error = self.$errorContainer;
+ msg = '<li>' + msg + '</li>';
+ self._addError('<ul>' + msg + '</ul>');
+ $error.find('ul').append(msg);
+ self.isError = true;
+ self._updateFileDetails(0);
+ self._raise('fileerror', [params, msg]);
+ _parseError: function (operation, jqXHR, errorThrown, fileName) {
+ /** @namespace jqXHR.responseJSON */
+ var self = this, errMsg = $.trim(errorThrown + ''), textPre, errText, text;
+ errText = jqXHR.responseJSON && jqXHR.responseJSON.error ? jqXHR.responseJSON.error.toString() : '';
+ text = errText ? errText : jqXHR.responseText;
+ if (self.cancelling && self.msgUploadAborted) {
+ errMsg = self.msgUploadAborted;
+ if (self.showAjaxErrorDetails && text) {
+ if (errText) {
+ errMsg = $.trim(errText + '');
+ text = $.trim(text.replace(/\n\s*\n/g, '\n'));
+ textPre = text.length ? '<pre>' + text + '</pre>' : '';
+ errMsg += errMsg ? textPre : text;
+ if (!errMsg) {
+ errMsg = self.msgAjaxError.replace('{operation}', operation);
+ return fileName ? '<b>' + fileName + ': </b>' + errMsg : errMsg;
+ _parseFileType: function (type, name) {
+ var self = this, isValid, vType, cat, i, types = self.allowedPreviewTypes || [];
+ if (type === 'application/text-plain') {
+ return 'text';
+ for (i = 0; i < types.length; i++) {
+ cat = types[i];
+ isValid = self.fileTypeSettings[cat];
+ vType = isValid(type, name) ? cat : '';
+ if (!$h.isEmpty(vType)) {
+ return vType;
+ return 'other';
+ _getPreviewIcon: function (fname) {
+ var self = this, ext, out = null;
+ if (fname && fname.indexOf('.') > -1) {
+ ext = fname.split('.').pop();
+ if (self.previewFileIconSettings) {
+ out = self.previewFileIconSettings[ext] || self.previewFileIconSettings[ext.toLowerCase()] || null;
+ if (self.previewFileExtSettings) {
+ $.each(self.previewFileExtSettings, function (key, func) {
+ if (self.previewFileIconSettings[key] && func(ext)) {
+ out = self.previewFileIconSettings[key];
+ //noinspection UnnecessaryReturnStatementJS
+ return out || self.previewFileIcon;
+ _parseFilePreviewIcon: function (content, fname) {
+ var self = this, icn = self._getPreviewIcon(fname), out = content;
+ if (out.indexOf('{previewFileIcon}') > -1) {
+ out = out.setTokens({'previewFileIconClass': self.previewFileIconClass, 'previewFileIcon': icn});
+ _raise: function (event, params) {
+ var self = this, e = $.Event(event);
+ if (params !== undefined) {
+ self.$element.trigger(e, params);
+ self.$element.trigger(e);
+ var out = e.result, isAborted = out === false;
+ if (e.isDefaultPrevented() || isAborted) {
+ if (e.type === 'filebatchpreupload' && (out || isAborted)) {
+ self.ajaxAborted = out;
+ switch (event) {
+ // ignore these events
+ case 'filebatchuploadcomplete':
+ case 'filebatchuploadsuccess':
+ case 'fileuploaded':
+ case 'fileclear':
+ case 'filecleared':
+ case 'filereset':
+ case 'fileerror':
+ case 'filefoldererror':
+ case 'filecustomerror':
+ case 'filesuccessremove':
+ // receive data response via `filecustomerror` event`
+ if (!self.ajaxAborted) {
+ _listenFullScreen: function (isFullScreen) {
+ var self = this, $modal = self.$modal, $btnFull, $btnBord;
+ if (!$modal || !$modal.length) {
+ $btnFull = $modal && $modal.find('.btn-kv-fullscreen');
+ $btnBord = $modal && $modal.find('.btn-kv-borderless');
+ if (!$btnFull.length || !$btnBord.length) {
+ $btnFull.removeClass('active').attr('aria-pressed', 'false');
+ $btnBord.removeClass('active').attr('aria-pressed', 'false');
+ $btnFull.addClass('active').attr('aria-pressed', 'true');
+ $btnBord.addClass('active').attr('aria-pressed', 'true');
+ if ($modal.hasClass('file-zoom-fullscreen')) {
+ self._maximizeZoomDialog();
+ _listen: function () {
+ var self = this, $el = self.$element, $form = self.$form, $cont = self.$container, fullScreenEv;
+ self._handler($el, 'click', function (e) {
+ self._initFileSelected();
+ if ($el.hasClass('file-no-browse')) {
+ if ($el.data('zoneClicked')) {
+ $el.data('zoneClicked', false);
+ self._handler($el, 'change', $.proxy(self._change, self));
+ self._handler(self.$caption, 'paste', $.proxy(self.paste, self));
+ if (self.showBrowse) {
+ self._handler(self.$btnFile, 'click', $.proxy(self._browse, self));
+ self._handler(self.$btnFile, 'keypress', function (e) {
+ var keycode = e.keyCode || e.which;
+ if (keycode === 13) {
+ $el.trigger('click');
+ self._browse(e);
+ $cont.find('.fileinput-remove').hide();
+ self._handler($cont.find('.fileinput-remove:not([disabled])'), 'click', $.proxy(self.clear, self));
+ self._handler($cont.find('.fileinput-cancel'), 'click', $.proxy(self.cancel, self));
+ self._handler($cont.find('.fileinput-pause'), 'click', $.proxy(self.pause, self));
+ self._initDragDrop();
+ self._handler($form, 'reset', $.proxy(self.clear, self));
+ self._handler($form, 'submit', $.proxy(self._submitForm, self));
+ self._handler(self.$container.find('.fileinput-upload'), 'click', $.proxy(self._uploadClick, self));
+ self._handler($(window), 'resize', function () {
+ self._listenFullScreen(screen.width === window.innerWidth && screen.height === window.innerHeight);
+ fullScreenEv = 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange';
+ self._handler($(document), fullScreenEv, function () {
+ self._listenFullScreen($h.checkFullScreen());
+ self.$caption.on('focus', function () {
+ self.$captionContainer.focus();
+ self._autoFitContent();
+ self._initClickable();
+ self._refreshPreview();
+ _autoFitContent: function () {
+ var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
+ self = this, config = width < 400 ? (self.previewSettingsSmall || self.defaults.previewSettingsSmall) :
+ (self.previewSettings || self.defaults.previewSettings), sel;
+ $.each(config, function (cat, settings) {
+ sel = '.file-preview-frame .file-preview-' + cat;
+ self.$preview.find(sel + '.kv-preview-data,' + sel + ' .kv-preview-data').css(settings);
+ _scanDroppedItems: function (item, files, path) {
+ path = path || '';
+ var self = this, i, dirReader, readDir, errorHandler = function (e) {
+ self._log($h.logMessages.badDroppedFiles);
+ self._log(e);
+ if (item.isFile) {
+ item.file(function (file) {
+ if (path) {
+ file.newPath = path + file.name;
+ files.push(file);
+ }, errorHandler);
+ if (item.isDirectory) {
+ dirReader = item.createReader();
+ readDir = function () {
+ dirReader.readEntries(function (entries) {
+ if (entries && entries.length > 0) {
+ for (i = 0; i < entries.length; i++) {
+ self._scanDroppedItems(entries[i], files, path + item.name + '/');
+ // recursively call readDir() again, since browser can only handle first 100 entries.
+ readDir();
+ _initDragDrop: function () {
+ var self = this, $zone = self.$dropZone;
+ if (self.dropZoneEnabled && self.showPreview) {
+ self._handler($zone, 'dragenter dragover', $.proxy(self._zoneDragEnter, self));
+ self._handler($zone, 'dragleave', $.proxy(self._zoneDragLeave, self));
+ self._handler($zone, 'drop', $.proxy(self._zoneDrop, self));
+ self._handler($(document), 'dragenter dragover drop', self._zoneDragDropInit);
+ _zoneDragDropInit: function (e) {
+ _zoneDragEnter: function (e) {
+ var self = this, dt = e.originalEvent.dataTransfer, hasFiles = $.inArray('Files', dt.types) > -1;
+ self._zoneDragDropInit(e);
+ if (self.isDisabled || !hasFiles) {
+ dt.effectAllowed = 'none';
+ dt.dropEffect = 'none';
+ dt.dropEffect = 'copy';
+ if (self._raise('fileDragEnter', {'sourceEvent': e, 'files': dt.types.Files})) {
+ $h.addCss(self.$dropZone, 'file-highlighted');
+ _zoneDragLeave: function (e) {
+ if (self._raise('fileDragLeave', {'sourceEvent': e})) {
+ self.$dropZone.removeClass('file-highlighted');
+ _dropFiles: function (e, files) {
+ var self = this, $el = self.$element;
+ self.changeTriggered = true;
+ $el.get(0).files = files;
+ self.changeTriggered = false;
+ $el.trigger('change' + self.namespace);
+ self._change(e, files);
+ _zoneDrop: function (e) {
+ /** @namespace e.originalEvent.dataTransfer */
+ var self = this, i, $el = self.$element, dt = e.originalEvent.dataTransfer,
+ files = dt.files, items = dt.items, folders = $h.getDragDropFolders(items);
+ if (self.isDisabled || $h.isEmpty(files)) {
+ if (!self._raise('fileDragDrop', {'sourceEvent': e, 'files': files})) {
+ if (folders > 0) {
+ self._showFolderError(folders);
+ files = [];
+ for (i = 0; i < items.length; i++) {
+ var item = items[i].webkitGetAsEntry();
+ if (item) {
+ self._scanDroppedItems(item, files);
+ self._dropFiles(e, files);
+ }, 500);
+ _uploadClick: function (e) {
+ var self = this, $btn = self.$container.find('.fileinput-upload'), $form,
+ isEnabled = !$btn.hasClass('disabled') && $h.isEmpty($btn.attr('disabled'));
+ if (e && e.isDefaultPrevented()) {
+ if (isEnabled && $btn.attr('type') !== 'submit') {
+ $form = $btn.closest('form');
+ // downgrade to normal form submit if possible
+ if ($form.length) {
+ $form.trigger('submit');
+ if (isEnabled) {
+ self.upload();
+ _submitForm: function () {
+ return self._isFileSelectionValid() && !self._abort({});
+ _clearPreview: function () {
+ var self = this,
+ $thumbs = self.showUploadedThumbs ? self.getFrames(':not(.file-preview-success)') : self.getFrames();
+ $thumbs.each(function () {
+ var $thumb = $(this);
+ $thumb.remove();
+ if (!self.getFrames().length || !self.showPreview) {
+ self._resetUpload();
+ self._validateDefaultPreview();
+ _initSortable: function () {
+ var self = this, $el = self.$preview, settings, selector = '.' + $h.SORT_CSS, $cont, $body = $('body'),
+ $html = $('html'), rev = self.reversePreviewOrder, Sortable = window.Sortable, beginGrab, endGrab;
+ if (!Sortable || $el.find(selector).length === 0) {
+ $cont = $body.length ? $body : ($html.length ? $html : self.$container);
+ beginGrab = function () {
+ $cont.addClass('file-grabbing');
+ endGrab = function () {
+ $cont.removeClass('file-grabbing');
+ settings = {
+ handle: '.drag-handle-init',
+ dataIdAttr: 'data-fileid',
+ animation: 600,
+ draggable: selector,
+ scroll: false,
+ forceFallback: true,
+ onChoose: beginGrab,
+ onStart: beginGrab,
+ onUnchoose: endGrab,
+ onEnd: endGrab,
+ onSort: function (e) {
+ var oldIndex = e.oldIndex, newIndex = e.newIndex, i = 0, len = self.initialPreviewConfig.length,
+ exceedsLast = len > 0 && newIndex >= len, $item = $(e.item), $first;
+ if (exceedsLast) {
+ newIndex = len - 1;
+ self.initialPreview = $h.moveArray(self.initialPreview, oldIndex, newIndex, rev);
+ self.initialPreviewConfig = $h.moveArray(self.initialPreviewConfig, oldIndex, newIndex, rev);
+ self.getFrames('.file-preview-initial').each(function () {
+ $(this).attr('data-fileindex', $h.INIT_FLAG + i);
+ i++;
+ $first = self.getFrames(':not(.file-preview-initial):first');
+ if ($first.length) {
+ $item.slideUp(function () {
+ $item.insertBefore($first).slideDown();
+ self._raise('filesorted', {
+ previewId: $item.attr('id'),
+ 'oldIndex': oldIndex,
+ 'newIndex': newIndex,
+ stack: self.initialPreviewConfig
+ $.extend(true, settings, self.fileActionSettings.dragSettings);
+ if (self.sortable) {
+ self.sortable.destroy();
+ self.sortable = Sortable.create($el[0], settings);
+ _setPreviewContent: function (content) {
+ $h.setHtml(self.$preview, content);
+ _initPreviewImageOrientations: function () {
+ var self = this, i = 0, canOrientImage = self.canOrientImage;
+ if (!self.autoOrientImageInitial && !canOrientImage) {
+ var $thumb = $(this), $img, $zoomImg, id, config = self.initialPreviewConfig[i];
+ /** @namespace config.exif */
+ if (config && config.exif && config.exif.Orientation) {
+ id = $thumb.attr('id');
+ $img = $thumb.find('>.kv-file-content img');
+ $zoomImg = self._getZoom(id, ' >.kv-file-content img');
+ if (canOrientImage) {
+ $img.css('image-orientation', (self.autoOrientImageInitial ? 'from-image' : 'none'));
+ self.setImageOrientation($img, $zoomImg, config.exif.Orientation, $thumb);
+ _initPreview: function (isInit) {
+ var self = this, cap = self.initialCaption || '', out;
+ if (!self.previewCache.count(true)) {
+ self._clearPreview();
+ if (isInit) {
+ self._setCaption(cap);
+ self._initCaption();
+ out = self.previewCache.out();
+ cap = isInit && self.initialCaption ? self.initialCaption : out.caption;
+ self._setPreviewContent(out.content);
+ self._setInitThumbAttr();
+ if (!$h.isEmpty(out.content)) {
+ self.$container.removeClass('file-input-new');
+ self._initPreviewImageOrientations();
+ _getZoomButton: function (type) {
+ var self = this, label = self.previewZoomButtonIcons[type], css = self.previewZoomButtonClasses[type],
+ title = ' title="' + (self.previewZoomButtonTitles[type] || '') + '" ', tag = $h.isBs(5) ? 'bs-' : '',
+ params = title + (type === 'close' ? ' data-' + tag + 'dismiss="modal" aria-hidden="true"' : '');
+ if (type === 'fullscreen' || type === 'borderless' || type === 'toggleheader') {
+ params += ' data-toggle="button" aria-pressed="false" autocomplete="off"';
+ return '<button type="button" class="' + css + ' btn-kv-' + type + '"' + params + '>' + label + '</button>';
+ _getModalContent: function () {
+ return self._getLayoutTemplate('modal').setTokens({
+ 'rtl': self.rtl ? ' kv-rtl' : '',
+ 'zoomFrameClass': self.frameClass,
+ 'prev': self._getZoomButton('prev'),
+ 'next': self._getZoomButton('next'),
+ 'rotate': self._getZoomButton('rotate'),
+ 'toggleheader': self._getZoomButton('toggleheader'),
+ 'fullscreen': self._getZoomButton('fullscreen'),
+ 'borderless': self._getZoomButton('borderless'),
+ 'close': self._getZoomButton('close')
+ _listenModalEvent: function (event) {
+ var self = this, $modal = self.$modal, getParams = function (e) {
+ return {
+ sourceEvent: e,
+ previewId: $modal.data('previewId'),
+ modal: $modal
+ $modal.on(event + '.bs.modal', function (e) {
+ if (e.namespace !== 'bs.modal') {
+ var $btnFull = $modal.find('.btn-fullscreen'), $btnBord = $modal.find('.btn-borderless');
+ if ($modal.data('fileinputPluginId') === self.$element.attr('id')) {
+ self._raise('filezoom' + event, getParams(e));
+ if (event === 'shown') {
+ self._handleRotation($modal, $modal.find('.file-zoom-detail'), $modal.data('angle'));
+ if ($h.checkFullScreen()) {
+ _initZoom: function () {
+ var self = this, $dialog, modalMain = self._getLayoutTemplate('modalMain'), modalId = '#' + $h.MODAL_ID;
+ modalMain = self._setTabIndex('modal', modalMain);
+ if (!self.showPreview) {
+ self.$modal = $(modalId);
+ if (!self.$modal || !self.$modal.length) {
+ $dialog = $h.createElement($h.cspBuffer.stash(modalMain)).insertAfter(self.$container);
+ self.$modal = $(modalId).insertBefore($dialog);
+ $h.cspBuffer.apply(self.$modal);
+ $dialog.remove();
+ $h.initModal(self.$modal);
+ self.$modal.html($h.cspBuffer.stash(self._getModalContent()));
+ $.each($h.MODAL_EVENTS, function (key, event) {
+ self._listenModalEvent(event);
+ _initZoomButtons: function () {
+ var self = this, $modal = self.$modal, previewId = $modal.data('previewId') || '', $first, $last,
+ thumbs = self.getFrames().toArray(), len = thumbs.length, $prev = $modal.find('.btn-kv-prev'),
+ $next = $modal.find('.btn-kv-next'), $rotate = $modal.find('.btn-kv-rotate');
+ if (thumbs.length < 2) {
+ $prev.hide();
+ $next.hide();
+ $prev.show();
+ $next.show();
+ if (!len) {
+ $first = $(thumbs[0]);
+ $last = $(thumbs[len - 1]);
+ $prev.removeAttr('disabled');
+ $next.removeAttr('disabled');
+ if (self.reversePreviewOrder) {
+ [$prev, $next] = [$next, $prev]; // swap
+ if ($first.length && $first.attr('id') === previewId) {
+ $prev.attr('disabled', true);
+ if ($last.length && $last.attr('id') === previewId) {
+ $next.attr('disabled', true);
+ _maximizeZoomDialog: function () {
+ var self = this, $modal = self.$modal, $head = $modal.find('.modal-header:visible'),
+ $foot = $modal.find('.modal-footer:visible'), $body = $modal.find('.kv-zoom-body'),
+ h = $(window).height(), diff = 0;
+ $modal.addClass('file-zoom-fullscreen');
+ if ($head && $head.length) {
+ h -= $head.outerHeight(true);
+ if ($foot && $foot.length) {
+ h -= $foot.outerHeight(true);
+ if ($body && $body.length) {
+ diff = $body.outerHeight(true) - $body.height();
+ h -= diff;
+ $modal.find('.kv-zoom-body').height(h);
+ _resizeZoomDialog: function (fullScreen) {
+ var self = this, $modal = self.$modal, $btnFull = $modal.find('.btn-kv-fullscreen'),
+ $btnBord = $modal.find('.btn-kv-borderless');
+ $h.toggleFullScreen(false);
+ if (!fullScreen) {
+ if (!$btnFull.hasClass('active')) {
+ $modal.removeClass('file-zoom-fullscreen');
+ self.$modal.find('.kv-zoom-body').css('height', self.zoomModalHeight);
+ self._resizeZoomDialog(true);
+ if ($btnBord.hasClass('active')) {
+ $h.toggleFullScreen(true);
+ $modal.focus();
+ _setZoomContent: function ($frame, navigate) {
+ var self = this, $content, tmplt, body, title, $body, $dataEl, config, previewId = $frame.attr('id'),
+ $zoomPreview = self._getZoom(previewId), $modal = self.$modal, $tmp, desc, $desc,
+ $btnFull = $modal.find('.btn-kv-fullscreen'), $btnBord = $modal.find('.btn-kv-borderless'), cap, size,
+ $btnTogh = $modal.find('.btn-kv-toggleheader'), dir = navigate === 'prev' ? 'Left' : 'Right',
+ slideIn = 'slideIn' + dir, slideOut = 'slideOut' + dir, parsed, zoomData = $frame.data('zoom');
+ if (zoomData) {
+ zoomData = decodeURIComponent(zoomData);
+ parsed = $zoomPreview.html().replace(self.zoomPlaceholder, '').setTokens({zoomData: zoomData});
+ $zoomPreview.html(parsed);
+ $frame.data('zoom', '');
+ $zoomPreview.attr('data-zoom', zoomData);
+ tmplt = $zoomPreview.attr('data-template') || 'generic';
+ $content = $zoomPreview.find('.kv-file-content');
+ body = $content.length ? $content.html() : '';
+ cap = $frame.data('caption') || self.msgZoomModalHeading;
+ size = $frame.data('size') || '';
+ desc = $frame.data('description') || '';
+ $modal.find('.kv-zoom-caption').attr('title', cap).html(cap);
+ $modal.find('.kv-zoom-size').html(size);
+ $desc = $modal.find('.kv-zoom-description').hide();
+ if (desc) {
+ if (self.showDescriptionClose) {
+ desc = self._getLayoutTemplate('descriptionClose').setTokens({
+ closeIcon: self.previewZoomButtonIcons.close
+ }) + '</button>' + desc;
+ $desc.show().html(desc);
+ self._handler($modal.find('.kv-desc-hide'), 'click', function () {
+ $(this).parent().fadeOut('fast', function () {
+ $body = $modal.find('.kv-zoom-body');
+ $modal.removeClass('kv-single-content');
+ if (navigate) {
+ $tmp = $body.addClass('file-thumb-loading').clone().insertAfter($body);
+ $h.setHtml($body, body).hide();
+ $tmp.fadeOut('fast', function () {
+ $body.fadeIn('fast', function () {
+ $body.removeClass('file-thumb-loading');
+ $h.setHtml($body, body);
+ config = self.previewZoomSettings[tmplt];
+ if (config) {
+ $dataEl = $body.find('.kv-preview-data');
+ $h.addCss($dataEl, 'file-zoom-detail');
+ $dataEl.css(key, value);
+ if (($dataEl.attr('width') && key === 'width') || ($dataEl.attr('height') && key === 'height')) {
+ $dataEl.removeAttr(key);
+ $modal.data('previewId', previewId);
+ self._handler($modal.find('.btn-kv-prev'), 'click', function () {
+ self._zoomSlideShow('prev', previewId);
+ self._handler($modal.find('.btn-kv-next'), 'click', function () {
+ self._zoomSlideShow('next', previewId);
+ self._handler($btnFull, 'click', function () {
+ self._handler($btnBord, 'click', function () {
+ self._resizeZoomDialog(false);
+ self._handler($btnTogh, 'click', function () {
+ var $header = $modal.find('.modal-header'), $floatBar = $modal.find('.floating-buttons'),
+ ht, $actions = $header.find('.kv-zoom-actions'), resize = function (height) {
+ var $body = self.$modal.find('.kv-zoom-body'), h = self.zoomModalHeight;
+ h = $body.outerHeight(true);
+ if (!height) {
+ h = h - $header.outerHeight(true);
+ $body.css('height', height ? h + height : h);
+ if ($header.is(':visible')) {
+ ht = $header.outerHeight(true);
+ $header.slideUp('slow', function () {
+ $actions.find('.btn').appendTo($floatBar);
+ resize(ht);
+ $floatBar.find('.btn').appendTo($actions);
+ $header.slideDown('slow', function () {
+ resize();
+ self._handler($modal, 'keydown', function (e) {
+ var key = e.which || e.keyCode, delay = self.processDelay + 1, $prev = $(this).find('.btn-kv-prev'),
+ $next = $(this).find('.btn-kv-next'), vId = $(this).data('previewId'), vPrevKey, vNextKey;
+ [vPrevKey, vNextKey] = self.rtl ? [39, 37] : [37, 39];
+ $.each({prev: [$prev, vPrevKey], next: [$next, vNextKey]}, function (direction, config) {
+ var $btn = config[0], vKey = config[1];
+ if (key === vKey && $btn.length) {
+ if (!$btn.attr('disabled')) {
+ $btn.blur();
+ $btn.focus();
+ self._zoomSlideShow(direction, vId);
+ if ($btn.attr('disabled')) {
+ _showModal: function ($frame) {
+ var self = this, $modal = self.$modal, $content, css, angle;
+ if (!$frame || !$frame.length) {
+ $h.initModal($modal);
+ $h.setHtml($modal, self._getModalContent());
+ self._setZoomContent($frame);
+ $modal.removeClass('rotatable');
+ $modal.data({backdrop: false, fileinputPluginId: self.$element.attr('id')});
+ $modal.find('.kv-zoom-body').css('height', self.zoomModalHeight);
+ $content = $frame.find('.kv-file-content > :first-child');
+ if ($content.length) {
+ css = $content.css('transform');
+ if (css) {
+ $modal.find('.file-zoom-detail').css('transform', css);
+ if ($frame.hasClass('rotatable')) {
+ $modal.addClass('rotatable');
+ if ($frame.data('angle')) {
+ $modal.data('angle', $frame.data('angle'));
+ angle = ($frame.data('angle') || 0);
+ $modal.modal('show');
+ self._initZoomButtons();
+ self._initRotateZoom($frame, $content);
+ _zoomPreview: function ($btn) {
+ var self = this, $frame;
+ if (!$btn.length) {
+ throw 'Cannot zoom to detailed preview!';
+ $frame = $btn.closest($h.FRAMES);
+ self._showModal($frame);
+ _zoomSlideShow: function (dir, previewId) {
+ var self = this, $modal = self.$modal, $btn = $modal.find('.kv-zoom-actions .btn-kv-' + dir), $targFrame, i,
+ $thumb, thumbsData = self.getFrames().toArray(), thumbs = [], len = thumbsData.length, out, angle,
+ $content;
+ dir = dir === 'prev' ? 'next' : 'prev';
+ $thumb = $(thumbsData[i]);
+ if ($thumb && $thumb.length && $thumb.find('.kv-file-zoom:visible').length) {
+ thumbs.push(thumbsData[i]);
+ len = thumbs.length;
+ if ($(thumbs[i]).attr('id') === previewId) {
+ out = dir === 'prev' ? i - 1 : i + 1;
+ if (out < 0 || out >= len || !thumbs[out]) {
+ $targFrame = $(thumbs[out]);
+ if ($targFrame.length) {
+ self._setZoomContent($targFrame, dir);
+ if ($targFrame.length && $targFrame.hasClass('rotatable')) {
+ angle = $targFrame.data('angle') || 0;
+ $modal.addClass('rotatable').data('angle', angle);
+ $content = $targFrame.find('.kv-file-content > :first-child');
+ self._initRotateZoom($targFrame, $content);
+ $modal.removeClass('rotatable').removeData('angle');
+ self._raise('filezoom' + dir, {'previewId': previewId, modal: self.$modal});
+ _initZoomButton: function () {
+ self.$preview.find('.kv-file-zoom').each(function () {
+ var $el = $(this);
+ self._handler($el, 'click', function () {
+ self._zoomPreview($el);
+ _inputFileCount: function () {
+ return this.$element[0].files.length;
+ _refreshPreview: function () {
+ var self = this, files;
+ if ((!self._inputFileCount() && !self.isAjaxUpload) || !self.showPreview || !self.isPreviewable) {
+ if (self.isAjaxUpload) {
+ if (self.fileManager.count() > 0) {
+ files = $.extend(true, [], self.getFileList());
+ self.fileManager.clear();
+ files = self.$element[0].files;
+ if (files && files.length) {
+ self.readFiles(files);
+ _clearObjects: function ($el) {
+ $el.find('video audio').each(function () {
+ this.pause();
+ $(this).remove();
+ $el.find('img object div').each(function () {
+ _clearFileInput: function () {
+ var self = this, $el = self.$element, $srcFrm, $tmpFrm, $tmpEl;
+ if (!self._inputFileCount()) {
+ $srcFrm = $el.closest('form');
+ $tmpFrm = $(document.createElement('form'));
+ $tmpEl = $(document.createElement('div'));
+ $el.before($tmpEl);
+ if ($srcFrm.length) {
+ $srcFrm.after($tmpFrm);
+ $tmpEl.after($tmpFrm);
+ $tmpFrm.append($el).trigger('reset');
+ $tmpEl.before($el).remove();
+ $tmpFrm.remove();
+ _resetUpload: function () {
+ self.uploadInitiated = false;
+ self.uploadCache = [];
+ self.$btnUpload.removeAttr('disabled');
+ self._setProgress(0);
+ self._hideProgress();
+ self._resetErrors(false);
+ self.fileManager.clearImages();
+ self._resetCanvas();
+ if (self.overwriteInitial) {
+ content: [],
+ config: [],
+ tags: []
+ _resetCanvas: function () {
+ if (self.imageCanvas && self.imageCanvasContext) {
+ self.imageCanvasContext.clearRect(0, 0, self.imageCanvas.width, self.imageCanvas.height);
+ _hasInitialPreview: function () {
+ return !self.overwriteInitial && self.previewCache.count(true);
+ _resetPreview: function () {
+ var self = this, out, cap, $div, hasSuc = self.showUploadedThumbs, hasErr = !self.removeFromPreviewOnError,
+ includeProcessed = (hasSuc || hasErr) && self.isDuplicateError;
+ if (self.previewCache.count(true)) {
+ if (includeProcessed) {
+ $div = $h.createElement('').insertAfter(self.$container);
+ self.getFrames().each(function () {
+ if ((hasSuc && $thumb.hasClass('file-preview-success')) ||
+ (hasErr && $thumb.hasClass('file-preview-error'))) {
+ $div.append($thumb);
+ cap = self.initialCaption ? self.initialCaption : out.caption;
+ $div.contents().appendTo(self.$preview);
+ $div.remove();
+ _clearDefaultPreview: function () {
+ self.$preview.find('.file-default-preview').remove();
+ _validateDefaultPreview: function () {
+ if (!self.showPreview || $h.isEmpty(self.defaultPreviewContent)) {
+ self._setPreviewContent('<div class="file-default-preview">' + self.defaultPreviewContent + '</div>');
+ _resetPreviewThumbs: function (isAjax) {
+ var self = this, out;
+ if (isAjax) {
+ if (self._hasInitialPreview()) {
+ self._setCaption(out.caption);
+ _getLayoutTemplate: function (t) {
+ var self = this, template = self.layoutTemplates[t];
+ if ($h.isEmpty(self.customLayoutTags)) {
+ return template;
+ return $h.replaceTags(template, self.customLayoutTags);
+ _getPreviewTemplate: function (t) {
+ var self = this, templates = self.previewTemplates, template = templates[t] || templates.other;
+ if ($h.isEmpty(self.customPreviewTags)) {
+ return $h.replaceTags(template, self.customPreviewTags);
+ _getOutData: function (formdata, jqXHR, responseData, filesData) {
+ jqXHR = jqXHR || {};
+ responseData = responseData || {};
+ filesData = filesData || self.fileManager.list();
+ formdata: formdata,
+ files: filesData,
+ filenames: self.filenames,
+ filescount: self.getFilesCount(),
+ extra: self._getExtraData(),
+ response: responseData,
+ reader: self.reader,
+ jqXHR: jqXHR
+ _getMsgSelected: function (n, processing) {
+ var self = this, strFiles = n === 1 ? self.fileSingle : self.filePlural;
+ return n > 0 ? self.msgSelected.replace('{n}', n).replace('{files}', strFiles) :
+ (processing ? self.msgProcessing : self.msgNoFilesSelected);
+ _getFrame: function (id, skipWarning) {
+ var self = this, $frame = $h.getFrameElement(self.$preview, id);
+ if (self.showPreview && !skipWarning && !$frame.length) {
+ self._log($h.logMessages.invalidThumb, {id: id});
+ return $frame;
+ _getZoom: function (id, selector) {
+ var self = this, $frame = $h.getZoomElement(self.$preview, id, selector);
+ if (self.showPreview && !$frame.length) {
+ _getThumbs: function (css) {
+ css = css || '';
+ return this.getFrames(':not(.file-preview-initial)' + css);
+ _getThumbId: function (fileId) {
+ return self.previewInitId + '-' + fileId;
+ _getExtraData: function (fileId, index) {
+ var self = this, data = self.uploadExtraData;
+ if (typeof self.uploadExtraData === 'function') {
+ data = self.uploadExtraData(fileId, index);
+ return data;
+ _initXhr: function (xhrobj, fileId) {
+ var self = this, fm = self.fileManager, func = function (event) {
+ var pct = 0, total = event.total, loaded = event.loaded || event.position,
+ stats = fm.getUploadStats(fileId, loaded, total);
+ /** @namespace event.lengthComputable */
+ if (event.lengthComputable && !self.enableResumableUpload) {
+ pct = $h.round(loaded / total * 100);
+ if (fileId) {
+ self._setFileUploadStats(fileId, pct, stats);
+ self._setProgress(pct, null, null, self._getStats(stats));
+ self._raise('fileajaxprogress', [stats]);
+ if (xhrobj.upload) {
+ if (self.progressDelay) {
+ func = $h.debounce(func, self.progressDelay);
+ xhrobj.upload.addEventListener('progress', func, false);
+ return xhrobj;
+ _initAjaxSettings: function () {
+ self._ajaxSettings = $.extend(true, {}, self.ajaxSettings);
+ self._ajaxDeleteSettings = $.extend(true, {}, self.ajaxDeleteSettings);
+ _mergeAjaxCallback: function (funcName, srcFunc, type) {
+ var self = this, settings = self._ajaxSettings, flag = self.mergeAjaxCallbacks, targFunc;
+ if (type === 'delete') {
+ settings = self._ajaxDeleteSettings;
+ flag = self.mergeAjaxDeleteCallbacks;
+ targFunc = settings[funcName];
+ if (flag && typeof targFunc === 'function') {
+ if (flag === 'before') {
+ settings[funcName] = function () {
+ targFunc.apply(this, arguments);
+ srcFunc.apply(this, arguments);
+ settings[funcName] = srcFunc;
+ _ajaxSubmit: function (fnBefore, fnSuccess, fnComplete, fnError, formdata, fileId, index, vUrl) {
+ var self = this, settings, defaults, data, tm = self.taskManager;
+ if (!self._raise('filepreajax', [formdata, fileId, index])) {
+ formdata.append('initialPreview', JSON.stringify(self.initialPreview));
+ formdata.append('initialPreviewConfig', JSON.stringify(self.initialPreviewConfig));
+ formdata.append('initialPreviewThumbTags', JSON.stringify(self.initialPreviewThumbTags));
+ self._initAjaxSettings();
+ self._mergeAjaxCallback('beforeSend', fnBefore);
+ self._mergeAjaxCallback('success', fnSuccess);
+ self._mergeAjaxCallback('complete', fnComplete);
+ self._mergeAjaxCallback('error', fnError);
+ vUrl = vUrl || self.uploadUrlThumb || self.uploadUrl;
+ if (typeof vUrl === 'function') {
+ vUrl = vUrl();
+ data = self._getExtraData(fileId, index) || {};
+ if (typeof data === 'object') {
+ $.each(data, function (key, value) {
+ formdata.append(key, value);
+ defaults = {
+ xhr: function () {
+ var xhrobj = $.ajaxSettings.xhr();
+ return self._initXhr(xhrobj, fileId);
+ url: self._encodeURI(vUrl),
+ type: 'POST',
+ dataType: 'json',
+ data: formdata,
+ cache: false,
+ processData: false,
+ contentType: false
+ settings = $.extend(true, {}, defaults, self._ajaxSettings);
+ self.ajaxQueue.push(settings);
+ tm.addTask(fileId + '-' + index, function () {
+ var self = this.self, config, xhr;
+ config = self.ajaxQueue.shift();
+ xhr = $.ajax(config);
+ self.ajaxRequests.push(xhr);
+ }).runWithContext({self: self});
+ _mergeArray: function (prop, content) {
+ var self = this, arr1 = $h.cleanArray(self[prop]), arr2 = $h.cleanArray(content);
+ self[prop] = arr1.concat(arr2);
+ _initUploadSuccess: function (out, $thumb, allFiles) {
+ var self = this, append, data, index, $div, content, config, tags, id, i;
+ if (!self.showPreview || typeof out !== 'object' || $.isEmptyObject(out)) {
+ self._resetCaption();
+ if (out.initialPreview !== undefined && out.initialPreview.length > 0) {
+ self.hasInitData = true;
+ content = out.initialPreview || [];
+ config = out.initialPreviewConfig || [];
+ tags = out.initialPreviewThumbTags || [];
+ append = out.append === undefined || out.append;
+ if (content.length) {
+ self._mergeArray('initialPreview', content);
+ self._mergeArray('initialPreviewConfig', config);
+ self._mergeArray('initialPreviewThumbTags', tags);
+ if ($thumb !== undefined) {
+ if (!allFiles) {
+ index = self.previewCache.add(content[0], config[0], tags[0], append);
+ data = self.previewCache.get(index, false);
+ $div = $h.createElement(data).hide().appendTo($thumb);
+ $thumb.fadeOut('slow', function () {
+ var $newThumb = $div.find('> .file-preview-frame');
+ if ($newThumb && $newThumb.length) {
+ $newThumb.insertBefore($thumb).fadeIn('slow').css('display:inline-block');
+ i = self._getUploadCacheIndex(id);
+ if (i !== null) {
+ self.uploadCache[i] = {
+ id: id,
+ content: content[0],
+ config: config[0] || [],
+ tags: tags[0] || [],
+ append: append
+ self.previewCache.set(content, config, tags, append);
+ self._initPreview();
+ _getUploadCacheIndex: function (id) {
+ var self = this, i, len = self.uploadCache.length, config;
+ config = self.uploadCache[i];
+ if (config.id === id) {
+ return i;
+ _initSuccessThumbs: function () {
+ self._getThumbs($h.FRAMES + '.file-preview-success').each(function () {
+ var $thumb = $(this), $remove = $thumb.find('.kv-file-remove');
+ $remove.removeAttr('disabled');
+ self._handler($remove, 'click', function () {
+ var id = $thumb.attr('id'),
+ out = self._raise('filesuccessremove', [id, $thumb.attr('data-fileindex')]);
+ $h.cleanMemory($thumb);
+ if (out === false) {
+ self.$caption.attr('title', '');
+ if (!self.getFrames().length) {
+ self.reset();
+ _updateInitialPreview: function () {
+ var self = this, u = self.uploadCache;
+ $.each(u, function (key, setting) {
+ self.previewCache.add(setting.content, setting.config, setting.tags, setting.append);
+ if (self.hasInitData) {
+ _getThumbFileId: function ($thumb) {
+ if (self.showPreview && $thumb !== undefined) {
+ return $thumb.attr('data-fileid');
+ _getThumbFile: function ($thumb) {
+ var self = this, id = self._getThumbFileId($thumb);
+ return id ? self.fileManager.getFile(id) : null;
+ _uploadSingle: function (i, id, isBatch, deferrer) {
+ var self = this, fm = self.fileManager, count = fm.count(), formdata = new FormData(), outData,
+ previewId = self._getThumbId(id), $thumb, chkComplete, $btnUpload, $btnDelete,
+ hasPostData = count > 0 || !$.isEmptyObject(self.uploadExtraData), uploadFailed, $prog, fnBefore,
+ errMsg, fnSuccess, fnComplete, fnError, updateUploadLog, op = self.ajaxOperations.uploadThumb,
+ fileObj = fm.getFile(id), params = {id: previewId, index: i, fileId: id},
+ fileName = self.fileManager.getFileName(id, true), resolve = function () {
+ if (deferrer && deferrer.resolve) {
+ deferrer.resolve();
+ }, reject = function () {
+ if (deferrer && deferrer.reject) {
+ deferrer.reject();
+ if (self.enableResumableUpload) { // not enabled for resumable uploads
+ self.uploadInitiated = true;
+ $thumb = fm.getThumb(id);
+ $prog = $thumb.find('.file-thumb-progress');
+ $btnUpload = $thumb.find('.kv-file-upload');
+ $btnDelete = $thumb.find('.kv-file-remove');
+ $prog.show();
+ if (count === 0 || !hasPostData || (self.showPreview && $btnUpload && $btnUpload.hasClass('disabled')) ||
+ self._abort(params)) {
+ updateUploadLog = function () {
+ if (!uploadFailed) {
+ fm.errors.push(id);
+ fm.setProcessed(id);
+ chkComplete();
+ chkComplete = function () {
+ var $initThumbs;
+ if (!self.fileBatchCompleted) {
+ var triggerReset = fm.count() === 0, errCount = fm.errors.length;
+ self._updateInitialPreview();
+ self.unlock(triggerReset);
+ if (triggerReset) {
+ $initThumbs = self.$preview.find('.file-preview-initial');
+ if (self.uploadAsync && $initThumbs.length) {
+ self._raise('filebatchuploadcomplete', [fm.stack, self._getExtraData()]);
+ if (!self.retryErrorUploads || errCount === 0) {
+ fm.clear();
+ outData = self._getOutData(formdata, jqXHR);
+ self.fileBatchCompleted = false;
+ if (!isBatch) {
+ $btnUpload.attr('disabled', true);
+ if (fm.errors.indexOf(id) !== -1) {
+ delete fm.errors[id];
+ self._raise('filepreupload', [outData, previewId, i, self._getThumbFileId($thumb)]);
+ $.extend(true, params, outData);
+ if (self._abort(params)) {
+ jqXHR.abort();
+ self._setThumbStatus($thumb, 'New');
+ $btnUpload.removeAttr('disabled');
+ $btnDelete.removeAttr('disabled');
+ self._setProgressCancelled();
+ var pid = self.showPreview && $thumb.attr('id') ? $thumb.attr('id') : previewId;
+ outData = self._getOutData(formdata, jqXHR, data);
+ if ($h.isEmpty(data) || $h.isEmpty(data.error)) {
+ $btnUpload.hide();
+ self._initUploadSuccess(data, $thumb, isBatch);
+ self._raise('fileuploaded', [outData, pid, i, self._getThumbFileId($thumb)]);
+ self.fileManager.remove($thumb);
+ updateUploadLog();
+ resolve();
+ uploadFailed = true;
+ errMsg = self._parseError(op, jqXHR, self.msgUploadError, self.fileManager.getFileName(id));
+ self._showFileError(errMsg, params);
+ if (!self.retryErrorUploads) {
+ if (isBatch) {
+ self._setProgress(101, self._getFrame(pid).find('.file-thumb-progress'),
+ self.msgUploadError);
+ self.unlock(false);
+ self._initSuccessThumbs();
+ errMsg = self._parseError(op, jqXHR, errorThrown, self.fileManager.getFileName(id));
+ var $prog;
+ reject();
+ self.fileManager.setProgress(id, 100);
+ $.extend(true, params, self._getOutData(formdata, jqXHR));
+ self._setProgress(101, self.$progress, self.msgAjaxProgressError.replace('{operation}', op));
+ $prog = self.showPreview && $thumb ? $thumb.find('.file-thumb-progress') : '';
+ self._setProgress(101, $prog, self.msgUploadError);
+ self._setFileData(formdata, fileObj.file, fileName, id);
+ self._setUploadData(formdata, {fileId: id});
+ self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata, id, i);
+ _setFileData: function (formdata, file, fileName, fileId) {
+ var self = this, preProcess = self.preProcessUpload;
+ if (preProcess && typeof preProcess === 'function') {
+ formdata.append(self.uploadFileAttr, preProcess(fileId, file));
+ formdata.append(self.uploadFileAttr, file, fileName);
+ _checkBatchPreupload: function (outData, jqXHR) {
+ var self = this, out = self._raise('filebatchpreupload', [outData]);
+ if (out) {
+ self._abort(outData);
+ if (jqXHR) {
+ var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'),
+ if ($thumb.hasClass('file-preview-loading')) {
+ _uploadBatch: function () {
+ var self = this, fm = self.fileManager, total = fm.total(), params = {}, fnBefore, fnSuccess, fnError,
+ fnComplete, hasPostData = total > 0 || !$.isEmptyObject(self.uploadExtraData), errMsg,
+ setAllUploaded, formdata = new FormData(), op = self.ajaxOperations.uploadBatch;
+ if (total === 0 || !hasPostData || self._abort(params)) {
+ setAllUploaded = function () {
+ fm.initStats();
+ var outData = self._getOutData(formdata, jqXHR);
+ self._checkBatchPreupload(outData, jqXHR);
+ /** @namespace data.errorkeys */
+ var outData = self._getOutData(formdata, jqXHR, data), key = 0,
+ $thumbs = self._getThumbs(':not(.file-preview-success)'),
+ keys = $h.isEmpty(data) || $h.isEmpty(data.errorkeys) ? [] : data.errorkeys;
+ self._raise('filebatchuploadsuccess', [outData]);
+ setAllUploaded();
+ $thumb.find('.kv-file-upload').hide().removeAttr('disabled');
+ self._initUploadSuccess(data);
+ $thumb.find('.kv-file-upload').removeAttr('disabled');
+ $thumb.find('.kv-file-remove').removeAttr('disabled');
+ if (keys.length === 0 || $.inArray(key, keys) !== -1) {
+ $thumb.find('.kv-file-upload').hide();
+ if (!$thumb.hasClass('file-preview-error') || self.retryErrorUploads) {
+ key++;
+ errMsg = self._parseError(op, jqXHR, self.msgUploadError);
+ self._showFileError(errMsg, outData, 'filebatchuploaderror');
+ self._setProgress(101, self.$progress, self.msgUploadError);
+ self._raise('filebatchuploadcomplete', [self.fileManager.stack, self._getExtraData()]);
+ errMsg = self._parseError(op, jqXHR, errorThrown);
+ self.uploadFileCount = total - 1;
+ if (self._getThumbFile($thumb)) {
+ self._setPreviewError($thumb);
+ self._getThumbs().removeClass('file-uploading');
+ self._getThumbs(' .kv-file-upload').removeAttr('disabled');
+ self._getThumbs(' .kv-file-delete').removeAttr('disabled');
+ var ctr = 0;
+ $.each(self.fileManager.stack, function (key, data) {
+ if (!$h.isEmpty(data.file)) {
+ self._setFileData(formdata, data.file, (data.nameFmt || ('untitled_' + ctr)), key);
+ ctr++;
+ self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata);
+ _uploadExtraOnly: function () {
+ var self = this, params = {}, fnBefore, fnSuccess, fnComplete, fnError, formdata = new FormData(), errMsg,
+ op = self.ajaxOperations.uploadExtra;
+ self._setProgress(50);
+ params.data = outData;
+ params.xhr = jqXHR;
+ var outData = self._getOutData(formdata, jqXHR, data);
+ _deleteFileIndex: function ($frame) {
+ var self = this, ind = $frame.attr('data-fileindex'), rev = self.reversePreviewOrder;
+ if (ind.substring(0, 5) === $h.INIT_FLAG) {
+ ind = parseInt(ind.replace($h.INIT_FLAG, ''));
+ self.initialPreview = $h.spliceArray(self.initialPreview, ind, rev);
+ self.initialPreviewConfig = $h.spliceArray(self.initialPreviewConfig, ind, rev);
+ self.initialPreviewThumbTags = $h.spliceArray(self.initialPreviewThumbTags, ind, rev);
+ var $nFrame = $(this), nInd = $nFrame.attr('data-fileindex');
+ if (nInd.substring(0, 5) === $h.INIT_FLAG) {
+ nInd = parseInt(nInd.replace($h.INIT_FLAG, ''));
+ if (nInd > ind) {
+ nInd--;
+ $nFrame.attr('data-fileindex', $h.INIT_FLAG + nInd);
+ _resetCaption: function () {
+ var cap = '', n, chk = self.previewCache.count(true), len = self.fileManager.count(), file,
+ incomplete = ':not(.file-preview-success):not(.file-preview-error)', cfg,
+ hasThumb = self.showPreview && self.getFrames(incomplete).length;
+ if (len === 0 && chk === 0 && !hasThumb) {
+ n = chk + len;
+ if (n > 1) {
+ cap = self._getMsgSelected(n);
+ cfg = self.initialPreviewConfig[0];
+ cap = '';
+ if (cfg) {
+ cap = cfg.caption || cfg.filename || '';
+ if (!cap) {
+ file = self.fileManager.getFirstFile();
+ cap = file ? file.nameFmt : '_';
+ _handleRotation: function ($el, $content, angle) {
+ var self = this, css, newCss, addCss = '', scale = 1, elContent = $content[0], quadrant, transform, h, w,
+ wNew, $parent = $content.parent(), hParent, wParent, $body = $('body'), bodyExists = !!$body.length;
+ if (bodyExists) {
+ $body.addClass('kv-overflow-hidden');
+ if (!$content.length || $el.hasClass('hide-rotate')) {
+ $body.removeClass('kv-overflow-hidden');
+ transform = $content.css('transform');
+ if (transform) {
+ $content.css('transform', 'none');
+ $content.css('transform', transform);
+ angle = angle || 0;
+ quadrant = angle % 360;
+ css = 'rotate(' + angle + 'deg)';
+ newCss = 'rotate(' + quadrant + 'deg)';
+ addCss = '';
+ if (quadrant === 90 || quadrant === 270) {
+ w = elContent.naturalWidth || $content.outerWidth() || 0;
+ h = elContent.naturalHeight || $content.outerHeight() || 0;
+ scale = w > h && w != 0 ? (h / w).toFixed(2) : 1;
+ if ($parent.length) {
+ hParent = $parent.height();
+ wParent = $parent.width();
+ wNew = Math.min(w, wParent);
+ if (hParent > scale * wNew) {
+ scale = wNew > hParent && wNew != 0 ? (hParent / wNew).toFixed(2) : 1;
+ if (scale !== 1) {
+ addCss = ' scale(' + scale + ')';
+ $content.addClass('rotate-animate').css('transform', css + addCss);
+ $content.removeClass('rotate-animate').css('transform', newCss + addCss);
+ $el.data('angle', quadrant);
+ }, self.fadeDelay);
+ _initRotateButton: function () {
+ self.getFrames('.rotatable .kv-file-rotate').each(function () {
+ var $el = $(this), $frame = $el.closest($h.FRAMES),
+ var angle = ($frame.data('angle') || 0) + 90;
+ self._handleRotation($frame, $content, angle);
+ _initRotateZoom: function ($frame, $content) {
+ var self = this, $modal = self.$modal, $rotate = $modal.find('.btn-kv-rotate'),
+ angle = $frame.data('angle');
+ $modal.data('angle', angle);
+ if ($rotate.length) {
+ $rotate.off('click');
+ if ($modal.hasClass('rotatable')) {
+ $rotate.on('click', function () {
+ angle = ($modal.data('angle') || 0) + 90;
+ self._handleRotation($modal, $modal.find('.file-zoom-detail'), angle);
+ if ($frame.hasClass('hide-rotate')) {
+ $frame.data('angle', angle);
+ _initFileActions: function () {
+ self._initZoomButton();
+ self._initRotateButton();
+ self.getFrames(' .kv-file-remove').each(function () {
+ var $el = $(this), $frame = $el.closest($h.FRAMES), hasError, id = $frame.attr('id'),
+ ind = $frame.attr('data-fileindex'), status, fm = self.fileManager;
+ status = self._raise('filepreremove', [id, ind]);
+ if (status === false || !self._validateMinCount()) {
+ hasError = $frame.hasClass('file-preview-error');
+ $h.cleanMemory($frame);
+ $frame.fadeOut('slow', function () {
+ self.fileManager.remove($frame);
+ self._clearObjects($frame);
+ $frame.remove();
+ if (id && hasError) {
+ self.$errorContainer.find('li[data-thumb-id="' + id + '"]').fadeOut('fast', function () {
+ self._raise('fileremoved', [id, ind]);
+ self.getFrames(' .kv-file-upload').each(function () {
+ var $frame = $el.closest($h.FRAMES), fileId = self._getThumbFileId($frame);
+ if ($frame.hasClass('file-preview-error') && !self.retryErrorUploads) {
+ self._uploadSingle(self.fileManager.getIndex(fileId), fileId, false);
+ _initPreviewActions: function () {
+ var self = this, $preview = self.$preview, deleteExtraData = self.deleteExtraData || {},
+ btnRemove = $h.FRAMES + ' .kv-file-remove', settings = self.fileActionSettings,
+ origClass = settings.removeClass, errClass = settings.removeErrorClass,
+ resetProgress = function () {
+ var hasFiles = self.isAjaxUpload ? self.previewCache.count(true) : self._inputFileCount();
+ if (!self.getFrames().length && !hasFiles) {
+ self._setCaption('');
+ self.initialCaption = '';
+ $preview.find(btnRemove).each(function () {
+ var $el = $(this), vUrl = $el.data('url') || self.deleteUrl, vKey = $el.data('key'), errMsg, fnBefore,
+ fnSuccess, fnError, op = self.ajaxOperations.deleteThumb;
+ if ($h.isEmpty(vUrl) || vKey === undefined) {
+ var $frame = $el.closest($h.FRAMES), cache = self.previewCache.data, settings, params, config,
+ fileName, extraData, index = $frame.attr('data-fileindex');
+ index = parseInt(index.replace($h.INIT_FLAG, ''));
+ config = $h.isEmpty(cache.config) && $h.isEmpty(cache.config[index]) ? null : cache.config[index];
+ extraData = $h.isEmpty(config) || $h.isEmpty(config.extra) ? deleteExtraData : config.extra;
+ fileName = config && (config.filename || config.caption) || '';
+ if (typeof extraData === 'function') {
+ extraData = extraData();
+ params = {id: $el.attr('id'), key: vKey, extra: extraData};
+ self._raise('filepredelete', [vKey, jqXHR, extraData]);
+ if (self._abort()) {
+ $el.removeClass(errClass);
+ $h.addCss($frame, 'file-uploading');
+ $h.addCss($el, 'disabled ' + origClass);
+ var n, cap;
+ if (!$h.isEmpty(data) && !$h.isEmpty(data.error)) {
+ params.jqXHR = jqXHR;
+ params.response = data;
+ errMsg = self._parseError(op, jqXHR, self.msgDeleteError, fileName);
+ self._showFileError(errMsg, params, 'filedeleteerror');
+ $frame.removeClass('file-uploading');
+ $el.removeClass('disabled ' + origClass).addClass(errClass);
+ resetProgress();
+ $frame.removeClass('file-uploading').addClass('file-deleted');
+ index = parseInt(($frame.attr('data-fileindex')).replace($h.INIT_FLAG, ''));
+ self.previewCache.unset(index);
+ self._deleteFileIndex($frame);
+ n = self.previewCache.count(true);
+ cap = n > 0 ? self._getMsgSelected(n) : '';
+ self._raise('filedeleted', [vKey, jqXHR, extraData]);
+ var errMsg = self._parseError(op, jqXHR, errorThrown, fileName);
+ params.response = {};
+ self._mergeAjaxCallback('beforeSend', fnBefore, 'delete');
+ self._mergeAjaxCallback('success', fnSuccess, 'delete');
+ self._mergeAjaxCallback('error', fnError, 'delete');
+ settings = $.extend(true, {}, {
+ data: $.extend(true, {}, {key: vKey}, extraData)
+ }, self._ajaxDeleteSettings);
+ if (!self._validateMinCount()) {
+ self._raise('filebeforedelete', [vKey, extraData]);
+ if (self.ajaxAborted instanceof Promise) {
+ self.ajaxAborted.then(function (result) {
+ if (!result) {
+ $.ajax(settings);
+ _hideFileIcon: function () {
+ self.$captionContainer.removeClass('icon-visible');
+ _showFileIcon: function () {
+ $h.addCss(self.$captionContainer, 'icon-visible');
+ _getSize: function (bytes, skipTemplate, sizeUnits) {
+ var self = this, size = parseFloat(bytes), i = 0, factor = self.bytesToKB, func = self.fileSizeGetter, out,
+ sizeHuman = size, newSize;
+ if (!$.isNumeric(bytes) || !$.isNumeric(size)) {
+ if (typeof func === 'function') {
+ out = func(size);
+ if (!sizeUnits) {
+ sizeUnits = self.sizeUnits;
+ if (size > 0) {
+ while (sizeHuman >= factor) {
+ sizeHuman /= factor;
+ ++i;
+ if (!sizeUnits[i]) {
+ sizeHuman = size;
+ i = 0;
+ newSize = sizeHuman.toFixed(2);
+ if (newSize == sizeHuman) {
+ newSize = sizeHuman;
+ out = newSize + ' ' + sizeUnits[i];
+ return skipTemplate ? out : self._getLayoutTemplate('size').replace('{sizeText}', out);
+ _getFileType: function (ftype) {
+ return self.mimeTypeAliases[ftype] || ftype;
+ _generatePreviewTemplate: function (
+ cat,
+ data,
+ fname,
+ ftype,
+ previewId,
+ fileId,
+ isError,
+ size,
+ fnameUpdated,
+ frameClass,
+ foot,
+ ind,
+ templ,
+ attrs,
+ zoomData
+ ) {
+ var self = this, caption = self.slug(fname), prevContent, zoomContent = '', styleAttribs = '',
+ filename = fnameUpdated || fname, isIconic, ext = filename.split('.').pop().toLowerCase(),
+ screenW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
+ config, title = caption, alt = caption, typeCss = 'type-default', getContent, addFrameCss,
+ footer = foot || self._renderFileFooter(cat, caption, size, 'auto', isError), isRotatable,
+ alwaysPreview = $.inArray(ext, self.alwaysPreviewFileExtensions) !== -1,
+ forcePrevIcon = self.preferIconicPreview && !alwaysPreview,
+ forceZoomIcon = self.preferIconicZoomPreview && !alwaysPreview, newCat = forcePrevIcon ? 'other' : cat;
+ config = screenW < 400 ? (self.previewSettingsSmall[newCat] || self.defaults.previewSettingsSmall[newCat]) :
+ (self.previewSettings[newCat] || self.defaults.previewSettings[newCat]);
+ $.each(config, function (key, val) {
+ styleAttribs += key + ':' + val + ';';
+ getContent = function (vCat, vData, zoom, frameCss, vZoomData) {
+ var id = zoom ? 'zoom-' + previewId : previewId, tmplt = self._getPreviewTemplate(vCat),
+ css = (frameClass || '') + ' ' + frameCss, tokens;
+ if (self.frameClass) {
+ css = self.frameClass + ' ' + css;
+ if (zoom) {
+ css = css.replace(' ' + $h.SORT_CSS, '');
+ tmplt = self._parseFilePreviewIcon(tmplt, fname);
+ if (cat === 'object' && !ftype) {
+ $.each(self.defaults.fileTypeSettings, function (key, func) {
+ if (key === 'object' || key === 'other') {
+ if (func(fname, ftype)) {
+ typeCss = 'type-' + key;
+ if (!$h.isEmpty(attrs)) {
+ if (attrs.title !== undefined && attrs.title !== null) {
+ title = attrs.title;
+ if (attrs.alt !== undefined && attrs.alt !== null) {
+ alt = title = attrs.alt;
+ tokens = {
+ 'previewId': id,
+ 'title': title,
+ 'alt': alt,
+ 'frameClass': css,
+ 'type': self._getFileType(ftype),
+ 'fileindex': ind,
+ 'fileid': fileId || '',
+ 'filename': filename,
+ 'typeCss': typeCss,
+ 'footer': footer,
+ 'data': zoom && vZoomData ? self.zoomPlaceholder + '{zoomData}' : vData,
+ 'template': templ || cat,
+ 'style': styleAttribs ? 'style="' + styleAttribs + '"' : '',
+ 'zoomData': vZoomData ? encodeURIComponent(vZoomData) : ''
+ tokens.zoomCache = '';
+ tokens.zoomData = '{zoomData}';
+ return tmplt.setTokens(tokens);
+ ind = ind || previewId.slice(previewId.lastIndexOf('-') + 1);
+ isRotatable = self.fileActionSettings.showRotate && $.inArray(ext, self.rotatableFileExtensions) !== -1;
+ if (self.fileActionSettings.showZoom) {
+ addFrameCss = 'kv-zoom-thumb';
+ if (isRotatable) {
+ addFrameCss += ' rotatable' + (forceZoomIcon ? ' hide-rotate' : '');
+ zoomContent = getContent((forceZoomIcon ? 'other' : cat), data, true, addFrameCss, zoomData);
+ zoomContent = '\n' + self._getLayoutTemplate('zoomCache').replace('{zoomContent}', zoomContent);
+ if (typeof self.sanitizeZoomCache === 'function') {
+ zoomContent = self.sanitizeZoomCache(zoomContent);
+ addFrameCss = 'kv-preview-thumb';
+ isIconic = forcePrevIcon || self.hideThumbnailContent || !!self.previewFileIconSettings[ext];
+ addFrameCss += ' rotatable' + (isIconic ? ' hide-rotate' : '');
+ prevContent = getContent((forcePrevIcon ? 'other' : cat), data, false, addFrameCss, zoomData);
+ return prevContent.setTokens({zoomCache: zoomContent});
+ _addToPreview: function ($preview, content) {
+ var self = this, $el;
+ content = $h.cspBuffer.stash(content);
+ $el = self.reversePreviewOrder ? $preview.prepend(content) : $preview.append(content);
+ $h.cspBuffer.apply($preview);
+ return $el;
+ _previewDefault: function (file, isDisabled) {
+ var self = this, $preview = self.$preview;
+ var fname = $h.getFileName(file), ftype = file ? file.type : '', content, size = file.size || 0,
+ caption = self._getFileName(file, ''), isError = isDisabled === true && !self.isAjaxUpload,
+ data = $h.createObjectURL(file), fileId = self.fileManager.getId(file),
+ previewId = self._getThumbId(fileId);
+ self._clearDefaultPreview();
+ content = self._generatePreviewTemplate('other', data, fname, ftype, previewId, fileId, isError, size);
+ self._addToPreview($preview, content);
+ self._setThumbAttr(previewId, caption, size);
+ if (isDisabled === true && self.isAjaxUpload) {
+ self._setThumbStatus(self._getFrame(previewId), 'Error');
+ _previewFile: function (i, file, theFile, data, fileInfo) {
+ if (!this.showPreview) {
+ var self = this, fname = $h.getFileName(file), ftype = fileInfo.type, content,
+ caption = fileInfo.name, cat = self._parseFileType(ftype, fname), $preview = self.$preview,
+ fsize = file.size || 0, iData = cat === 'image' ? theFile.target.result : data, fm = self.fileManager,
+ fileId = fm.getId(file), previewId = self._getThumbId(fileId);
+ /** @namespace window.DOMPurify */
+ content = self._generatePreviewTemplate(cat, iData, fname, ftype, previewId, fileId, false, fsize, fileInfo.filename);
+ var $thumb = self._getFrame(previewId);
+ self._validateImageOrientation($thumb.find('img'), file, previewId, fileId, caption, ftype, fsize, iData);
+ self._setThumbAttr(previewId, caption, fsize);
+ _setThumbAttr: function (id, caption, size, description) {
+ var self = this, $frame = self._getFrame(id);
+ if ($frame.length) {
+ size = size && size > 0 ? self._getSize(size) : '';
+ $frame.data({'caption': caption, 'size': size, 'description': description || ''});
+ _setInitThumbAttr: function () {
+ var self = this, data = self.previewCache.data, len = self.previewCache.count(true), config,
+ caption, size, description, previewId;
+ for (var i = 0; i < len; i++) {
+ config = data.config[i];
+ previewId = self.previewInitId + '-' + $h.INIT_FLAG + i;
+ caption = $h.ifSet('caption', config, $h.ifSet('filename', config));
+ size = $h.ifSet('size', config);
+ description = $h.ifSet('description', config);
+ self._setThumbAttr(previewId, caption, size, description);
+ _slugDefault: function (text) {
+ // noinspection RegExpRedundantEscape
+ return $h.isEmpty(text, true) ? '' : String(text).replace(/[\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, '_');
+ _updateFileDetails: function (numFiles) {
+ var self = this, $el = self.$element, label, n, log, nFiles, file,
+ name = ($h.isIE(9) && $h.findFileName($el.val())) || ($el[0].files[0] && $el[0].files[0].name);
+ if (!name && self.fileManager.count() > 0) {
+ label = file.nameFmt;
+ label = name ? self.slug(name) : '_';
+ n = self.isAjaxUpload ? self.fileManager.count() : numFiles;
+ nFiles = self.previewCache.count(true) + n;
+ log = n === 1 ? label : self._getMsgSelected(nFiles, !self.isAjaxUpload && !self.isError);
+ if (self.isError) {
+ self.$previewContainer.removeClass('file-thumb-loading');
+ self._initCapStatus();
+ self.$previewStatus.html('');
+ self._showFileIcon();
+ self._setCaption(log, self.isError);
+ self.$container.removeClass('file-input-new file-input-ajax-new');
+ self._raise('fileselect', [numFiles, label]);
+ _setThumbStatus: function ($thumb, status) {
+ var icon = 'indicator' + status, msg = icon + 'Title',
+ css = 'file-preview-' + status.toLowerCase(),
+ $indicator = $thumb.find('.file-upload-indicator'),
+ config = self.fileActionSettings;
+ $thumb.removeClass('file-preview-success file-preview-error file-preview-paused file-preview-loading');
+ if (status === 'Success') {
+ $thumb.find('.file-drag-handle').remove();
+ $h.setHtml($indicator, config[icon]);
+ $indicator.attr('title', config[msg]);
+ $thumb.addClass(css);
+ if (status === 'Error' && !self.retryErrorUploads) {
+ $thumb.find('.kv-file-upload').attr('disabled', true);
+ _setProgressCancelled: function () {
+ self._setProgress(101, self.$progress, self.msgCancelled);
+ _setProgress: function (p, $el, error, stats) {
+ $el = $el || self.$progress;
+ if (!$el.length) {
+ var pct = Math.min(p, 100), out, pctLimit = self.progressUploadThreshold,
+ t = p <= 100 ? self.progressTemplate : self.progressCompleteTemplate,
+ template = pct < 100 ? self.progressTemplate :
+ (error ? (self.paused ? self.progressPauseTemplate : self.progressErrorTemplate) : t);
+ if (p >= 100) {
+ stats = '';
+ if (!$h.isEmpty(template)) {
+ if (pctLimit && pct > pctLimit && p <= 100) {
+ out = template.setTokens({'percent': pctLimit, 'status': self.msgUploadThreshold});
+ out = template.setTokens({'percent': pct, 'status': (p > 100 ? self.msgUploadEnd : pct + '%')});
+ stats = stats || '';
+ out = out.setTokens({stats: stats});
+ $h.setHtml($el, out);
+ if (error) {
+ $h.setHtml($el.find('[role="progressbar"]'), error);
+ _hasFiles: function () {
+ var el = this.$element[0];
+ return !!(el && el.files && el.files.length);
+ _setFileDropZoneTitle: function () {
+ var self = this, $zone = self.$container.find('.file-drop-zone'), title = self.dropZoneTitle, strFiles;
+ if (self.isClickable) {
+ strFiles = $h.isEmpty(self.$element.attr('multiple')) ? self.fileSingle : self.filePlural;
+ title += self.dropZoneClickTitle.replace('{files}', strFiles);
+ $zone.find('.' + self.dropZoneTitleClass).remove();
+ if (!self.showPreview || $zone.length === 0 || self.fileManager.count() > 0 || !self.dropZoneEnabled ||
+ self.previewCache.count() > 0 || (!self.isAjaxUpload && self._hasFiles())) {
+ if ($zone.find($h.FRAMES).length === 0 && $h.isEmpty(self.defaultPreviewContent)) {
+ $zone.prepend('<div class="' + self.dropZoneTitleClass + '">' + title + '</div>');
+ $h.addCss(self.$container, 'file-input-ajax-new');
+ _getStats: function (stats) {
+ var self = this, pendingTime, t;
+ if (!self.showUploadStats || !stats || !stats.bitrate) {
+ t = self._getLayoutTemplate('stats');
+ pendingTime = (!stats.elapsed || !stats.bps) ? self.msgCalculatingTime :
+ self.msgPendingTime.setTokens({time: $h.getElapsed(Math.ceil(stats.pendingBytes / stats.bps))});
+ return t.setTokens({
+ uploadSpeed: stats.bitrate,
+ pendingTime: pendingTime
+ _setResumableProgress: function (pct, stats, $thumb) {
+ var self = this, rm = self.resumableManager, obj = $thumb ? rm : self,
+ $prog = $thumb ? $thumb.find('.file-thumb-progress') : null;
+ if (obj.lastProgress === 0) {
+ obj.lastProgress = pct;
+ if (pct < obj.lastProgress) {
+ pct = obj.lastProgress;
+ self._setProgress(pct, $prog, null, self._getStats(stats));
+ _toggleResumableProgress: function (template, message) {
+ var self = this, $progress = self.$progress;
+ if ($progress && $progress.length) {
+ $h.setHtml($progress, template.setTokens({
+ percent: 101,
+ status: message,
+ stats: ''
+ }));
+ _setFileUploadStats: function (id, pct, stats) {
+ var self = this, $prog = self.$progress;
+ if (!self.showPreview && (!$prog || !$prog.length)) {
+ var fm = self.fileManager, rm = self.resumableManager, $thumb = fm.getThumb(id), pctTot,
+ totUpSize = 0, totSize = fm.getTotalSize(), totStats = $.extend(true, {}, stats);
+ if (self.enableResumableUpload) {
+ var loaded = stats.loaded, currUplSize = rm.getUploadedSize(), currTotSize = rm.file.size, totLoaded;
+ loaded += currUplSize;
+ totLoaded = fm.uploadedSize + loaded;
+ pct = $h.round(100 * loaded / currTotSize);
+ stats.pendingBytes = currTotSize - currUplSize;
+ self._setResumableProgress(pct, stats, $thumb);
+ pctTot = Math.floor(100 * totLoaded / totSize);
+ totStats.pendingBytes = totSize - totLoaded;
+ self._setResumableProgress(pctTot, totStats);
+ fm.setProgress(id, pct);
+ $prog = $thumb && $thumb.length ? $thumb.find('.file-thumb-progress') : null;
+ $.each(fm.stats, function (id, cfg) {
+ totUpSize += cfg.loaded;
+ totStats.pendingBytes = totSize - totUpSize;
+ pctTot = $h.round(totUpSize / totSize * 100);
+ self._setProgress(pctTot, null, null, self._getStats(totStats));
+ _validateMinCount: function () {
+ var self = this, len = self.isAjaxUpload ? self.fileManager.count() : self._inputFileCount();
+ if (self.validateInitialCount && self.minFileCount > 0 && self._getFileCount(len - 1) < self.minFileCount) {
+ self._noFilesError({});
+ _getFileCount: function (fileCount, includeInitial) {
+ var self = this, addCount = 0;
+ if (includeInitial === undefined) {
+ includeInitial = self.validateInitialCount && !self.overwriteInitial;
+ if (includeInitial) {
+ addCount = self.previewCache.count(true);
+ fileCount += addCount;
+ return fileCount;
+ _getFileId: function (file) {
+ return $h.getFileId(file, this.generateFileId);
+ _getFileName: function (file, defaultValue) {
+ var self = this, fileName = $h.getFileName(file);
+ return fileName ? self.slug(fileName) : defaultValue;
+ _getFileNames: function (skipNull) {
+ return self.filenames.filter(function (n) {
+ return (skipNull ? n !== undefined : n !== undefined && n !== null);
+ _setPreviewError: function ($thumb, keepFile) {
+ var self = this, removeFrame = self.removeFromPreviewOnError && !self.retryErrorUploads;
+ if (!keepFile || removeFrame) {
+ if (removeFrame) {
+ self._refreshUploadButton($thumb);
+ _refreshUploadButton: function ($thumb) {
+ var self = this, $btn = $thumb.find('.kv-file-upload'), cfg = self.fileActionSettings,
+ icon = cfg.uploadIcon, title = cfg.uploadTitle;
+ if (self.retryErrorUploads) {
+ icon = cfg.uploadRetryIcon;
+ title = cfg.uploadRetryTitle;
+ $btn.attr('title', title);
+ $h.setHtml($btn, icon);
+ _isValidSize: function (size, type, $image, $thumb, filename, params) {
+ var self = this, msg, dim, $img, tag = size === 'Small' ? 'min' : 'max', limit = self[tag + 'Image' + type];
+ if ($h.isEmpty(limit) || !$image.length) {
+ $img = $image[0];
+ dim = (type === 'Width') ? $img.naturalWidth || $img.width : $img.naturalHeight || $img.height;
+ if (size === 'Small' ? dim >= limit : dim <= limit) {
+ msg = self['msgImage' + type + size] || 'Image "{name}" has a size validation error (limit "{size}").';
+ self._showFileError(msg.setTokens({'name': filename, 'size': limit, 'dimension': dim}), params);
+ _getExifObj: function (data) {
+ var self = this, exifObj, error = $h.logMessages.exifWarning;
+ if (data.slice(0, 23) !== 'data:image/jpeg;base64,' && data.slice(0, 22) !== 'data:image/jpg;base64,') {
+ exifObj = null;
+ exifObj = window.piexif ? window.piexif.load(data) : null;
+ error = err && err.message || '';
+ if (!exifObj && self.showExifErrorLog) {
+ self._log($h.logMessages.badExifParser, {details: error});
+ return exifObj;
+ setImageOrientation: function ($img, $zoomImg, value, $thumb) {
+ var self = this, invalidImg = !$img || !$img.length, invalidZoomImg = !$zoomImg || !$zoomImg.length, $mark,
+ isHidden = false, $div, zoomOnly = invalidImg && $thumb && $thumb.attr('data-template') === 'image', ev;
+ if (invalidImg && invalidZoomImg) {
+ ev = 'load.fileinputimageorient';
+ if (zoomOnly) {
+ $img = $zoomImg;
+ $zoomImg = null;
+ $img.css(self.previewSettings.image);
+ $div = $(document.createElement('div')).appendTo($thumb.find('.kv-file-content'));
+ $mark = $(document.createElement('span')).insertBefore($img);
+ $img.css('visibility', 'hidden').removeClass('file-zoom-detail').appendTo($div);
+ isHidden = !$img.is(':visible');
+ $img.off(ev).on(ev, function () {
+ if (isHidden) {
+ self.$preview.removeClass('hide-content');
+ $thumb.find('.kv-file-content').css('visibility', 'hidden');
+ var img = $img[0], zoomImg = $zoomImg && $zoomImg.length ? $zoomImg[0] : null,
+ h = img.offsetHeight, w = img.offsetWidth, r = $h.getRotation(value);
+ $thumb.find('.kv-file-content').css('visibility', 'visible');
+ self.$preview.addClass('hide-content');
+ $img.data('orientation', value);
+ if (zoomImg) {
+ $zoomImg.data('orientation', value);
+ if (value < 5) {
+ $h.setTransform(img, r);
+ $h.setTransform(zoomImg, r);
+ var offsetAngle = Math.atan(w / h), origFactor = Math.sqrt(Math.pow(h, 2) + Math.pow(w, 2)),
+ scale = !origFactor ? 1 : (h / Math.cos(Math.PI / 2 + offsetAngle)) / origFactor,
+ s = ' scale(' + Math.abs(scale) + ')';
+ $h.setTransform(img, r + s);
+ $h.setTransform(zoomImg, r + s);
+ $img.css('visibility', 'visible').insertAfter($mark).addClass('file-zoom-detail');
+ $mark.remove();
+ _validateImageOrientation: function ($img, file, previewId, fileId, caption, ftype, fsize, iData) {
+ var self = this, exifObj = null, value, autoOrientImage = self.autoOrientImage, selector;
+ exifObj = self._getExifObj(iData);
+ if (self.canOrientImage) {
+ $img.css('image-orientation', (autoOrientImage ? 'from-image' : 'none'));
+ self._validateImage(previewId, fileId, caption, ftype, fsize, iData, exifObj);
+ selector = $h.getZoomSelector(previewId, ' img');
+ value = exifObj ? exifObj['0th'][piexif.ImageIFD.Orientation] : null; // jshint ignore:line
+ self.setImageOrientation($img, $(selector), value, self._getFrame(previewId));
+ self._raise('fileimageoriented', {'$img': $img, 'file': file});
+ _validateImage: function (previewId, fileId, fname, ftype, fsize, iData, exifObj) {
+ var self = this, $preview = self.$preview, params, w1, w2, $thumb = self._getFrame(previewId),
+ i = $thumb.attr('data-fileindex'), $img = $thumb.find('img');
+ fname = fname || 'Untitled';
+ $img.one('load', function () {
+ if ($img.data('validated')) {
+ $img.data('validated', true);
+ w1 = $thumb.width();
+ w2 = $preview.width();
+ if (w1 > w2) {
+ $img.css('width', '100%');
+ params = {ind: i, id: previewId, fileId: fileId};
+ var isValidWidth, isValidHeight;
+ isValidWidth = self._isValidSize('Small', 'Width', $img, $thumb, fname, params);
+ isValidHeight = self._isValidSize('Small', 'Height', $img, $thumb, fname, params);
+ if (!self.resizeImage) {
+ isValidWidth = isValidWidth && self._isValidSize('Large', 'Width', $img, $thumb, fname, params);
+ isValidHeight = isValidHeight && self._isValidSize('Large', 'Height', $img, $thumb, fname, params);
+ self._raise('fileimageloaded', [previewId]);
+ $thumb.data('exif', exifObj);
+ if (isValidWidth && isValidHeight) {
+ self.fileManager.addImage(fileId, {
+ ind: i,
+ img: $img,
+ thumb: $thumb,
+ pid: previewId,
+ typ: ftype,
+ siz: fsize,
+ validated: false,
+ imgData: iData,
+ exifObj: exifObj
+ self._validateAllImages();
+ }).one('error', function () {
+ self._raise('fileimageloaderror', [previewId]);
+ _validateAllImages: function () {
+ var self = this, counter = {val: 0}, numImgs = self.fileManager.getImageCount(), fsize,
+ minSize = self.resizeIfSizeMoreThan;
+ if (numImgs !== self.fileManager.totalImages) {
+ self._raise('fileimagesloaded');
+ $.each(self.fileManager.loadedImages, function (id, config) {
+ if (!config.validated) {
+ fsize = config.siz;
+ if (fsize && fsize > minSize * self.bytesToKB) {
+ self._getResizedImage(id, config, counter, numImgs);
+ config.validated = true;
+ _getResizedImage: function (id, config, counter, numImgs) {
+ var self = this, img = $(config.img)[0], width = img.naturalWidth, height = img.naturalHeight, blob,
+ ratio = 1, maxWidth = self.maxImageWidth || width, maxHeight = self.maxImageHeight || height,
+ isValidImage = !!(width && height), chkWidth, chkHeight, canvas = self.imageCanvas, dataURI,
+ context = self.imageCanvasContext, type = config.typ, pid = config.pid, ind = config.ind,
+ $thumb = config.thumb, throwError, msg, exifObj = config.exifObj, exifStr, file, params, evParams;
+ throwError = function (msg, params, ev) {
+ self._showFileError(msg, params, ev);
+ self._showError(msg, params, ev);
+ file = self.fileManager.getFile(id);
+ params = {id: pid, 'index': ind, fileId: id};
+ evParams = [id, pid, ind];
+ if (!file || !isValidImage || (width <= maxWidth && height <= maxHeight)) {
+ if (isValidImage && file) {
+ self._raise('fileimageresized', evParams);
+ counter.val++;
+ if (counter.val === numImgs) {
+ self._raise('fileimagesresized');
+ if (!isValidImage) {
+ throwError(self.msgImageResizeError, params, 'fileimageresizeerror');
+ type = type || self.resizeDefaultImageType;
+ chkWidth = width > maxWidth;
+ chkHeight = height > maxHeight;
+ if (self.resizePreference === 'width') {
+ ratio = chkWidth ? maxWidth / width : (chkHeight ? maxHeight / height : 1);
+ ratio = chkHeight ? maxHeight / height : (chkWidth ? maxWidth / width : 1);
+ width *= ratio;
+ height *= ratio;
+ canvas.width = width;
+ canvas.height = height;
+ context.drawImage(img, 0, 0, width, height);
+ dataURI = canvas.toDataURL(type, self.resizeQuality);
+ if (exifObj) {
+ exifStr = window.piexif.dump(exifObj);
+ dataURI = window.piexif.insert(exifStr, dataURI);
+ blob = $h.dataURI2Blob(dataURI);
+ self.fileManager.setFile(id, blob);
+ self._raise('fileimagesresized', [undefined, undefined]);
+ if (!(blob instanceof Blob)) {
+ msg = self.msgImageResizeException.replace('{errors}', err.message);
+ throwError(msg, params, 'fileimageresizeexception');
+ _showProgress: function () {
+ if (self.$progress && self.$progress.length) {
+ self.$progress.show();
+ _hideProgress: function () {
+ self.$progress.hide();
+ _initBrowse: function ($container) {
+ self.$btnFile = $container.find('.btn-file').append($el);
+ $el.appendTo($container).attr('tabindex', -1);
+ $h.addCss($el, 'file-no-browse');
+ _initClickable: function () {
+ var self = this, $zone, $tmpZone;
+ if (!self.isClickable) {
+ $zone = self.$dropZone;
+ $tmpZone = self.$preview.find('.file-default-preview');
+ if ($tmpZone.length) {
+ $zone = $tmpZone;
+ $h.addCss($zone, 'clickable');
+ $zone.attr('tabindex', -1);
+ self._handler($zone, 'click', function (e) {
+ var $tar = $(e.target);
+ if (!self.$errorContainer.is(':visible') && (!$tar.parents(
+ '.file-preview-thumbnails').length || $tar.parents(
+ '.file-default-preview').length)) {
+ $zone.blur();
+ _initCaption: function () {
+ var self = this, cap = self.initialCaption || '';
+ if (self.overwriteInitial || $h.isEmpty(cap)) {
+ self.$caption.val('');
+ _setCaption: function (content, isError) {
+ var self = this, title, out, icon, n, cap, file;
+ if (!self.$caption.length) {
+ if (isError) {
+ title = $('<div>' + self.msgValidationError + '</div>').text();
+ n = self.fileManager.count();
+ if (n) {
+ cap = n === 1 && file ? file.nameFmt : self._getMsgSelected(n);
+ cap = self._getMsgSelected(self.msgNo);
+ out = $h.isEmpty(content) ? cap : content;
+ icon = '<span class="' + self.msgValidationErrorClass + '">' + self.msgValidationErrorIcon + '</span>';
+ if ($h.isEmpty(content)) {
+ title = $('<div>' + content + '</div>').text();
+ out = title;
+ icon = self._getLayoutTemplate('fileIcon');
+ self.$captionContainer.addClass('icon-visible');
+ self.$caption.attr('title', title).val(out);
+ $h.setHtml(self.$captionIcon, icon);
+ _createContainer: function () {
+ var self = this, attribs = {'class': 'file-input file-input-new' + (self.rtl ? ' kv-rtl' : '')},
+ $container = $h.createElement($h.cspBuffer.stash(self._renderMain()));
+ $h.cspBuffer.apply($container);
+ $container.insertBefore(self.$element).attr(attribs);
+ self._initBrowse($container);
+ if (self.theme) {
+ $container.addClass('theme-' + self.theme);
+ return $container;
+ _refreshContainer: function () {
+ var self = this, $container = self.$container, $el = self.$element;
+ $el.insertAfter($container);
+ $h.setHtml($container, self._renderMain());
+ _validateDisabled: function () {
+ self.$caption.attr({readonly: self.isDisabled});
+ _setTabIndex: function (type, html) {
+ var self = this, index = self.tabIndexConfig[type];
+ return html.setTokens({
+ tabIndexConfig: index === undefined || index === null ? '' : 'tabindex="' + index + '"'
+ _renderMain: function () {
+ dropCss = self.dropZoneEnabled ? ' file-drop-zone' : 'file-drop-disabled',
+ close = !self.showClose ? '' : self._getLayoutTemplate('close'),
+ preview = !self.showPreview ? '' : self._getLayoutTemplate('preview')
+ .setTokens({'class': self.previewClass, 'dropClass': dropCss}),
+ css = self.isDisabled ? self.captionClass + ' file-caption-disabled' : self.captionClass,
+ caption = self.captionTemplate.setTokens({'class': css + ' kv-fileinput-caption'});
+ caption = self._setTabIndex('caption', caption);
+ return self.mainTemplate.setTokens({
+ 'class': self.mainClass + (!self.showBrowse && self.showCaption ? ' no-browse' : ''),
+ 'inputGroupClass': self.inputGroupClass,
+ 'preview': preview,
+ 'close': close,
+ 'upload': self._renderButton('upload'),
+ 'remove': self._renderButton('remove'),
+ 'cancel': self._renderButton('cancel'),
+ 'pause': self._renderButton('pause'),
+ 'browse': self._renderButton('browse')
+ _renderButton: function (type) {
+ var self = this, tmplt = self._getLayoutTemplate('btnDefault'), css = self[type + 'Class'],
+ title = self[type + 'Title'], icon = self[type + 'Icon'], label = self[type + 'Label'],
+ status = self.isDisabled ? ' disabled' : '', btnType = 'button';
+ switch (type) {
+ case 'remove':
+ if (!self.showRemove) {
+ case 'cancel':
+ if (!self.showCancel) {
+ css += ' kv-hidden';
+ case 'pause':
+ if (!self.showPause) {
+ case 'upload':
+ if (!self.showUpload) {
+ if (self.isAjaxUpload && !self.isDisabled) {
+ tmplt = self._getLayoutTemplate('btnLink').replace('{href}', self.uploadUrl);
+ btnType = 'submit';
+ case 'browse':
+ if (!self.showBrowse) {
+ tmplt = self._getLayoutTemplate('btnBrowse');
+ tmplt = self._setTabIndex(type, tmplt);
+ css += type === 'browse' ? ' btn-file' : ' fileinput-' + type + ' fileinput-' + type + '-button';
+ if (!$h.isEmpty(label)) {
+ label = ' <span class="' + self.buttonLabelClass + '">' + label + '</span>';
+ return tmplt.setTokens({
+ 'type': btnType, 'css': css, 'title': title, 'status': status, 'icon': icon, 'label': label
+ _renderThumbProgress: function () {
+ return '<div class="file-thumb-progress kv-hidden">' +
+ self.progressInfoTemplate.setTokens({percent: 101, status: self.msgUploadBegin, stats: ''}) +
+ _renderFileFooter: function (cat, caption, size, width, isError) {
+ var self = this, config = self.fileActionSettings, rem = config.showRemove, drg = config.showDrag,
+ upl = config.showUpload, rot = config.showRotate, zoom = config.showZoom, out, params,
+ template = self._getLayoutTemplate('footer'), tInd = self._getLayoutTemplate('indicator'),
+ ind = isError ? config.indicatorError : config.indicatorNew,
+ title = isError ? config.indicatorErrorTitle : config.indicatorNewTitle,
+ indicator = tInd.setTokens({'indicator': ind, 'indicatorTitle': title});
+ size = self._getSize(size);
+ params = {type: cat, caption: caption, size: size, width: width, progress: '', indicator: indicator};
+ params.progress = self._renderThumbProgress();
+ params.actions = self._renderFileActions(params, upl, false, rem, rot, zoom, drg, false, false, false);
+ params.actions = self._renderFileActions(params, false, false, false, false, zoom, drg, false, false, false);
+ out = template.setTokens(params);
+ out = $h.replaceTags(out, self.previewThumbTags);
+ _renderFileActions: function (
+ cfg,
+ showUpl,
+ showDwn,
+ showDel,
+ showRot,
+ showZoom,
+ showDrag,
+ disabled,
+ url,
+ key,
+ isInit,
+ dUrl,
+ dFile
+ if (!cfg.type && isInit) {
+ cfg.type = 'image';
+ showUpl = false;
+ if (typeof showUpl === 'function') {
+ showUpl = showUpl(cfg);
+ if (typeof showDwn === 'function') {
+ showDwn = showDwn(cfg);
+ if (typeof showDel === 'function') {
+ showDel = showDel(cfg);
+ if (typeof showZoom === 'function') {
+ showZoom = showZoom(cfg);
+ if (typeof showDrag === 'function') {
+ showDrag = showDrag(cfg);
+ if (typeof showRot === 'function') {
+ showRot = showRot(cfg);
+ if (!showUpl && !showDwn && !showDel && !showRot && !showZoom && !showDrag) {
+ var vUrl = url === false ? '' : ' data-url="' + url + '"', btnZoom = '', btnDrag = '', btnRotate = '', css,
+ vKey = key === false ? '' : ' data-key="' + key + '"', btnDelete = '', btnUpload = '', btnDownload = '',
+ template = self._getLayoutTemplate('actions'), config = self.fileActionSettings,
+ otherButtons = self.otherActionButtons.setTokens({'dataKey': vKey, 'key': key}),
+ removeClass = disabled ? config.removeClass + ' disabled' : config.removeClass;
+ if (showDel) {
+ btnDelete = self._getLayoutTemplate('actionDelete').setTokens({
+ 'removeClass': removeClass,
+ 'removeIcon': config.removeIcon,
+ 'removeTitle': config.removeTitle,
+ 'dataUrl': vUrl,
+ 'dataKey': vKey,
+ 'key': key
+ if (showRot) {
+ btnRotate = self._getLayoutTemplate('actionRotate').setTokens({
+ 'rotateClass': config.rotateClass,
+ 'rotateIcon': config.rotateIcon,
+ 'rotateTitle': config.rotateTitle
+ if (showUpl) {
+ btnUpload = self._getLayoutTemplate('actionUpload').setTokens({
+ 'uploadClass': config.uploadClass,
+ 'uploadIcon': config.uploadIcon,
+ 'uploadTitle': config.uploadTitle
+ if (showDwn) {
+ btnDownload = self._getLayoutTemplate('actionDownload').setTokens({
+ 'downloadClass': config.downloadClass,
+ 'downloadIcon': config.downloadIcon,
+ 'downloadTitle': config.downloadTitle,
+ 'downloadUrl': dUrl || self.initialPreviewDownloadUrl
+ btnDownload = btnDownload.setTokens({'filename': dFile, 'key': key});
+ if (showZoom) {
+ btnZoom = self._getLayoutTemplate('actionZoom').setTokens({
+ 'zoomClass': config.zoomClass,
+ 'zoomIcon': config.zoomIcon,
+ 'zoomTitle': config.zoomTitle
+ if (showDrag && isInit) {
+ css = 'drag-handle-init ' + config.dragClass;
+ btnDrag = self._getLayoutTemplate('actionDrag').setTokens({
+ 'dragClass': css,
+ 'dragTitle': config.dragTitle,
+ 'dragIcon': config.dragIcon
+ return template.setTokens({
+ 'delete': btnDelete,
+ 'upload': btnUpload,
+ 'download': btnDownload,
+ 'rotate': btnRotate,
+ 'zoom': btnZoom,
+ 'drag': btnDrag,
+ 'other': otherButtons
+ _browse: function (e) {
+ if (e && e.isDefaultPrevented() || !self._raise('filebrowse')) {
+ if (self.isError && !self.isAjaxUpload) {
+ if (self.focusCaptionOnBrowse) {
+ _change: function (e) {
+ $(document.body).off('focusin.fileinput focusout.fileinput');
+ if (self.changeTriggered) {
+ self._toggleLoading('show');
+ var $el = self.$element, isDragDrop = arguments.length > 1, isAjaxUpload = self.isAjaxUpload,
+ tfiles, files = isDragDrop ? arguments[1] : $el[0].files, ctr = self.fileManager.count(),
+ total, initCount, len, isSingleUpl = $h.isEmpty($el.attr('multiple')),
+ maxCount = !isAjaxUpload && isSingleUpl ? 1 : self.maxFileCount, maxTotCount = self.maxTotalFileCount,
+ inclAll = maxTotCount > 0 && maxTotCount > maxCount, flagSingle = (isSingleUpl && ctr > 0),
+ throwError = function (mesg, file, previewId, index) {
+ var p1 = $.extend(true, {}, self._getOutData(null, {}, {}, files), {id: previewId, index: index}),
+ p2 = {id: previewId, index: index, file: file, files: files};
+ self.isPersistentError = true;
+ return isAjaxUpload ? self._showFileError(mesg, p1) : self._showError(mesg, p2);
+ maxCountCheck = function (n, m, all) {
+ var msg = all ? self.msgTotalFilesTooMany : self.msgFilesTooMany;
+ msg = msg.replace('{m}', m).replace('{n}', n);
+ self.isError = throwError(msg, null, null, null);
+ self._setCaption('', true);
+ self._hideFileIcon();
+ if (self.dropZoneEnabled) {
+ self.$container.find('.file-drop-zone .' + self.dropZoneTitleClass).remove();
+ if (!isAjaxUpload) {
+ if (e.target && e.target.files === undefined) {
+ files = e.target.value ? [{name: e.target.value.replace(/^.+\\/, '')}] : [];
+ files = e.target.files || {};
+ tfiles = files;
+ if ($h.isEmpty(tfiles) || tfiles.length === 0) {
+ self._raise('fileselectnone');
+ len = tfiles.length;
+ initCount = isAjaxUpload ? (self.fileManager.count() + len) : len;
+ total = self._getFileCount(initCount, inclAll ? false : undefined);
+ if (maxCount > 0 && total > maxCount) {
+ if (!self.autoReplace || len > maxCount) {
+ maxCountCheck((self.autoReplace && len > maxCount ? len : total), maxCount);
+ if (total > maxCount) {
+ self._resetPreviewThumbs(isAjaxUpload);
+ if (inclAll) {
+ total = self._getFileCount(initCount, true);
+ if (maxTotCount > 0 && total > maxTotCount) {
+ maxCountCheck((self.autoReplace && len > maxTotCount ? len : total), maxTotCount, true);
+ if (!isAjaxUpload || flagSingle) {
+ self._resetPreviewThumbs(false);
+ if (flagSingle) {
+ if (isAjaxUpload && ctr === 0 && (!self.previewCache.count(true) || self.overwriteInitial)) {
+ self._resetPreviewThumbs(true);
+ if (self.autoReplace) {
+ if ($thumb.hasClass('file-preview-success') || $thumb.hasClass('file-preview-error')) {
+ self.readFiles(tfiles);
+ _abort: function (params) {
+ var self = this, data;
+ if (self.ajaxAborted && typeof self.ajaxAborted === 'object' && self.ajaxAborted.message !== undefined) {
+ data = $.extend(true, {}, self._getOutData(null), params);
+ data.abortData = self.ajaxAborted.data || {};
+ data.abortMessage = self.ajaxAborted.message;
+ self._showFileError(self.ajaxAborted.message, data, 'filecustomerror');
+ self.cancel();
+ return !!self.ajaxAborted;
+ _resetFileStack: function () {
+ var self = this, i = 0;
+ var $thumb = $(this), ind = $thumb.attr('data-fileindex'), pid = $thumb.attr('id');
+ if (ind === '-1' || ind === -1) {
+ if (!self._getThumbFile($thumb)) {
+ $thumb.attr({'data-fileindex': i});
+ $thumb.attr({'data-fileindex': '-1'});
+ self._getZoom(pid).attr({
+ 'data-fileindex': $thumb.attr('data-fileindex')
+ _isFileSelectionValid: function (cnt) {
+ cnt = cnt || 0;
+ if (self.required && !self.getFilesCount()) {
+ self._showFileError(self.msgFileRequired);
+ if (self.minFileCount > 0 && self._getFileCount(cnt) < self.minFileCount) {
+ _canPreview: function (file) {
+ if (!file || !self.showPreview || !self.$preview || !self.$preview.length) {
+ var name = file.name || '', type = file.type || '', size = (file.size || 0) / self.bytesToKB,
+ cat = self._parseFileType(type, name), allowedTypes, allowedMimes, allowedExts, skipPreview,
+ types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes,
+ exts = self.allowedPreviewExtensions || [], dTypes = self.disabledPreviewTypes,
+ dMimes = self.disabledPreviewMimeTypes, dExts = self.disabledPreviewExtensions || [],
+ maxSize = self.maxFilePreviewSize && parseFloat(self.maxFilePreviewSize) || 0,
+ expAllExt = new RegExp('\\.(' + exts.join('|') + ')$', 'i'),
+ expDisExt = new RegExp('\\.(' + dExts.join('|') + ')$', 'i');
+ allowedTypes = !types || types.indexOf(cat) !== -1;
+ allowedMimes = !mimes || mimes.indexOf(type) !== -1;
+ allowedExts = !exts.length || $h.compare(name, expAllExt);
+ skipPreview = (dTypes && dTypes.indexOf(cat) !== -1) || (dMimes && dMimes.indexOf(type) !== -1) ||
+ (dExts.length && $h.compare(name, expDisExt)) || (maxSize && !isNaN(maxSize) && size > maxSize);
+ return !skipPreview && (allowedTypes || allowedMimes || allowedExts);
+ addToStack: function (file, id) {
+ self.stackIsUpdating = true;
+ self.stackIsUpdating = false;
+ clearFileStack: function () {
+ self._initResumableUpload();
+ if (self.showPause === null) {
+ self.showPause = true;
+ if (self.showCancel === null) {
+ self.showCancel = false;
+ self.showPause = false;
+ self.showCancel = true;
+ return self.$element;
+ getFileStack: function () {
+ return this.fileManager.stack;
+ getFileList: function () {
+ return this.fileManager.list();
+ getFilesSize: function () {
+ return this.fileManager.getTotalSize();
+ getFilesCount: function (includeInitial) {
+ len += self.previewCache.count(true);
+ return self._getFileCount(len);
+ _initCapStatus: function (status) {
+ var self = this, $cap = self.$caption;
+ $cap.removeClass('is-valid file-processing');
+ if (status === 'processing') {
+ $cap.addClass('file-processing');
+ $cap.addClass('is-valid');
+ _toggleLoading: function (type) {
+ self.$previewStatus.html(type === 'hide' ? '' : self.msgProcessing);
+ self.$container.removeClass('file-thumb-loading');
+ self._initCapStatus(type === 'hide' ? '' : 'processing');
+ if (type !== 'hide') {
+ self.$container.addClass('file-thumb-loading');
+ _initFileSelected: function () {
+ var self = this, $el = self.$element, $body = $(document.body), ev = 'focusin.fileinput focusout.fileinput';
+ $body.off(ev).on('focusout.fileinput', function () {
+ readFiles: function (files) {
+ this.reader = new FileReader();
+ var self = this, reader = self.reader, $container = self.$previewContainer,
+ $status = self.$previewStatus, msgLoading = self.msgLoading, msgProgress = self.msgProgress,
+ previewInitId = self.previewInitId, numFiles = files.length, settings = self.fileTypeSettings,
+ readFile, fileTypes = self.allowedFileTypes, typLen = fileTypes ? fileTypes.length : 0,
+ fileExt = self.allowedFileExtensions, strExt = $h.isEmpty(fileExt) ? '' : fileExt.join(', '),
+ throwError = function (msg, file, previewId, index, fileId) {
+ var $thumb, p1 = $.extend(true, {}, self._getOutData(null, {}, {}, files),
+ {id: previewId, index: index, fileId: fileId}),
+ p2 = {id: previewId, index: index, fileId: fileId, file: file, files: files};
+ self._previewDefault(file, true);
+ $thumb = self._getFrame(previewId, true);
+ readFile(index + 1);
+ numFiles = 0;
+ if (self.removeFromPreviewOnError && $thumb.length) {
+ self._initFileActions();
+ $thumb.find('.kv-file-upload').remove();
+ self.isError = self.isAjaxUpload ? self._showFileError(msg, p1) : self._showError(msg, p2);
+ self._updateFileDetails(numFiles);
+ $.each(files, function (key, file) {
+ var func = self.fileTypeSettings.image;
+ if (func && func(file.type)) {
+ self.fileManager.totalImages++;
+ readFile = function (i) {
+ var $error = self.$errorContainer, errors, fm = self.fileManager;
+ if (i >= numFiles) {
+ if (self.duplicateErrors.length) {
+ errors = '<li>' + self.duplicateErrors.join('</li><li>') + '</li>';
+ $h.setHtml($error, self.errorCloseButton + '<ul>' + errors + '</ul>');
+ $error.find('ul').append(errors);
+ $error.fadeOut(self.fadeDelay);
+ self._raise('filebatchselected', [fm.stack]);
+ if (fm.count() === 0 && !self.isError) {
+ self._raise('filebatchselected', [files]);
+ $container.removeClass('file-thumb-loading');
+ self._initCapStatus('valid');
+ $status.html('');
+ self.lock(true);
+ var file = files[i], id, previewId, fileProcessed,
+ fSize = (file && file.size || 0), sizeHuman = self._getSize(fSize, true), j, msg,
+ fnImage = settings.image, chk, typ, typ1, typ2, caption, fileSize = fSize / self.bytesToKB,
+ fileExtExpr = '', previewData, fileCount = 0, strTypes = '', fileId, canLoad,
+ fileReaderAborted = false, func, knownTypes = 0, isImage, processFileLoaded, initFileData;
+ initFileData = function (dataSource) {
+ dataSource = dataSource || file;
+ id = fileId = self._getFileId(file);
+ previewId = previewInitId + '-' + id;
+ previewData = $h.createObjectURL(dataSource);
+ caption = self._getFileName(file, '');
+ processFileLoaded = function () {
+ var isImageResized = !!fm.loadedImages[id], msg = msgProgress.setTokens({
+ 'index': i + 1,
+ 'files': numFiles,
+ 'percent': 50,
+ 'name': caption
+ $status.html(msg);
+ if (self.getFilesCount(true) > 0 && self.getFrames(':visible')) {
+ self.$dropZone.find('.' + self.dropZoneTitleClass).remove();
+ readFile(i + 1);
+ if (self._raise('fileloaded', [file, previewId, id, i, reader]) && self.isAjaxUpload) {
+ if (!isImageResized) {
+ fm.add(file);
+ if (isImageResized) {
+ initFileData();
+ if (typLen > 0) {
+ for (j = 0; j < typLen; j++) {
+ typ1 = fileTypes[j];
+ typ2 = self.msgFileTypes[typ1] || typ1;
+ strTypes += j === 0 ? typ2 : ', ' + typ2;
+ if (caption === false) {
+ if (caption.length === 0) {
+ msg = self.msgInvalidFileName.replace('{name}', $h.htmlEncode($h.getFileName(file), '[unknown]'));
+ throwError(msg, file, previewId, i, fileId);
+ if (!$h.isEmpty(fileExt)) {
+ fileExtExpr = new RegExp('\\.(' + fileExt.join('|') + ')$', 'i');
+ if (self.isAjaxUpload && fm.exists(fileId) || self._getFrame(previewId, true).length) {
+ var p2 = {id: previewId, index: i, fileId: fileId, file: file, files: files};
+ msg = self.msgDuplicateFile.setTokens({name: caption, size: sizeHuman});
+ if (!self.stackIsUpdating) {
+ self.duplicateErrors.push(msg);
+ self.isDuplicateError = true;
+ self._raise('fileduplicateerror', [file, fileId, caption, sizeHuman, previewId, i]);
+ self._showError(msg, p2);
+ if (self.maxFileSize > 0 && fileSize > self.maxFileSize) {
+ msg = self.msgSizeTooLarge.setTokens({
+ 'name': caption,
+ 'size': sizeHuman,
+ 'maxSize': self._getSize(self.maxFileSize * self.bytesToKB, true)
+ if (self.minFileSize !== null && fileSize <= $h.getNum(self.minFileSize)) {
+ msg = self.msgSizeTooSmall.setTokens({
+ 'minSize': self._getSize(self.minFileSize * self.bytesToKB, true)
+ if (!$h.isEmpty(fileTypes) && $h.isArray(fileTypes)) {
+ for (j = 0; j < fileTypes.length; j += 1) {
+ typ = fileTypes[j];
+ func = settings[typ];
+ fileCount += !func || (typeof func !== 'function') ? 0 : (func(file.type,
+ $h.getFileName(file)) ? 1 : 0);
+ if (fileCount === 0) {
+ msg = self.msgInvalidFileType.setTokens({name: caption, types: strTypes});
+ if (fileCount === 0 && !$h.isEmpty(fileExt) && $h.isArray(fileExt) && !$h.isEmpty(fileExtExpr)) {
+ chk = $h.compare(caption, fileExtExpr);
+ fileCount += $h.isEmpty(chk) ? 0 : chk.length;
+ msg = self.msgInvalidFileExtension.setTokens({name: caption, extensions: strExt});
+ if (!self._canPreview(file)) {
+ canLoad = self._raise('filebeforeload', [file, i, reader]);
+ if (self.isAjaxUpload && canLoad) {
+ if (self.showPreview && canLoad) {
+ $container.addClass('file-thumb-loading');
+ self._initCapStatus('processing');
+ self._previewDefault(file);
+ if (canLoad) {
+ self._raise('fileloaded', [file, previewId, id, i]);
+ }, 10);
+ isImage = fnImage(file.type, caption);
+ $status.html(msgLoading.replace('{index}', i + 1).replace('{files}', numFiles));
+ reader.onerror = function (evt) {
+ self._errorHandler(evt, caption);
+ reader.onload = function (theFile) {
+ var hex, fileInfo, fileData, byte, bytes = [], contents, mime,
+ processPreview = function (fType, ext) {
+ if ($h.isEmpty(fType)) { // look for ascii text content
+ contents = $h.arrayBuffer2String(reader.result);
+ fType = $h.isSvg(contents) ? 'image/svg+xml' : $h.getMimeType(hex, contents, file.type);
+ fileInfo = {'name': caption, 'type': fType || ''};
+ if (ext && typeof File !== "undefined") {
+ var fName = fileInfo.filename = caption + '.' + ext;
+ fileProcessed = new File([file], fName, {type: fileInfo.type});
+ initFileData(fileProcessed);
+ isImage = fnImage(fType, '');
+ if (isImage) {
+ var newReader = new FileReader();
+ newReader.onerror = function (theFileNew) {
+ self._errorHandler(theFileNew, caption);
+ newReader.onload = function (theFileNew) {
+ if (self.isAjaxUpload && !self._raise('filebeforeload', [file, i, reader])) {
+ fileReaderAborted = true;
+ reader.abort();
+ self.enable();
+ self._previewFile(i, file, theFileNew, previewData, fileInfo);
+ processFileLoaded();
+ newReader.readAsDataURL(file);
+ self._previewFile(i, file, theFile, previewData, fileInfo);
+ mime = file.type;
+ fileInfo = {'name': caption, 'type': mime};
+ $.each(settings, function (k, f) {
+ if (k !== 'object' && k !== 'other' && typeof f === 'function' && f(mime, caption)) {
+ knownTypes++;
+ if (typeof FileTypeParser !== "undefined") {
+ fileData = new Uint8Array(theFile.target.result);
+ new FileTypeParser().parse(fileData).then(function (result) {
+ processPreview(result && result.mime || mime, result && result.ext || '');
+ if (knownTypes === 0) { // auto detect mime types from content if no known file types detected
+ for (j = 0; j < fileData.length; j++) {
+ byte = fileData[j].toString(16);
+ bytes.push(byte);
+ hex = bytes.join('').toLowerCase().substring(0, 8);
+ mime = $h.getMimeType(hex, '', '');
+ processPreview(mime);
+ reader.onprogress = function (data) {
+ if (data.lengthComputable) {
+ var fact = (data.loaded / data.total) * 100, progress = Math.ceil(fact);
+ msg = msgProgress.setTokens({
+ 'percent': progress,
+ if (!fileReaderAborted) {
+ reader.readAsArrayBuffer(file);
+ readFile(0);
+ lock: function (selectMode) {
+ var self = this, $container = self.$container;
+ if (!selectMode && self.showCancel) {
+ $container.find('.fileinput-cancel').show();
+ if (!selectMode && self.showPause) {
+ $container.find('.fileinput-pause').show();
+ self._raise('filelock', [self.fileManager.stack, self._getExtraData()]);
+ unlock: function (reset) {
+ if (reset === undefined) {
+ reset = true;
+ $container.removeClass('is-locked');
+ if (self.showCancel) {
+ $container.find('.fileinput-cancel').hide();
+ if (self.showPause) {
+ $container.find('.fileinput-pause').hide();
+ if (reset) {
+ self._resetFileStack();
+ self._raise('fileunlock', [self.fileManager.stack, self._getExtraData()]);
+ resume: function () {
+ var self = this, fm = self.fileManager, flag = false, rm = self.resumableManager;
+ if (self.paused) {
+ self._toggleResumableProgress(self.progressPauseTemplate, self.msgUploadResume);
+ flag = true;
+ if (flag) {
+ self._toggleResumableProgress(self.progressInfoTemplate, self.msgUploadBegin);
+ rm.upload();
+ paste: function (e) {
+ var self = this, ev = e.originalEvent, files = ev.clipboardData && ev.clipboardData.files || null;
+ if (files) {
+ pause: function () {
+ var self = this, rm = self.resumableManager, xhr = self.ajaxRequests, len = xhr.length, i,
+ pct = rm.getProgress(), actions = self.fileActionSettings, tm = self.taskManager,
+ pool = tm.getPool(rm.id);
+ if (pool) {
+ pool.cancel();
+ self._raise('fileuploadpaused', [self.fileManager, rm]);
+ if (len > 0) {
+ for (i = 0; i < len; i += 1) {
+ self.paused = true;
+ xhr[i].abort();
+ var $thumb = $(this), t = self._getLayoutTemplate('stats'), stats,
+ $indicator = $thumb.find('.file-upload-indicator');
+ if ($indicator.attr('title') === actions.indicatorLoadingTitle) {
+ self._setThumbStatus($thumb, 'Paused');
+ stats = t.setTokens({pendingTime: self.msgPaused, uploadSpeed: ''});
+ self._setProgress(pct, $thumb.find('.file-thumb-progress'), pct + '%', stats);
+ $thumb.find('.kv-file-remove').removeClass('disabled').removeAttr('disabled');
+ self._setProgress(101, self.$progress, self.msgPaused);
+ cancel: function () {
+ var self = this, xhr = self.ajaxRequests,
+ rm = self.resumableManager, tm = self.taskManager,
+ pool = rm ? tm.getPool(rm.id) : undefined, len = xhr.length, i;
+ if (self.enableResumableUpload && pool) {
+ pool.cancel().done(function () {
+ self._raise('fileuploadcancelled', [self.fileManager, rm]);
+ if (self.ajaxPool) {
+ self.ajaxPool.cancel();
+ self._raise('fileuploadcancelled', [self.fileManager]);
+ self.cancelling = true;
+ var $thumb = $(this), $prog = $thumb.find('.file-thumb-progress');
+ self._setProgress(0, $prog);
+ $prog.hide();
+ $thumb.find('.kv-file-upload').removeClass('disabled').removeAttr('disabled');
+ var self = this, cap;
+ if (!self._raise('fileclear')) {
+ self.clearInput = true;
+ self._getThumbs().find('video,audio,img').each(function () {
+ $h.cleanMemory($(this));
+ self._resetErrors(true);
+ self._resetPreview();
+ self._clearObjects($(this));
+ self.previewCache.data = {};
+ self.$preview.html('');
+ cap = (!self.overwriteInitial && self.initialCaption.length > 0) ? self.initialCaption : '';
+ self.$caption.attr('title', '').val(cap);
+ $h.addCss(self.$container, 'file-input-new');
+ if (self.$container.find($h.FRAMES).length === 0) {
+ if (!self._initCaption()) {
+ if (self.focusCaptionOnClear) {
+ self._raise('filecleared');
+ if (!self._raise('filereset')) {
+ self.$container.find('.fileinput-filename').text('');
+ if (self.getFrames().length) {
+ disable: function () {
+ self.isDisabled = true;
+ self._raise('filedisabled');
+ self.$element.attr('disabled', 'disabled');
+ $container.addClass('is-locked');
+ $h.addCss($container.find('.btn-file'), 'disabled');
+ $container.find('.kv-fileinput-caption').addClass('file-caption-disabled');
+ $container.find('.fileinput-remove, .fileinput-upload, .file-preview-frame button')
+ .attr('disabled', true);
+ enable: function () {
+ self.isDisabled = false;
+ self._raise('fileenabled');
+ self.$element.removeAttr('disabled');
+ $container.find('.kv-fileinput-caption').removeClass('file-caption-disabled');
+ .removeAttr('disabled');
+ $container.find('.btn-file').removeClass('disabled');
+ var self = this, fm = self.fileManager, totLen = fm.count(), i, outData, tm = self.taskManager,
+ hasExtraData = !$.isEmptyObject(self._getExtraData());
+ if (!self.isAjaxUpload || self.isDisabled || !self._isFileSelectionValid(totLen)) {
+ if (totLen === 0 && !hasExtraData) {
+ self._showFileError(self.msgUploadEmpty);
+ self._showProgress();
+ if (totLen === 0 && hasExtraData) {
+ self._setProgress(2);
+ self._uploadExtraOnly();
+ return self.resume();
+ if (self.uploadAsync || self.enableResumableUpload) {
+ outData = self._getOutData(null);
+ if (!self._checkBatchPreupload(outData)) {
+ var previewId = self._getThumbId(id);
+ self.uploadCache.push({id: previewId, content: null, config: null, tags: null, append: true});
+ self.$preview.find('.file-preview-initial').removeClass($h.SORT_CSS);
+ self.hasInitData = false;
+ if (self.uploadAsync) {
+ var pool = self.ajaxPool = tm.addPool($h.uniqId());
+ pool.addTask(id + i, function (deferrer) {
+ self._uploadSingle(i, id, true, deferrer);
+ pool.run(self.maxAjaxThreads).done(function () {
+ self._log('Async upload batch completed successfully.');
+ self._raise('filebatchuploadsuccess', [fm.stack, self._getExtraData()]);
+ self._log('Async upload batch completed with errors.');
+ self._raise('filebatchuploaderror', [fm.stack, self._getExtraData()]);
+ self._uploadBatch();
+ destroy: function () {
+ var self = this, $form = self.$form, $cont = self.$container, $el = self.$element, ns = self.namespace;
+ $(document).off(ns);
+ $(window).off(ns);
+ if ($form && $form.length) {
+ $form.off(ns);
+ $el.insertBefore($cont).off(ns).removeData();
+ $cont.off().remove();
+ refresh: function (options) {
+ if (typeof options !== 'object' || $h.isEmpty(options)) {
+ options = self.options;
+ options = $.extend(true, {}, self.options, options);
+ self._init(options, true);
+ zoom: function (frameId) {
+ var self = this, $frame = self._getFrame(frameId);
+ getExif: function (frameId) {
+ return $frame && $frame.data('exif') || null;
+ getFrames: function (cssFilter) {
+ var self = this, $frames;
+ cssFilter = cssFilter || '';
+ $frames = self.$preview.find($h.FRAMES + cssFilter);
+ $frames = $($frames.get().reverse());
+ return $frames;
+ getPreview: function () {
+ content: self.initialPreview,
+ $.fn.fileinput = function (option) {
+ if (!$h.hasFileAPISupport() && !$h.isIE(9)) {
+ var args = Array.apply(null, arguments), retvals = [];
+ args.shift();
+ this.each(function () {
+ var self = $(this), data = self.data('fileinput'), options = typeof option === 'object' && option,
+ theme = options.theme || self.data('theme'), l = {}, t = {},
+ lang = options.language || self.data('language') || $.fn.fileinput.defaults.language || 'en', opt;
+ if (!data) {
+ if (theme) {
+ t = $.fn.fileinputThemes[theme] || {};
+ if (lang !== 'en' && !$h.isEmpty($.fn.fileinputLocales[lang])) {
+ l = $.fn.fileinputLocales[lang] || {};
+ opt = $.extend(true, {}, $.fn.fileinput.defaults, t, $.fn.fileinputLocales.en, l, options, self.data());
+ data = new FileInput(this, opt);
+ self.data('fileinput', data);
+ if (typeof option === 'string') {
+ retvals.push(data[option].apply(data, args));
+ switch (retvals.length) {
+ return this;
+ return retvals[0];
+ return retvals;
+ var IFRAME_ATTRIBS = 'class="kv-preview-data file-preview-pdf" src="{renderer}?file={data}" {style}',
+ defBtnCss1 = 'btn btn-sm btn-kv ' + $h.defaultButtonCss(), defBtnCss2 = 'btn ' + $h.defaultButtonCss();
+ $.fn.fileinput.defaults = {
+ language: 'en',
+ bytesToKB: 1024,
+ showCaption: true,
+ showBrowse: true,
+ showPreview: true,
+ showUploadStats: true,
+ showCancel: null,
+ showPause: null,
+ showClose: true,
+ showUploadedThumbs: true,
+ showConsoleLogs: false,
+ browseOnZoneClick: false,
+ autoReplace: false,
+ showDescriptionClose: true,
+ autoOrientImage: function () { // applicable for JPEG images only and non ios safari
+ var ua = window.navigator.userAgent, webkit = !!ua.match(/WebKit/i),
+ iOS = !!ua.match(/iP(od|ad|hone)/i), iOSSafari = iOS && webkit && !ua.match(/CriOS/i);
+ return !iOSSafari;
+ autoOrientImageInitial: true,
+ showExifErrorLog: false,
+ required: false,
+ rtl: false,
+ hideThumbnailContent: false,
+ encodeUrl: true,
+ focusCaptionOnBrowse: true,
+ focusCaptionOnClear: true,
+ generateFileId: null,
+ previewClass: '',
+ captionClass: '',
+ frameClass: 'krajee-default',
+ mainClass: '',
+ inputGroupClass: '',
+ mainTemplate: null,
+ fileSizeGetter: null,
+ initialCaption: '',
+ initialPreview: [],
+ initialPreviewDelimiter: '*$$*',
+ initialPreviewAsData: false,
+ initialPreviewFileType: 'image',
+ initialPreviewConfig: [],
+ initialPreviewThumbTags: [],
+ previewThumbTags: {},
+ initialPreviewShowDelete: true,
+ initialPreviewDownloadUrl: '',
+ removeFromPreviewOnError: false,
+ deleteUrl: '',
+ deleteExtraData: {},
+ overwriteInitial: true,
+ sanitizeZoomCache: function (content) {
+ var $container = $h.createElement(content);
+ $container.find('input,textarea,select,datalist,form,.file-thumbnail-footer').remove();
+ return $container.html();
+ previewZoomButtonIcons: {
+ prev: '<i class="bi-chevron-left"></i>',
+ next: '<i class="bi-chevron-right"></i>',
+ rotate: '<i class="bi-arrow-clockwise"></i>',
+ toggleheader: '<i class="bi-arrows-expand"></i>',
+ fullscreen: '<i class="bi-arrows-fullscreen"></i>',
+ borderless: '<i class="bi-arrows-angle-expand"></i>',
+ close: '<i class="bi-x-lg"></i>'
+ previewZoomButtonClasses: {
+ prev: 'btn btn-default btn-outline-secondary btn-navigate',
+ next: 'btn btn-default btn-outline-secondary btn-navigate',
+ rotate: defBtnCss1,
+ toggleheader: defBtnCss1,
+ fullscreen: defBtnCss1,
+ borderless: defBtnCss1,
+ close: defBtnCss1
+ previewContentTemplates: {},
+ preferIconicPreview: false,
+ preferIconicZoomPreview: false,
+ alwaysPreviewFileExtensions: [],
+ rotatableFileExtensions: ['jpg', 'jpeg', 'png', 'gif'],
+ allowedFileTypes: null,
+ allowedFileExtensions: null,
+ allowedPreviewTypes: undefined,
+ allowedPreviewMimeTypes: null,
+ allowedPreviewExtensions: null,
+ disabledPreviewTypes: undefined,
+ disabledPreviewExtensions: ['msi', 'exe', 'com', 'zip', 'rar', 'app', 'vb', 'scr'],
+ disabledPreviewMimeTypes: null,
+ defaultPreviewContent: null,
+ customLayoutTags: {},
+ customPreviewTags: {},
+ previewFileIcon: '<i class="bi-file-earmark-fill"></i>',
+ previewFileIconClass: 'file-other-icon',
+ previewFileIconSettings: {},
+ previewFileExtSettings: {},
+ buttonLabelClass: 'hidden-xs',
+ browseIcon: '<i class="bi-folder2-open"></i> ',
+ browseClass: 'btn btn-primary',
+ removeClass: defBtnCss2,
+ cancelIcon: '<i class="bi-slash-circle"></i>',
+ cancelClass: defBtnCss2,
+ pauseIcon: '<i class="bi-pause-fill"></i>',
+ pauseClass: defBtnCss2,
+ uploadClass: defBtnCss2,
+ uploadUrl: null,
+ uploadUrlThumb: null,
+ uploadAsync: true,
+ uploadParamNames: {
+ chunkCount: 'chunkCount',
+ chunkIndex: 'chunkIndex',
+ chunkSize: 'chunkSize',
+ chunkSizeStart: 'chunkSizeStart',
+ chunksUploaded: 'chunksUploaded',
+ fileBlob: 'fileBlob',
+ fileId: 'fileId',
+ fileName: 'fileName',
+ fileRelativePath: 'fileRelativePath',
+ fileSize: 'fileSize',
+ retryCount: 'retryCount'
+ maxAjaxThreads: 5,
+ fadeDelay: 800,
+ processDelay: 100,
+ bitrateUpdateDelay: 500,
+ queueDelay: 10, // must be lesser than process delay
+ progressDelay: 0, // must be lesser than process delay
+ enableResumableUpload: false,
+ resumableUploadOptions: {
+ fallback: null,
+ testUrl: null, // used for checking status of chunks/ files previously / partially uploaded
+ chunkSize: 2048, // in KB
+ maxThreads: 4,
+ maxRetries: 3,
+ showErrorLog: true,
+ retainErrorHistory: false, // when set to true, display complete error history always unless user explicitly resets upload
+ skipErrorsAndProceed: false // when set to true, files with errors will be skipped and upload will continue with other files
+ uploadExtraData: {},
+ zoomModalHeight: 485, // 5px more than the default preview content heights set for text, html, pdf etc.
+ minImageWidth: null,
+ minImageHeight: null,
+ maxImageWidth: null,
+ maxImageHeight: null,
+ resizeImage: false,
+ resizePreference: 'width',
+ resizeQuality: 0.92,
+ resizeDefaultImageType: 'image/jpeg',
+ resizeIfSizeMoreThan: 0, // in KB
+ minFileSize: -1,
+ maxFileSize: 0,
+ maxFilePreviewSize: 25600, // 25 MB
+ minFileCount: 0,
+ maxFileCount: 0,
+ maxTotalFileCount: 0,
+ validateInitialCount: false,
+ msgValidationErrorClass: 'text-danger',
+ msgValidationErrorIcon: '<i class="bi-exclamation-circle-fill"></i> ',
+ msgErrorClass: 'file-error-message',
+ progressThumbClass: 'progress-bar progress-bar-striped active progress-bar-animated',
+ progressClass: 'progress-bar bg-success progress-bar-success progress-bar-striped active progress-bar-animated',
+ progressInfoClass: 'progress-bar bg-info progress-bar-info progress-bar-striped active progress-bar-animated',
+ progressCompleteClass: 'progress-bar bg-success progress-bar-success',
+ progressPauseClass: 'progress-bar bg-primary progress-bar-primary progress-bar-striped active progress-bar-animated',
+ progressErrorClass: 'progress-bar bg-danger progress-bar-danger',
+ progressUploadThreshold: 99,
+ previewFileType: 'image',
+ elCaptionContainer: null,
+ elCaptionText: null,
+ elPreviewContainer: null,
+ elPreviewImage: null,
+ elPreviewStatus: null,
+ elErrorContainer: null,
+ errorCloseButton: undefined,
+ slugCallback: null,
+ dropZoneEnabled: true,
+ dropZoneTitleClass: 'file-drop-zone-title',
+ fileActionSettings: {},
+ otherActionButtons: '',
+ textEncoding: 'UTF-8',
+ preProcessUpload: null,
+ ajaxSettings: {},
+ ajaxDeleteSettings: {},
+ showAjaxErrorDetails: true,
+ mergeAjaxCallbacks: false,
+ mergeAjaxDeleteCallbacks: false,
+ retryErrorUploads: true,
+ reversePreviewOrder: false,
+ usePdfRenderer: function () {
+ var isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
+ return !!navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/i) || isIE11;
+ pdfRendererUrl: '',
+ pdfRendererTemplate: '<iframe ' + IFRAME_ATTRIBS + '></iframe>',
+ tabIndexConfig: {
+ browse: 500,
+ remove: 500,
+ upload: 500,
+ cancel: null,
+ pause: null,
+ modal: -1
+ $.fn.fileinputLocales.en = {
+ sizeUnits: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
+ bitRateUnits: ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s', 'ZB/s', 'YB/s'],
+ fileSingle: 'file',
+ filePlural: 'files',
+ browseLabel: 'Browse …',
+ removeLabel: 'Remove',
+ removeTitle: 'Clear all unprocessed files',
+ cancelLabel: 'Cancel',
+ cancelTitle: 'Abort ongoing upload',
+ pauseLabel: 'Pause',
+ pauseTitle: 'Pause ongoing upload',
+ uploadLabel: 'Upload',
+ uploadTitle: 'Upload selected files',
+ msgNo: 'No',
+ msgNoFilesSelected: 'No files selected',
+ msgCancelled: 'Cancelled',
+ msgPaused: 'Paused',
+ msgPlaceholder: 'Select {files} ...',
+ msgZoomModalHeading: 'Detailed Preview',
+ msgFileRequired: 'You must select a file to upload.',
+ msgSizeTooSmall: 'File "{name}" (<b>{size}</b>) is too small and must be larger than <b>{minSize}</b>.',
+ msgSizeTooLarge: 'File "{name}" (<b>{size}</b>) exceeds maximum allowed upload size of <b>{maxSize}</b>.',
+ msgFilesTooLess: 'You must select at least <b>{n}</b> {files} to upload.',
+ msgFilesTooMany: 'Number of files selected for upload <b>({n})</b> exceeds maximum allowed limit of <b>{m}</b>.',
+ msgTotalFilesTooMany: 'You can upload a maximum of <b>{m}</b> files (<b>{n}</b> files detected).',
+ msgFileNotFound: 'File "{name}" not found!',
+ msgFileSecured: 'Security restrictions prevent reading the file "{name}".',
+ msgFileNotReadable: 'File "{name}" is not readable.',
+ msgFilePreviewAborted: 'File preview aborted for "{name}".',
+ msgFilePreviewError: 'An error occurred while reading the file "{name}".',
+ msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".',
+ msgInvalidFileType: 'Invalid type for file "{name}". Only "{types}" files are supported.',
+ msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.',
+ msgFileTypes: {
+ 'image': 'image',
+ 'html': 'HTML',
+ 'text': 'text',
+ 'video': 'video',
+ 'audio': 'audio',
+ 'flash': 'flash',
+ 'pdf': 'PDF',
+ 'object': 'object'
+ msgUploadAborted: 'The file upload was aborted',
+ msgUploadThreshold: 'Processing …',
+ msgUploadBegin: 'Initializing …',
+ msgUploadEnd: 'Done',
+ msgUploadResume: 'Resuming upload …',
+ msgUploadEmpty: 'No valid data available for upload.',
+ msgUploadError: 'Upload Error',
+ msgDeleteError: 'Delete Error',
+ msgProgressError: 'Error',
+ msgValidationError: 'Validation Error',
+ msgLoading: 'Loading file {index} of {files} …',
+ msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.',
+ msgSelected: '{n} {files} selected',
+ msgProcessing: 'Processing ...',
+ msgFoldersNotAllowed: 'Drag & drop files only! {n} folder(s) dropped were skipped.',
+ msgImageWidthSmall: 'Width of image file "{name}" must be at least <b>{size} px</b> (detected <b>{dimension} px</b>).',
+ msgImageHeightSmall: 'Height of image file "{name}" must be at least <b>{size} px</b> (detected <b>{dimension} px</b>).',
+ msgImageWidthLarge: 'Width of image file "{name}" cannot exceed <b>{size} px</b> (detected <b>{dimension} px</b>).',
+ msgImageHeightLarge: 'Height of image file "{name}" cannot exceed <b>{size} px</b> (detected <b>{dimension} px</b>).',
+ msgImageResizeError: 'Could not get the image dimensions to resize.',
+ msgImageResizeException: 'Error while resizing the image.<pre>{errors}</pre>',
+ msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!',
+ msgAjaxProgressError: '{operation} failed',
+ msgDuplicateFile: 'File "{name}" of same size "{size}" has already been selected earlier. Skipping duplicate selection.',
+ msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>',
+ msgPendingTime: '{time} remaining',
+ msgCalculatingTime: 'calculating time remaining',
+ ajaxOperations: {
+ deleteThumb: 'file delete',
+ uploadThumb: 'file upload',
+ uploadBatch: 'batch file upload',
+ uploadExtra: 'form data upload'
+ dropZoneTitle: 'Drag & drop files here …',
+ dropZoneClickTitle: '<br>(or click to select {files})',
+ previewZoomButtonTitles: {
+ prev: 'View previous file',
+ next: 'View next file',
+ rotate: 'Rotate 90 deg. clockwise',
+ toggleheader: 'Toggle header',
+ fullscreen: 'Toggle full screen',
+ borderless: 'Toggle borderless mode',
+ close: 'Close detailed preview'
+ $.fn.fileinput.Constructor = FileInput;
+ * Convert automatically file inputs with class 'file' into a bootstrap fileinput control.
+ $(document).ready(function () {
+ var $input = $('input.file[type=file]');
+ if ($input.length) {
+ $input.fileinput();
+}));
@@ -0,0 +1,40 @@
+const gulp = require('gulp');
+const uglify = require('gulp-uglify');
+const rename = require("gulp-rename");
+const sourcemaps = require('gulp-sourcemaps');
+const sass = require('gulp-sass')(require('sass'));
+const filenameJs = "fileinput.js";
+const filenameCss = "fileinput.scss"
+gulp.task('js-compress', function() {
+ return gulp.src(`./js/${filenameJs}`)
+ .pipe(sourcemaps.init()) // init sourcemaps
+ .pipe(uglify())
+ .pipe(rename(function(path) {
+ path.basename += ".min";
+ path.extname = ".js";
+ }))
+ .pipe(sourcemaps.write('./'))
+ .pipe(gulp.dest('./dist/js'));
+});
+gulp.task('js-original', function() {
+gulp.task('css-compress', function () {
+ return gulp.src(`./scss/${filenameCss}`)
+ .pipe(sass().on('error', sass.logError))
+ .pipe(gulp.dest('./dist/css'))
+ .pipe(sourcemaps.init())
+ .pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
+ path.extname = ".css";
+ .pipe(gulp.dest('./dist/css'));
+gulp.task('js-build', gulp.parallel('js-compress', 'js-original'));
@@ -0,0 +1,8612 @@
+{
+ "name": "bootstrap-fileinput",
+ "version": "5.5.3",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "bootstrap": ">= 3.0.0",
+ "gulp-cli": "^2.3.0",
+ "gulp-sourcemaps": "^3.0.0",
+ "jquery": ">= 1.9.0",
+ "opencollective-postinstall": "^2.0.2"
+ "devDependencies": {
+ "gulp": "^4.0.2",
+ "gulp-minify-css": "^1.2.4",
+ "gulp-rename": "^2.0.0",
+ "gulp-sass": "^5.1.0",
+ "gulp-uglify": "^3.0.2",
+ "sass": "^1.64.1"
+ "peerDependencies": {
+ "jquery": ">= 1.9.0"
+ "node_modules/@gulp-sourcemaps/identity-map": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz",
+ "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==",
+ "acorn": "^6.4.1",
+ "normalize-path": "^3.0.0",
+ "postcss": "^7.0.16",
+ "source-map": "^0.6.0",
+ "through2": "^3.0.1"
+ "engines": {
+ "node": ">= 0.10"
+ "node_modules/@gulp-sourcemaps/identity-map/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "node": ">=0.10.0"
+ "node_modules/@gulp-sourcemaps/identity-map/node_modules/through2": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
+ "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
+ "inherits": "^2.0.4",
+ "readable-stream": "2 || 3"
+ "node_modules/@gulp-sourcemaps/map-sources": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz",
+ "integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==",
+ "normalize-path": "^2.0.1",
+ "through2": "^2.0.3"
+ "node_modules/@gulp-sourcemaps/map-sources/node_modules/normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
+ "remove-trailing-separator": "^1.0.1"
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ "node_modules/acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "bin": {
+ "acorn": "bin/acorn"
+ "node": ">=0.4.0"
+ "node_modules/amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==",
+ "dev": true,
+ "node": ">=0.4.2"
+ "node_modules/ansi-colors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+ "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+ "ansi-wrap": "^0.1.0"
+ "node_modules/ansi-gray": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+ "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==",
+ "ansi-wrap": "0.1.0"
+ "node_modules/ansi-regex": {
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "node_modules/ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
+ "node_modules/ansi-wrap": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+ "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==",
+ "node_modules/anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ "node_modules/anymatch/node_modules/normalize-path": {
+ "node_modules/append-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+ "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==",
+ "buffer-equal": "^1.0.0"
+ "node_modules/archy": {
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw=="
+ "node_modules/arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==",
+ "node_modules/arr-filter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
+ "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==",
+ "make-iterator": "^1.0.0"
+ "node_modules/arr-flatten": {
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "node_modules/arr-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
+ "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==",
+ "node_modules/arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==",
+ "node_modules/array-differ": {
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
+ "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==",
+ "node_modules/array-each": {
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==",
+ "node_modules/array-initial": {
+ "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
+ "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==",
+ "array-slice": "^1.0.0",
+ "is-number": "^4.0.0"
+ "node_modules/array-initial/node_modules/is-number": {
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "node_modules/array-last": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
+ "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+ "node_modules/array-last/node_modules/is-number": {
+ "node_modules/array-slice": {
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+ "node_modules/array-sort": {
+ "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
+ "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
+ "default-compare": "^1.0.0",
+ "get-value": "^2.0.6",
+ "kind-of": "^5.0.2"
+ "node_modules/array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==",
+ "node_modules/array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==",
+ "node_modules/assign-symbols": {
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==",
+ "node_modules/async-done": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz",
+ "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.2",
+ "process-nextick-args": "^2.0.0",
+ "stream-exhaust": "^1.0.1"
+ "node_modules/async-each": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz",
+ "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ ]
+ "node_modules/async-settle": {
+ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
+ "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==",
+ "async-done": "^1.2.2"
+ "node_modules/atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "atob": "bin/atob.js"
+ "node": ">= 4.5.0"
+ "node_modules/bach": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
+ "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==",
+ "arr-filter": "^1.1.1",
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "array-each": "^1.0.0",
+ "array-initial": "^1.0.0",
+ "array-last": "^1.1.1",
+ "async-done": "^1.2.2",
+ "async-settle": "^1.0.0",
+ "now-and-later": "^2.0.0"
+ "node_modules/balanced-match": {
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ "node_modules/base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ "node_modules/base/node_modules/define-property": {
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "is-descriptor": "^1.0.0"
+ "node_modules/beeper": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz",
+ "integrity": "sha512-3vqtKL1N45I5dV0RdssXZG7X6pCqQrWPNOlBPZPrd+QkE2HEhR57Z04m0KtpbsZH73j+a3F8UD1TQnn+ExTvIA==",
+ "node_modules/binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "node_modules/bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "optional": true,
+ "file-uri-to-path": "1.0.0"
+ "node_modules/bootstrap": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.1.tgz",
+ "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==",
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ "url": "https://opencollective.com/bootstrap"
+ ],
+ "@popperjs/core": "^2.11.8"
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ "node_modules/braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ "node_modules/braces/node_modules/extend-shallow": {
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "is-extendable": "^0.1.0"
+ "node_modules/braces/node_modules/is-extendable": {
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+ "node_modules/buffer-equal": {
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz",
+ "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==",
+ "node": ">=0.4"
+ "url": "https://github.com/sponsors/ljharb"
+ "node_modules/buffer-from": {
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+ "node_modules/bufferstreams": {
+ "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-1.0.1.tgz",
+ "integrity": "sha512-LZmiIfQprMLS6/k42w/PTc7awhU8AdNNcUerxTgr01WlP9agR2SgMv0wjlYYFD6eDOi8WvofrTX8RayjR/AeUQ==",
+ "readable-stream": "^1.0.33"
+ "node": ">= 0.10.0"
+ "node_modules/bufferstreams/node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "node_modules/bufferstreams/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ "node_modules/bufferstreams/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+ "node_modules/cache-base": {
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "collection-visit": "^1.0.0",
+ "has-value": "^1.0.0",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ "node_modules/call-bind": {
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ "node_modules/camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==",
+ "node_modules/chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ "node_modules/chokidar": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+ "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+ "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies",
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ "optionalDependencies": {
+ "fsevents": "^1.2.7"
+ "node_modules/class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ "node_modules/class-utils/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+ "is-descriptor": "^0.1.0"
+ "node_modules/class-utils/node_modules/is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+ "kind-of": "^3.0.2"
+ "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "is-buffer": "^1.1.5"
+ "node_modules/class-utils/node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+ "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "node_modules/class-utils/node_modules/is-descriptor": {
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ "node_modules/clean-css": {
+ "version": "3.4.28",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz",
+ "integrity": "sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw==",
+ "commander": "2.8.x",
+ "source-map": "0.4.x"
+ "cleancss": "bin/cleancss"
+ "node_modules/clean-css/node_modules/source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==",
+ "amdefine": ">=0.0.4"
+ "node": ">=0.8.0"
+ "node_modules/cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ "node_modules/clone": {
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "node": ">=0.8"
+ "node_modules/clone-buffer": {
+ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+ "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==",
+ "node_modules/clone-stats": {
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
+ "node_modules/cloneable-readable": {
+ "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
+ "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.5"
+ "node_modules/code-point-at": {
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
+ "node_modules/collection-map": {
+ "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
+ "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==",
+ "arr-map": "^2.0.2",
+ "for-own": "^1.0.0",
+ "node_modules/collection-visit": {
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==",
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ "node_modules/color-support": {
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "color-support": "bin.js"
+ "node_modules/commander": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
+ "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==",
+ "graceful-readlink": ">= 1.0.0"
+ "node": ">= 0.6.x"
+ "node_modules/component-emitter": {
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
+ "node_modules/concat-map": {
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "engines": [
+ "node >= 0.8"
+ "buffer-from": "^1.0.0",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ "node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
+ "node_modules/copy-descriptor": {
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
+ "node_modules/copy-props": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz",
+ "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==",
+ "each-props": "^1.3.2",
+ "is-plain-object": "^5.0.0"
+ "node_modules/core-util-is": {
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+ "node_modules/css": {
+ "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
+ "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.6.0"
+ "node_modules/css/node_modules/source-map": {
+ "node_modules/css/node_modules/source-map-resolve": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
+ "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
+ "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0"
+ "node_modules/d": {
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ "node_modules/dateformat": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
+ "integrity": "sha512-GODcnWq3YGoTnygPfi02ygEiRxqUxpJwuRHjdhJYuxpcZmDq4rjBiXYmbCCzStxo176ixfLT6i4NPwQooRySnw==",
+ "node": "*"
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "ms": "2.0.0"
+ "node_modules/debug-fabulous": {
+ "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz",
+ "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==",
+ "debug": "3.X",
+ "memoizee": "0.4.X",
+ "object-assign": "4.X"
+ "node_modules/debug-fabulous/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "ms": "^2.1.1"
+ "node_modules/debug-fabulous/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ "node_modules/decamelize": {
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+ "node_modules/decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "node": ">=0.10"
+ "node_modules/default-compare": {
+ "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
+ "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
+ "node_modules/default-resolution": {
+ "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
+ "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==",
+ "node_modules/define-properties": {
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
+ "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ "node": ">= 0.4"
+ "node_modules/define-property": {
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ "node_modules/detect-file": {
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
+ "node_modules/detect-newline": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+ "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==",
+ "node_modules/duplexer2": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
+ "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==",
+ "readable-stream": "~1.1.9"
+ "node_modules/duplexer2/node_modules/isarray": {
+ "node_modules/duplexer2/node_modules/readable-stream": {
+ "node_modules/duplexer2/node_modules/string_decoder": {
+ "node_modules/duplexify": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+ "end-of-stream": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ "node_modules/each-props": {
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
+ "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
+ "is-plain-object": "^2.0.1",
+ "object.defaults": "^1.1.0"
+ "node_modules/each-props/node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "once": "^1.4.0"
+ "node_modules/error-ex": {
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "is-arrayish": "^0.2.1"
+ "node_modules/es5-ext": {
+ "version": "0.10.62",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+ "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ "node_modules/es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ "node_modules/es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ "node_modules/es6-weak-map": {
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "es5-ext": "^0.10.46",
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "node_modules/event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+ "es5-ext": "~0.10.14"
+ "node_modules/expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==",
+ "debug": "^2.3.3",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "node_modules/expand-brackets/node_modules/define-property": {
+ "node_modules/expand-brackets/node_modules/extend-shallow": {
+ "node_modules/expand-brackets/node_modules/is-accessor-descriptor": {
+ "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "node_modules/expand-brackets/node_modules/is-data-descriptor": {
+ "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "node_modules/expand-brackets/node_modules/is-descriptor": {
+ "node_modules/expand-brackets/node_modules/is-extendable": {
+ "node_modules/expand-tilde": {
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
+ "homedir-polyfill": "^1.0.1"
+ "node_modules/ext": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+ "type": "^2.7.2"
+ "node_modules/ext/node_modules/type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
+ "node_modules/extend": {
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ "node_modules/extend-shallow": {
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ "node_modules/extglob": {
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "expand-brackets": "^2.1.4",
+ "fragment-cache": "^0.2.1",
+ "node_modules/extglob/node_modules/define-property": {
+ "node_modules/extglob/node_modules/extend-shallow": {
+ "node_modules/extglob/node_modules/is-extendable": {
+ "node_modules/fancy-log": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
+ "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
+ "ansi-gray": "^0.1.1",
+ "color-support": "^1.1.3",
+ "parse-node-version": "^1.0.0",
+ "time-stamp": "^1.0.0"
+ "node_modules/fast-levenshtein": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz",
+ "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==",
+ "node_modules/file-uri-to-path": {
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "optional": true
+ "node_modules/fill-range": {
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ "node_modules/fill-range/node_modules/extend-shallow": {
+ "node_modules/fill-range/node_modules/is-extendable": {
+ "node_modules/find-up": {
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==",
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ "node_modules/findup-sync": {
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
+ "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+ "detect-file": "^1.0.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
+ "node_modules/fined": {
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
+ "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^2.0.3",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.2.0",
+ "parse-filepath": "^1.0.1"
+ "node_modules/fined/node_modules/is-plain-object": {
+ "node_modules/flagged-respawn": {
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
+ "node_modules/flush-write-stream": {
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+ "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+ "readable-stream": "^2.3.6"
+ "node_modules/for-in": {
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
+ "node_modules/for-own": {
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
+ "for-in": "^1.0.1"
+ "node_modules/fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==",
+ "map-cache": "^0.2.2"
+ "node_modules/fs-mkdirp-stream": {
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
+ "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==",
+ "graceful-fs": "^4.1.11",
+ "node_modules/fs.realpath": {
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "node_modules/fsevents": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+ "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2",
+ "os": [
+ "darwin"
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
+ "node": ">= 4.0"
+ "node_modules/function-bind": {
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ "node_modules/get-caller-file": {
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
+ "node_modules/get-intrinsic": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+ "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "has": "^1.0.3",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3"
+ "node_modules/get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==",
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ "url": "https://github.com/sponsors/isaacs"
+ "node_modules/glob-parent": {
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ "node_modules/glob-parent/node_modules/is-glob": {
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
+ "is-extglob": "^2.1.0"
+ "node_modules/glob-stream": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+ "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==",
+ "extend": "^3.0.0",
+ "glob": "^7.1.1",
+ "is-negated-glob": "^1.0.0",
+ "ordered-read-streams": "^1.0.0",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.1.5",
+ "remove-trailing-separator": "^1.0.1",
+ "to-absolute-glob": "^2.0.0",
+ "unique-stream": "^2.0.2"
+ "node_modules/glob-watcher": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz",
+ "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==",
+ "async-done": "^1.2.0",
+ "chokidar": "^2.0.0",
+ "just-debounce": "^1.0.0",
+ "node_modules/global-modules": {
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ "node_modules/global-prefix": {
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "which": "^1.2.14"
+ "node_modules/glogg": {
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
+ "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==",
+ "sparkles": "^1.0.0"
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+ "node_modules/graceful-readlink": {
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+ "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==",
+ "node_modules/gulp": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
+ "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==",
+ "glob-watcher": "^5.0.3",
+ "gulp-cli": "^2.2.0",
+ "undertaker": "^1.2.1",
+ "vinyl-fs": "^3.0.0"
+ "gulp": "bin/gulp.js"
+ "node_modules/gulp-cli": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz",
+ "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==",
+ "ansi-colors": "^1.0.1",
+ "archy": "^1.0.0",
+ "array-sort": "^1.0.0",
+ "concat-stream": "^1.6.0",
+ "copy-props": "^2.0.1",
+ "fancy-log": "^1.3.2",
+ "gulplog": "^1.0.0",
+ "interpret": "^1.4.0",
+ "liftoff": "^3.1.0",
+ "matchdep": "^2.0.0",
+ "mute-stdout": "^1.0.0",
+ "pretty-hrtime": "^1.0.0",
+ "replace-homedir": "^1.0.0",
+ "semver-greatest-satisfied-range": "^1.1.0",
+ "v8flags": "^3.2.0",
+ "yargs": "^7.1.0"
+ "node_modules/gulp-minify-css": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/gulp-minify-css/-/gulp-minify-css-1.2.4.tgz",
+ "integrity": "sha512-byBqFQM/HrZoUVYihu/03iYH4m7U5TjSGhr6/7JvpMHh9+woewsCtEp6Noif2VXB+idDoM4ECd9sw+St+KFqsg==",
+ "deprecated": "Please use gulp-clean-css",
+ "clean-css": "^3.3.3",
+ "gulp-util": "^3.0.5",
+ "object-assign": "^4.0.1",
+ "vinyl-bufferstream": "^1.0.1",
+ "vinyl-sourcemaps-apply": "^0.2.0"
+ "node_modules/gulp-rename": {
+ "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz",
+ "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==",
+ "node": ">=4"
+ "node_modules/gulp-sass": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-5.1.0.tgz",
+ "integrity": "sha512-7VT0uaF+VZCmkNBglfe1b34bxn/AfcssquLKVDYnCDJ3xNBaW7cUuI3p3BQmoKcoKFrs9jdzUxyb+u+NGfL4OQ==",
+ "lodash.clonedeep": "^4.5.0",
+ "picocolors": "^1.0.0",
+ "plugin-error": "^1.0.1",
+ "replace-ext": "^2.0.0",
+ "strip-ansi": "^6.0.1",
+ "vinyl-sourcemaps-apply": "^0.2.1"
+ "node": ">=12"
+ "node_modules/gulp-sass/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "node": ">=8"
+ "node_modules/gulp-sass/node_modules/picocolors": {
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "node_modules/gulp-sass/node_modules/replace-ext": {
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "node": ">= 10"
+ "node_modules/gulp-sass/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "ansi-regex": "^5.0.1"
+ "node_modules/gulp-sourcemaps": {
+ "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz",
+ "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==",
+ "@gulp-sourcemaps/identity-map": "^2.0.1",
+ "@gulp-sourcemaps/map-sources": "^1.0.0",
+ "convert-source-map": "^1.0.0",
+ "css": "^3.0.0",
+ "debug-fabulous": "^1.0.0",
+ "detect-newline": "^2.0.0",
+ "graceful-fs": "^4.0.0",
+ "strip-bom-string": "^1.0.0",
+ "through2": "^2.0.0"
+ "node": ">= 6"
+ "node_modules/gulp-sourcemaps/node_modules/source-map": {
+ "node_modules/gulp-uglify": {
+ "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz",
+ "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==",
+ "array-each": "^1.0.1",
+ "extend-shallow": "^3.0.2",
+ "has-gulplog": "^0.1.0",
+ "make-error-cause": "^1.1.1",
+ "safe-buffer": "^5.1.2",
+ "through2": "^2.0.0",
+ "uglify-js": "^3.0.5",
+ "node_modules/gulp-util": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz",
+ "integrity": "sha512-q5oWPc12lwSFS9h/4VIjG+1NuNDlJ48ywV2JKItY4Ycc/n1fXJeYPVQsfu5ZrhQi7FGSDBalwUCLar/GyHXKGw==",
+ "deprecated": "gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5",
+ "array-differ": "^1.0.0",
+ "array-uniq": "^1.0.2",
+ "beeper": "^1.0.0",
+ "chalk": "^1.0.0",
+ "dateformat": "^2.0.0",
+ "fancy-log": "^1.1.0",
+ "lodash._reescape": "^3.0.0",
+ "lodash._reevaluate": "^3.0.0",
+ "lodash._reinterpolate": "^3.0.0",
+ "lodash.template": "^3.0.0",
+ "minimist": "^1.1.0",
+ "multipipe": "^0.1.2",
+ "object-assign": "^3.0.0",
+ "replace-ext": "0.0.1",
+ "vinyl": "^0.5.0"
+ "node_modules/gulp-util/node_modules/clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "node_modules/gulp-util/node_modules/clone-stats": {
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
+ "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==",
+ "node_modules/gulp-util/node_modules/object-assign": {
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
+ "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==",
+ "node_modules/gulp-util/node_modules/replace-ext": {
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
+ "integrity": "sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==",
+ "node_modules/gulp-util/node_modules/vinyl": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz",
+ "integrity": "sha512-P5zdf3WB9uzr7IFoVQ2wZTmUwHL8cMZWJGzLBNCHNZ3NB6HTMsYABtt7z8tAGIINLXyAob9B9a1yzVGMFOYKEA==",
+ "clone": "^1.0.0",
+ "clone-stats": "^0.0.1",
+ "replace-ext": "0.0.1"
+ "node": ">= 0.9"
+ "node_modules/gulplog": {
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
+ "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==",
+ "glogg": "^1.0.0"
+ "node_modules/has": {
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "function-bind": "^1.1.1"
+ "node": ">= 0.4.0"
+ "node_modules/has-ansi": {
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
+ "ansi-regex": "^2.0.0"
+ "node_modules/has-gulplog": {
+ "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz",
+ "integrity": "sha512-+F4GzLjwHNNDEAJW2DC1xXfEoPkRDmUdJ7CBYw4MpqtDwOnqdImJl7GWlpqx+Wko6//J8uKTnIe4wZSv7yCqmw==",
+ "node_modules/has-property-descriptors": {
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "get-intrinsic": "^1.1.1"
+ "node_modules/has-proto": {
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "node_modules/has-symbols": {
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "node_modules/has-value": {
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ "node_modules/has-values": {
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==",
+ "kind-of": "^4.0.0"
+ "node_modules/has-values/node_modules/kind-of": {
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==",
+ "node_modules/homedir-polyfill": {
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "parse-passwd": "^1.0.0"
+ "node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
+ "node_modules/immutable": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.1.tgz",
+ "integrity": "sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==",
+ "node_modules/inflight": {
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "wrappy": "1"
+ "node_modules/inherits": {
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ "node_modules/interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "node_modules/invert-kv": {
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==",
+ "node_modules/is-absolute": {
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ "node_modules/is-accessor-descriptor": {
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "kind-of": "^6.0.0"
+ "node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "node_modules/is-arrayish": {
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
+ "node_modules/is-binary-path": {
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==",
+ "binary-extensions": "^1.0.0"
+ "node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+ "node_modules/is-core-module": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
+ "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
+ "has": "^1.0.3"
+ "node_modules/is-data-descriptor": {
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "node_modules/is-data-descriptor/node_modules/kind-of": {
+ "node_modules/is-descriptor": {
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ "node_modules/is-descriptor/node_modules/kind-of": {
+ "node_modules/is-extendable": {
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "is-plain-object": "^2.0.4"
+ "node_modules/is-extendable/node_modules/is-plain-object": {
+ "node_modules/is-extglob": {
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "node_modules/is-fullwidth-code-point": {
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "number-is-nan": "^1.0.0"
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "is-extglob": "^2.1.1"
+ "node_modules/is-negated-glob": {
+ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+ "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==",
+ "node_modules/is-number": {
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "node_modules/is-number/node_modules/kind-of": {
+ "node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "node_modules/is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
+ "node_modules/is-relative": {
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "is-unc-path": "^1.0.0"
+ "node_modules/is-unc-path": {
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "unc-path-regex": "^0.1.2"
+ "node_modules/is-utf8": {
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q=="
+ "node_modules/is-valid-glob": {
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+ "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==",
+ "node_modules/is-windows": {
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "node_modules/isarray": {
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+ "node_modules/isexe": {
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "node_modules/jquery": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz",
+ "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ=="
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "node_modules/just-debounce": {
+ "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz",
+ "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==",
+ "node_modules/kind-of": {
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "node_modules/last-run": {
+ "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
+ "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==",
+ "default-resolution": "^2.0.0",
+ "es6-weak-map": "^2.0.1"
+ "node_modules/lazystream": {
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
+ "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
+ "readable-stream": "^2.0.5"
+ "node": ">= 0.6.3"
+ "node_modules/lcid": {
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==",
+ "invert-kv": "^1.0.0"
+ "node_modules/lead": {
+ "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
+ "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==",
+ "flush-write-stream": "^1.0.2"
+ "node_modules/liftoff": {
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
+ "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==",
+ "findup-sync": "^3.0.0",
+ "fined": "^1.0.1",
+ "flagged-respawn": "^1.0.0",
+ "is-plain-object": "^2.0.4",
+ "object.map": "^1.0.0",
+ "rechoir": "^0.6.2",
+ "resolve": "^1.1.7"
+ "node": ">= 0.8"
+ "node_modules/liftoff/node_modules/is-plain-object": {
+ "node_modules/load-json-file": {
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==",
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ "node_modules/lodash._basecopy": {
+ "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
+ "integrity": "sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ==",
+ "node_modules/lodash._basetostring": {
+ "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz",
+ "integrity": "sha512-mTzAr1aNAv/i7W43vOR/uD/aJ4ngbtsRaCubp2BfZhlGU/eORUjg/7F6X0orNMdv33JOrdgGybtvMN/po3EWrA==",
+ "node_modules/lodash._basevalues": {
+ "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz",
+ "integrity": "sha512-H94wl5P13uEqlCg7OcNNhMQ8KvWSIyqXzOPusRgHC9DK3o54P6P3xtbXlVbRABG4q5gSmp7EDdJ0MSuW9HX6Mg==",
+ "node_modules/lodash._getnative": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+ "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==",
+ "node_modules/lodash._isiterateecall": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
+ "integrity": "sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ==",
+ "node_modules/lodash._reescape": {
+ "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz",
+ "integrity": "sha512-Sjlavm5y+FUVIF3vF3B75GyXrzsfYV8Dlv3L4mEpuB9leg8N6yf/7rU06iLPx9fY0Mv3khVp9p7Dx0mGV6V5OQ==",
+ "node_modules/lodash._reevaluate": {
+ "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz",
+ "integrity": "sha512-OrPwdDc65iJiBeUe5n/LIjd7Viy99bKwDdk7Z5ljfZg0uFRFlfQaCy9tZ4YMAag9WAZmlVpe1iZrkIMMSMHD3w==",
+ "node_modules/lodash._reinterpolate": {
+ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
+ "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==",
+ "node_modules/lodash._root": {
+ "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
+ "integrity": "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==",
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+ "node_modules/lodash.escape": {
+ "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz",
+ "integrity": "sha512-n1PZMXgaaDWZDSvuNZ/8XOcYO2hOKDqZel5adtR30VKQAtoWs/5AOeFA0vPV8moiPzlqe7F4cP2tzpFewQyelQ==",
+ "lodash._root": "^3.0.0"
+ "node_modules/lodash.isarguments": {
+ "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+ "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==",
+ "node_modules/lodash.isarray": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+ "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==",
+ "node_modules/lodash.keys": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+ "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==",
+ "lodash._getnative": "^3.0.0",
+ "lodash.isarguments": "^3.0.0",
+ "lodash.isarray": "^3.0.0"
+ "node_modules/lodash.restparam": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
+ "integrity": "sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==",
+ "node_modules/lodash.template": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz",
+ "integrity": "sha512-0B4Y53I0OgHUJkt+7RmlDFWKjVAI/YUpWNiL9GQz5ORDr4ttgfQGo+phBWKFLJbBdtOwgMuUkdOHOnPg45jKmQ==",
+ "lodash._basecopy": "^3.0.0",
+ "lodash._basetostring": "^3.0.0",
+ "lodash._basevalues": "^3.0.0",
+ "lodash._isiterateecall": "^3.0.0",
+ "lodash.escape": "^3.0.0",
+ "lodash.keys": "^3.0.0",
+ "lodash.restparam": "^3.0.0",
+ "lodash.templatesettings": "^3.0.0"
+ "node_modules/lodash.templatesettings": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz",
+ "integrity": "sha512-TcrlEr31tDYnWkHFWDCV3dHYroKEXpJZ2YJYvJdhN+y4AkWMDZ5I4I8XDtUKqSAyG81N7w+I1mFEJtcED+tGqQ==",
+ "lodash.escape": "^3.0.0"
+ "node_modules/lru-queue": {
+ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
+ "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==",
+ "es5-ext": "~0.10.2"
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "node_modules/make-error-cause": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz",
+ "integrity": "sha512-4TO2Y3HkBnis4c0dxhAgD/jprySYLACf7nwN6V0HAHDx59g12WlRpUmFy1bRHamjGUEEBrEvCq6SUpsEE2lhUg==",
+ "make-error": "^1.2.0"
+ "node_modules/make-iterator": {
+ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+ "node_modules/make-iterator/node_modules/kind-of": {
+ "node_modules/map-cache": {
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
+ "node_modules/map-visit": {
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==",
+ "node_modules/matchdep": {
+ "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
+ "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==",
+ "findup-sync": "^2.0.0",
+ "resolve": "^1.4.0",
+ "stack-trace": "0.0.10"
+ "node_modules/matchdep/node_modules/findup-sync": {
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+ "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==",
+ "node_modules/matchdep/node_modules/is-glob": {
+ "node_modules/memoizee": {
+ "version": "0.4.15",
+ "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz",
+ "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==",
+ "es5-ext": "^0.10.53",
+ "es6-weak-map": "^2.0.3",
+ "event-emitter": "^0.3.5",
+ "is-promise": "^2.2.2",
+ "lru-queue": "^0.1.0",
+ "next-tick": "^1.1.0",
+ "timers-ext": "^0.1.7"
+ "node_modules/micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "arr-diff": "^4.0.0",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extglob": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "to-regex": "^3.0.2"
+ "node_modules/micromatch/node_modules/kind-of": {
+ "node_modules/minimatch": {
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "brace-expansion": "^1.1.7"
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "node_modules/mixin-deep": {
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "for-in": "^1.0.2",
+ "node_modules/ms": {
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ "node_modules/multipipe": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
+ "integrity": "sha512-7ZxrUybYv9NonoXgwoOqtStIu18D1c3eFZj27hqgf5kBrBF8Q+tE8V0MW8dKM5QLkQPh1JhhbKgHLY9kifov4Q==",
+ "duplexer2": "0.0.2"
+ "node_modules/mute-stdout": {
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
+ "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
+ "node_modules/nan": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
+ "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
+ "node_modules/nanomatch": {
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "is-windows": "^1.0.2",
+ "node_modules/nanomatch/node_modules/kind-of": {
+ "node_modules/next-tick": {
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
+ "node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ "node_modules/normalize-path": {
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "node_modules/now-and-later": {
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
+ "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
+ "once": "^1.3.2"
+ "node_modules/number-is-nan": {
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "node_modules/object-copy": {
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==",
+ "copy-descriptor": "^0.1.0",
+ "kind-of": "^3.0.3"
+ "node_modules/object-copy/node_modules/define-property": {
+ "node_modules/object-copy/node_modules/is-accessor-descriptor": {
+ "node_modules/object-copy/node_modules/is-data-descriptor": {
+ "node_modules/object-copy/node_modules/is-descriptor": {
+ "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": {
+ "node_modules/object-copy/node_modules/kind-of": {
+ "node_modules/object-keys": {
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "node_modules/object-visit": {
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==",
+ "node_modules/object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "node_modules/object.defaults": {
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
+ "node_modules/object.map": {
+ "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
+ "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==",
+ "node_modules/object.pick": {
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
+ "node_modules/object.reduce": {
+ "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
+ "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==",
+ "node_modules/once": {
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "node_modules/opencollective-postinstall": {
+ "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
+ "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
+ "opencollective-postinstall": "index.js"
+ "node_modules/ordered-read-streams": {
+ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+ "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==",
+ "readable-stream": "^2.0.1"
+ "node_modules/os-locale": {
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==",
+ "lcid": "^1.0.0"
+ "node_modules/parse-filepath": {
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ "node_modules/parse-json": {
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==",
+ "error-ex": "^1.2.0"
+ "node_modules/parse-node-version": {
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+ "node_modules/parse-passwd": {
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
+ "node_modules/pascalcase": {
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==",
+ "node_modules/path-dirname": {
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==",
+ "node_modules/path-exists": {
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==",
+ "node_modules/path-is-absolute": {
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ "node_modules/path-root": {
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
+ "path-root-regex": "^0.1.0"
+ "node_modules/path-root-regex": {
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
+ "node_modules/path-type": {
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==",
+ "node_modules/picocolors": {
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "node": ">=8.6"
+ "url": "https://github.com/sponsors/jonschlinkert"
+ "node_modules/pify": {
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "node_modules/pinkie": {
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
+ "node_modules/pinkie-promise": {
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
+ "pinkie": "^2.0.0"
+ "node_modules/plugin-error": {
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
+ "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
+ "extend-shallow": "^3.0.2"
+ "node_modules/posix-character-classes": {
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==",
+ "node_modules/postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ "node": ">=6.0.0"
+ "url": "https://opencollective.com/postcss/"
+ "node_modules/postcss/node_modules/source-map": {
+ "node_modules/pretty-hrtime": {
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==",
+ "node_modules/process-nextick-args": {
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ "node_modules/pump": {
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "once": "^1.3.1"
+ "node_modules/pumpify": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+ "duplexify": "^3.6.0",
+ "pump": "^2.0.0"
+ "node_modules/read-pkg": {
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==",
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ "node_modules/read-pkg-up": {
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==",
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ "node_modules/readdirp": {
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ "node_modules/rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+ "resolve": "^1.1.6"
+ "node_modules/regex-not": {
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "safe-regex": "^1.1.0"
+ "node_modules/remove-bom-buffer": {
+ "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
+ "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
+ "is-buffer": "^1.1.5",
+ "is-utf8": "^0.2.1"
+ "node_modules/remove-bom-stream": {
+ "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
+ "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==",
+ "remove-bom-buffer": "^3.0.0",
+ "safe-buffer": "^5.1.0",
+ "node_modules/remove-trailing-separator": {
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="
+ "node_modules/repeat-element": {
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
+ "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
+ "node_modules/repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
+ "node_modules/replace-ext": {
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
+ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
+ "node_modules/replace-homedir": {
+ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
+ "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==",
+ "remove-trailing-separator": "^1.1.0"
+ "node_modules/require-directory": {
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "node_modules/require-main-filename": {
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug=="
+ "node_modules/resolve": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
+ "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
+ "is-core-module": "^2.11.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ "resolve": "bin/resolve"
+ "node_modules/resolve-dir": {
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ "node_modules/resolve-options": {
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
+ "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==",
+ "value-or-function": "^3.0.0"
+ "node_modules/resolve-url": {
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==",
+ "deprecated": "https://github.com/lydell/resolve-url#deprecated"
+ "node_modules/ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "node": ">=0.12"
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ "node_modules/safe-regex": {
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==",
+ "ret": "~0.1.10"
+ "node_modules/sass": {
+ "version": "1.64.1",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.64.1.tgz",
+ "integrity": "sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ==",
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ "sass": "sass.js"
+ "node": ">=14.0.0"
+ "node_modules/sass/node_modules/anymatch": {
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "picomatch": "^2.0.4"
+ "node": ">= 8"
+ "node_modules/sass/node_modules/binary-extensions": {
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "node_modules/sass/node_modules/braces": {
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "fill-range": "^7.0.1"
+ "node_modules/sass/node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ "node": ">= 8.10.0"
+ "fsevents": "~2.3.2"
+ "node_modules/sass/node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "to-regex-range": "^5.0.1"
+ "node_modules/sass/node_modules/fsevents": {
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ "node_modules/sass/node_modules/glob-parent": {
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "is-glob": "^4.0.1"
+ "node_modules/sass/node_modules/is-binary-path": {
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "binary-extensions": "^2.0.0"
+ "node_modules/sass/node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "node": ">=0.12.0"
+ "node_modules/sass/node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "picomatch": "^2.2.1"
+ "node": ">=8.10.0"
+ "node_modules/sass/node_modules/to-regex-range": {
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "is-number": "^7.0.0"
+ "node": ">=8.0"
+ "node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "semver": "bin/semver"
+ "node_modules/semver-greatest-satisfied-range": {
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
+ "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==",
+ "sver-compat": "^1.5.0"
+ "node_modules/set-blocking": {
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+ "node_modules/set-value": {
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "is-extendable": "^0.1.1",
+ "split-string": "^3.0.1"
+ "node_modules/set-value/node_modules/extend-shallow": {
+ "node_modules/set-value/node_modules/is-extendable": {
+ "node_modules/set-value/node_modules/is-plain-object": {
+ "node_modules/snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ "node_modules/snapdragon-node": {
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "snapdragon-util": "^3.0.1"
+ "node_modules/snapdragon-node/node_modules/define-property": {
+ "node_modules/snapdragon-util": {
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "kind-of": "^3.2.0"
+ "node_modules/snapdragon-util/node_modules/kind-of": {
+ "node_modules/snapdragon/node_modules/define-property": {
+ "node_modules/snapdragon/node_modules/extend-shallow": {
+ "node_modules/snapdragon/node_modules/is-accessor-descriptor": {
+ "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "node_modules/snapdragon/node_modules/is-data-descriptor": {
+ "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "node_modules/snapdragon/node_modules/is-descriptor": {
+ "node_modules/snapdragon/node_modules/is-extendable": {
+ "node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "node_modules/source-map-js": {
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "node_modules/source-map-resolve": {
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ "node_modules/source-map-url": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
+ "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
+ "deprecated": "See https://github.com/lydell/source-map-url#deprecated"
+ "node_modules/sparkles": {
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
+ "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
+ "node_modules/spdx-correct": {
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ "node_modules/spdx-exceptions": {
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
+ "node_modules/spdx-expression-parse": {
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "spdx-exceptions": "^2.1.0",
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.13",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
+ "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w=="
+ "node_modules/split-string": {
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "extend-shallow": "^3.0.0"
+ "node_modules/stack-trace": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+ "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+ "node_modules/static-extend": {
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==",
+ "object-copy": "^0.1.0"
+ "node_modules/static-extend/node_modules/define-property": {
+ "node_modules/static-extend/node_modules/is-accessor-descriptor": {
+ "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "node_modules/static-extend/node_modules/is-data-descriptor": {
+ "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": {
+ "node_modules/static-extend/node_modules/is-descriptor": {
+ "node_modules/stream-exhaust": {
+ "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+ "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
+ "node_modules/stream-shift": {
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+ "node_modules/string_decoder": {
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "safe-buffer": "~5.1.0"
+ "node_modules/string-width": {
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ "node_modules/strip-ansi": {
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "node_modules/strip-bom": {
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==",
+ "is-utf8": "^0.2.0"
+ "node_modules/strip-bom-string": {
+ "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
+ "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==",
+ "node_modules/supports-color": {
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
+ "node_modules/supports-preserve-symlinks-flag": {
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "node_modules/sver-compat": {
+ "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
+ "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==",
+ "es6-iterator": "^2.0.1",
+ "node_modules/through2": {
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ "node_modules/through2-filter": {
+ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
+ "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
+ "through2": "~2.0.0",
+ "xtend": "~4.0.0"
+ "node_modules/time-stamp": {
+ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
+ "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==",
+ "node_modules/timers-ext": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
+ "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
+ "es5-ext": "~0.10.46",
+ "next-tick": "1"
+ "node_modules/to-absolute-glob": {
+ "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+ "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==",
+ "is-negated-glob": "^1.0.0"
+ "node_modules/to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==",
+ "node_modules/to-object-path/node_modules/kind-of": {
+ "node_modules/to-regex": {
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "regex-not": "^1.0.2",
+ "node_modules/to-regex-range": {
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "repeat-string": "^1.6.1"
+ "node_modules/to-through": {
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
+ "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==",
+ "node_modules/type": {
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
+ "node_modules/uglify-js": {
+ "version": "3.17.4",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
+ "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+ "uglifyjs": "bin/uglifyjs"
+ "node_modules/unc-path-regex": {
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
+ "node_modules/undertaker": {
+ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz",
+ "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==",
+ "bach": "^1.0.0",
+ "collection-map": "^1.0.0",
+ "es6-weak-map": "^2.0.1",
+ "fast-levenshtein": "^1.0.0",
+ "last-run": "^1.1.0",
+ "object.defaults": "^1.0.0",
+ "object.reduce": "^1.0.0",
+ "undertaker-registry": "^1.0.0"
+ "node_modules/undertaker-registry": {
+ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
+ "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==",
+ "node_modules/union-value": {
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "set-value": "^2.0.1"
+ "node_modules/union-value/node_modules/is-extendable": {
+ "node_modules/unique-stream": {
+ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
+ "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "through2-filter": "^3.0.0"
+ "node_modules/unset-value": {
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==",
+ "has-value": "^0.3.1",
+ "node_modules/unset-value/node_modules/has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
+ "isarray": "1.0.0"
+ "node_modules/unset-value/node_modules/has-values": {
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==",
+ "node_modules/upath": {
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "node": ">=4",
+ "yarn": "*"
+ "node_modules/urix": {
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==",
+ "deprecated": "Please see https://github.com/lydell/urix#deprecated"
+ "node_modules/use": {
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "node_modules/util-deprecate": {
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ "node_modules/v8flags": {
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
+ "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+ "node_modules/validate-npm-package-license": {
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ "node_modules/value-or-function": {
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
+ "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==",
+ "node_modules/vinyl": {
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
+ "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "replace-ext": "^1.0.0"
+ "node_modules/vinyl-bufferstream": {
+ "resolved": "https://registry.npmjs.org/vinyl-bufferstream/-/vinyl-bufferstream-1.0.1.tgz",
+ "integrity": "sha512-yCCIoTf26Q9SQ0L9cDSavSL7Nt6wgQw8TU1B/bb9b9Z4A3XTypXCGdc5BvXl4ObQvVY8JrDkFnWa/UqBqwM2IA==",
+ "bufferstreams": "1.0.1"
+ "node_modules/vinyl-fs": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
+ "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
+ "fs-mkdirp-stream": "^1.0.0",
+ "glob-stream": "^6.1.0",
+ "is-valid-glob": "^1.0.0",
+ "lazystream": "^1.0.0",
+ "lead": "^1.0.0",
+ "object.assign": "^4.0.4",
+ "readable-stream": "^2.3.3",
+ "remove-bom-stream": "^1.2.0",
+ "resolve-options": "^1.1.0",
+ "to-through": "^2.0.0",
+ "value-or-function": "^3.0.0",
+ "vinyl": "^2.0.0",
+ "vinyl-sourcemap": "^1.1.0"
+ "node_modules/vinyl-sourcemap": {
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
+ "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==",
+ "append-buffer": "^1.0.2",
+ "convert-source-map": "^1.5.0",
+ "graceful-fs": "^4.1.6",
+ "normalize-path": "^2.1.1",
+ "now-and-later": "^2.0.0",
+ "vinyl": "^2.0.0"
+ "node_modules/vinyl-sourcemap/node_modules/normalize-path": {
+ "node_modules/vinyl-sourcemaps-apply": {
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
+ "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==",
+ "source-map": "^0.5.1"
+ "node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "isexe": "^2.0.0"
+ "which": "bin/which"
+ "node_modules/which-module": {
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ=="
+ "node_modules/wrap-ansi": {
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==",
+ "strip-ansi": "^3.0.1"
+ "node_modules/wrappy": {
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "node_modules/xtend": {
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "node_modules/y18n": {
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
+ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ=="
+ "node_modules/yargs": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz",
+ "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==",
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.1"
+ "node_modules/yargs-parser": {
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz",
+ "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==",
+ "object.assign": "^4.1.0"
+ "@gulp-sourcemaps/identity-map": {
+ "requires": {
+ "source-map": {
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ "through2": {
+ "@gulp-sourcemaps/map-sources": {
+ "normalize-path": {
+ "@popperjs/core": {
+ "peer": true
+ "acorn": {
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ=="
+ "amdefine": {
+ "ansi-colors": {
+ "ansi-gray": {
+ "ansi-regex": {
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="
+ "ansi-styles": {
+ "ansi-wrap": {
+ "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw=="
+ "anymatch": {
+ "append-buffer": {
+ "archy": {
+ "arr-diff": {
+ "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA=="
+ "arr-filter": {
+ "arr-flatten": {
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
+ "arr-map": {
+ "arr-union": {
+ "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q=="
+ "array-differ": {
+ "array-each": {
+ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA=="
+ "array-initial": {
+ "is-number": {
+ "array-last": {
+ "array-slice": {
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w=="
+ "array-sort": {
+ "array-uniq": {
+ "array-unique": {
+ "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ=="
+ "assign-symbols": {
+ "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw=="
+ "async-done": {
+ "async-each": {
+ "async-settle": {
+ "atob": {
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
+ "bach": {
+ "balanced-match": {
+ "base": {
+ "define-property": {
+ "beeper": {
+ "binary-extensions": {
+ "bindings": {
+ "bootstrap": {
+ "requires": {}
+ "brace-expansion": {
+ "braces": {
+ "extend-shallow": {
+ "is-extendable": {
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="
+ "buffer-equal": {
+ "buffer-from": {
+ "bufferstreams": {
+ "isarray": {
+ "readable-stream": {
+ "string_decoder": {
+ "cache-base": {
+ "call-bind": {
+ "camelcase": {
+ "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg=="
+ "chalk": {
+ "chokidar": {
+ "fsevents": "^1.2.7",
+ "class-utils": {
+ "is-accessor-descriptor": {
+ "kind-of": {
+ "is-data-descriptor": {
+ "is-descriptor": {
+ "clean-css": {
+ "cliui": {
+ "clone": {
+ "clone-buffer": {
+ "clone-stats": {
+ "cloneable-readable": {
+ "code-point-at": {
+ "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA=="
+ "collection-map": {
+ "collection-visit": {
+ "color-support": {
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
+ "commander": {
+ "component-emitter": {
+ "concat-map": {
+ "concat-stream": {
+ "convert-source-map": {
+ "copy-descriptor": {
+ "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw=="
+ "copy-props": {
+ "core-util-is": {
+ "css": {
+ "source-map-resolve": {
+ "d": {
+ "dateformat": {
+ "debug": {
+ "debug-fabulous": {
+ "ms": {
+ "decamelize": {
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
+ "decode-uri-component": {
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="
+ "default-compare": {
+ "default-resolution": {
+ "define-properties": {
+ "detect-file": {
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q=="
+ "detect-newline": {
+ "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg=="
+ "duplexer2": {
+ "duplexify": {
+ "each-props": {
+ "is-plain-object": {
+ "end-of-stream": {
+ "error-ex": {
+ "es5-ext": {
+ "es6-iterator": {
+ "es6-symbol": {
+ "es6-weak-map": {
+ "escape-string-regexp": {
+ "event-emitter": {
+ "expand-brackets": {
+ "expand-tilde": {
+ "ext": {
+ "type": {
+ "extend": {
+ "extglob": {
+ "fancy-log": {
+ "fast-levenshtein": {
+ "file-uri-to-path": {
+ "fill-range": {
+ "find-up": {
+ "findup-sync": {
+ "fined": {
+ "flagged-respawn": {
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q=="
+ "flush-write-stream": {
+ "for-in": {
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ=="
+ "for-own": {
+ "fragment-cache": {
+ "fs-mkdirp-stream": {
+ "fs.realpath": {
+ "fsevents": {
+ "function-bind": {
+ "get-caller-file": {
+ "get-intrinsic": {
+ "get-value": {
+ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA=="
+ "glob": {
+ "glob-parent": {
+ "is-glob": {
+ "glob-stream": {
+ "glob-watcher": {
+ "global-modules": {
+ "global-prefix": {
+ "glogg": {
+ "graceful-fs": {
+ "graceful-readlink": {
+ "gulp": {
+ "gulp-cli": {
+ "gulp-minify-css": {
+ "gulp-rename": {
+ "gulp-sass": {
+ "picocolors": {
+ "replace-ext": {
+ "strip-ansi": {
+ "gulp-sourcemaps": {
+ "gulp-uglify": {
+ "gulp-util": {
+ "object-assign": {
+ "vinyl": {
+ "gulplog": {
+ "has": {
+ "has-ansi": {
+ "has-gulplog": {
+ "has-property-descriptors": {
+ "has-proto": {
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
+ "has-symbols": {
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+ "has-value": {
+ "has-values": {
+ "homedir-polyfill": {
+ "hosted-git-info": {
+ "immutable": {
+ "inflight": {
+ "inherits": {
+ "ini": {
+ "interpret": {
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
+ "invert-kv": {
+ "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ=="
+ "is-absolute": {
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
+ "is-arrayish": {
+ "is-binary-path": {
+ "is-buffer": {
+ "is-core-module": {
+ "is-extglob": {
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
+ "is-fullwidth-code-point": {
+ "is-negated-glob": {
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
+ "is-promise": {
+ "is-relative": {
+ "is-unc-path": {
+ "is-utf8": {
+ "is-valid-glob": {
+ "is-windows": {
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
+ "isexe": {
+ "isobject": {
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="
+ "jquery": {
+ "json-stable-stringify-without-jsonify": {
+ "just-debounce": {
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ "last-run": {
+ "lazystream": {
+ "lcid": {
+ "lead": {
+ "liftoff": {
+ "load-json-file": {
+ "lodash._basecopy": {
+ "lodash._basetostring": {
+ "lodash._basevalues": {
+ "lodash._getnative": {
+ "lodash._isiterateecall": {
+ "lodash._reescape": {
+ "lodash._reevaluate": {
+ "lodash._reinterpolate": {
+ "lodash._root": {
+ "lodash.clonedeep": {
+ "lodash.escape": {
+ "lodash.isarguments": {
+ "lodash.isarray": {
+ "lodash.keys": {
+ "lodash.restparam": {
+ "lodash.template": {
+ "lodash.templatesettings": {
+ "lru-queue": {
+ "make-error": {
+ "make-error-cause": {
+ "make-iterator": {
+ "map-cache": {
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="
+ "map-visit": {
+ "matchdep": {
+ "memoizee": {
+ "micromatch": {
+ "minimatch": {
+ "minimist": {
+ "mixin-deep": {
+ "multipipe": {
+ "mute-stdout": {
+ "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg=="
+ "nan": {
+ "nanomatch": {
+ "next-tick": {
+ "normalize-package-data": {
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+ "now-and-later": {
+ "number-is-nan": {
+ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ=="
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+ "object-copy": {
+ "object-keys": {
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ "object-visit": {
+ "object.assign": {
+ "object.defaults": {
+ "object.map": {
+ "object.pick": {
+ "object.reduce": {
+ "once": {
+ "opencollective-postinstall": {
+ "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q=="
+ "ordered-read-streams": {
+ "os-locale": {
+ "parse-filepath": {
+ "parse-json": {
+ "parse-node-version": {
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA=="
+ "parse-passwd": {
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q=="
+ "pascalcase": {
+ "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw=="
+ "path-dirname": {
+ "path-exists": {
+ "path-is-absolute": {
+ "path-parse": {
+ "path-root": {
+ "path-root-regex": {
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ=="
+ "path-type": {
+ "picomatch": {
+ "pify": {
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="
+ "pinkie": {
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg=="
+ "pinkie-promise": {
+ "plugin-error": {
+ "posix-character-classes": {
+ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg=="
+ "postcss": {
+ "pretty-hrtime": {
+ "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A=="
+ "process-nextick-args": {
+ "pump": {
+ "pumpify": {
+ "read-pkg": {
+ "read-pkg-up": {
+ "readdirp": {
+ "rechoir": {
+ "regex-not": {
+ "remove-bom-buffer": {
+ "remove-bom-stream": {
+ "remove-trailing-separator": {
+ "repeat-element": {
+ "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ=="
+ "repeat-string": {
+ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w=="
+ "replace-homedir": {
+ "require-directory": {
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
+ "require-main-filename": {
+ "resolve": {
+ "resolve-dir": {
+ "resolve-options": {
+ "resolve-url": {
+ "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg=="
+ "ret": {
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
+ "safe-buffer": {
+ "safe-regex": {
+ "sass": {
+ "fsevents": "~2.3.2",
+ "to-regex-range": {
+ "semver": {
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
+ "semver-greatest-satisfied-range": {
+ "set-blocking": {
+ "set-value": {
+ "snapdragon": {
+ "snapdragon-node": {
+ "snapdragon-util": {
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="
+ "source-map-js": {
+ "source-map-url": {
+ "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw=="
+ "sparkles": {
+ "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw=="
+ "spdx-correct": {
+ "spdx-exceptions": {
+ "spdx-expression-parse": {
+ "spdx-license-ids": {
+ "split-string": {
+ "stack-trace": {
+ "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="
+ "static-extend": {
+ "stream-exhaust": {
+ "stream-shift": {
+ "string-width": {
+ "strip-bom": {
+ "strip-bom-string": {
+ "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="
+ "supports-color": {
+ "supports-preserve-symlinks-flag": {
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+ "sver-compat": {
+ "through2-filter": {
+ "time-stamp": {
+ "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw=="
+ "timers-ext": {
+ "to-absolute-glob": {
+ "to-object-path": {
+ "to-regex": {
+ "to-through": {
+ "typedarray": {
+ "uglify-js": {
+ "unc-path-regex": {
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="
+ "undertaker": {
+ "undertaker-registry": {
+ "union-value": {
+ "unique-stream": {
+ "unset-value": {
+ "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ=="
+ "upath": {
+ "urix": {
+ "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg=="
+ "use": {
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
+ "util-deprecate": {
+ "v8flags": {
+ "validate-npm-package-license": {
+ "value-or-function": {
+ "vinyl-bufferstream": {
+ "vinyl-fs": {
+ "vinyl-sourcemap": {
+ "vinyl-sourcemaps-apply": {
+ "which": {
+ "which-module": {
+ "wrap-ansi": {
+ "wrappy": {
+ "xtend": {
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+ "y18n": {
+ "yargs": {
+ "yargs-parser": {
@@ -26,7 +26,9 @@
"gallery"
],
"dependencies": {
- "bootstrap": ">= 3.4.1",
"jquery": ">= 1.9.0",
"opencollective-postinstall": "^2.0.2"
},
@@ -34,8 +36,8 @@
"style": "./css/fileinput.css",
"sass": "scss/fileinput.scss",
"peerDependencies": {
- "jquery": ">= 1.9.0",
- "bootstrap": ">= 3.0.0"
"license": "BSD-3-Clause",
"collective": {
@@ -43,6 +45,16 @@
"url": "https://opencollective.com/bootstrap-fileinput"
"scripts": {
- "postinstall": "opencollective-postinstall || true"
+ "postinstall": "opencollective-postinstall || true",
+ "js-build": "gulp js-build",
+ "css-build": "gulp css-compress"
}
-}