angular-file
Advanced tools
| /** | ||
| * Generated bundle index. Do not edit. | ||
| */ | ||
| export * from './index'; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1maWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FuZ3VsYXItZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHZW5lcmF0ZWQgYnVuZGxlIGluZGV4LiBEbyBub3QgZWRpdC5cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2luZGV4JztcbiJdfQ== |
| export const isFileInput = function (elm) { | ||
| const ty = elm.getAttribute('type'); | ||
| return elm.tagName.toLowerCase() === 'input' && ty && ty.toLowerCase() === 'file'; | ||
| }; | ||
| let initialTouchStartY = 0; | ||
| let initialTouchStartX = 0; | ||
| export const detectSwipe = function (evt) { | ||
| var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches); | ||
| if (touches) { | ||
| if (evt.type === 'touchstart') { | ||
| initialTouchStartX = touches[0].clientX; | ||
| initialTouchStartY = touches[0].clientY; | ||
| return true; // don't block event default | ||
| } | ||
| else { | ||
| // prevent scroll from triggering event | ||
| if (evt.type === 'touchend') { | ||
| var currentX = touches[0].clientX; | ||
| var currentY = touches[0].clientY; | ||
| if ((Math.abs(currentX - initialTouchStartX) > 20) || | ||
| (Math.abs(currentY - initialTouchStartY) > 20)) { | ||
| evt.stopPropagation(); | ||
| if (evt.cancelable) { | ||
| evt.preventDefault(); | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }; | ||
| export const createInvisibleFileInputWrap = function () { | ||
| var fileElem = createFileInput(); | ||
| var label = document.createElement('label'); | ||
| label.innerHTML = 'upload'; | ||
| label.style.visibility = 'hidden'; | ||
| label.style.position = 'absolute'; | ||
| label.style.overflow = 'hidden'; | ||
| label.style.width = '0px'; | ||
| label.style.height = '0px'; | ||
| label.style.border = 'none'; | ||
| label.style.margin = '0px'; | ||
| label.style.padding = '0px'; | ||
| label.setAttribute('tabindex', '-1'); | ||
| //bindAttrToFileInput(fileElem, label); | ||
| //generatedElems.push({el: elem, ref: label}); | ||
| label.appendChild(fileElem); | ||
| //document.body.appendChild( label ); | ||
| return label; | ||
| }; | ||
| export const createFileInput = function () { | ||
| var fileElem = document.createElement('input'); | ||
| fileElem.type = "file"; | ||
| return fileElem; | ||
| }; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jLWV2ZW50LWhlbHAuZnVuY3Rpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2ZpbGUtdXBsb2FkL2RvYy1ldmVudC1oZWxwLmZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsVUFBUyxHQUFPO0lBQ3pDLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDbkMsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxLQUFLLE9BQU8sSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLE1BQU0sQ0FBQztBQUNwRixDQUFDLENBQUE7QUFFRCxJQUFJLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQUMzQixJQUFJLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQUMzQixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsVUFBUyxHQUFPO0lBQ3pDLElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQyxjQUFjLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxJQUFJLEdBQUcsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDNUYsSUFBSSxPQUFPLEVBQUU7UUFDWCxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFO1lBQzdCLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDeEMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUN4QyxPQUFPLElBQUksQ0FBQyxDQUFDLDRCQUE0QjtTQUMxQzthQUFNO1lBQ0wsdUNBQXVDO1lBQ3ZDLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUU7Z0JBQzNCLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQ2xDLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDaEQsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO29CQUNoRCxHQUFHLENBQUMsZUFBZSxFQUFFLENBQUM7b0JBQ3RCLElBQUksR0FBRyxDQUFDLFVBQVUsRUFBRTt3QkFDbEIsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO3FCQUN0QjtvQkFDRCxPQUFPLEtBQUssQ0FBQztpQkFDZDthQUNGO1lBQ0QsT0FBTyxJQUFJLENBQUM7U0FDYjtLQUNGO0lBQ0QsT0FBTyxLQUFLLENBQUE7QUFDZCxDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBRztJQUMxQyxJQUFJLFFBQVEsR0FBRyxlQUFlLEVBQUUsQ0FBQTtJQUNoQyxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLEtBQUssQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFBO0lBQzFCLEtBQUssQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQTtJQUNqQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUE7SUFDakMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFBO0lBQy9CLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQTtJQUN6QixLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUE7SUFDMUIsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO0lBQzNCLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQTtJQUMxQixLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUE7SUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUMsSUFBSSxDQUFDLENBQUE7SUFFbkMsdUNBQXVDO0lBQ3ZDLDhDQUE4QztJQUU5QyxLQUFLLENBQUMsV0FBVyxDQUFFLFFBQVEsQ0FBRSxDQUFBO0lBQzdCLHFDQUFxQztJQUVyQyxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRztJQUM3QixJQUFJLFFBQVEsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9DLFFBQVEsQ0FBQyxJQUFJLEdBQUMsTUFBTSxDQUFBO0lBQ3BCLE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCBpc0ZpbGVJbnB1dCA9IGZ1bmN0aW9uKGVsbTphbnkpe1xuICBjb25zdCB0eSA9IGVsbS5nZXRBdHRyaWJ1dGUoJ3R5cGUnKVxuICByZXR1cm4gZWxtLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0JyAmJiB0eSAmJiB0eS50b0xvd2VyQ2FzZSgpID09PSAnZmlsZSc7XG59XG5cbmxldCBpbml0aWFsVG91Y2hTdGFydFkgPSAwO1xubGV0IGluaXRpYWxUb3VjaFN0YXJ0WCA9IDA7XG5leHBvcnQgY29uc3QgZGV0ZWN0U3dpcGUgPSBmdW5jdGlvbihldnQ6YW55KTpib29sZWFuIHtcbiAgdmFyIHRvdWNoZXMgPSBldnQuY2hhbmdlZFRvdWNoZXMgfHwgKGV2dC5vcmlnaW5hbEV2ZW50ICYmIGV2dC5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzKTtcbiAgaWYgKHRvdWNoZXMpIHtcbiAgICBpZiAoZXZ0LnR5cGUgPT09ICd0b3VjaHN0YXJ0Jykge1xuICAgICAgaW5pdGlhbFRvdWNoU3RhcnRYID0gdG91Y2hlc1swXS5jbGllbnRYO1xuICAgICAgaW5pdGlhbFRvdWNoU3RhcnRZID0gdG91Y2hlc1swXS5jbGllbnRZO1xuICAgICAgcmV0dXJuIHRydWU7IC8vIGRvbid0IGJsb2NrIGV2ZW50IGRlZmF1bHRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcHJldmVudCBzY3JvbGwgZnJvbSB0cmlnZ2VyaW5nIGV2ZW50XG4gICAgICBpZiAoZXZ0LnR5cGUgPT09ICd0b3VjaGVuZCcpIHtcbiAgICAgICAgdmFyIGN1cnJlbnRYID0gdG91Y2hlc1swXS5jbGllbnRYO1xuICAgICAgICB2YXIgY3VycmVudFkgPSB0b3VjaGVzWzBdLmNsaWVudFk7XG4gICAgICAgIGlmICgoTWF0aC5hYnMoY3VycmVudFggLSBpbml0aWFsVG91Y2hTdGFydFgpID4gMjApIHx8XG4gICAgICAgICAgKE1hdGguYWJzKGN1cnJlbnRZIC0gaW5pdGlhbFRvdWNoU3RhcnRZKSA+IDIwKSkge1xuICAgICAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICBpZiAoZXZ0LmNhbmNlbGFibGUpIHtcbiAgICAgICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUludmlzaWJsZUZpbGVJbnB1dFdyYXAgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGZpbGVFbGVtID0gY3JlYXRlRmlsZUlucHV0KClcbiAgdmFyIGxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgbGFiZWwuaW5uZXJIVE1MID0gJ3VwbG9hZCdcbiAgbGFiZWwuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nXG4gIGxhYmVsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJ1xuICBsYWJlbC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nXG4gIGxhYmVsLnN0eWxlLndpZHRoID0gJzBweCdcbiAgbGFiZWwuc3R5bGUuaGVpZ2h0ID0gJzBweCdcbiAgbGFiZWwuc3R5bGUuYm9yZGVyID0gJ25vbmUnXG4gIGxhYmVsLnN0eWxlLm1hcmdpbiA9ICcwcHgnXG4gIGxhYmVsLnN0eWxlLnBhZGRpbmcgPSAnMHB4J1xuICBsYWJlbC5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywnLTEnKVxuICBcbiAgLy9iaW5kQXR0clRvRmlsZUlucHV0KGZpbGVFbGVtLCBsYWJlbCk7XG4gIC8vZ2VuZXJhdGVkRWxlbXMucHVzaCh7ZWw6IGVsZW0sIHJlZjogbGFiZWx9KTtcblxuICBsYWJlbC5hcHBlbmRDaGlsZCggZmlsZUVsZW0gKVxuICAvL2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoIGxhYmVsICk7XG5cbiAgcmV0dXJuIGxhYmVsO1xufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlRmlsZUlucHV0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmaWxlRWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gIGZpbGVFbGVtLnR5cGU9XCJmaWxlXCJcbiAgcmV0dXJuIGZpbGVFbGVtO1xufVxuIl19 |
| export function getWindow() { return window; } | ||
| export function acceptType(accept, type, name) { | ||
| if (!accept) { | ||
| return true; | ||
| } | ||
| const defs = accept.split(','); | ||
| let regx; | ||
| let acceptRegString; | ||
| for (let x = defs.length - 1; x >= 0; --x) { | ||
| //Escapes dots in mimetype | ||
| acceptRegString = defs[x]; | ||
| //trim | ||
| acceptRegString = acceptRegString.replace(/(^\s+|\s+$)/g, ''); | ||
| //Escapes stars in mimetype | ||
| acceptRegString = acceptRegString.replace(/\*/g, '.*'); | ||
| //let acceptReg = '^((' + acceptRegString | ||
| //acceptReg = acceptReg.replace(/,/g,')|(') + '))$' | ||
| //try by mime | ||
| regx = new RegExp(acceptRegString, 'gi'); | ||
| if (type.search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| //try by ext | ||
| if (acceptRegString.substring(0, 1) == '.') { | ||
| acceptRegString = '\\' + acceptRegString; //.substring(1, acceptRegString.length-1)//remove dot at front | ||
| regx = new RegExp(acceptRegString + '$', 'i'); | ||
| if ((name || type).search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| export function arrayBufferToBase64(buffer) { | ||
| var binary = ''; | ||
| var bytes = new Uint8Array(buffer); | ||
| var len = bytes.byteLength; | ||
| for (var i = 0; i < len; i++) { | ||
| binary += String.fromCharCode(bytes[i]); | ||
| } | ||
| return window.btoa(binary); | ||
| } | ||
| export function dataUrltoBlob(dataurl, name, origSize) { | ||
| var arr = dataurl.split(','); | ||
| var mimeMatch = arr[0].match(/:(.*?);/); | ||
| var mime = mimeMatch ? mimeMatch[1] : 'text/plain'; | ||
| var bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); | ||
| while (n--) { | ||
| u8arr[n] = bstr.charCodeAt(n); | ||
| } | ||
| var blob = new window.Blob([u8arr], { type: mime }); | ||
| blob["name"] = name; | ||
| blob["$ngfOrigSize"] = origSize; | ||
| return blob; | ||
| } | ||
| export function applyTransform(ctx, orientation, width, height) { | ||
| switch (orientation) { | ||
| case 2: | ||
| return ctx.transform(-1, 0, 0, 1, width, 0); | ||
| case 3: | ||
| return ctx.transform(-1, 0, 0, -1, width, height); | ||
| case 4: | ||
| return ctx.transform(1, 0, 0, -1, 0, height); | ||
| case 5: | ||
| return ctx.transform(0, 1, 1, 0, 0, 0); | ||
| case 6: | ||
| return ctx.transform(0, 1, -1, 0, height, 0); | ||
| case 7: | ||
| return ctx.transform(0, -1, -1, 0, height, width); | ||
| case 8: | ||
| return ctx.transform(0, -1, 1, 0, 0, width); | ||
| } | ||
| } | ||
| export function fixFileOrientationByMeta(file, result) { | ||
| return dataUrl(file, true) | ||
| .then(url => { | ||
| var canvas = document.createElement('canvas'); | ||
| var img = document.createElement('img'); | ||
| return new Promise(function (res, rej) { | ||
| img.onload = function () { | ||
| try { | ||
| canvas.width = result.orientation > 4 ? img.height : img.width; | ||
| canvas.height = result.orientation > 4 ? img.width : img.height; | ||
| var ctx = canvas.getContext('2d'); | ||
| applyTransform(ctx, result.orientation, img.width, img.height); | ||
| ctx.drawImage(img, 0, 0); | ||
| var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934); | ||
| const base = arrayBufferToBase64(result.fixedArrayBuffer); | ||
| dataUrl = restoreExif(base, dataUrl); | ||
| var blob = dataUrltoBlob(dataUrl, file.name); | ||
| const newFile = blobToFile(blob, file.name); | ||
| res(newFile); | ||
| } | ||
| catch (e) { | ||
| rej(e); | ||
| } | ||
| }; | ||
| img.onerror = rej; | ||
| img.src = url; | ||
| }); | ||
| }); | ||
| } | ||
| export function applyExifRotation(file) { | ||
| if (file.type.indexOf('image/jpeg') !== 0) { | ||
| return Promise.resolve(file); | ||
| } | ||
| return readOrientation(file) | ||
| .then((result) => { | ||
| if (result.orientation < 2 || result.orientation > 8) { | ||
| return file; | ||
| } | ||
| return fixFileOrientationByMeta(file, result); | ||
| }); | ||
| } | ||
| export function readOrientation(file) { | ||
| return new Promise((res, rej) => { | ||
| var reader = new FileReader(); | ||
| var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file; | ||
| reader.readAsArrayBuffer(slicedFile); | ||
| reader.onerror = rej; | ||
| reader.onload = function (e) { | ||
| var result = { orientation: 1 }; | ||
| var view = new DataView(this.result); | ||
| if (view.getUint16(0, false) !== 0xFFD8) | ||
| return res(result); | ||
| var length = view.byteLength, offset = 2; | ||
| while (offset < length) { | ||
| var marker = view.getUint16(offset, false); | ||
| offset += 2; | ||
| if (marker === 0xFFE1) { | ||
| if (view.getUint32(offset += 2, false) !== 0x45786966) | ||
| return res(result); | ||
| var little = view.getUint16(offset += 6, false) === 0x4949; | ||
| offset += view.getUint32(offset + 4, little); | ||
| var tags = view.getUint16(offset, little); | ||
| offset += 2; | ||
| for (var i = 0; i < tags; i++) | ||
| if (view.getUint16(offset + (i * 12), little) === 0x0112) { | ||
| var orientation = view.getUint16(offset + (i * 12) + 8, little); | ||
| if (orientation >= 2 && orientation <= 8) { | ||
| view.setUint16(offset + (i * 12) + 8, 1, little); | ||
| result.fixedArrayBuffer = e.target.result; | ||
| } | ||
| result.orientation = orientation; | ||
| return res(result); | ||
| } | ||
| } | ||
| else if ((marker & 0xFF00) !== 0xFF00) | ||
| break; | ||
| else | ||
| offset += view.getUint16(offset, false); | ||
| } | ||
| return res(result); | ||
| }; | ||
| }); | ||
| } | ||
| /** converts file-input file into base64 dataUri */ | ||
| export function dataUrl(file, disallowObjectUrl) { | ||
| if (!file) | ||
| return Promise.resolve(file); | ||
| if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { | ||
| return Promise.resolve(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl); | ||
| } | ||
| var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; | ||
| if (p) | ||
| return p; | ||
| const win = getWindow(); | ||
| let deferred; | ||
| if (win.FileReader && file && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { | ||
| //prefer URL.createObjectURL for handling refrences to files of all sizes | ||
| //since it doesn´t build a large string in memory | ||
| var URL = win.URL || win.webkitURL; | ||
| if (FileReader) { | ||
| deferred = new Promise((res, rej) => { | ||
| var fileReader = new FileReader(); | ||
| fileReader.onload = function (event) { | ||
| file.$ngfDataUrl = event.target.result; | ||
| delete file.$ngfDataUrl; | ||
| res(event.target.result); | ||
| }; | ||
| fileReader.onerror = function (e) { | ||
| file.$ngfDataUrl = ''; | ||
| rej(e); | ||
| }; | ||
| fileReader.readAsDataURL(file); | ||
| }); | ||
| } | ||
| else { | ||
| var url; | ||
| try { | ||
| url = URL.createObjectURL(file); | ||
| } | ||
| catch (e) { | ||
| return Promise.reject(e); | ||
| } | ||
| deferred = Promise.resolve(url); | ||
| file.$ngfBlobUrl = url; | ||
| } | ||
| } | ||
| else { | ||
| file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; | ||
| return Promise.reject(new Error('Browser does not support window.FileReader, window.FileReader, or window.FileAPI')); //deferred.reject(); | ||
| } | ||
| if (disallowObjectUrl) { | ||
| p = file.$$ngfDataUrlPromise = deferred; | ||
| } | ||
| else { | ||
| p = file.$$ngfBlobUrlPromise = deferred; | ||
| } | ||
| p = p.then((x) => { | ||
| delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; | ||
| return x; | ||
| }); | ||
| return p; | ||
| } | ||
| export function restoreExif(orig, resized) { | ||
| var ExifRestorer = { | ||
| KEY_STR: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' | ||
| }; | ||
| ExifRestorer.encode64 = function (input) { | ||
| var output = '', chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0; | ||
| do { | ||
| chr1 = input[i++]; | ||
| chr2 = input[i++]; | ||
| chr3 = input[i++]; | ||
| enc1 = chr1 >> 2; | ||
| enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | ||
| enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | ||
| enc4 = chr3 & 63; | ||
| if (isNaN(chr2)) { | ||
| enc3 = enc4 = 64; | ||
| } | ||
| else if (isNaN(chr3)) { | ||
| enc4 = 64; | ||
| } | ||
| output = output + | ||
| this.KEY_STR.charAt(enc1) + | ||
| this.KEY_STR.charAt(enc2) + | ||
| this.KEY_STR.charAt(enc3) + | ||
| this.KEY_STR.charAt(enc4); | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return output; | ||
| }; | ||
| ExifRestorer.restore = function (origFileBase64, resizedFileBase64) { | ||
| if (origFileBase64.match('data:image/jpeg;base64,')) { | ||
| origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', ''); | ||
| } | ||
| var rawImage = this.decode64(origFileBase64); | ||
| var segments = this.slice2Segments(rawImage); | ||
| var image = this.exifManipulation(resizedFileBase64, segments); | ||
| return 'data:image/jpeg;base64,' + this.encode64(image); | ||
| }; | ||
| ExifRestorer.exifManipulation = function (resizedFileBase64, segments) { | ||
| var exifArray = this.getExifArray(segments), newImageArray = this.insertExif(resizedFileBase64, exifArray); | ||
| return new Uint8Array(newImageArray); | ||
| }; | ||
| ExifRestorer.getExifArray = function (segments) { | ||
| var seg; | ||
| for (var x = 0; x < segments.length; x++) { | ||
| seg = segments[x]; | ||
| if (seg[0] === 255 && seg[1] === 225) //(ff e1) | ||
| { | ||
| return seg; | ||
| } | ||
| } | ||
| return []; | ||
| }; | ||
| ExifRestorer.insertExif = function (resizedFileBase64, exifArray) { | ||
| var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''), buf = this.decode64(imageData), separatePoint = buf.indexOf(255, 3), mae = buf.slice(0, separatePoint), ato = buf.slice(separatePoint), array = mae; | ||
| array = array.concat(exifArray); | ||
| array = array.concat(ato); | ||
| return array; | ||
| }; | ||
| ExifRestorer.slice2Segments = function (rawImageArray) { | ||
| var head = 0, segments = []; | ||
| while (1) { | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 218) { | ||
| break; | ||
| } | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 216) { | ||
| head += 2; | ||
| } | ||
| else { | ||
| var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3]; | ||
| var endPoint = head + length + 2; | ||
| var seg = rawImageArray.slice(head, endPoint); | ||
| segments.push(seg); | ||
| head = endPoint; | ||
| } | ||
| if (head > rawImageArray.length) { | ||
| break; | ||
| } | ||
| } | ||
| return segments; | ||
| }; | ||
| ExifRestorer.decode64 = function (input) { | ||
| var chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0, buf = []; | ||
| // remove all characters that are not A-Z, a-z, 0-9, +, /, or = | ||
| var base64test = /[^A-Za-z0-9\+\/\=]/g; | ||
| if (base64test.exec(input)) { | ||
| console.log('There were invalid base64 characters in the input text.'); | ||
| } | ||
| input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); | ||
| do { | ||
| enc1 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc2 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc3 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc4 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| chr1 = (enc1 << 2) | (enc2 >> 4); | ||
| chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); | ||
| chr3 = ((enc3 & 3) << 6) | enc4; | ||
| buf.push(chr1); | ||
| if (enc3 !== 64) { | ||
| buf.push(chr2); | ||
| } | ||
| if (enc4 !== 64) { | ||
| buf.push(chr3); | ||
| } | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return buf; | ||
| }; | ||
| return ExifRestorer.restore(orig, resized); //<= EXIF | ||
| } | ||
| ; | ||
| function blobToFile(theBlob, fileName) { | ||
| var b = theBlob; | ||
| //A Blob() is almost a File() - it's just missing the two properties below which we will add | ||
| b.lastModifiedDate = new Date(); | ||
| b.name = fileName; | ||
| //Cast to a File() type | ||
| return theBlob; | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZVRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2ZpbGUtdXBsb2FkL2ZpbGVUb29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLFVBQVUsU0FBUyxLQUFPLE9BQU8sTUFBTSxDQUFBLENBQUEsQ0FBQztBQUU5QyxNQUFNLFVBQVUsVUFBVSxDQUFDLE1BQWEsRUFBRSxJQUFXLEVBQUUsSUFBWTtJQUNqRSxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQ1gsT0FBTyxJQUFJLENBQUE7S0FDWjtJQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDOUIsSUFBSSxJQUFXLENBQUE7SUFDZixJQUFJLGVBQXNCLENBQUE7SUFFMUIsS0FBSSxJQUFJLENBQUMsR0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFDO1FBQ25DLDJCQUEyQjtRQUMzQixlQUFlLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ3pCLE1BQU07UUFDTixlQUFlLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUMsRUFBRSxDQUFDLENBQUE7UUFDNUQsNEJBQTRCO1FBQzVCLGVBQWUsR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBQyxJQUFJLENBQUMsQ0FBQTtRQUNyRCx5Q0FBeUM7UUFDekMsbURBQW1EO1FBRW5ELGFBQWE7UUFDYixJQUFJLEdBQUcsSUFBSSxNQUFNLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxDQUFBO1FBQ3hDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBRSxDQUFDLEVBQUU7WUFDeEIsT0FBTyxJQUFJLENBQUE7U0FDWjtRQUVELFlBQVk7UUFDWixJQUFJLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJ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QUNmLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDaEI7WUFDRCxJQUFJLElBQUksS0FBSyxFQUFFLEVBQUU7Z0JBQ2YsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNoQjtZQUVELElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUN4QixJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1NBRWhDLFFBQVEsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUU7UUFFM0IsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDLENBQUM7SUFFRixPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUUsU0FBUztBQUN4RCxDQUFDO0FBQUEsQ0FBQztBQUVGLFNBQVMsVUFBVSxDQUFDLE9BQWEsRUFBRSxRQUFlO0lBQ2hELElBQUksQ0FBQyxHQUFRLE9BQU8sQ0FBQztJQUNyQiw0RkFBNEY7SUFDNUYsQ0FBQyxDQUFDLGdCQUFnQixHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFDaEMsQ0FBQyxDQUFDLElBQUksR0FBRyxRQUFRLENBQUM7SUFFbEIsdUJBQXVCO0lBQ3ZCLE9BQWEsT0FBTyxDQUFDO0FBQ3ZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gZ2V0V2luZG93KCk6YW55e3JldHVybiB3aW5kb3d9XG5cbmV4cG9ydCBmdW5jdGlvbiBhY2NlcHRUeXBlKGFjY2VwdDpzdHJpbmcsIHR5cGU6c3RyaW5nLCBuYW1lPzpzdHJpbmcpOmJvb2xlYW4geyAgIFxuICBpZiggIWFjY2VwdCApe1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBjb25zdCBkZWZzID0gYWNjZXB0LnNwbGl0KCcsJylcbiAgbGV0IHJlZ3g6UmVnRXhwXG4gIGxldCBhY2NlcHRSZWdTdHJpbmc6c3RyaW5nXG5cbiAgZm9yKGxldCB4PWRlZnMubGVuZ3RoLTE7IHggPj0gMDsgLS14KXtcbiAgICAvL0VzY2FwZXMgZG90cyBpbiBtaW1ldHlwZSBcbiAgICBhY2NlcHRSZWdTdHJpbmcgPSBkZWZzW3hdXG4gICAgLy90cmltXG4gICAgYWNjZXB0UmVnU3RyaW5nID0gYWNjZXB0UmVnU3RyaW5nLnJlcGxhY2UoLyheXFxzK3xcXHMrJCkvZywnJylcbiAgICAvL0VzY2FwZXMgc3RhcnMgaW4gbWltZXR5cGUgXG4gICAgYWNjZXB0UmVnU3RyaW5nID0gYWNjZXB0UmVnU3RyaW5nLnJlcGxhY2UoL1xcKi9nLCcuKicpXG4gICAgLy9sZXQgYWNjZXB0UmVnID0gJ14oKCcgKyBhY2NlcHRSZWdTdHJpbmdcbiAgICAvL2FjY2VwdFJlZyA9IGFjY2VwdFJlZy5yZXBsYWNlKC8sL2csJyl8KCcpICsgJykpJCdcbiAgICBcbiAgICAvL3RyeSBieSBtaW1lXG4gICAgcmVneCA9IG5ldyBSZWdFeHAoYWNjZXB0UmVnU3RyaW5nLCAnZ2knKVxuICAgIGlmKCB0eXBlLnNlYXJjaChyZWd4KT49MCApe1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICAvL3RyeSBieSBleHRcbiAgICBpZiggYWNjZXB0UmVnU3RyaW5nLnN1YnN0cmluZygwLCAxKT09Jy4nICl7ICAgICAgXG4gICAgICBhY2NlcHRSZWdTdHJpbmcgPSAnXFxcXCcrIGFjY2VwdFJlZ1N0cmluZy8vLnN1YnN0cmluZygxLCBhY2NlcHRSZWdTdHJpbmcubGVuZ3RoLTEpLy9yZW1vdmUgZG90IGF0IGZyb250XG4gICAgICByZWd4ID0gbmV3IFJlZ0V4cChhY2NlcHRSZWdTdHJpbmcrJyQnLCAnaScpXG4gICAgICBpZiggKG5hbWV8fHR5cGUpLnNlYXJjaChyZWd4KT49MCApe1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbnZhbGlkRmlsZUl0ZW17XG4gIGZpbGU6RmlsZVxuICB0eXBlOnN0cmluZ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlCdWZmZXJUb0Jhc2U2NChidWZmZXI6YW55KSB7XG4gIHZhciBiaW5hcnkgPSAnJztcbiAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcbiAgdmFyIGxlbiA9IGJ5dGVzLmJ5dGVMZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7XG4gIH1cbiAgcmV0dXJuIHdpbmRvdy5idG9hKGJpbmFyeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkYXRhVXJsdG9CbG9iKFxuICBkYXRhdXJsOnN0cmluZyxcbiAgbmFtZTpzdHJpbmcsXG4gIG9yaWdTaXplPzphbnlcbik6QmxvYntcbiAgdmFyIGFyciA9IGRhdGF1cmwuc3BsaXQoJywnKTtcbiAgdmFyIG1pbWVNYXRjaCA9IGFyclswXS5tYXRjaCgvOiguKj8pOy8pXG4gIHZhciBtaW1lOnN0cmluZyA9IG1pbWVNYXRjaCA/IG1pbWVNYXRjaFsxXSA6ICd0ZXh0L3BsYWluJ1xuICB2YXIgYnN0ciA9IGF0b2IoYXJyWzFdKSwgbiA9IGJzdHIubGVuZ3RoLCB1OGFyciA9IG5ldyBVaW50OEFycmF5KG4pO1xuICB3aGlsZSAobi0tKSB7XG4gICAgdThhcnJbbl0gPSBic3RyLmNoYXJDb2RlQXQobik7XG4gIH1cbiAgXG4gIHZhciBibG9iOiBhbnkgPSBuZXcgd2luZG93LkJsb2IoW3U4YXJyXSwge3R5cGU6IG1pbWV9KTtcbiAgYmxvYltcIm5hbWVcIl0gPSBuYW1lO1xuICBibG9iW1wiJG5nZk9yaWdTaXplXCJdID0gb3JpZ1NpemU7XG4gIHJldHVybiBibG9iO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIG9yaWVudGF0aW9uTWV0YXtcbiAgb3JpZW50YXRpb246IG51bWJlclxuICBmaXhlZEFycmF5QnVmZmVyPzphbnlbXVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlUcmFuc2Zvcm0oXG4gIGN0eDpDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIG9yaWVudGF0aW9uOm51bWJlcixcbiAgd2lkdGg6bnVtYmVyLFxuICBoZWlnaHQ6bnVtYmVyXG4pIHtcbiAgc3dpdGNoIChvcmllbnRhdGlvbikge1xuICAgIGNhc2UgMjpcbiAgICAgIHJldHVybiBjdHgudHJhbnNmb3JtKC0xLCAwLCAwLCAxLCB3aWR0aCwgMCk7XG4gICAgY2FzZSAzOlxuICAgICAgcmV0dXJuIGN0eC50cmFuc2Zvcm0oLTEsIDAsIDAsIC0xLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICBjYXNlIDQ6XG4gICAgICByZXR1cm4gY3R4LnRyYW5zZm9ybSgxLCAwLCAwLCAtMSwgMCwgaGVpZ2h0KTtcbiAgICBjYXNlIDU6XG4gICAgICByZXR1cm4gY3R4LnRyYW5zZm9ybSgwLCAxLCAxLCAwLCAwLCAwKTtcbiAgICBjYXNlIDY6XG4gICAgICByZXR1cm4gY3R4LnRyYW5zZm9ybSgwLCAxLCAtMSwgMCwgaGVpZ2h0LCAwKTtcbiAgICBjYXNlIDc6XG4gICAgICByZXR1cm4gY3R4LnRyYW5zZm9ybSgwLCAtMSwgLTEsIDAsIGhlaWdodCwgd2lkdGgpO1xuICAgIGNhc2UgODpcbiAgICAgIHJldHVybiBjdHgudHJhbnNmb3JtKDAsIC0xLCAxLCAwLCAwLCB3aWR0aCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpeEZpbGVPcmllbnRhdGlvbkJ5TWV0YShcbiAgZmlsZTpGaWxlLCByZXN1bHQ6b3JpZW50YXRpb25NZXRhXG4pOlByb21pc2U8RmlsZT57XG4gIHJldHVybiBkYXRhVXJsKGZpbGUsIHRydWUpXG4gIC50aGVuKHVybD0+e1xuICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICB2YXIgaW1nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7XG5cbiAgICByZXR1cm4gPFByb21pc2U8RmlsZT4+bmV3IFByb21pc2UoZnVuY3Rpb24ocmVzLHJlail7XG4gICAgICBpbWcub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNhbnZhcy53aWR0aCA9IHJlc3VsdC5vcmllbnRhdGlvbiA+IDQgPyBpbWcuaGVpZ2h0IDogaW1nLndpZHRoXG4gICAgICAgICAgY2FudmFzLmhlaWdodCA9IHJlc3VsdC5vcmllbnRhdGlvbiA+IDQgPyBpbWcud2lkdGggOiBpbWcuaGVpZ2h0XG4gICAgICAgICAgdmFyIGN0eCA9IDxDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ+Y2FudmFzLmdldENvbnRleHQoJzJkJylcbiAgICAgICAgICBhcHBseVRyYW5zZm9ybShjdHgsIHJlc3VsdC5vcmllbnRhdGlvbiwgaW1nLndpZHRoLCBpbWcuaGVpZ2h0KVxuICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoaW1nLCAwLCAwKTtcbiAgICAgICAgICB2YXIgZGF0YVVybCA9IGNhbnZhcy50b0RhdGFVUkwoZmlsZS50eXBlIHx8ICdpbWFnZS9XZWJQJywgMC45MzQpXG4gICAgICAgICAgY29uc3QgYmFzZSA9IGFycmF5QnVmZmVyVG9CYXNlNjQocmVzdWx0LmZpeGVkQXJyYXlCdWZmZXIpXG4gICAgICAgICAgZGF0YVVybCA9IHJlc3RvcmVFeGlmKGJhc2UsIGRhdGFVcmwpXG4gICAgICAgICAgdmFyIGJsb2IgPSBkYXRhVXJsdG9CbG9iKGRhdGFVcmwsIGZpbGUubmFtZSlcbiAgICAgICAgICBjb25zdCBuZXdGaWxlID0gYmxvYlRvRmlsZShibG9iLCBmaWxlLm5hbWUpO1xuICAgICAgICAgIHJlcyhuZXdGaWxlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJlaihlKVxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgaW1nLm9uZXJyb3IgPSByZWo7XG4gICAgICBpbWcuc3JjID0gdXJsOyAgICBcbiAgICB9KVxuICB9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlFeGlmUm90YXRpb24oXG4gIGZpbGU6RmlsZVxuKTpQcm9taXNlPEZpbGU+e1xuICBpZiAoZmlsZS50eXBlLmluZGV4T2YoJ2ltYWdlL2pwZWcnKSAhPT0gMCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmlsZSk7XG4gIH1cblxuICByZXR1cm4gcmVhZE9yaWVudGF0aW9uKGZpbGUpXG4gIC50aGVuKChyZXN1bHQ6b3JpZW50YXRpb25NZXRhKT0+e1xuICAgIGlmIChyZXN1bHQub3JpZW50YXRpb24gPCAyIHx8IHJlc3VsdC5vcmllbnRhdGlvbiA+IDgpIHtcbiAgICAgIHJldHVybiBmaWxlXG4gICAgfVxuICAgIFxuICAgIHJldHVybiBmaXhGaWxlT3JpZW50YXRpb25CeU1ldGEoZmlsZSxyZXN1bHQpXG4gIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkT3JpZW50YXRpb24oXG4gIGZpbGU6RmlsZVxuKTpQcm9taXNlPG9yaWVudGF0aW9uTWV0YT57XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzLHJlaik9PntcbiAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICB2YXIgc2xpY2VkRmlsZSA9IGZpbGUuc2xpY2UgPyBmaWxlLnNsaWNlKDAsIDY0ICogMTAyNCkgOiBmaWxlO1xuICAgIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihzbGljZWRGaWxlKTtcbiAgICByZWFkZXIub25lcnJvciA9IHJlalxuICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoZTphbnkpIHtcbiAgICAgIHZhciByZXN1bHQ6b3JpZW50YXRpb25NZXRhID0ge29yaWVudGF0aW9uOiAxfTtcbiAgICAgIHZhciB2aWV3ID0gbmV3IERhdGFWaWV3KCA8QXJyYXlCdWZmZXI+dGhpcy5yZXN1bHQgKTtcbiAgICAgIGlmICh2aWV3LmdldFVpbnQxNigwLCBmYWxzZSkgIT09IDB4RkZEOCkgcmV0dXJuIHJlcyhyZXN1bHQpO1xuXG4gICAgICB2YXIgbGVuZ3RoID0gdmlldy5ieXRlTGVuZ3RoLFxuICAgICAgICBvZmZzZXQgPSAyO1xuICAgICAgd2hpbGUgKG9mZnNldCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgbWFya2VyID0gdmlldy5nZXRVaW50MTYob2Zmc2V0LCBmYWxzZSk7XG4gICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICBpZiAobWFya2VyID09PSAweEZGRTEpIHtcbiAgICAgICAgICBpZiAodmlldy5nZXRVaW50MzIob2Zmc2V0ICs9IDIsIGZhbHNlKSAhPT0gMHg0NTc4Njk2NikgcmV0dXJuIHJlcyhyZXN1bHQpO1xuXG4gICAgICAgICAgdmFyIGxpdHRsZSA9IHZpZXcuZ2V0VWludDE2KG9mZnNldCArPSA2LCBmYWxzZSkgPT09IDB4NDk0OTtcbiAgICAgICAgICBvZmZzZXQgKz0gdmlldy5nZXRVaW50MzIob2Zmc2V0ICsgNCwgbGl0dGxlKTtcbiAgICAgICAgICB2YXIgdGFncyA9IHZpZXcuZ2V0VWludDE2KG9mZnNldCwgbGl0dGxlKTtcbiAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRhZ3M7IGkrKylcbiAgICAgICAgICAgIGlmICh2aWV3LmdldFVpbnQxNihvZmZzZXQgKyAoaSAqIDEyKSwgbGl0dGxlKSA9PT0gMHgwMTEyKSB7XG4gICAgICAgICAgICAgIHZhciBvcmllbnRhdGlvbiA9IHZpZXcuZ2V0VWludDE2KG9mZnNldCArIChpICogMTIpICsgOCwgbGl0dGxlKTtcbiAgICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uID49IDIgJiYgb3JpZW50YXRpb24gPD0gOCkge1xuICAgICAgICAgICAgICAgIHZpZXcuc2V0VWludDE2KG9mZnNldCArIChpICogMTIpICsgOCwgMSwgbGl0dGxlKTtcbiAgICAgICAgICAgICAgICByZXN1bHQuZml4ZWRBcnJheUJ1ZmZlciA9IGUudGFyZ2V0LnJlc3VsdDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXN1bHQub3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlcyhyZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKChtYXJrZXIgJiAweEZGMDApICE9PSAweEZGMDApIGJyZWFrO1xuICAgICAgICBlbHNlIG9mZnNldCArPSB2aWV3LmdldFVpbnQxNihvZmZzZXQsIGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMocmVzdWx0KTtcbiAgICB9O1xuICB9KVxufVxuXG4vKiogY29udmVydHMgZmlsZS1pbnB1dCBmaWxlIGludG8gYmFzZTY0IGRhdGFVcmkgKi9cbmV4cG9ydCBmdW5jdGlvbiBkYXRhVXJsKFxuICBmaWxlOmFueSxcbiAgZGlzYWxsb3dPYmplY3RVcmw/OmFueVxuKTpQcm9taXNlPHN0cmluZz57XG4gIGlmICghZmlsZSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmaWxlKVxuICBcbiAgaWYgKChkaXNhbGxvd09iamVjdFVybCAmJiBmaWxlLiRuZ2ZEYXRhVXJsICE9IG51bGwpIHx8ICghZGlzYWxsb3dPYmplY3RVcmwgJiYgZmlsZS4kbmdmQmxvYlVybCAhPSBudWxsKSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoIGRpc2FsbG93T2JqZWN0VXJsID8gZmlsZS4kbmdmRGF0YVVybCA6IGZpbGUuJG5nZkJsb2JVcmwgKVxuICB9XG5cbiAgdmFyIHAgPSBkaXNhbGxvd09iamVjdFVybCA/IGZpbGUuJCRuZ2ZEYXRhVXJsUHJvbWlzZSA6IGZpbGUuJCRuZ2ZCbG9iVXJsUHJvbWlzZTtcbiAgaWYgKHApIHJldHVybiBwO1xuXG4gIGNvbnN0IHdpbiA9IGdldFdpbmRvdygpXG4gIGxldCBkZWZlcnJlZDpQcm9taXNlPHN0cmluZz5cbiAgaWYgKHdpbi5GaWxlUmVhZGVyICYmIGZpbGUgJiZcbiAgICAoIXdpbi5GaWxlQVBJIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignTVNJRSA4JykgPT09IC0xIHx8IGZpbGUuc2l6ZSA8IDIwMDAwKSAmJlxuICAgICghd2luLkZpbGVBUEkgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdNU0lFIDknKSA9PT0gLTEgfHwgZmlsZS5zaXplIDwgNDAwMDAwMCkpIHtcbiAgICAvL3ByZWZlciBVUkwuY3JlYXRlT2JqZWN0VVJMIGZvciBoYW5kbGluZyByZWZyZW5jZXMgdG8gZmlsZXMgb2YgYWxsIHNpemVzXG4gICAgLy9zaW5jZSBpdCBkb2VzbsK0dCBidWlsZCBhIGxhcmdlIHN0cmluZyBpbiBtZW1vcnlcbiAgICB2YXIgVVJMID0gd2luLlVSTCB8fCB3aW4ud2Via2l0VVJMO1xuICAgIGlmIChGaWxlUmVhZGVyKSB7XG4gICAgICBkZWZlcnJlZCA9IG5ldyBQcm9taXNlKChyZXMscmVqKT0+e1xuICAgICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24gKGV2ZW50OmFueSkge1xuICAgICAgICAgIGZpbGUuJG5nZkRhdGFVcmwgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgICAgIGRlbGV0ZSBmaWxlLiRuZ2ZEYXRhVXJsO1xuICAgICAgICAgIHJlcyggZXZlbnQudGFyZ2V0LnJlc3VsdCApXG4gICAgICAgIH07XG4gICAgICAgIGZpbGVSZWFkZXIub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgZmlsZS4kbmdmRGF0YVVybCA9ICcnO1xuICAgICAgICAgIHJlaihlKVxuICAgICAgICB9O1xuICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdXJsOmFueTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgZGVmZXJyZWQgPSBQcm9taXNlLnJlc29sdmUoIHVybCApXG4gICAgICBmaWxlLiRuZ2ZCbG9iVXJsID0gdXJsO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmaWxlW2Rpc2FsbG93T2JqZWN0VXJsID8gJyRuZ2ZEYXRhVXJsJyA6ICckbmdmQmxvYlVybCddID0gJyc7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCBuZXcgRXJyb3IoJ0Jyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCB3aW5kb3cuRmlsZVJlYWRlciwgd2luZG93LkZpbGVSZWFkZXIsIG9yIHdpbmRvdy5GaWxlQVBJJykgKS8vZGVmZXJyZWQucmVqZWN0KCk7XG4gIH1cblxuICBpZiAoZGlzYWxsb3dPYmplY3RVcmwpIHtcbiAgICBwID0gZmlsZS4kJG5nZkRhdGFVcmxQcm9taXNlID0gZGVmZXJyZWQ7XG4gIH0gZWxzZSB7XG4gICAgcCA9IGZpbGUuJCRuZ2ZCbG9iVXJsUHJvbWlzZSA9IGRlZmVycmVkO1xuICB9XG5cbiAgcCA9IHAudGhlbigoeDphbnkpPT57XG4gICAgZGVsZXRlIGZpbGVbZGlzYWxsb3dPYmplY3RVcmwgPyAnJCRuZ2ZEYXRhVXJsUHJvbWlzZScgOiAnJCRuZ2ZCbG9iVXJsUHJvbWlzZSddO1xuICAgIHJldHVybiB4XG4gIH0pXG5cbiAgcmV0dXJuIHA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXN0b3JlRXhpZihvcmlnOmFueSwgcmVzaXplZDphbnkpIHtcbiAgdmFyIEV4aWZSZXN0b3JlcjphbnkgPSB7XG4gICAgS0VZX1NUUjonQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz0nXG4gIH1cblxuICBFeGlmUmVzdG9yZXIuZW5jb2RlNjQgPSBmdW5jdGlvbiAoaW5wdXQ6YW55KSB7XG4gICAgdmFyIG91dHB1dCA9ICcnLFxuICAgICAgY2hyMSwgY2hyMiwgY2hyMzphbnkgPSAnJyxcbiAgICAgIGVuYzEsIGVuYzIsIGVuYzMsIGVuYzQ6YW55ID0gJycsXG4gICAgICBpID0gMDtcblxuICAgIGRvIHtcbiAgICAgIGNocjEgPSBpbnB1dFtpKytdO1xuICAgICAgY2hyMiA9IGlucHV0W2krK107XG4gICAgICBjaHIzID0gaW5wdXRbaSsrXTtcblxuICAgICAgZW5jMSA9IGNocjEgPj4gMjtcbiAgICAgIGVuYzIgPSAoKGNocjEgJiAzKSA8PCA0KSB8IChjaHIyID4+IDQpO1xuICAgICAgZW5jMyA9ICgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpO1xuICAgICAgZW5jNCA9IGNocjMgJiA2MztcblxuICAgICAgaWYgKGlzTmFOKGNocjIpKSB7XG4gICAgICAgIGVuYzMgPSBlbmM0ID0gNjQ7XG4gICAgICB9IGVsc2UgaWYgKGlzTmFOKGNocjMpKSB7XG4gICAgICAgIGVuYzQgPSA2NDtcbiAgICAgIH1cblxuICAgICAgb3V0cHV0ID0gb3V0cHV0ICtcbiAgICAgICAgdGhpcy5LRVlfU1RSLmNoYXJBdChlbmMxKSArXG4gICAgICAgIHRoaXMuS0VZX1NUUi5jaGFyQXQoZW5jMikgK1xuICAgICAgICB0aGlzLktFWV9TVFIuY2hhckF0KGVuYzMpICtcbiAgICAgICAgdGhpcy5LRVlfU1RSLmNoYXJBdChlbmM0KTtcbiAgICAgIGNocjEgPSBjaHIyID0gY2hyMyA9ICcnO1xuICAgICAgZW5jMSA9IGVuYzIgPSBlbmMzID0gZW5jNCA9ICcnO1xuICAgIH0gd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpO1xuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfTtcblxuICBFeGlmUmVzdG9yZXIucmVzdG9yZSA9IGZ1bmN0aW9uIChvcmlnRmlsZUJhc2U2NDphbnksIHJlc2l6ZWRGaWxlQmFzZTY0OmFueSkge1xuICAgIGlmIChvcmlnRmlsZUJhc2U2NC5tYXRjaCgnZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwnKSkge1xuICAgICAgb3JpZ0ZpbGVCYXNlNjQgPSBvcmlnRmlsZUJhc2U2NC5yZXBsYWNlKCdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcsICcnKTtcbiAgICB9XG5cbiAgICB2YXIgcmF3SW1hZ2U6bnVtYmVyW10gPSB0aGlzLmRlY29kZTY0KG9yaWdGaWxlQmFzZTY0KTtcbiAgICB2YXIgc2VnbWVudHMgPSB0aGlzLnNsaWNlMlNlZ21lbnRzKHJhd0ltYWdlKTtcblxuICAgIHZhciBpbWFnZSA9IHRoaXMuZXhpZk1hbmlwdWxhdGlvbihyZXNpemVkRmlsZUJhc2U2NCwgc2VnbWVudHMpO1xuXG4gICAgcmV0dXJuICdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcgKyB0aGlzLmVuY29kZTY0KGltYWdlKTtcbiAgfTtcblxuXG4gIEV4aWZSZXN0b3Jlci5leGlmTWFuaXB1bGF0aW9uID0gZnVuY3Rpb24gKHJlc2l6ZWRGaWxlQmFzZTY0OmFueSwgc2VnbWVudHM6YW55KSB7XG4gICAgdmFyIGV4aWZBcnJheSA9IHRoaXMuZ2V0RXhpZkFycmF5KHNlZ21lbnRzKSxcbiAgICAgIG5ld0ltYWdlQXJyYXkgPSB0aGlzLmluc2VydEV4aWYocmVzaXplZEZpbGVCYXNlNjQsIGV4aWZBcnJheSk7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG5ld0ltYWdlQXJyYXkpO1xuICB9O1xuXG4gIEV4aWZSZXN0b3Jlci5nZXRFeGlmQXJyYXkgPSBmdW5jdGlvbiAoc2VnbWVudHM6bnVtYmVyW11bXSkge1xuICAgIHZhciBzZWc7XG4gICAgZm9yICh2YXIgeCA9IDA7IHggPCBzZWdtZW50cy5sZW5ndGg7IHgrKykge1xuICAgICAgc2VnID0gc2VnbWVudHNbeF07XG4gICAgICBpZiAoc2VnWzBdID09PSAyNTUgJiYgc2VnWzFdID09PSAyMjUpIC8vKGZmIGUxKVxuICAgICAge1xuICAgICAgICByZXR1cm4gc2VnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH07XG5cblxuICBFeGlmUmVzdG9yZXIuaW5zZXJ0RXhpZiA9IGZ1bmN0aW9uIChyZXNpemVkRmlsZUJhc2U2NDphbnksIGV4aWZBcnJheTphbnkpIHtcbiAgICB2YXIgaW1hZ2VEYXRhID0gcmVzaXplZEZpbGVCYXNlNjQucmVwbGFjZSgnZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwnLCAnJyksXG4gICAgICBidWYgPSB0aGlzLmRlY29kZTY0KGltYWdlRGF0YSksXG4gICAgICBzZXBhcmF0ZVBvaW50ID0gYnVmLmluZGV4T2YoMjU1LCAzKSxcbiAgICAgIG1hZSA9IGJ1Zi5zbGljZSgwLCBzZXBhcmF0ZVBvaW50KSxcbiAgICAgIGF0byA9IGJ1Zi5zbGljZShzZXBhcmF0ZVBvaW50KSxcbiAgICAgIGFycmF5ID0gbWFlO1xuXG4gICAgYXJyYXkgPSBhcnJheS5jb25jYXQoZXhpZkFycmF5KTtcbiAgICBhcnJheSA9IGFycmF5LmNvbmNhdChhdG8pO1xuICAgIHJldHVybiBhcnJheTtcbiAgfTtcblxuXG4gIEV4aWZSZXN0b3Jlci5zbGljZTJTZWdtZW50cyA9IGZ1bmN0aW9uKFxuICAgIHJhd0ltYWdlQXJyYXk6bnVtYmVyW11cbiAgKSB7XG4gICAgdmFyIGhlYWQ6bnVtYmVyID0gMCxcbiAgICAgIHNlZ21lbnRzOm51bWJlcltdW10gPSBbXTtcblxuICAgIHdoaWxlICgxKSB7XG4gICAgICBpZiAocmF3SW1hZ2VBcnJheVtoZWFkXSA9PT0gMjU1ICYmIHJhd0ltYWdlQXJyYXlbaGVhZCArIDFdID09PSAyMTgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAocmF3SW1hZ2VBcnJheVtoZWFkXSA9PT0gMjU1ICYmIHJhd0ltYWdlQXJyYXlbaGVhZCArIDFdID09PSAyMTYpIHtcbiAgICAgICAgaGVhZCArPSAyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHZhciBsZW5ndGggPSByYXdJbWFnZUFycmF5W2hlYWQgKyAyXSAqIDI1NiArIHJhd0ltYWdlQXJyYXlbaGVhZCArIDNdXG4gICAgICAgIHZhciBlbmRQb2ludCA9IGhlYWQgKyBsZW5ndGggKyAyXG4gICAgICAgIHZhciBzZWc6bnVtYmVyW10gPSByYXdJbWFnZUFycmF5LnNsaWNlKGhlYWQsIGVuZFBvaW50KVxuICAgICAgICBzZWdtZW50cy5wdXNoKHNlZyk7XG4gICAgICAgIGhlYWQgPSBlbmRQb2ludDtcbiAgICAgIH1cbiAgICAgIGlmIChoZWFkID4gcmF3SW1hZ2VBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlZ21lbnRzO1xuICB9O1xuXG5cbiAgRXhpZlJlc3RvcmVyLmRlY29kZTY0ID0gZnVuY3Rpb24gKFxuICAgIGlucHV0OmFueVxuICApOm51bWJlcltde1xuICAgIHZhciBjaHIxLCBjaHIyLCBjaHIzOmFueSA9ICcnLFxuICAgICAgZW5jMSwgZW5jMiwgZW5jMywgZW5jNDphbnkgPSAnJyxcbiAgICAgIGkgPSAwLFxuICAgICAgYnVmOm51bWJlcltdID0gW107XG5cbiAgICAvLyByZW1vdmUgYWxsIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IEEtWiwgYS16LCAwLTksICssIC8sIG9yID1cbiAgICB2YXIgYmFzZTY0dGVzdCA9IC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZztcbiAgICBpZiAoYmFzZTY0dGVzdC5leGVjKGlucHV0KSkge1xuICAgICAgY29uc29sZS5sb2coJ1RoZXJlIHdlcmUgaW52YWxpZCBiYXNlNjQgY2hhcmFjdGVycyBpbiB0aGUgaW5wdXQgdGV4dC4nKTtcbiAgICB9XG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZywgJycpO1xuXG4gICAgZG8ge1xuICAgICAgZW5jMSA9IHRoaXMuS0VZX1NUUi5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgIGVuYzIgPSB0aGlzLktFWV9TVFIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICBlbmMzID0gdGhpcy5LRVlfU1RSLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgZW5jNCA9IHRoaXMuS0VZX1NUUi5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcblxuICAgICAgY2hyMSA9IChlbmMxIDw8IDIpIHwgKGVuYzIgPj4gNCk7XG4gICAgICBjaHIyID0gKChlbmMyICYgMTUpIDw8IDQpIHwgKGVuYzMgPj4gMik7XG4gICAgICBjaHIzID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0O1xuXG4gICAgICBidWYucHVzaChjaHIxKTtcblxuICAgICAgaWYgKGVuYzMgIT09IDY0KSB7XG4gICAgICAgIGJ1Zi5wdXNoKGNocjIpO1xuICAgICAgfVxuICAgICAgaWYgKGVuYzQgIT09IDY0KSB7XG4gICAgICAgIGJ1Zi5wdXNoKGNocjMpO1xuICAgICAgfVxuXG4gICAgICBjaHIxID0gY2hyMiA9IGNocjMgPSAnJztcbiAgICAgIGVuYzEgPSBlbmMyID0gZW5jMyA9IGVuYzQgPSAnJztcblxuICAgIH0gd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpO1xuXG4gICAgcmV0dXJuIGJ1ZjtcbiAgfTtcblxuICByZXR1cm4gRXhpZlJlc3RvcmVyLnJlc3RvcmUob3JpZywgcmVzaXplZCk7ICAvLzw9IEVYSUZcbn07XG5cbmZ1bmN0aW9uIGJsb2JUb0ZpbGUodGhlQmxvYjogQmxvYiwgZmlsZU5hbWU6c3RyaW5nKTogRmlsZSB7XG4gIHZhciBiOiBhbnkgPSB0aGVCbG9iO1xuICAvL0EgQmxvYigpIGlzIGFsbW9zdCBhIEZpbGUoKSAtIGl0J3MganVzdCBtaXNzaW5nIHRoZSB0d28gcHJvcGVydGllcyBiZWxvdyB3aGljaCB3ZSB3aWxsIGFkZFxuICBiLmxhc3RNb2RpZmllZERhdGUgPSBuZXcgRGF0ZSgpO1xuICBiLm5hbWUgPSBmaWxlTmFtZTtcblxuICAvL0Nhc3QgdG8gYSBGaWxlKCkgdHlwZVxuICByZXR1cm4gPEZpbGU+dGhlQmxvYjtcbn1cbiJdfQ== |
| import { Directive, EventEmitter, Input, Output, HostListener } from '@angular/core'; | ||
| import { createInvisibleFileInputWrap, isFileInput, detectSwipe } from "./doc-event-help.functions"; | ||
| import { acceptType, applyExifRotation, dataUrl } from "./fileTools"; | ||
| import * as i0 from "@angular/core"; | ||
| /** A master base set of logic intended to support file select/drag/drop operations | ||
| NOTE: Use ngfDrop for full drag/drop. Use ngfSelect for selecting | ||
| */ | ||
| export class ngf { | ||
| constructor(element) { | ||
| this.element = element; | ||
| this.filters = []; | ||
| this.lastFileCount = 0; | ||
| this.ngfFixOrientation = true; | ||
| this.fileDropDisabled = false; | ||
| this.selectable = false; | ||
| this.directiveInit = new EventEmitter(); | ||
| this.lastInvalids = []; | ||
| this.lastInvalidsChange = new EventEmitter(); | ||
| this.lastBaseUrlChange = new EventEmitter(); | ||
| this.fileChange = new EventEmitter(); | ||
| this.files = []; | ||
| this.filesChange = new EventEmitter(); | ||
| this.fileSelectStart = new EventEmitter(); | ||
| this.initFilters(); | ||
| } | ||
| initFilters() { | ||
| // the order is important | ||
| this.filters.push({ name: 'accept', fn: this._acceptFilter }); | ||
| this.filters.push({ name: 'fileSize', fn: this._fileSizeFilter }); | ||
| //this.filters.push({name: 'fileType', fn: this._fileTypeFilter}) | ||
| //this.filters.push({name: 'queueLimit', fn: this._queueLimitFilter}) | ||
| //this.filters.push({name: 'mimeType', fn: this._mimeTypeFilter}) | ||
| } | ||
| ngOnDestroy() { | ||
| delete this.fileElm; //faster memory release of dom element | ||
| this.destroyPasteListener(); | ||
| } | ||
| ngOnInit() { | ||
| const selectable = (this.selectable || this.selectable === '') && !['false', 'null', '0'].includes(this.selectable); | ||
| if (selectable) { | ||
| this.enableSelecting(); | ||
| } | ||
| if (this.multiple) { | ||
| this.paramFileElm().setAttribute('multiple', this.multiple); | ||
| } | ||
| this.evalCapturePaste(); | ||
| // create reference to this class with one cycle delay to avoid ExpressionChangedAfterItHasBeenCheckedError | ||
| setTimeout(() => { | ||
| this.directiveInit.emit(this); | ||
| }, 0); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.accept) { | ||
| this.paramFileElm().setAttribute('accept', changes.accept.currentValue || '*'); | ||
| } | ||
| if (changes.capturePaste) { | ||
| this.evalCapturePaste(); | ||
| } | ||
| // Did we go from having a file to not having a file? Clear file element then | ||
| if (changes.file && changes.file.previousValue && !changes.file.currentValue) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| // Did we go from having files to not having files? Clear file element then | ||
| if (changes.files) { | ||
| const filesWentToZero = changes.files.previousValue?.length && !changes.files.currentValue?.length; | ||
| if (filesWentToZero) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| } | ||
| } | ||
| evalCapturePaste() { | ||
| const isActive = this.capturePaste || this.capturePaste === '' || ['false', '0', 'null'].includes(this.capturePaste); | ||
| if (isActive) { | ||
| if (this.pasteCapturer) { | ||
| return; // already listening | ||
| } | ||
| this.pasteCapturer = (e) => { | ||
| const clip = e.clipboardData; | ||
| if (clip && clip.files && clip.files.length) { | ||
| this.handleFiles(clip.files); | ||
| e.preventDefault(); | ||
| } | ||
| }; | ||
| window.addEventListener('paste', this.pasteCapturer); | ||
| return; | ||
| } | ||
| this.destroyPasteListener(); | ||
| } | ||
| destroyPasteListener() { | ||
| if (this.pasteCapturer) { | ||
| window.removeEventListener('paste', this.pasteCapturer); | ||
| delete this.pasteCapturer; | ||
| } | ||
| } | ||
| paramFileElm() { | ||
| if (this.fileElm) | ||
| return this.fileElm; // already defined | ||
| // elm already is a file input | ||
| const isFile = isFileInput(this.element.nativeElement); | ||
| if (isFile) { | ||
| return this.fileElm = this.element.nativeElement; | ||
| } | ||
| // the host elm is NOT a file input | ||
| return this.fileElm = this.createFileElm({ | ||
| change: this.changeFn.bind(this) | ||
| }); | ||
| } | ||
| /** Only used when host element we are attached to is NOT a fileElement */ | ||
| createFileElm({ change }) { | ||
| // use specific technique to hide file element within | ||
| const label = createInvisibleFileInputWrap(); | ||
| const fileElm = label.getElementsByTagName('input')[0]; | ||
| fileElm.addEventListener('change', change); | ||
| this.element.nativeElement.appendChild(label); // put on html stage | ||
| return fileElm; | ||
| } | ||
| enableSelecting() { | ||
| let elm = this.element.nativeElement; | ||
| if (isFileInput(elm)) { | ||
| const bindedHandler = event => this.beforeSelect(event); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| return; | ||
| } | ||
| const bindedHandler = ev => this.clickHandler(ev); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| elm.addEventListener('touchend', bindedHandler); | ||
| } | ||
| getValidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (this.isFileValid(files[x])) { | ||
| rtn.push(files[x]); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| getInvalidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| let failReason = this.getFileFilterFailName(files[x]); | ||
| if (failReason) { | ||
| rtn.push({ | ||
| file: files[x], | ||
| type: failReason | ||
| }); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| // Primary handler of files coming in | ||
| handleFiles(files) { | ||
| const valids = this.getValidFiles(files); | ||
| if (files.length != valids.length) { | ||
| this.lastInvalids = this.getInvalidFiles(files); | ||
| } | ||
| else { | ||
| delete this.lastInvalids; | ||
| } | ||
| this.lastInvalidsChange.emit(this.lastInvalids); | ||
| if (valids.length) { | ||
| if (this.ngfFixOrientation) { | ||
| this.applyExifRotations(valids) | ||
| .then(fixedFiles => this.que(fixedFiles)); | ||
| } | ||
| else { | ||
| this.que(valids); | ||
| } | ||
| } | ||
| if (this.isEmptyAfterSelection()) { | ||
| this.element.nativeElement.value = ''; | ||
| } | ||
| } | ||
| que(files) { | ||
| this.files = this.files || []; | ||
| Array.prototype.push.apply(this.files, files); | ||
| //below break memory ref and doesnt act like a que | ||
| //this.files = files//causes memory change which triggers bindings like <ngfFormData [files]="files"></ngfFormData> | ||
| this.filesChange.emit(this.files); | ||
| if (files.length) { | ||
| this.fileChange.emit(this.file = files[0]); | ||
| if (this.lastBaseUrlChange.observers.length) { | ||
| dataUrl(files[0]) | ||
| .then(url => this.lastBaseUrlChange.emit(url)); | ||
| } | ||
| } | ||
| //will be checked for input value clearing | ||
| this.lastFileCount = this.files.length; | ||
| } | ||
| /** called when input has files */ | ||
| changeFn(event) { | ||
| var fileList = event.__files_ || (event.target && event.target.files); | ||
| if (!fileList) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(fileList); | ||
| } | ||
| clickHandler(evt) { | ||
| const elm = this.element.nativeElement; | ||
| if (elm.getAttribute('disabled') || this.fileDropDisabled) { | ||
| return false; | ||
| } | ||
| var r = detectSwipe(evt); | ||
| // prevent the click if it is a swipe | ||
| if (r !== false) | ||
| return r; | ||
| const fileElm = this.paramFileElm(); | ||
| fileElm.click(); | ||
| //fileElm.dispatchEvent( new Event('click') ); | ||
| this.beforeSelect(evt); | ||
| return false; | ||
| } | ||
| beforeSelect(event) { | ||
| this.fileSelectStart.emit(event); | ||
| if (this.files && this.lastFileCount === this.files.length) | ||
| return; | ||
| // if no files in array, be sure browser does not prevent reselect of same file (see github issue 27) | ||
| this.clearFileElmValue(); | ||
| } | ||
| clearFileElmValue() { | ||
| if (!this.fileElm) | ||
| return; | ||
| this.fileElm.value = null; | ||
| } | ||
| isEmptyAfterSelection() { | ||
| return !!this.element.nativeElement.attributes.multiple; | ||
| } | ||
| stopEvent(event) { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| } | ||
| transferHasFiles(transfer) { | ||
| if (!transfer.types) { | ||
| return false; | ||
| } | ||
| if (transfer.types.indexOf) { | ||
| return transfer.types.indexOf('Files') !== -1; | ||
| } | ||
| else if (transfer.types.contains) { | ||
| return transfer.types.contains('Files'); | ||
| } | ||
| else { | ||
| return false; | ||
| } | ||
| } | ||
| eventToFiles(event) { | ||
| const transfer = eventToTransfer(event); | ||
| if (transfer) { | ||
| if (transfer.files && transfer.files.length) { | ||
| return transfer.files; | ||
| } | ||
| if (transfer.items && transfer.items.length) { | ||
| return transfer.items; | ||
| } | ||
| } | ||
| return []; | ||
| } | ||
| applyExifRotations(files) { | ||
| const mapper = (file, index) => { | ||
| return applyExifRotation(file) | ||
| .then(fixedFile => files.splice(index, 1, fixedFile)); | ||
| }; | ||
| const proms = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| proms[x] = mapper(files[x], x); | ||
| } | ||
| return Promise.all(proms).then(() => files); | ||
| } | ||
| onChange(event) { | ||
| let files = this.element.nativeElement.files || this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| getFileFilterFailName(file) { | ||
| for (let i = 0; i < this.filters.length; i++) { | ||
| if (!this.filters[i].fn.call(this, file)) { | ||
| return this.filters[i].name; | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| isFileValid(file) { | ||
| const noFilters = !this.accept && (!this.filters || !this.filters.length); | ||
| if (noFilters) { | ||
| return true; //we have no filters so all files are valid | ||
| } | ||
| return this.getFileFilterFailName(file) ? false : true; | ||
| } | ||
| isFilesValid(files) { | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (!this.isFileValid(files[x])) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| _acceptFilter(item) { | ||
| return acceptType(this.accept, item.type, item.name); | ||
| } | ||
| _fileSizeFilter(item) { | ||
| return !(this.maxSize && item.size > this.maxSize); | ||
| } | ||
| } | ||
| ngf.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngf.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngf, selector: "[ngf]", inputs: { multiple: "multiple", accept: "accept", maxSize: "maxSize", ngfFixOrientation: "ngfFixOrientation", fileDropDisabled: "fileDropDisabled", selectable: "selectable", lastInvalids: "lastInvalids", lastBaseUrl: "lastBaseUrl", file: "file", files: "files", capturePaste: "capturePaste" }, outputs: { directiveInit: "init", lastInvalidsChange: "lastInvalidsChange", lastBaseUrlChange: "lastBaseUrlChange", fileChange: "fileChange", filesChange: "filesChange", fileSelectStart: "fileSelectStart" }, host: { listeners: { "change": "onChange($event)" } }, exportAs: ["ngf"], usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngf]", | ||
| exportAs: "ngf" | ||
| }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { multiple: [{ | ||
| type: Input | ||
| }], accept: [{ | ||
| type: Input | ||
| }], maxSize: [{ | ||
| type: Input | ||
| }], ngfFixOrientation: [{ | ||
| type: Input | ||
| }], fileDropDisabled: [{ | ||
| type: Input | ||
| }], selectable: [{ | ||
| type: Input | ||
| }], directiveInit: [{ | ||
| type: Output, | ||
| args: ['init'] | ||
| }], lastInvalids: [{ | ||
| type: Input | ||
| }], lastInvalidsChange: [{ | ||
| type: Output | ||
| }], lastBaseUrl: [{ | ||
| type: Input | ||
| }], lastBaseUrlChange: [{ | ||
| type: Output | ||
| }], file: [{ | ||
| type: Input | ||
| }], fileChange: [{ | ||
| type: Output | ||
| }], files: [{ | ||
| type: Input | ||
| }], filesChange: [{ | ||
| type: Output | ||
| }], fileSelectStart: [{ | ||
| type: Output | ||
| }], capturePaste: [{ | ||
| type: Input | ||
| }], onChange: [{ | ||
| type: HostListener, | ||
| args: ['change', ['$event']] | ||
| }] } }); | ||
| /** browsers try hard to conceal data about file drags, this tends to undo that */ | ||
| export function filesToWriteableObject(files) { | ||
| const jsonFiles = []; | ||
| for (let x = 0; x < files.length; ++x) { | ||
| jsonFiles.push({ | ||
| type: files[x].type, | ||
| kind: files[x]["kind"] | ||
| }); | ||
| } | ||
| return jsonFiles; | ||
| } | ||
| export function eventToTransfer(event) { | ||
| if (event.dataTransfer) | ||
| return event.dataTransfer; | ||
| return event.originalEvent ? event.originalEvent.dataTransfer : null; | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2YuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFjLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQUNoSCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFBO0FBQ25HLE9BQU8sRUFDTCxVQUFVLEVBQ1YsaUJBQWlCLEVBQUUsT0FBTyxFQUMzQixNQUFNLGFBQWEsQ0FBQTs7QUFPcEI7O0VBRUU7QUFLRixNQUFNLE9BQU8sR0FBRztJQWdDZCxZQUFtQixPQUFrQjtRQUFsQixZQUFPLEdBQVAsT0FBTyxDQUFXO1FBOUJyQyxZQUFPLEdBQStDLEVBQUUsQ0FBQTtRQUN4RCxrQkFBYSxHQUFXLENBQUMsQ0FBQTtRQUtoQixzQkFBaUIsR0FBWSxJQUFJLENBQUE7UUFFakMscUJBQWdCLEdBQVksS0FBSyxDQUFBO1FBQ2pDLGVBQVUsR0FBcUIsS0FBSyxDQUFBO1FBQzdCLGtCQUFhLEdBQXFCLElBQUksWUFBWSxFQUFFLENBQUE7UUFFM0QsaUJBQVksR0FBcUIsRUFBRSxDQUFBO1FBQ2xDLHVCQUFrQixHQUEyQyxJQUFJLFlBQVksRUFBRSxDQUFBO1FBRy9FLHNCQUFpQixHQUF3QixJQUFJLFlBQVksRUFBRSxDQUFBO1FBRzNELGVBQVUsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQUVwRCxVQUFLLEdBQVUsRUFBRSxDQUFBO1FBQ2hCLGdCQUFXLEdBQXdCLElBQUksWUFBWSxFQUFVLENBQUM7UUFFOUQsb0JBQWUsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQU9oRSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDcEIsQ0FBQztJQUVELFdBQVc7UUFDVCx5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SUFBSSxDQUFDO1lBQ2IsSUFBSSxFQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJO1lBQ2xCLElBQUksRUFBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1NBQ3RCLENBQUMsQ0FBQTtLQUNIO0lBQ0QsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQztBQUVELE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBVTtJQUN4QyxJQUFHLEtBQUssQ0FBQyxZQUFZO1FBQUMsT0FBTyxLQUFLLENBQUMsWUFBWSxDQUFBO0lBQy9DLE9BQVEsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtBQUN2RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIEVsZW1lbnRSZWYsIElucHV0LCBPdXRwdXQsIEhvc3RMaXN0ZW5lciwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgY3JlYXRlSW52aXNpYmxlRmlsZUlucHV0V3JhcCwgaXNGaWxlSW5wdXQsIGRldGVjdFN3aXBlIH0gZnJvbSBcIi4vZG9jLWV2ZW50LWhlbHAuZnVuY3Rpb25zXCJcbmltcG9ydCB7XG4gIGFjY2VwdFR5cGUsIEludmFsaWRGaWxlSXRlbSxcbiAgYXBwbHlFeGlmUm90YXRpb24sIGRhdGFVcmxcbn0gZnJvbSBcIi4vZmlsZVRvb2xzXCJcblxuZXhwb3J0IGludGVyZmFjZSBkcmFnTWV0YXtcbiAgdHlwZTpzdHJpbmdcbiAga2luZDpzdHJpbmdcbn1cblxuLyoqIEEgbWFzdGVyIGJhc2Ugc2V0IG9mIGxvZ2ljIGludGVuZGVkIHRvIHN1cHBvcnQgZmlsZSBzZWxlY3QvZHJhZy9kcm9wIG9wZXJhdGlvbnNcbiBOT1RFOiBVc2UgbmdmRHJvcCBmb3IgZnVsbCBkcmFnL2Ryb3AuIFVzZSBuZ2ZTZWxlY3QgZm9yIHNlbGVjdGluZ1xuKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogXCJbbmdmXVwiLFxuICBleHBvcnRBczpcIm5nZlwiXG59KVxuZXhwb3J0IGNsYXNzIG5nZiB7XG4gIGZpbGVFbG06IGFueVxuICBmaWx0ZXJzOiB7bmFtZTogc3RyaW5nLCBmbjogKGZpbGU6RmlsZSk9PmJvb2xlYW59W10gPSBbXVxuICBsYXN0RmlsZUNvdW50OiBudW1iZXIgPSAwXG5cbiAgQElucHV0KCkgbXVsdGlwbGUgITpzdHJpbmdcbiAgQElucHV0KCkgYWNjZXB0ICAgITpzdHJpbmdcbiAgQElucHV0KCkgbWF4U2l6ZSAgITpudW1iZXJcbiAgQElucHV0KCkgbmdmRml4T3JpZW50YXRpb246IGJvb2xlYW4gPSB0cnVlXG5cbiAgQElucHV0KCkgZmlsZURyb3BEaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlXG4gIEBJbnB1dCgpIHNlbGVjdGFibGU6IGJvb2xlYW4gfCBzdHJpbmcgPSBmYWxzZVxuICBAT3V0cHV0KCdpbml0JykgZGlyZWN0aXZlSW5pdDpFdmVudEVtaXR0ZXI8bmdmPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGxhc3RJbnZhbGlkczpJbnZhbGlkRmlsZUl0ZW1bXSA9IFtdXG4gIEBPdXRwdXQoKSBsYXN0SW52YWxpZHNDaGFuZ2U6RXZlbnRFbWl0dGVyPHtmaWxlOkZpbGUsdHlwZTpzdHJpbmd9W10+ID0gbmV3IEV2ZW50RW1pdHRlcigpXG5cbiAgQElucHV0KCkgbGFzdEJhc2VVcmwhOiBzdHJpbmcvL2Jhc2U2NCBsYXN0IGZpbGUgdXBsb2FkZWQgdXJsXG4gIEBPdXRwdXQoKSBsYXN0QmFzZVVybENoYW5nZTpFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGZpbGU/OiBGaWxlLy9sYXN0IGZpbGUgdXBsb2FkZWRcbiAgQE91dHB1dCgpIGZpbGVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxGaWxlPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGZpbGVzOkZpbGVbXSA9IFtdXG4gIEBPdXRwdXQoKSBmaWxlc0NoYW5nZTpFdmVudEVtaXR0ZXI8RmlsZVtdPiA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZVtdPigpO1xuXG4gIEBPdXRwdXQoKSBmaWxlU2VsZWN0U3RhcnQ6RXZlbnRFbWl0dGVyPEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGNhcHR1cmVQYXN0ZTogYm9vbGVhbiAvLyB3aW5kb3cgcGFzdGUgZmlsZSB3YXRjaGluZyAoZW1wdHkgc3RyaW5nIHR1cm5zIG9uKVxuXG4gIHBhc3RlQ2FwdHVyZXIhOiAoZTogRXZlbnQpID0+IHZvaWQgLy8gZ29lcyB3aXRoIGNhcHR1cmVQYXN0ZVxuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBlbGVtZW50OkVsZW1lbnRSZWYpe1xuICAgIHRoaXMuaW5pdEZpbHRlcnMoKVxuICB9XG5cbiAgaW5pdEZpbHRlcnMoKXtcbiAgICAvLyB0aGUgb3JkZXIgaXMgaW1wb3J0YW50XG4gICAgdGhpcy5maWx0ZXJzLnB1c2goe25hbWU6ICdhY2NlcHQnLCBmbjogdGhpcy5fYWNjZXB0RmlsdGVyfSlcbiAgICB0aGlzLmZpbHRlcnMucHVzaCh7bmFtZTogJ2ZpbGVTaXplJywgZm46IHRoaXMuX2ZpbGVTaXplRmlsdGVyfSlcblxuICAgIC8vdGhpcy5maWx0ZXJzLnB1c2goe25hbWU6ICdmaWxlVHlwZScsIGZuOiB0aGlzLl9maWxlVHlwZUZpbHRlcn0pXG4gICAgLy90aGlzLmZpbHRlcnMucHVzaCh7bmFtZTogJ3F1ZXVlTGltaXQnLCBmbjogdGhpcy5fcXVldWVMaW1pdEZpbHRlcn0pXG4gICAgLy90aGlzLmZpbHRlcnMucHVzaCh7bmFtZTogJ21pbWVUeXBlJywgZm46IHRoaXMuX21pbWVUeXBlRmlsdGVyfSlcbiAgfVxuXG4gIG5nT25EZXN0cm95KCl7XG4gICAgZGVsZXRlIHRoaXMuZmlsZUVsbS8vZmFzdGVyIG1lbW9yeSByZWxlYXNlIG9mIGRvbSBlbGVtZW50XG4gICAgdGhpcy5kZXN0cm95UGFzdGVMaXN0ZW5lcigpO1xuICB9XG5cbiAgbmdPbkluaXQoKXtcbiAgICBjb25zdCBzZWxlY3RhYmxlID0gKHRoaXMuc2VsZWN0YWJsZSB8fCB0aGlzLnNlbGVjdGFibGU9PT0nJykgJiYgIVsnZmFsc2UnLCAnbnVsbCcsICcwJ10uaW5jbHVkZXModGhpcy5zZWxlY3RhYmxlIGFzIHN0cmluZyk7XG4gICAgaWYoIHNlbGVjdGFibGUgKXtcbiAgICAgIHRoaXMuZW5hYmxlU2VsZWN0aW5nKClcbiAgICB9XG5cbiAgICBpZiggdGhpcy5tdWx0aXBsZSApe1xuICAgICAgdGhpcy5wYXJhbUZpbGVFbG0oKS5zZXRBdHRyaWJ1dGUoJ211bHRpcGxlJywgdGhpcy5tdWx0aXBsZSlcbiAgICB9XG5cbiAgICB0aGlzLmV2YWxDYXB0dXJlUGFzdGUoKTtcblxuICAgIC8vIGNyZWF0ZSByZWZlcmVuY2UgdG8gdGhpcyBjbGFzcyB3aXRoIG9uZSBjeWNsZSBkZWxheSB0byBhdm9pZCBFeHByZXNzaW9uQ2hhbmdlZEFmdGVySXRIYXNCZWVuQ2hlY2tlZEVycm9yXG4gICAgc2V0VGltZW91dCgoKT0+e1xuICAgICAgdGhpcy5kaXJlY3RpdmVJbml0LmVtaXQodGhpcylcbiAgICB9LCAwKVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoIGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMgKXtcbiAgICBpZiggY2hhbmdlcy5hY2NlcHQgKXtcbiAgICAgIHRoaXMucGFyYW1GaWxlRWxtKCkuc2V0QXR0cmlidXRlKCdhY2NlcHQnLCBjaGFuZ2VzLmFjY2VwdC5jdXJyZW50VmFsdWUgfHwgJyonKVxuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzLmNhcHR1cmVQYXN0ZSkge1xuICAgICAgdGhpcy5ldmFsQ2FwdHVyZVBhc3RlKCk7XG4gICAgfVxuXG4gICAgLy8gRGlkIHdlIGdvIGZyb20gaGF2aW5nIGEgZmlsZSB0byBub3QgaGF2aW5nIGEgZmlsZT8gQ2xlYXIgZmlsZSBlbGVtZW50IHRoZW5cbiAgICBpZiAoY2hhbmdlcy5maWxlICYmIGNoYW5nZXMuZmlsZS5wcmV2aW91c1ZhbHVlICYmICFjaGFuZ2VzLmZpbGUuY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLmNsZWFyRmlsZUVsbVZhbHVlKClcbiAgICB9XG5cbiAgICAvLyBEaWQgd2UgZ28gZnJvbSBoYXZpbmcgZmlsZXMgdG8gbm90IGhhdmluZyBmaWxlcz8gQ2xlYXIgZmlsZSBlbGVtZW50IHRoZW5cbiAgICBpZiAoY2hhbmdlcy5maWxlcykge1xuICAgICAgY29uc3QgZmlsZXNXZW50VG9aZXJvID0gY2hhbmdlcy5maWxlcy5wcmV2aW91c1ZhbHVlPy5sZW5ndGggJiYgIWNoYW5nZXMuZmlsZXMuY3VycmVudFZhbHVlPy5sZW5ndGhcblxuICAgICAgaWYgKGZpbGVzV2VudFRvWmVybykge1xuICAgICAgICB0aGlzLmNsZWFyRmlsZUVsbVZhbHVlKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBldmFsQ2FwdHVyZVBhc3RlKCkge1xuICAgIGNvbnN0IGlzQWN0aXZlID0gdGhpcy5jYXB0dXJlUGFzdGUgfHwgKHRoaXMuY2FwdHVyZVBhc3RlIGFzIGFueSk9PT0nJyB8fCBbJ2ZhbHNlJywgJzAnLCAnbnVsbCddLmluY2x1ZGVzKHRoaXMuY2FwdHVyZVBhc3RlIGFzIGFueSk7XG5cbiAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgIGlmICh0aGlzLnBhc3RlQ2FwdHVyZXIpIHtcbiAgICAgICAgcmV0dXJuOyAvLyBhbHJlYWR5IGxpc3RlbmluZ1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBhc3RlQ2FwdHVyZXIgPSAoZTogRXZlbnQpID0+IHtcbiAgICAgICAgY29uc3QgY2xpcCA9IChlIGFzIGFueSkuY2xpcGJvYXJkRGF0YTtcbiAgICAgICAgaWYgKGNsaXAgJiYgY2xpcC5maWxlcyAmJiBjbGlwLmZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuaGFuZGxlRmlsZXMoY2xpcC5maWxlcyk7XG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwYXN0ZScsIHRoaXMucGFzdGVDYXB0dXJlcik7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmRlc3Ryb3lQYXN0ZUxpc3RlbmVyKCk7XG4gIH1cblxuICBkZXN0cm95UGFzdGVMaXN0ZW5lcigpIHtcbiAgICBpZiAodGhpcy5wYXN0ZUNhcHR1cmVyKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncGFzdGUnLCB0aGlzLnBhc3RlQ2FwdHVyZXIpO1xuICAgICAgZGVsZXRlIHRoaXMucGFzdGVDYXB0dXJlcjtcbiAgICB9XG4gIH1cblxuICBwYXJhbUZpbGVFbG0oKXtcbiAgICBpZiggdGhpcy5maWxlRWxtIClyZXR1cm4gdGhpcy5maWxlRWxtIC8vIGFscmVhZHkgZGVmaW5lZFxuXG4gICAgLy8gZWxtIGFscmVhZHkgaXMgYSBmaWxlIGlucHV0XG4gICAgY29uc3QgaXNGaWxlID0gaXNGaWxlSW5wdXQoIHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50IClcbiAgICBpZihpc0ZpbGUpe1xuICAgICAgcmV0dXJuIHRoaXMuZmlsZUVsbSA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50XG4gICAgfVxuXG4gICAgLy8gdGhlIGhvc3QgZWxtIGlzIE5PVCBhIGZpbGUgaW5wdXRcbiAgICByZXR1cm4gdGhpcy5maWxlRWxtID0gdGhpcy5jcmVhdGVGaWxlRWxtKHtcbiAgICAgIGNoYW5nZTogdGhpcy5jaGFuZ2VGbi5iaW5kKHRoaXMpXG4gICAgfSlcbiAgfVxuXG4gIC8qKiBPbmx5IHVzZWQgd2hlbiBob3N0IGVsZW1lbnQgd2UgYXJlIGF0dGFjaGVkIHRvIGlzIE5PVCBhIGZpbGVFbGVtZW50ICovXG4gIGNyZWF0ZUZpbGVFbG0oe2NoYW5nZX06IHtjaGFuZ2U6KCkgPT4gYW55fSkge1xuICAgIC8vIHVzZSBzcGVjaWZpYyB0ZWNobmlxdWUgdG8gaGlkZSBmaWxlIGVsZW1lbnQgd2l0aGluXG4gICAgY29uc3QgbGFiZWwgPSBjcmVhdGVJbnZpc2libGVGaWxlSW5wdXRXcmFwKClcbiAgICBjb25zdCBmaWxlRWxtID0gbGFiZWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0JylbMF1cblxuICAgIGZpbGVFbG0uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgY2hhbmdlKTtcbiAgICB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZCggbGFiZWwgKSAvLyBwdXQgb24gaHRtbCBzdGFnZVxuXG4gICAgcmV0dXJuIGZpbGVFbG1cbiAgfVxuXG4gIGVuYWJsZVNlbGVjdGluZygpe1xuICAgIGxldCBlbG0gPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudFxuXG4gICAgaWYoIGlzRmlsZUlucHV0KGVsbSkgKXtcbiAgICAgIGNvbnN0IGJpbmRlZEhhbmRsZXIgPSBldmVudCA9PiB0aGlzLmJlZm9yZVNlbGVjdChldmVudClcbiAgICAgIGVsbS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGJpbmRlZEhhbmRsZXIpXG4gICAgICBlbG0uYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGJpbmRlZEhhbmRsZXIpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBiaW5kZWRIYW5kbGVyID0gZXYgPT4gdGhpcy5jbGlja0hhbmRsZXIoZXYpXG4gICAgZWxtLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYmluZGVkSGFuZGxlcilcbiAgICBlbG0uYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGJpbmRlZEhhbmRsZXIpXG4gICAgZWxtLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgYmluZGVkSGFuZGxlcilcbiAgfVxuXG4gIGdldFZhbGlkRmlsZXMoIGZpbGVzOkZpbGVbXSApOkZpbGVbXXtcbiAgICBjb25zdCBydG46RmlsZVtdID0gW11cbiAgICBmb3IobGV0IHg9ZmlsZXMubGVuZ3RoLTE7IHggPj0gMDsgLS14KXtcbiAgICAgIGlmKCB0aGlzLmlzRmlsZVZhbGlkKGZpbGVzW3hdKSApe1xuICAgICAgICBydG4ucHVzaCggZmlsZXNbeF0gKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcnRuXG4gIH1cblxuICBnZXRJbnZhbGlkRmlsZXMoZmlsZXM6RmlsZVtdKTpJbnZhbGlkRmlsZUl0ZW1bXXtcbiAgICBjb25zdCBydG46SW52YWxpZEZpbGVJdGVtW10gPSBbXVxuICAgIGZvcihsZXQgeD1maWxlcy5sZW5ndGgtMTsgeCA+PSAwOyAtLXgpe1xuICAgICAgbGV0IGZhaWxSZWFzb24gPSB0aGlzLmdldEZpbGVGaWx0ZXJGYWlsTmFtZShmaWxlc1t4XSlcbiAgICAgIGlmKCBmYWlsUmVhc29uICl7XG4gICAgICAgIHJ0bi5wdXNoKHtcbiAgICAgICAgICBmaWxlIDogZmlsZXNbeF0sXG4gICAgICAgICAgdHlwZSA6IGZhaWxSZWFzb25cbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJ0blxuICB9XG5cbiAgLy8gUHJpbWFyeSBoYW5kbGVyIG9mIGZpbGVzIGNvbWluZyBpblxuICBoYW5kbGVGaWxlcyhmaWxlczpGaWxlW10pe1xuICAgIGNvbnN0IHZhbGlkcyA9IHRoaXMuZ2V0VmFsaWRGaWxlcyhmaWxlcylcblxuICAgIGlmKGZpbGVzLmxlbmd0aCE9dmFsaWRzLmxlbmd0aCl7XG4gICAgICB0aGlzLmxhc3RJbnZhbGlkcyA9IHRoaXMuZ2V0SW52YWxpZEZpbGVzKGZpbGVzKVxuICAgIH1lbHNle1xuICAgICAgZGVsZXRlIHRoaXMubGFzdEludmFsaWRzXG4gICAgfVxuXG4gICAgdGhpcy5sYXN0SW52YWxpZHNDaGFuZ2UuZW1pdCh0aGlzLmxhc3RJbnZhbGlkcylcblxuICAgIGlmKCB2YWxpZHMubGVuZ3RoICl7XG4gICAgICBpZiggdGhpcy5uZ2ZGaXhPcmllbnRhdGlvbiApe1xuICAgICAgICB0aGlzLmFwcGx5RXhpZlJvdGF0aW9ucyh2YWxpZHMpXG4gICAgICAgIC50aGVuKCBmaXhlZEZpbGVzPT50aGlzLnF1ZShmaXhlZEZpbGVzKSApXG4gICAgICB9ZWxzZXtcbiAgICAgICAgdGhpcy5xdWUodmFsaWRzKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmlzRW1wdHlBZnRlclNlbGVjdGlvbigpKSB7XG4gICAgICB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnXG4gICAgfVxuICB9XG5cbiAgcXVlKCBmaWxlczpGaWxlW10gKXtcbiAgICB0aGlzLmZpbGVzID0gdGhpcy5maWxlcyB8fCBbXVxuICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRoaXMuZmlsZXMsIGZpbGVzKVxuXG4gICAgLy9iZWxvdyBicmVhayBtZW1vcnkgcmVmIGFuZCBkb2VzbnQgYWN0IGxpa2UgYSBxdWVcbiAgICAvL3RoaXMuZmlsZXMgPSBmaWxlcy8vY2F1c2VzIG1lbW9yeSBjaGFuZ2Ugd2hpY2ggdHJpZ2dlcnMgYmluZGluZ3MgbGlrZSA8bmdmRm9ybURhdGEgW2ZpbGVzXT1cImZpbGVzXCI+PC9uZ2ZGb3JtRGF0YT5cblxuICAgIHRoaXMuZmlsZXNDaGFuZ2UuZW1pdCggdGhpcy5maWxlcyApXG5cbiAgICBpZihmaWxlcy5sZW5ndGgpe1xuICAgICAgdGhpcy5maWxlQ2hhbmdlLmVtaXQoIHRoaXMuZmlsZT1maWxlc1swXSApXG5cbiAgICAgIGlmKHRoaXMubGFzdEJhc2VVcmxDaGFuZ2Uub2JzZXJ2ZXJzLmxlbmd0aCl7XG4gICAgICAgIGRhdGFVcmwoIGZpbGVzWzBdIClcbiAgICAgICAgLnRoZW4oIHVybD0+dGhpcy5sYXN0QmFzZVVybENoYW5nZS5lbWl0KHVybCkgKVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vd2lsbCBiZSBjaGVja2VkIGZvciBpbnB1dCB2YWx1ZSBjbGVhcmluZ1xuICAgIHRoaXMubGFzdEZpbGVDb3VudCA9IHRoaXMuZmlsZXMubGVuZ3RoXG4gIH1cblxuICAvKiogY2FsbGVkIHdoZW4gaW5wdXQgaGFzIGZpbGVzICovXG4gIGNoYW5nZUZuKGV2ZW50OmFueSkge1xuICAgIHZhciBmaWxlTGlzdCA9IGV2ZW50Ll9fZmlsZXNfIHx8IChldmVudC50YXJnZXQgJiYgZXZlbnQudGFyZ2V0LmZpbGVzKVxuXG4gICAgaWYgKCFmaWxlTGlzdCkgcmV0dXJuO1xuXG4gICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgIHRoaXMuaGFuZGxlRmlsZXMoZmlsZUxpc3QpXG4gIH1cblxuICBjbGlja0hhbmRsZXIoZXZ0OiBFdmVudCl7XG4gICAgY29uc3QgZWxtID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnRcbiAgICBpZiAoZWxtLmdldEF0dHJpYnV0ZSgnZGlzYWJsZWQnKSB8fCB0aGlzLmZpbGVEcm9wRGlzYWJsZWQpe1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciByID0gZGV0ZWN0U3dpcGUoZXZ0KTtcbiAgICAvLyBwcmV2ZW50IHRoZSBjbGljayBpZiBpdCBpcyBhIHN3aXBlXG4gICAgaWYgKCByIT09ZmFsc2UgKSByZXR1cm4gcjtcblxuICAgIGNvbnN0IGZpbGVFbG0gPSB0aGlzLnBhcmFtRmlsZUVsbSgpXG4gICAgZmlsZUVsbS5jbGljaygpXG4gICAgLy9maWxlRWxtLmRpc3BhdGNoRXZlbnQoIG5ldyBFdmVudCgnY2xpY2snKSApO1xuICAgIHRoaXMuYmVmb3JlU2VsZWN0KGV2dClcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGJlZm9yZVNlbGVjdChldmVudDogRXZlbnQpe1xuICAgIHRoaXMuZmlsZVNlbGVjdFN0YXJ0LmVtaXQoZXZlbnQpXG5cbiAgICBpZiggdGhpcy5maWxlcyAmJiB0aGlzLmxhc3RGaWxlQ291bnQ9PT10aGlzLmZpbGVzLmxlbmd0aCApcmV0dXJuXG5cbiAgICAvLyBpZiBubyBmaWxlcyBpbiBhcnJheSwgYmUgc3VyZSBicm93c2VyIGRvZXMgbm90IHByZXZlbnQgcmVzZWxlY3Qgb2Ygc2FtZSBmaWxlIChzZWUgZ2l0aHViIGlzc3VlIDI3KVxuICAgIHRoaXMuY2xlYXJGaWxlRWxtVmFsdWUoKVxuICB9XG5cbiAgY2xlYXJGaWxlRWxtVmFsdWUoKSB7XG4gICAgaWYgKCF0aGlzLmZpbGVFbG0pIHJldHVyblxuXG4gICAgdGhpcy5maWxlRWxtLnZhbHVlID0gbnVsbFxuICB9XG5cbiAgaXNFbXB0eUFmdGVyU2VsZWN0aW9uKCk6Ym9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuYXR0cmlidXRlcy5tdWx0aXBsZTtcbiAgfVxuXG4gIHN0b3BFdmVudChldmVudDphbnkpOmFueSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHRyYW5zZmVySGFzRmlsZXModHJhbnNmZXI6YW55KTphbnkge1xuICAgIGlmICghdHJhbnNmZXIudHlwZXMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodHJhbnNmZXIudHlwZXMuaW5kZXhPZikge1xuICAgICAgcmV0dXJuIHRyYW5zZmVyLnR5cGVzLmluZGV4T2YoJ0ZpbGVzJykgIT09IC0xO1xuICAgIH0gZWxzZSBpZiAodHJhbnNmZXIudHlwZXMuY29udGFpbnMpIHtcbiAgICAgIHJldHVybiB0cmFuc2Zlci50eXBlcy5jb250YWlucygnRmlsZXMnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGV2ZW50VG9GaWxlcyhldmVudDpFdmVudCl7XG4gICAgY29uc3QgdHJhbnNmZXIgPSBldmVudFRvVHJhbnNmZXIoZXZlbnQpO1xuICAgIGlmKCB0cmFuc2ZlciApe1xuICAgICAgaWYodHJhbnNmZXIuZmlsZXMgJiYgdHJhbnNmZXIuZmlsZXMubGVuZ3RoKXtcbiAgICAgICAgcmV0dXJuIHRyYW5zZmVyLmZpbGVzXG4gICAgICB9XG4gICAgICBpZih0cmFuc2Zlci5pdGVtcyAmJiB0cmFuc2Zlci5pdGVtcy5sZW5ndGgpe1xuICAgICAgICByZXR1cm4gdHJhbnNmZXIuaXRlbXNcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFtdXG4gIH1cblxuICBhcHBseUV4aWZSb3RhdGlvbnMoXG4gICAgZmlsZXM6RmlsZVtdXG4gICk6UHJvbWlzZTxGaWxlW10+e1xuICAgIGNvbnN0IG1hcHBlciA9IChcbiAgICAgIGZpbGU6RmlsZSxpbmRleDpudW1iZXJcbiAgICApOlByb21pc2U8YW55Pj0+e1xuICAgICAgcmV0dXJuIGFwcGx5RXhpZlJvdGF0aW9uKGZpbGUpXG4gICAgICAudGhlbiggZml4ZWRGaWxlPT5maWxlcy5zcGxpY2UoaW5kZXgsIDEsIGZpeGVkRmlsZSkgKVxuICAgIH1cblxuICAgIGNvbnN0IHByb21zOlByb21pc2U8YW55PltdID0gW11cbiAgICBmb3IobGV0IHg9ZmlsZXMubGVuZ3RoLTE7IHggPj0gMDsgLS14KXtcbiAgICAgIHByb21zW3hdID0gbWFwcGVyKCBmaWxlc1t4XSwgeCApXG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLmFsbCggcHJvbXMgKS50aGVuKCAoKT0+ZmlsZXMgKVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignY2hhbmdlJywgWyckZXZlbnQnXSlcbiAgb25DaGFuZ2UoZXZlbnQ6RXZlbnQpOnZvaWQge1xuICAgIGxldCBmaWxlcyA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmZpbGVzIHx8IHRoaXMuZXZlbnRUb0ZpbGVzKGV2ZW50KVxuXG4gICAgaWYoIWZpbGVzLmxlbmd0aClyZXR1cm5cblxuICAgIHRoaXMuc3RvcEV2ZW50KGV2ZW50KTtcbiAgICB0aGlzLmhhbmRsZUZpbGVzKGZpbGVzKVxuICB9XG5cbiAgZ2V0RmlsZUZpbHRlckZhaWxOYW1lKFxuICAgIGZpbGU6RmlsZVxuICApOnN0cmluZyB8IHVuZGVmaW5lZHtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5maWx0ZXJzLmxlbmd0aDsgaSsrKXtcbiAgICAgIGlmKCAhdGhpcy5maWx0ZXJzW2ldLmZuLmNhbGwodGhpcywgZmlsZSkgKXtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyc1tpXS5uYW1lXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIGlzRmlsZVZhbGlkKGZpbGU6RmlsZSk6Ym9vbGVhbntcbiAgICBjb25zdCBub0ZpbHRlcnMgPSAhdGhpcy5hY2NlcHQgJiYgKCF0aGlzLmZpbHRlcnMgfHwgIXRoaXMuZmlsdGVycy5sZW5ndGgpXG4gICAgaWYoIG5vRmlsdGVycyApe1xuICAgICAgcmV0dXJuIHRydWUvL3dlIGhhdmUgbm8gZmlsdGVycyBzbyBhbGwgZmlsZXMgYXJlIHZhbGlkXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ2V0RmlsZUZpbHRlckZhaWxOYW1lKGZpbGUpID8gZmFsc2UgOiB0cnVlXG4gIH1cblxuICBpc0ZpbGVzVmFsaWQoZmlsZXM6RmlsZVtdKXtcbiAgICBmb3IobGV0IHg9ZmlsZXMubGVuZ3RoLTE7IHggPj0gMDsgLS14KXtcbiAgICAgIGlmKCAhdGhpcy5pc0ZpbGVWYWxpZChmaWxlc1t4XSkgKXtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBwcm90ZWN0ZWQgX2FjY2VwdEZpbHRlcihpdGVtOkZpbGUpOmJvb2xlYW4ge1xuICAgIHJldHVybiBhY2NlcHRUeXBlKHRoaXMuYWNjZXB0LCBpdGVtLnR5cGUsIGl0ZW0ubmFtZSlcbiAgfVxuXG4gIHByb3RlY3RlZCBfZmlsZVNpemVGaWx0ZXIoaXRlbTpGaWxlKTpib29sZWFuIHtcbiAgICByZXR1cm4gISh0aGlzLm1heFNpemUgJiYgaXRlbS5zaXplID4gdGhpcy5tYXhTaXplKTtcbiAgfVxufVxuXG5cbi8qKiBicm93c2VycyB0cnkgaGFyZCB0byBjb25jZWFsIGRhdGEgYWJvdXQgZmlsZSBkcmFncywgdGhpcyB0ZW5kcyB0byB1bmRvIHRoYXQgKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWxlc1RvV3JpdGVhYmxlT2JqZWN0KCBmaWxlczpGaWxlW10gKTpkcmFnTWV0YVtde1xuICBjb25zdCBqc29uRmlsZXM6ZHJhZ01ldGFbXSA9IFtdXG4gIGZvcihsZXQgeD0wOyB4IDwgZmlsZXMubGVuZ3RoOyArK3gpe1xuICAgIGpzb25GaWxlcy5wdXNoKHtcbiAgICAgIHR5cGU6ZmlsZXNbeF0udHlwZSxcbiAgICAgIGtpbmQ6ZmlsZXNbeF1bXCJraW5kXCJdXG4gICAgfSlcbiAgfVxuICByZXR1cm4ganNvbkZpbGVzXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldmVudFRvVHJhbnNmZXIoZXZlbnQ6IGFueSk6IFRyYW5zZmVyT2JqZWN0IHtcbiAgaWYoZXZlbnQuZGF0YVRyYW5zZmVyKXJldHVybiBldmVudC5kYXRhVHJhbnNmZXJcbiAgcmV0dXJuICBldmVudC5vcmlnaW5hbEV2ZW50ID8gZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXIgOiBudWxsXG59XG5cblxuaW50ZXJmYWNlIFRyYW5zZmVyT2JqZWN0IHtcbiAgaXRlbXM/OiBhbnlbXVxuICBmaWxlcz86IGFueVtdXG4gIGRyb3BFZmZlY3Q/OiAnY29weScgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0RhdGFUcmFuc2Zlci9kcm9wRWZmZWN0XG59XG4iXX0= |
| import { CommonModule } from '@angular/common'; | ||
| import { NgModule } from '@angular/core'; | ||
| import { ngfBackground } from './ngfBackground.directive'; | ||
| import { ngfDrop } from './ngfDrop.directive'; | ||
| import { ngf } from './ngf.directive'; | ||
| import { ngfSelect } from './ngfSelect.directive'; | ||
| import { ngfUploadStatus } from './ngfUploadStatus.directive'; | ||
| import { ngfFormData } from './ngfFormData.directive'; | ||
| import { ngfSrc } from './ngfSrc.directive'; | ||
| import * as i0 from "@angular/core"; | ||
| //import{ HttpModule } from '@angular/http'; | ||
| const declarations = [ | ||
| ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf | ||
| ]; | ||
| export class ngfModule { | ||
| } | ||
| ngfModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); | ||
| ngfModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, declarations: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf], imports: [CommonModule | ||
| //,HttpModule | ||
| ], exports: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf] }); | ||
| ngfModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, imports: [[ | ||
| CommonModule | ||
| //,HttpModule | ||
| ]] }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, decorators: [{ | ||
| type: NgModule, | ||
| args: [{ | ||
| imports: [ | ||
| CommonModule | ||
| //,HttpModule | ||
| ], | ||
| declarations: declarations, | ||
| exports: declarations //[HttpModule, ...declarations] | ||
| }] | ||
| }] }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2YubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXpDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7QUFDNUMsNENBQTRDO0FBRTVDLE1BQU0sWUFBWSxHQUFHO0lBQ25CLE9BQU87SUFDUCxTQUFTO0lBQ1QsYUFBYTtJQUNiLE1BQU07SUFDTixlQUFlO0lBQ2YsV0FBVztJQUNYLEdBQUc7Q0FDSixDQUFBO0FBU0UsTUFBTSxPQUFPLFNBQVM7O3VHQUFULFNBQVM7d0dBQVQsU0FBUyxpQkFoQnZCLE9BQU87UUFDUCxTQUFTO1FBQ1QsYUFBYTtRQUNiLE1BQU07UUFDTixlQUFlO1FBQ2YsV0FBVztRQUNYLEdBQUcsYUFLRCxZQUFZO1FBQ1osYUFBYTtpQkFaZixPQUFPO1FBQ1AsU0FBUztRQUNULGFBQWE7UUFDYixNQUFNO1FBQ04sZUFBZTtRQUNmLFdBQVc7UUFDWCxHQUFHO3dHQVVXLFNBQVMsWUFOZDtZQUNQLFlBQVk7WUFDWixhQUFhO1NBQ2Q7NEZBR2EsU0FBUztrQkFQeEIsUUFBUTttQkFBQztvQkFDUixPQUFPLEVBQUU7d0JBQ1AsWUFBWTt3QkFDWixhQUFhO3FCQUNkO29CQUNELFlBQVksRUFBRSxZQUFZO29CQUMxQixPQUFPLEVBQUUsWUFBWSxDQUFBLCtCQUErQjtpQkFDckQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgbmdmQmFja2dyb3VuZCB9IGZyb20gJy4vbmdmQmFja2dyb3VuZC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgbmdmRHJvcCB9IGZyb20gJy4vbmdmRHJvcC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgbmdmIH0gZnJvbSAnLi9uZ2YuZGlyZWN0aXZlJztcbmltcG9ydCB7IG5nZlNlbGVjdCB9IGZyb20gJy4vbmdmU2VsZWN0LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBuZ2ZVcGxvYWRTdGF0dXMgfSBmcm9tICcuL25nZlVwbG9hZFN0YXR1cy5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgbmdmRm9ybURhdGEgfSBmcm9tICcuL25nZkZvcm1EYXRhLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBuZ2ZTcmMgfSBmcm9tICcuL25nZlNyYy5kaXJlY3RpdmUnO1xuLy9pbXBvcnR7IEh0dHBNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9odHRwJztcblxuY29uc3QgZGVjbGFyYXRpb25zID0gW1xuICBuZ2ZEcm9wLFxuICBuZ2ZTZWxlY3QsXG4gIG5nZkJhY2tncm91bmQsXG4gIG5nZlNyYyxcbiAgbmdmVXBsb2FkU3RhdHVzLFxuICBuZ2ZGb3JtRGF0YSxcbiAgbmdmXG5dXG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGVcbiAgICAvLyxIdHRwTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogZGVjbGFyYXRpb25zLFxuICBleHBvcnRzOiBkZWNsYXJhdGlvbnMvL1tIdHRwTW9kdWxlLCAuLi5kZWNsYXJhdGlvbnNdXG59KSBleHBvcnQgY2xhc3MgbmdmTW9kdWxlIHt9Il19 |
| import { Directive, Input } from '@angular/core'; | ||
| import { dataUrl } from './fileTools'; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfBackground { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => { | ||
| const urlString = 'url(\'' + (src || '') + '\')'; | ||
| this.ElementRef.nativeElement.style.backgroundImage = urlString; | ||
| }); | ||
| } | ||
| } | ||
| ngfBackground.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfBackground.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfBackground, selector: "[ngfBackground]", inputs: { file: ["ngfBackground", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfBackground]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfBackground'] | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmQmFja2dyb3VuZC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZmlsZS11cGxvYWQvbmdmQmFja2dyb3VuZC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGFBQWEsQ0FBQzs7QUFHdEMsTUFBTSxPQUFPLGFBQWE7SUFHeEIsWUFBbUIsVUFBcUI7UUFBckIsZUFBVSxHQUFWLFVBQVUsQ0FBVztJQUFFLENBQUM7SUFFM0MsV0FBVyxDQUFFLFFBQVk7UUFDdkIsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDakIsSUFBSSxDQUFDLEdBQUcsQ0FBQSxFQUFFO1lBQ1QsTUFBTSxTQUFTLEdBQUcsUUFBUSxHQUFHLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQTtZQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLFNBQVMsQ0FBQTtRQUNqRSxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7OzJHQVhVLGFBQWE7K0ZBQWIsYUFBYTs0RkFBYixhQUFhO2tCQUR6QixTQUFTO21CQUFDLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDO2lHQUVkLElBQUk7c0JBQTNCLEtBQUs7dUJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGRhdGFVcmwgfSBmcm9tICcuL2ZpbGVUb29scyc7XG5cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnW25nZkJhY2tncm91bmRdJ30pXG5leHBvcnQgY2xhc3MgbmdmQmFja2dyb3VuZCB7XG4gIEBJbnB1dCgnbmdmQmFja2dyb3VuZCcpIGZpbGU6YW55XG5cbiAgY29uc3RydWN0b3IocHVibGljIEVsZW1lbnRSZWY6RWxlbWVudFJlZil7fVxuXG4gIG5nT25DaGFuZ2VzKCBfY2hhbmdlczphbnkgKXtcbiAgICBkYXRhVXJsKHRoaXMuZmlsZSlcbiAgICAudGhlbihzcmM9PntcbiAgICAgIGNvbnN0IHVybFN0cmluZyA9ICd1cmwoXFwnJyArIChzcmMgfHwgJycpICsgJ1xcJyknXG4gICAgICB0aGlzLkVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSB1cmxTdHJpbmdcbiAgICB9KVxuICB9XG59XG4iXX0= |
| import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core'; | ||
| import { ngf, eventToTransfer, filesToWriteableObject } from "./ngf.directive"; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfDrop extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.fileOver = new EventEmitter(); | ||
| this.validDrag = false; | ||
| this.validDragChange = new EventEmitter(); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange = new EventEmitter(); | ||
| this.dragFilesChange = new EventEmitter(); | ||
| } | ||
| onDrop(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| let files = this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| handleFiles(files) { | ||
| this.fileOver.emit(false); //turn-off dragover | ||
| super.handleFiles(files); | ||
| } | ||
| onDragOver(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| const transfer = eventToTransfer(event); | ||
| let files = this.eventToFiles(event); | ||
| let jsonFiles = filesToWriteableObject(files); | ||
| this.dragFilesChange.emit(this.dragFiles = jsonFiles); | ||
| if (files.length) { | ||
| this.validDrag = this.isFilesValid(files); | ||
| } | ||
| else { | ||
| //Safari, IE11 & some browsers do NOT tell you about dragged files until dropped. Always consider a valid drag | ||
| this.validDrag = true; | ||
| } | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = !this.validDrag; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| transfer.dropEffect = 'copy'; // change cursor and visual display | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(true); | ||
| } | ||
| closeDrags() { | ||
| delete this.validDrag; | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| delete this.dragFiles; | ||
| this.dragFilesChange.emit(this.dragFiles); | ||
| } | ||
| onDragLeave(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| if (this.element) { | ||
| if (event.currentTarget === this.element[0]) { | ||
| return; | ||
| } | ||
| } | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(false); | ||
| } | ||
| } | ||
| ngfDrop.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfDrop.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfDrop, selector: "[ngfDrop]", inputs: { validDrag: "validDrag", invalidDrag: "invalidDrag", dragFiles: "dragFiles" }, outputs: { fileOver: "fileOver", validDragChange: "validDragChange", invalidDragChange: "invalidDragChange", dragFilesChange: "dragFilesChange" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)" } }, exportAs: ["ngfDrop"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfDrop]", | ||
| exportAs: "ngfDrop" | ||
| }] | ||
| }], propDecorators: { fileOver: [{ | ||
| type: Output | ||
| }], validDrag: [{ | ||
| type: Input | ||
| }], validDragChange: [{ | ||
| type: Output | ||
| }], invalidDrag: [{ | ||
| type: Input | ||
| }], invalidDragChange: [{ | ||
| type: Output | ||
| }], dragFiles: [{ | ||
| type: Input | ||
| }], dragFilesChange: [{ | ||
| type: Output | ||
| }], onDrop: [{ | ||
| type: HostListener, | ||
| args: ['drop', ['$event']] | ||
| }], onDragOver: [{ | ||
| type: HostListener, | ||
| args: ['dragover', ['$event']] | ||
| }], onDragLeave: [{ | ||
| type: HostListener, | ||
| args: ['dragleave', ['$event']] | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmRHJvcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZmlsZS11cGxvYWQvbmdmRHJvcC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFBRSxZQUFZLEVBQ3ZCLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUM1QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsR0FBRyxFQUFZLGVBQWUsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlCQUFpQixDQUFBOztBQU14RixNQUFNLE9BQU8sT0FBUSxTQUFRLEdBQUc7SUFKaEM7O1FBS1ksYUFBUSxHQUFxQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBRWpELGNBQVMsR0FBVyxLQUFLLENBQUE7UUFDeEIsb0JBQWUsR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQUUzRCxnQkFBVyxHQUFHLEtBQUssQ0FBQTtRQUNsQixzQkFBaUIsR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQUc1RCxvQkFBZSxHQUE0QixJQUFJLFlBQVksRUFBRSxDQUFBO0tBaUZ4RTtJQTlFQyxNQUFNLENBQUMsS0FBVztRQUNoQixJQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBQztZQUN2QixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RCLE9BQU07U0FDUDtRQUVELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUNqQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRXBDLElBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTTtZQUFDLE9BQU07UUFFdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3pCLENBQUM7SUFFRCxXQUFXLENBQUMsS0FBWTtRQUN0QixJQUFJ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O2dCQUVFLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0ksZUFBZTtzQkFBeEIsTUFBTTtnQkFHUCxNQUFNO3NCQURMLFlBQVk7dUJBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQXNCaEMsVUFBVTtzQkFEVCxZQUFZO3VCQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkF5Q3BDLFdBQVc7c0JBRFYsWUFBWTt1QkFBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBEaXJlY3RpdmUsIEV2ZW50RW1pdHRlcixcbiAgSG9zdExpc3RlbmVyLCBJbnB1dCwgT3V0cHV0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgbmdmLCBkcmFnTWV0YSwgZXZlbnRUb1RyYW5zZmVyLCBmaWxlc1RvV3JpdGVhYmxlT2JqZWN0IH0gZnJvbSBcIi4vbmdmLmRpcmVjdGl2ZVwiXG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogXCJbbmdmRHJvcF1cIixcbiAgZXhwb3J0QXM6IFwibmdmRHJvcFwiXG59KVxuZXhwb3J0IGNsYXNzIG5nZkRyb3AgZXh0ZW5kcyBuZ2Yge1xuICBAT3V0cHV0KCkgZmlsZU92ZXI6RXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgQElucHV0KCkgdmFsaWREcmFnOmJvb2xlYW4gPSBmYWxzZVxuICBAT3V0cHV0KCkgdmFsaWREcmFnQ2hhbmdlOkV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGludmFsaWREcmFnID0gZmFsc2VcbiAgQE91dHB1dCgpIGludmFsaWREcmFnQ2hhbmdlOkV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGRyYWdGaWxlcyAhOiBkcmFnTWV0YVtdXG4gIEBPdXRwdXQoKSBkcmFnRmlsZXNDaGFuZ2U6RXZlbnRFbWl0dGVyPGRyYWdNZXRhW10+ID0gbmV3IEV2ZW50RW1pdHRlcigpXG5cbiAgQEhvc3RMaXN0ZW5lcignZHJvcCcsIFsnJGV2ZW50J10pXG4gIG9uRHJvcChldmVudDpFdmVudCk6dm9pZCB7XG4gICAgaWYodGhpcy5maWxlRHJvcERpc2FibGVkKXtcbiAgICAgIHRoaXMuc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuY2xvc2VEcmFncygpXG4gICAgbGV0IGZpbGVzID0gdGhpcy5ldmVudFRvRmlsZXMoZXZlbnQpXG5cbiAgICBpZighZmlsZXMubGVuZ3RoKXJldHVyblxuXG4gICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgIHRoaXMuaGFuZGxlRmlsZXMoZmlsZXMpXG4gIH1cblxuICBoYW5kbGVGaWxlcyhmaWxlczpGaWxlW10pe1xuICAgIHRoaXMuZmlsZU92ZXIuZW1pdChmYWxzZSkvL3R1cm4tb2ZmIGRyYWdvdmVyXG4gICAgc3VwZXIuaGFuZGxlRmlsZXMoZmlsZXMpXG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkcmFnb3ZlcicsIFsnJGV2ZW50J10pXG4gIG9uRHJhZ092ZXIoZXZlbnQ6RXZlbnQpOnZvaWQge1xuICAgIGlmKHRoaXMuZmlsZURyb3BEaXNhYmxlZCl7XG4gICAgICB0aGlzLnN0b3BFdmVudChldmVudCk7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc2ZlciA9IGV2ZW50VG9UcmFuc2ZlcihldmVudClcblxuICAgIGxldCBmaWxlcyA9IHRoaXMuZXZlbnRUb0ZpbGVzKGV2ZW50KVxuXG4gICAgbGV0IGpzb25GaWxlcyA9IGZpbGVzVG9Xcml0ZWFibGVPYmplY3QoZmlsZXMpXG4gICAgdGhpcy5kcmFnRmlsZXNDaGFuZ2UuZW1pdCggdGhpcy5kcmFnRmlsZXM9anNvbkZpbGVzIClcblxuICAgIGlmKCBmaWxlcy5sZW5ndGggKXtcbiAgICAgIHRoaXMudmFsaWREcmFnID0gdGhpcy5pc0ZpbGVzVmFsaWQoZmlsZXMpXG4gICAgfWVsc2V7XG4gICAgICAvL1NhZmFyaSwgSUUxMSAmIHNvbWUgYnJvd3NlcnMgZG8gTk9UIHRlbGwgeW91IGFib3V0IGRyYWdnZWQgZmlsZXMgdW50aWwgZHJvcHBlZC4gQWx3YXlzIGNvbnNpZGVyIGEgdmFsaWQgZHJhZ1xuICAgICAgdGhpcy52YWxpZERyYWcgPSB0cnVlXG4gICAgfVxuXG4gICAgdGhpcy52YWxpZERyYWdDaGFuZ2UuZW1pdCh0aGlzLnZhbGlkRHJhZylcblxuICAgIHRoaXMuaW52YWxpZERyYWcgPSAhdGhpcy52YWxpZERyYWdcbiAgICB0aGlzLmludmFsaWREcmFnQ2hhbmdlLmVtaXQodGhpcy5pbnZhbGlkRHJhZylcblxuICAgIHRyYW5zZmVyLmRyb3BFZmZlY3QgPSAnY29weScgLy8gY2hhbmdlIGN1cnNvciBhbmQgdmlzdWFsIGRpc3BsYXlcbiAgICB0aGlzLnN0b3BFdmVudChldmVudClcbiAgICB0aGlzLmZpbGVPdmVyLmVtaXQodHJ1ZSlcbiAgfVxuXG4gIGNsb3NlRHJhZ3MoKXtcbiAgICBkZWxldGUgdGhpcy52YWxpZERyYWdcbiAgICB0aGlzLnZhbGlkRHJhZ0NoYW5nZS5lbWl0KHRoaXMudmFsaWREcmFnKVxuICAgIHRoaXMuaW52YWxpZERyYWcgPSBmYWxzZVxuICAgIHRoaXMuaW52YWxpZERyYWdDaGFuZ2UuZW1pdCh0aGlzLmludmFsaWREcmFnKVxuICAgIGRlbGV0ZSB0aGlzLmRyYWdGaWxlc1xuICAgIHRoaXMuZHJhZ0ZpbGVzQ2hhbmdlLmVtaXQoIHRoaXMuZHJhZ0ZpbGVzIClcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIFsnJGV2ZW50J10pXG4gIG9uRHJhZ0xlYXZlKGV2ZW50OkV2ZW50KTphbnkge1xuICAgIGlmKHRoaXMuZmlsZURyb3BEaXNhYmxlZCl7XG4gICAgICB0aGlzLnN0b3BFdmVudChldmVudCk7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlRHJhZ3MoKVxuXG4gICAgaWYgKCh0aGlzIGFzIGFueSkuZWxlbWVudCkge1xuICAgICAgaWYgKGV2ZW50LmN1cnJlbnRUYXJnZXQgPT09ICh0aGlzIGFzIGFueSkuZWxlbWVudFswXSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgIHRoaXMuZmlsZU92ZXIuZW1pdChmYWxzZSk7XG4gIH1cbn0iXX0= |
| import { Directive, EventEmitter, Output, Input } from '@angular/core'; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfFormData { | ||
| constructor(IterableDiffers) { | ||
| this.postName = "file"; | ||
| this.FormData = new FormData(); | ||
| this.FormDataChange = new EventEmitter(); | ||
| this.differ = IterableDiffers.find([]).create(); | ||
| } | ||
| ngDoCheck() { | ||
| var changes = this.differ.diff(this.files); | ||
| if (changes) { | ||
| setTimeout(() => this.buildFormData(), 0); | ||
| } | ||
| } | ||
| buildFormData() { | ||
| const isArray = typeof (this.files) === 'object' && this.files.constructor === Array; | ||
| if (isArray) { | ||
| this.FormData = new FormData(); | ||
| const files = this.files || []; | ||
| files.forEach(file => this.FormData.append(this.postName, file, this.fileName || file.name)); | ||
| this.FormDataChange.emit(this.FormData); | ||
| } | ||
| else { | ||
| delete this.FormData; | ||
| } | ||
| } | ||
| } | ||
| ngfFormData.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, deps: [{ token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfFormData.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfFormData, selector: "ngfFormData", inputs: { files: "files", postName: "postName", fileName: "fileName", FormData: "FormData" }, outputs: { FormDataChange: "FormDataChange" }, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfFormData' }] | ||
| }], ctorParameters: function () { return [{ type: i0.IterableDiffers }]; }, propDecorators: { files: [{ | ||
| type: Input | ||
| }], postName: [{ | ||
| type: Input | ||
| }], fileName: [{ | ||
| type: Input | ||
| }], FormData: [{ | ||
| type: Input | ||
| }], FormDataChange: [{ | ||
| type: Output | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmRm9ybURhdGEuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2ZpbGUtdXBsb2FkL25nZkZvcm1EYXRhLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0wsU0FBUyxFQUFFLFlBQVksRUFDdkIsTUFBTSxFQUFFLEtBQUssRUFDZCxNQUFNLGVBQWUsQ0FBQzs7QUFHdkIsTUFBTSxPQUFPLFdBQVc7SUFVdEIsWUFBWSxlQUFnQztRQVJuQyxhQUFRLEdBQVUsTUFBTSxDQUFBO1FBR3hCLGFBQVEsR0FBWSxJQUFJLFFBQVEsRUFBRSxDQUFBO1FBQ2pDLG1CQUFjLEdBQTBCLElBQUksWUFBWSxFQUFFLENBQUE7UUFLbEUsSUFBSSxDQUFDLE1BQU0sR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFBO0lBQ2pELENBQUM7SUFFRCxTQUFTO1FBQ1AsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUUsSUFBSSxDQUFDLEtBQUssQ0FBRSxDQUFDO1FBRTdDLElBQUksT0FBTyxFQUFFO1lBQ1gsVUFBVSxDQUFDLEdBQUUsRUFBRSxDQUFBLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQTtTQUN4QztJQUNILENBQUM7SUFFRCxhQUFhO1FBQ1gsTUFBTSxPQUFPLEdBQUcsT0FBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBRyxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUcsS0FBSyxDQUFBO1FBRS9FLElBQUksT0FBTyxFQUFFO1lBQ1gsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFBO1lBQzlCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFBO1lBQzlCLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFBLEVBQUUsQ0FDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsSUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQ3BFLENBQUE7WUFDRCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsUUFBUSxDQUFFLENBQUE7U0FDMUM7YUFBSTtZQUNILE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQTtTQUNyQjtJQUNILENBQUM7O3lHQW5DVSxXQUFXOzZGQUFYLFdBQVc7NEZBQVgsV0FBVztrQkFEdkIsU0FBUzttQkFBQyxFQUFDLFFBQVEsRUFBRSxhQUFhLEVBQUM7c0dBRXpCLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFDSSxjQUFjO3NCQUF2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSXRlcmFibGVEaWZmZXIsXG4gIEl0ZXJhYmxlRGlmZmVycyxcbiAgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsXG4gIE91dHB1dCwgSW5wdXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnbmdmRm9ybURhdGEnfSlcbmV4cG9ydCBjbGFzcyBuZ2ZGb3JtRGF0YSB7XG4gIEBJbnB1dCgpIGZpbGVzICE6IEZpbGVbXVxuICBASW5wdXQoKSBwb3N0TmFtZTpzdHJpbmcgPSBcImZpbGVcIlxuICBASW5wdXQoKSBmaWxlTmFtZSAhOiBzdHJpbmcvL2ZvcmNlIGZpbGUgbmFtZVxuXG4gIEBJbnB1dCgpIEZvcm1EYXRhOkZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKClcbiAgQE91dHB1dCgpIEZvcm1EYXRhQ2hhbmdlOkV2ZW50RW1pdHRlcjxGb3JtRGF0YT4gPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBkaWZmZXI6SXRlcmFibGVEaWZmZXI8e30+XG5cbiAgY29uc3RydWN0b3IoSXRlcmFibGVEaWZmZXJzOiBJdGVyYWJsZURpZmZlcnMpe1xuICAgIHRoaXMuZGlmZmVyID0gSXRlcmFibGVEaWZmZXJzLmZpbmQoW10pLmNyZWF0ZSgpXG4gIH1cblxuICBuZ0RvQ2hlY2soKXtcbiAgICB2YXIgY2hhbmdlcyA9IHRoaXMuZGlmZmVyLmRpZmYoIHRoaXMuZmlsZXMgKTtcblxuICAgIGlmIChjaGFuZ2VzKSB7XG4gICAgICBzZXRUaW1lb3V0KCgpPT50aGlzLmJ1aWxkRm9ybURhdGEoKSwgMClcbiAgICB9XG4gIH1cblxuICBidWlsZEZvcm1EYXRhKCl7XG4gICAgY29uc3QgaXNBcnJheSA9IHR5cGVvZih0aGlzLmZpbGVzKT09PSdvYmplY3QnICYmIHRoaXMuZmlsZXMuY29uc3RydWN0b3I9PT1BcnJheVxuXG4gICAgaWYoIGlzQXJyYXkgKXtcbiAgICAgIHRoaXMuRm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKVxuICAgICAgY29uc3QgZmlsZXMgPSB0aGlzLmZpbGVzIHx8IFtdXG4gICAgICBmaWxlcy5mb3JFYWNoKGZpbGU9PlxuICAgICAgICB0aGlzLkZvcm1EYXRhLmFwcGVuZCh0aGlzLnBvc3ROYW1lLCBmaWxlLCB0aGlzLmZpbGVOYW1lfHxmaWxlLm5hbWUpXG4gICAgICApXG4gICAgICB0aGlzLkZvcm1EYXRhQ2hhbmdlLmVtaXQoIHRoaXMuRm9ybURhdGEgKVxuICAgIH1lbHNle1xuICAgICAgZGVsZXRlIHRoaXMuRm9ybURhdGFcbiAgICB9XG4gIH1cbn0iXX0= |
| import { Directive, Input } from "@angular/core"; | ||
| import { ngf } from "./ngf.directive"; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfSelect extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.selectable = true; | ||
| } | ||
| } | ||
| ngfSelect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSelect.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSelect, selector: "[ngfSelect]", inputs: { selectable: "selectable" }, exportAs: ["ngfSelect"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfSelect]", | ||
| exportAs: "ngfSelect" | ||
| }] | ||
| }], propDecorators: { selectable: [{ | ||
| type: Input | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmU2VsZWN0LmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2ZTZWxlY3QuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2hELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTs7QUFNckMsTUFBTSxPQUFPLFNBQVUsU0FBUSxHQUFHO0lBSmxDOztRQUtXLGVBQVUsR0FBTyxJQUFJLENBQUE7S0FDL0I7O3VHQUZZLFNBQVM7MkZBQVQsU0FBUzs0RkFBVCxTQUFTO2tCQUpyQixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxhQUFhO29CQUN2QixRQUFRLEVBQUUsV0FBVztpQkFDdEI7OEJBRVUsVUFBVTtzQkFBbEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgSW5wdXQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiXG5pbXBvcnQgeyBuZ2YgfSBmcm9tIFwiLi9uZ2YuZGlyZWN0aXZlXCJcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBcIltuZ2ZTZWxlY3RdXCIsXG4gIGV4cG9ydEFzOiBcIm5nZlNlbGVjdFwiXG59KVxuZXhwb3J0IGNsYXNzIG5nZlNlbGVjdCBleHRlbmRzIG5nZiB7XG4gIEBJbnB1dCgpIHNlbGVjdGFibGU6YW55ID0gdHJ1ZVxufSJdfQ== |
| import { Directive, Input } from '@angular/core'; | ||
| import { dataUrl } from './fileTools'; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfSrc { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => this.ElementRef.nativeElement.src = src); | ||
| } | ||
| } | ||
| ngfSrc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSrc.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSrc, selector: "[ngfSrc]", inputs: { file: ["ngfSrc", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfSrc]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfSrc'] | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmU3JjLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2ZTcmMuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUM7O0FBR3RDLE1BQU0sT0FBTyxNQUFNO0lBR2pCLFlBQW1CLFVBQXNCO1FBQXRCLGVBQVUsR0FBVixVQUFVLENBQVk7SUFBSSxDQUFDO0lBRTlDLFdBQVcsQ0FBQyxRQUFhO1FBQ3ZCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ2pCLElBQUksQ0FBQyxHQUFHLENBQUEsRUFBRSxDQUNULElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQ3hDLENBQUE7SUFDSCxDQUFDOztvR0FWVSxNQUFNO3dGQUFOLE1BQU07NEZBQU4sTUFBTTtrQkFEbEIsU0FBUzttQkFBQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUU7aUdBRWhCLElBQUk7c0JBQXBCLEtBQUs7dUJBQUMsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGRhdGFVcmwgfSBmcm9tICcuL2ZpbGVUb29scyc7XG5cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1tuZ2ZTcmNdJyB9KVxuZXhwb3J0IGNsYXNzIG5nZlNyYyB7XG4gIEBJbnB1dCgnbmdmU3JjJykgZmlsZTogYW55XG5cbiAgY29uc3RydWN0b3IocHVibGljIEVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHsgfVxuXG4gIG5nT25DaGFuZ2VzKF9jaGFuZ2VzOiBhbnkpIHtcbiAgICBkYXRhVXJsKHRoaXMuZmlsZSlcbiAgICAudGhlbihzcmM9PlxuICAgICAgdGhpcy5FbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc3JjID0gc3JjXG4gICAgKVxuICB9XG59XG4iXX0= |
| import { Directive, EventEmitter, Output, Input } from '@angular/core'; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfUploadStatus { | ||
| constructor() { | ||
| this.percent = 0; | ||
| this.percentChange = new EventEmitter(); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.httpEvent && changes.httpEvent.currentValue) { | ||
| const event = changes.httpEvent.currentValue; | ||
| if (event.loaded && event.total) { | ||
| setTimeout(() => { | ||
| this.percent = Math.round(100 * event.loaded / event.total); | ||
| this.percentChange.emit(this.percent); | ||
| }, 0); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ngfUploadStatus.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, deps: [], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfUploadStatus.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfUploadStatus, selector: "ngfUploadStatus", inputs: { percent: "percent", httpEvent: "httpEvent" }, outputs: { percentChange: "percentChange" }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfUploadStatus' }] | ||
| }], propDecorators: { percent: [{ | ||
| type: Input | ||
| }], percentChange: [{ | ||
| type: Output | ||
| }], httpEvent: [{ | ||
| type: Input | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmVXBsb2FkU3RhdHVzLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2ZVcGxvYWRTdGF0dXMuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBR3ZFLE1BQU0sT0FBTyxlQUFlO0lBRDVCO1FBRVcsWUFBTyxHQUFVLENBQUMsQ0FBQTtRQUNqQixrQkFBYSxHQUF3QixJQUFJLFlBQVksRUFBRSxDQUFBO0tBY2xFO0lBWEMsV0FBVyxDQUFFLE9BQU87UUFDbEIsSUFBSSxPQUFPLENBQUMsU0FBUyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFO1lBQ3ZELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFBO1lBQzVDLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO2dCQUMvQixVQUFVLENBQUMsR0FBRSxFQUFFO29CQUNiLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzVELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFFLElBQUksQ0FBQyxPQUFPLENBQUUsQ0FBQTtnQkFDekMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO2FBQ047U0FDRjtJQUNILENBQUM7OzZHQWZVLGVBQWU7aUdBQWYsZUFBZTs0RkFBZixlQUFlO2tCQUQzQixTQUFTO21CQUFDLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDOzhCQUU3QixPQUFPO3NCQUFmLEtBQUs7Z0JBQ0ksYUFBYTtzQkFBdEIsTUFBTTtnQkFDRSxTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIE91dHB1dCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7c2VsZWN0b3I6ICduZ2ZVcGxvYWRTdGF0dXMnfSlcbmV4cG9ydCBjbGFzcyBuZ2ZVcGxvYWRTdGF0dXMge1xuICBASW5wdXQoKSBwZXJjZW50Om51bWJlciA9IDBcbiAgQE91dHB1dCgpIHBlcmNlbnRDaGFuZ2U6RXZlbnRFbWl0dGVyPG51bWJlcj4gPSBuZXcgRXZlbnRFbWl0dGVyKClcbiAgQElucHV0KCkgaHR0cEV2ZW50ICE6IEV2ZW50XG5cbiAgbmdPbkNoYW5nZXMoIGNoYW5nZXMgKXtcbiAgICBpZiggY2hhbmdlcy5odHRwRXZlbnQgJiYgY2hhbmdlcy5odHRwRXZlbnQuY3VycmVudFZhbHVlICl7XG4gICAgICBjb25zdCBldmVudCA9IGNoYW5nZXMuaHR0cEV2ZW50LmN1cnJlbnRWYWx1ZVxuICAgICAgaWYgKGV2ZW50LmxvYWRlZCAmJiBldmVudC50b3RhbCkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpPT57XG4gICAgICAgICAgdGhpcy5wZXJjZW50ID0gTWF0aC5yb3VuZCgxMDAgKiBldmVudC5sb2FkZWQgLyBldmVudC50b3RhbCk7XG4gICAgICAgICAgdGhpcy5wZXJjZW50Q2hhbmdlLmVtaXQoIHRoaXMucGVyY2VudCApXG4gICAgICAgIH0sIDApXG4gICAgICB9XG4gICAgfVxuICB9XG59Il19 |
| export * from './file-upload/ngf.module'; | ||
| export { ngfSrc } from './file-upload/ngfSrc.directive'; | ||
| export { ngfFormData } from './file-upload/ngfFormData.directive'; | ||
| export { ngfSelect } from './file-upload/ngfSelect.directive'; | ||
| export { ngfUploadStatus } from './file-upload/ngfUploadStatus.directive'; | ||
| export { ngfDrop } from './file-upload/ngfDrop.directive'; | ||
| export { ngf } from './file-upload/ngf.directive'; | ||
| export { ngfBackground } from './file-upload/ngfBackground.directive'; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywwQkFBMEIsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0NBQWdDLENBQUE7QUFDdkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFDQUFxQyxDQUFBO0FBQ2pFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQTtBQUM3RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0seUNBQXlDLENBQUE7QUFDekUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlDQUFpQyxDQUFBO0FBQ3pELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQTtBQUNqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sdUNBQXVDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2ZpbGUtdXBsb2FkL25nZi5tb2R1bGUnXG5leHBvcnQgeyBuZ2ZTcmMgfSBmcm9tICcuL2ZpbGUtdXBsb2FkL25nZlNyYy5kaXJlY3RpdmUnXG5leHBvcnQgeyBuZ2ZGb3JtRGF0YSB9IGZyb20gJy4vZmlsZS11cGxvYWQvbmdmRm9ybURhdGEuZGlyZWN0aXZlJ1xuZXhwb3J0IHsgbmdmU2VsZWN0IH0gZnJvbSAnLi9maWxlLXVwbG9hZC9uZ2ZTZWxlY3QuZGlyZWN0aXZlJ1xuZXhwb3J0IHsgbmdmVXBsb2FkU3RhdHVzIH0gZnJvbSAnLi9maWxlLXVwbG9hZC9uZ2ZVcGxvYWRTdGF0dXMuZGlyZWN0aXZlJ1xuZXhwb3J0IHsgbmdmRHJvcCB9IGZyb20gJy4vZmlsZS11cGxvYWQvbmdmRHJvcC5kaXJlY3RpdmUnXG5leHBvcnQgeyBuZ2YgfSBmcm9tICcuL2ZpbGUtdXBsb2FkL25nZi5kaXJlY3RpdmUnXG5leHBvcnQgeyBuZ2ZCYWNrZ3JvdW5kIH0gZnJvbSAnLi9maWxlLXVwbG9hZC9uZ2ZCYWNrZ3JvdW5kLmRpcmVjdGl2ZSciXX0= |
| /** | ||
| * Generated bundle index. Do not edit. | ||
| */ | ||
| export * from './public-api'; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1maWxlLXNyYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hbmd1bGFyLWZpbGUtc3JjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG4iXX0= |
| export const isFileInput = function (elm) { | ||
| const ty = elm.getAttribute('type'); | ||
| return elm.tagName.toLowerCase() === 'input' && ty && ty.toLowerCase() === 'file'; | ||
| }; | ||
| let initialTouchStartY = 0; | ||
| let initialTouchStartX = 0; | ||
| export const detectSwipe = function (evt) { | ||
| var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches); | ||
| if (touches) { | ||
| if (evt.type === 'touchstart') { | ||
| initialTouchStartX = touches[0].clientX; | ||
| initialTouchStartY = touches[0].clientY; | ||
| return true; // don't block event default | ||
| } | ||
| else { | ||
| // prevent scroll from triggering event | ||
| if (evt.type === 'touchend') { | ||
| var currentX = touches[0].clientX; | ||
| var currentY = touches[0].clientY; | ||
| if ((Math.abs(currentX - initialTouchStartX) > 20) || | ||
| (Math.abs(currentY - initialTouchStartY) > 20)) { | ||
| evt.stopPropagation(); | ||
| if (evt.cancelable) { | ||
| evt.preventDefault(); | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }; | ||
| export const createInvisibleFileInputWrap = function () { | ||
| var fileElem = createFileInput(); | ||
| var label = document.createElement('label'); | ||
| label.innerHTML = 'upload'; | ||
| label.style.visibility = 'hidden'; | ||
| label.style.position = 'absolute'; | ||
| label.style.overflow = 'hidden'; | ||
| label.style.width = '0px'; | ||
| label.style.height = '0px'; | ||
| label.style.border = 'none'; | ||
| label.style.margin = '0px'; | ||
| label.style.padding = '0px'; | ||
| label.setAttribute('tabindex', '-1'); | ||
| //bindAttrToFileInput(fileElem, label); | ||
| //generatedElems.push({el: elem, ref: label}); | ||
| label.appendChild(fileElem); | ||
| //document.body.appendChild( label ); | ||
| return label; | ||
| }; | ||
| export const createFileInput = function () { | ||
| var fileElem = document.createElement('input'); | ||
| fileElem.type = "file"; | ||
| return fileElem; | ||
| }; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jLWV2ZW50LWhlbHAuZnVuY3Rpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2ZpbGUtdXBsb2FkL2RvYy1ldmVudC1oZWxwLmZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsVUFBUyxHQUFPO0lBQ3pDLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDbkMsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxLQUFLLE9BQU8sSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLE1BQU0sQ0FBQztBQUNwRixDQUFDLENBQUE7QUFFRCxJQUFJLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQUMzQixJQUFJLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQUMzQixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsVUFBUyxHQUFPO0lBQ3pDLElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQyxjQUFjLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxJQUFJLEdBQUcsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDNUYsSUFBSSxPQUFPLEVBQUU7UUFDWCxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFO1lBQzdCLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDeEMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUN4QyxPQUFPLElBQUksQ0FBQyxDQUFDLDRCQUE0QjtTQUMxQzthQUFNO1lBQ0wsdUNBQXVDO1lBQ3ZDLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUU7Z0JBQzNCLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQ2xDLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDaEQsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO29CQUNoRCxHQUFHLENBQUMsZUFBZSxFQUFFLENBQUM7b0JBQ3RCLElBQUksR0FBRyxDQUFDLFVBQVUsRUFBRTt3QkFDbEIsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO3FCQUN0QjtvQkFDRCxPQUFPLEtBQUssQ0FBQztpQkFDZDthQUNGO1lBQ0QsT0FBTyxJQUFJLENBQUM7U0FDYjtLQUNGO0lBQ0QsT0FBTyxLQUFLLENBQUE7QUFDZCxDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBRztJQUMxQyxJQUFJLFFBQVEsR0FBRyxlQUFlLEVBQUUsQ0FBQTtJQUNoQyxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLEtBQUssQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFBO0lBQzFCLEtBQUssQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQTtJQUNqQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUE7SUFDakMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFBO0lBQy9CLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQTtJQUN6QixLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUE7SUFDMUIsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO0lBQzNCLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQTtJQUMxQixLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUE7SUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUMsSUFBSSxDQUFDLENBQUE7SUFFbkMsdUNBQXVDO0lBQ3ZDLDhDQUE4QztJQUU5QyxLQUFLLENBQUMsV0FBVyxDQUFFLFFBQVEsQ0FBRSxDQUFBO0lBQzdCLHFDQUFxQztJQUVyQyxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRztJQUM3QixJQUFJLFFBQVEsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9DLFFBQVEsQ0FBQyxJQUFJLEdBQUMsTUFBTSxDQUFBO0lBQ3BCLE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCBpc0ZpbGVJbnB1dCA9IGZ1bmN0aW9uKGVsbTphbnkpe1xuICBjb25zdCB0eSA9IGVsbS5nZXRBdHRyaWJ1dGUoJ3R5cGUnKVxuICByZXR1cm4gZWxtLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0JyAmJiB0eSAmJiB0eS50b0xvd2VyQ2FzZSgpID09PSAnZmlsZSc7XG59XG5cbmxldCBpbml0aWFsVG91Y2hTdGFydFkgPSAwO1xubGV0IGluaXRpYWxUb3VjaFN0YXJ0WCA9IDA7XG5leHBvcnQgY29uc3QgZGV0ZWN0U3dpcGUgPSBmdW5jdGlvbihldnQ6YW55KTpib29sZWFuIHtcbiAgdmFyIHRvdWNoZXMgPSBldnQuY2hhbmdlZFRvdWNoZXMgfHwgKGV2dC5vcmlnaW5hbEV2ZW50ICYmIGV2dC5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzKTtcbiAgaWYgKHRvdWNoZXMpIHtcbiAgICBpZiAoZXZ0LnR5cGUgPT09ICd0b3VjaHN0YXJ0Jykge1xuICAgICAgaW5pdGlhbFRvdWNoU3RhcnRYID0gdG91Y2hlc1swXS5jbGllbnRYO1xuICAgICAgaW5pdGlhbFRvdWNoU3RhcnRZID0gdG91Y2hlc1swXS5jbGllbnRZO1xuICAgICAgcmV0dXJuIHRydWU7IC8vIGRvbid0IGJsb2NrIGV2ZW50IGRlZmF1bHRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcHJldmVudCBzY3JvbGwgZnJvbSB0cmlnZ2VyaW5nIGV2ZW50XG4gICAgICBpZiAoZXZ0LnR5cGUgPT09ICd0b3VjaGVuZCcpIHtcbiAgICAgICAgdmFyIGN1cnJlbnRYID0gdG91Y2hlc1swXS5jbGllbnRYO1xuICAgICAgICB2YXIgY3VycmVudFkgPSB0b3VjaGVzWzBdLmNsaWVudFk7XG4gICAgICAgIGlmICgoTWF0aC5hYnMoY3VycmVudFggLSBpbml0aWFsVG91Y2hTdGFydFgpID4gMjApIHx8XG4gICAgICAgICAgKE1hdGguYWJzKGN1cnJlbnRZIC0gaW5pdGlhbFRvdWNoU3RhcnRZKSA+IDIwKSkge1xuICAgICAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICBpZiAoZXZ0LmNhbmNlbGFibGUpIHtcbiAgICAgICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUludmlzaWJsZUZpbGVJbnB1dFdyYXAgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGZpbGVFbGVtID0gY3JlYXRlRmlsZUlucHV0KClcbiAgdmFyIGxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgbGFiZWwuaW5uZXJIVE1MID0gJ3VwbG9hZCdcbiAgbGFiZWwuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nXG4gIGxhYmVsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJ1xuICBsYWJlbC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nXG4gIGxhYmVsLnN0eWxlLndpZHRoID0gJzBweCdcbiAgbGFiZWwuc3R5bGUuaGVpZ2h0ID0gJzBweCdcbiAgbGFiZWwuc3R5bGUuYm9yZGVyID0gJ25vbmUnXG4gIGxhYmVsLnN0eWxlLm1hcmdpbiA9ICcwcHgnXG4gIGxhYmVsLnN0eWxlLnBhZGRpbmcgPSAnMHB4J1xuICBsYWJlbC5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywnLTEnKVxuICBcbiAgLy9iaW5kQXR0clRvRmlsZUlucHV0KGZpbGVFbGVtLCBsYWJlbCk7XG4gIC8vZ2VuZXJhdGVkRWxlbXMucHVzaCh7ZWw6IGVsZW0sIHJlZjogbGFiZWx9KTtcblxuICBsYWJlbC5hcHBlbmRDaGlsZCggZmlsZUVsZW0gKVxuICAvL2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoIGxhYmVsICk7XG5cbiAgcmV0dXJuIGxhYmVsO1xufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlRmlsZUlucHV0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmaWxlRWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gIGZpbGVFbGVtLnR5cGU9XCJmaWxlXCJcbiAgcmV0dXJuIGZpbGVFbGVtO1xufVxuIl19 |
| export function getWindow() { return window; } | ||
| export function acceptType(accept, type, name) { | ||
| if (!accept) { | ||
| return true; | ||
| } | ||
| const defs = accept.split(','); | ||
| let regx; | ||
| let acceptRegString; | ||
| for (let x = defs.length - 1; x >= 0; --x) { | ||
| //Escapes dots in mimetype | ||
| acceptRegString = defs[x]; | ||
| //trim | ||
| acceptRegString = acceptRegString.replace(/(^\s+|\s+$)/g, ''); | ||
| //Escapes stars in mimetype | ||
| acceptRegString = acceptRegString.replace(/\*/g, '.*'); | ||
| //let acceptReg = '^((' + acceptRegString | ||
| //acceptReg = acceptReg.replace(/,/g,')|(') + '))$' | ||
| //try by mime | ||
| regx = new RegExp(acceptRegString, 'gi'); | ||
| if (type.search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| //try by ext | ||
| if (acceptRegString.substring(0, 1) == '.') { | ||
| acceptRegString = '\\' + acceptRegString; //.substring(1, acceptRegString.length-1)//remove dot at front | ||
| regx = new RegExp(acceptRegString + '$', 'i'); | ||
| if ((name || type).search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| export function arrayBufferToBase64(buffer) { | ||
| var binary = ''; | ||
| var bytes = new Uint8Array(buffer); | ||
| var len = bytes.byteLength; | ||
| for (var i = 0; i < len; i++) { | ||
| binary += String.fromCharCode(bytes[i]); | ||
| } | ||
| return window.btoa(binary); | ||
| } | ||
| export function dataUrltoBlob(dataurl, name, origSize) { | ||
| var arr = dataurl.split(','); | ||
| var mimeMatch = arr[0].match(/:(.*?);/); | ||
| var mime = mimeMatch ? mimeMatch[1] : 'text/plain'; | ||
| var bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); | ||
| while (n--) { | ||
| u8arr[n] = bstr.charCodeAt(n); | ||
| } | ||
| var blob = new window.Blob([u8arr], { type: mime }); | ||
| blob["name"] = name; | ||
| blob["$ngfOrigSize"] = origSize; | ||
| return blob; | ||
| } | ||
| export function applyTransform(ctx, orientation, width, height) { | ||
| switch (orientation) { | ||
| case 2: | ||
| return ctx.transform(-1, 0, 0, 1, width, 0); | ||
| case 3: | ||
| return ctx.transform(-1, 0, 0, -1, width, height); | ||
| case 4: | ||
| return ctx.transform(1, 0, 0, -1, 0, height); | ||
| case 5: | ||
| return ctx.transform(0, 1, 1, 0, 0, 0); | ||
| case 6: | ||
| return ctx.transform(0, 1, -1, 0, height, 0); | ||
| case 7: | ||
| return ctx.transform(0, -1, -1, 0, height, width); | ||
| case 8: | ||
| return ctx.transform(0, -1, 1, 0, 0, width); | ||
| } | ||
| } | ||
| export function fixFileOrientationByMeta(file, result) { | ||
| return dataUrl(file, true) | ||
| .then(url => { | ||
| var canvas = document.createElement('canvas'); | ||
| var img = document.createElement('img'); | ||
| return new Promise(function (res, rej) { | ||
| img.onload = function () { | ||
| try { | ||
| canvas.width = result.orientation > 4 ? img.height : img.width; | ||
| canvas.height = result.orientation > 4 ? img.width : img.height; | ||
| var ctx = canvas.getContext('2d'); | ||
| applyTransform(ctx, result.orientation, img.width, img.height); | ||
| ctx.drawImage(img, 0, 0); | ||
| var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934); | ||
| const base = arrayBufferToBase64(result.fixedArrayBuffer); | ||
| dataUrl = restoreExif(base, dataUrl); | ||
| var blob = dataUrltoBlob(dataUrl, file.name); | ||
| const newFile = blobToFile(blob, file.name); | ||
| res(newFile); | ||
| } | ||
| catch (e) { | ||
| rej(e); | ||
| } | ||
| }; | ||
| img.onerror = rej; | ||
| img.src = url; | ||
| }); | ||
| }); | ||
| } | ||
| export function applyExifRotation(file) { | ||
| if (file.type.indexOf('image/jpeg') !== 0) { | ||
| return Promise.resolve(file); | ||
| } | ||
| return readOrientation(file) | ||
| .then((result) => { | ||
| if (result.orientation < 2 || result.orientation > 8) { | ||
| return file; | ||
| } | ||
| return fixFileOrientationByMeta(file, result); | ||
| }); | ||
| } | ||
| export function readOrientation(file) { | ||
| return new Promise((res, rej) => { | ||
| var reader = new FileReader(); | ||
| var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file; | ||
| reader.readAsArrayBuffer(slicedFile); | ||
| reader.onerror = rej; | ||
| reader.onload = function (e) { | ||
| var result = { orientation: 1 }; | ||
| var view = new DataView(this.result); | ||
| if (view.getUint16(0, false) !== 0xFFD8) | ||
| return res(result); | ||
| var length = view.byteLength, offset = 2; | ||
| while (offset < length) { | ||
| var marker = view.getUint16(offset, false); | ||
| offset += 2; | ||
| if (marker === 0xFFE1) { | ||
| if (view.getUint32(offset += 2, false) !== 0x45786966) | ||
| return res(result); | ||
| var little = view.getUint16(offset += 6, false) === 0x4949; | ||
| offset += view.getUint32(offset + 4, little); | ||
| var tags = view.getUint16(offset, little); | ||
| offset += 2; | ||
| for (var i = 0; i < tags; i++) | ||
| if (view.getUint16(offset + (i * 12), little) === 0x0112) { | ||
| var orientation = view.getUint16(offset + (i * 12) + 8, little); | ||
| if (orientation >= 2 && orientation <= 8) { | ||
| view.setUint16(offset + (i * 12) + 8, 1, little); | ||
| result.fixedArrayBuffer = e.target.result; | ||
| } | ||
| result.orientation = orientation; | ||
| return res(result); | ||
| } | ||
| } | ||
| else if ((marker & 0xFF00) !== 0xFF00) | ||
| break; | ||
| else | ||
| offset += view.getUint16(offset, false); | ||
| } | ||
| return res(result); | ||
| }; | ||
| }); | ||
| } | ||
| /** converts file-input file into base64 dataUri */ | ||
| export function dataUrl(file, disallowObjectUrl) { | ||
| if (!file) | ||
| return Promise.resolve(file); | ||
| if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { | ||
| return Promise.resolve(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl); | ||
| } | ||
| var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; | ||
| if (p) | ||
| return p; | ||
| const win = getWindow(); | ||
| let deferred; | ||
| if (win.FileReader && file && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { | ||
| //prefer URL.createObjectURL for handling refrences to files of all sizes | ||
| //since it doesn´t build a large string in memory | ||
| var URL = win.URL || win.webkitURL; | ||
| if (FileReader) { | ||
| deferred = new Promise((res, rej) => { | ||
| var fileReader = new FileReader(); | ||
| fileReader.onload = function (event) { | ||
| file.$ngfDataUrl = event.target.result; | ||
| delete file.$ngfDataUrl; | ||
| res(event.target.result); | ||
| }; | ||
| fileReader.onerror = function (e) { | ||
| file.$ngfDataUrl = ''; | ||
| rej(e); | ||
| }; | ||
| fileReader.readAsDataURL(file); | ||
| }); | ||
| } | ||
| else { | ||
| var url; | ||
| try { | ||
| url = URL.createObjectURL(file); | ||
| } | ||
| catch (e) { | ||
| return Promise.reject(e); | ||
| } | ||
| deferred = Promise.resolve(url); | ||
| file.$ngfBlobUrl = url; | ||
| } | ||
| } | ||
| else { | ||
| file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; | ||
| return Promise.reject(new Error('Browser does not support window.FileReader, window.FileReader, or window.FileAPI')); //deferred.reject(); | ||
| } | ||
| if (disallowObjectUrl) { | ||
| p = file.$$ngfDataUrlPromise = deferred; | ||
| } | ||
| else { | ||
| p = file.$$ngfBlobUrlPromise = deferred; | ||
| } | ||
| p = p.then((x) => { | ||
| delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; | ||
| return x; | ||
| }); | ||
| return p; | ||
| } | ||
| export function restoreExif(orig, resized) { | ||
| var ExifRestorer = { | ||
| KEY_STR: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' | ||
| }; | ||
| ExifRestorer.encode64 = function (input) { | ||
| var output = '', chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0; | ||
| do { | ||
| chr1 = input[i++]; | ||
| chr2 = input[i++]; | ||
| chr3 = input[i++]; | ||
| enc1 = chr1 >> 2; | ||
| enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | ||
| enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | ||
| enc4 = chr3 & 63; | ||
| if (isNaN(chr2)) { | ||
| enc3 = enc4 = 64; | ||
| } | ||
| else if (isNaN(chr3)) { | ||
| enc4 = 64; | ||
| } | ||
| output = output + | ||
| this.KEY_STR.charAt(enc1) + | ||
| this.KEY_STR.charAt(enc2) + | ||
| this.KEY_STR.charAt(enc3) + | ||
| this.KEY_STR.charAt(enc4); | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return output; | ||
| }; | ||
| ExifRestorer.restore = function (origFileBase64, resizedFileBase64) { | ||
| if (origFileBase64.match('data:image/jpeg;base64,')) { | ||
| origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', ''); | ||
| } | ||
| var rawImage = this.decode64(origFileBase64); | ||
| var segments = this.slice2Segments(rawImage); | ||
| var image = this.exifManipulation(resizedFileBase64, segments); | ||
| return 'data:image/jpeg;base64,' + this.encode64(image); | ||
| }; | ||
| ExifRestorer.exifManipulation = function (resizedFileBase64, segments) { | ||
| var exifArray = this.getExifArray(segments), newImageArray = this.insertExif(resizedFileBase64, exifArray); | ||
| return new Uint8Array(newImageArray); | ||
| }; | ||
| ExifRestorer.getExifArray = function (segments) { | ||
| var seg; | ||
| for (var x = 0; x < segments.length; x++) { | ||
| seg = segments[x]; | ||
| if (seg[0] === 255 && seg[1] === 225) //(ff e1) | ||
| { | ||
| return seg; | ||
| } | ||
| } | ||
| return []; | ||
| }; | ||
| ExifRestorer.insertExif = function (resizedFileBase64, exifArray) { | ||
| var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''), buf = this.decode64(imageData), separatePoint = buf.indexOf(255, 3), mae = buf.slice(0, separatePoint), ato = buf.slice(separatePoint), array = mae; | ||
| array = array.concat(exifArray); | ||
| array = array.concat(ato); | ||
| return array; | ||
| }; | ||
| ExifRestorer.slice2Segments = function (rawImageArray) { | ||
| var head = 0, segments = []; | ||
| while (1) { | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 218) { | ||
| break; | ||
| } | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 216) { | ||
| head += 2; | ||
| } | ||
| else { | ||
| var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3]; | ||
| var endPoint = head + length + 2; | ||
| var seg = rawImageArray.slice(head, endPoint); | ||
| segments.push(seg); | ||
| head = endPoint; | ||
| } | ||
| if (head > rawImageArray.length) { | ||
| break; | ||
| } | ||
| } | ||
| return segments; | ||
| }; | ||
| ExifRestorer.decode64 = function (input) { | ||
| var chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0, buf = []; | ||
| // remove all characters that are not A-Z, a-z, 0-9, +, /, or = | ||
| var base64test = /[^A-Za-z0-9\+\/\=]/g; | ||
| if (base64test.exec(input)) { | ||
| console.log('There were invalid base64 characters in the input text.'); | ||
| } | ||
| input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); | ||
| do { | ||
| enc1 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc2 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc3 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc4 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| chr1 = (enc1 << 2) | (enc2 >> 4); | ||
| chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); | ||
| chr3 = ((enc3 & 3) << 6) | enc4; | ||
| buf.push(chr1); | ||
| if (enc3 !== 64) { | ||
| buf.push(chr2); | ||
| } | ||
| if (enc4 !== 64) { | ||
| buf.push(chr3); | ||
| } | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return buf; | ||
| }; | ||
| return ExifRestorer.restore(orig, resized); //<= EXIF | ||
| } | ||
| ; | ||
| function blobToFile(theBlob, fileName) { | ||
| var b = theBlob; | ||
| //A Blob() is almost a File() - it's just missing the two properties below which we will add | ||
| b.lastModifiedDate = new Date(); | ||
| b.name = fileName; | ||
| //Cast to a File() type | ||
| return theBlob; | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZVRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2ZpbGUtdXBsb2FkL2ZpbGVUb29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLFVBQVUsU0FBUyxLQUFPLE9BQU8sTUFBTSxDQUFBLENBQUEsQ0FBQztBQUU5QyxNQUFNLFVBQVUsVUFBVSxDQUFDLE1BQWEsRUFBRSxJQUFXLEVBQUUsSUFBWTtJQUNqRSxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQ1gsT0FBTyxJQUFJLENBQUE7S0FDWjtJQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDOUIsSUFBSSxJQUFXLENBQUE7SUFDZixJQUFJLGVBQXNCLENBQUE7SUFFMUIsS0FBSSxJQUFJLENBQUMsR0FBQyxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFDO1FBQ25DLDJCQUEyQjtRQUMzQixlQUFlLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ3pCLE1BQU07UUFDTixlQUFlLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUMsRUFBRSxDQUFDLENBQUE7UUFDNUQsNEJBQTRCO1FBQzVCLGVBQWUsR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBQyxJQUFJLENBQUMsQ0FBQTtRQUNyRCx5Q0FBeUM7UUFDekMsbURBQW1EO1FBRW5ELGFBQWE7UUFDYixJQUFJLEdBQUcsSUFBSSxNQUFNLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxDQUFBO1FBQ3hDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBRSxDQUFDLEVBQUU7WUFDeEIsT0FBTyxJQUFJLENBQUE7U0FDWjtRQUVELFlBQVk7UUFDWixJQUFJLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FB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O2dCQUNmLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDaEI7WUFDRCxJQUFJLElBQUksS0FBSyxFQUFFLEVBQUU7Z0JBQ2YsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNoQjtZQUVELElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUN4QixJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1NBRWhDLFFBQVEsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUU7UUFFM0IsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDLENBQUM7SUFFRixPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUUsU0FBUztBQUN4RCxDQUFDO0FBQUEsQ0FBQztBQUVGLFNBQVMsVUFBVSxDQUFDLE9BQWEsRUFBRSxRQUFlO0lBQ2hELElBQUksQ0FBQyxHQUFRLE9BQU8sQ0FBQztJQUNyQiw0RkFBNEY7SUFDNUYsQ0FBQyxDQUFDLGdCQUFnQixHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFDaEMsQ0FBQyxDQUFDLElBQUksR0FBRyxRQUFRLENBQUM7SUFFbEIsdUJBQXVCO0lBQ3ZCLE9BQWEsT0FBTyxDQUFDO0FBQ3ZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gZ2V0V2luZG93KCk6YW55e3JldHVybiB3aW5kb3d9XG5cbmV4cG9ydCBmdW5jdGlvbiBhY2NlcHRUeXBlKGFjY2VwdDpzdHJpbmcsIHR5cGU6c3RyaW5nLCBuYW1lPzpzdHJpbmcpOmJvb2xlYW4geyAgIFxuICBpZiggIWFjY2VwdCApe1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBjb25zdCBkZWZzID0gYWNjZXB0LnNwbGl0KCcsJylcbiAgbGV0IHJlZ3g6UmVnRXhwXG4gIGxldCBhY2NlcHRSZWdTdHJpbmc6c3RyaW5nXG5cbiAgZm9yKGxldCB4PWRlZnMubGVuZ3RoLTE7IHggPj0gMDsgLS14KXtcbiAgICAvL0VzY2FwZXMgZG90cyBpbiBtaW1ldHlwZSBcbiAgICBhY2NlcHRSZWdTdHJpbmcgPSBkZWZzW3hdXG4gICAgLy90cmltXG4gICAgYWNjZXB0UmVnU3RyaW5nID0gYWNjZXB0UmVnU3RyaW5nLnJlcGxhY2UoLyheXFxzK3xcXHMrJCkvZywnJylcbiAgICAvL0VzY2FwZXMgc3RhcnMgaW4gbWltZXR5cGUgXG4gICAgYWNjZXB0UmVnU3RyaW5nID0gYWNjZXB0UmVnU3RyaW5nLnJlcGxhY2UoL1xcKi9nLCcuKicpXG4gICAgLy9sZXQgYWNjZXB0UmVnID0gJ14oKCcgKyBhY2NlcHRSZWdTdHJpbmdcbiAgICAvL2FjY2VwdFJlZyA9IGFjY2VwdFJlZy5yZXBsYWNlKC8sL2csJyl8KCcpICsgJykpJCdcbiAgICBcbiAgICAvL3RyeSBieSBtaW1lXG4gICAgcmVneCA9IG5ldyBSZWdFeHAoYWNjZXB0UmVnU3RyaW5nLCAnZ2knKVxuICAgIGlmKCB0eXBlLnNlYXJjaChyZWd4KT49MCApe1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICAvL3RyeSBieSBleHRcbiAgICBpZiggYWNjZXB0UmVnU3RyaW5nLnN1YnN0cmluZygwLCAxKT09Jy4nICl7ICAgICAgXG4gICAgICBhY2NlcHRSZWdTdHJpbmcgPSAnXFxcXCcrIGFjY2VwdFJlZ1N0cmluZy8vLnN1YnN0cmluZygxLCBhY2NlcHRSZWdTdHJpbmcubGVuZ3RoLTEpLy9yZW1vdmUgZG90IGF0IGZyb250XG4gICAgICByZWd4ID0gbmV3IFJlZ0V4cChhY2NlcHRSZWdTdHJpbmcrJyQnLCAnaScpXG4gICAgICBpZiggKG5hbWV8fHR5cGUpLnNlYXJjaChyZWd4KT49MCApe1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbnZhbGlkRmlsZUl0ZW17XG4gIGZpbGU6RmlsZVxuICB0eXBlOnN0cmluZ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlCdWZmZXJUb0Jhc2U2NChidWZmZXI6YW55KSB7XG4gIHZhciBiaW5hcnkgPSAnJztcbiAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcbiAgdmFyIGxlbiA9IGJ5dGVzLmJ5dGVMZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7XG4gIH1cbiAgcmV0dXJuIHdpbmRvdy5idG9hKGJpbmFyeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkYXRhVXJsdG9CbG9iKFxuICBkYXRhdXJsOnN0cmluZyxcbiAgbmFtZTpzdHJpbmcsXG4gIG9yaWdTaXplPzphbnlcbik6QmxvYntcbiAgdmFyIGFyciA9IGRhdGF1cmwuc3BsaXQoJywnKTtcbiAgdmFyIG1pbWVNYXRjaCA9IGFyclswXS5tYXRjaCgvOiguKj8pOy8pXG4gIHZhciBtaW1lOnN0cmluZyA9IG1pbWVNYXRjaCA/IG1pbWVNYXRjaFsxXSA6ICd0ZXh0L3BsYWluJ1xuICB2YXIgYnN0ciA9IGF0b2IoYXJyWzFdKSwgbiA9IGJzdHIubGVuZ3RoLCB1OGFyciA9IG5ldyBVaW50OEFycmF5KG4pO1xuICB3aGlsZSAobi0tKSB7XG4gICAgdThhcnJbbl0gPSBic3RyLmNoYXJDb2RlQXQobik7XG4gIH1cbiAgXG4gIHZhciBibG9iOiBhbnkgPSBuZXcgd2luZG93LkJsb2IoW3U4YXJyXSwge3R5cGU6IG1pbWV9KTtcbiAgYmxvYltcIm5hbWVcIl0gPSBuYW1lO1xuICBibG9iW1wiJG5nZk9yaWdTaXplXCJdID0gb3JpZ1NpemU7XG4gIHJldHVybiBibG9iO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIG9yaWVudGF0aW9uTWV0YXtcbiAgb3JpZW50YXRpb246IG51bWJlclxuICBmaXhlZEFycmF5QnVmZmVyPzphbnlbXVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlUcmFuc2Zvcm0oXG4gIGN0eDpDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIG9yaWVudGF0aW9uOm51bWJlcixcbiAgd2lkdGg6bnVtYmVyLFxuICBoZWlnaHQ6bnVtYmVyXG4pIHtcbiAgc3dpdGNoIChvcmllbnRhdGlvbikge1xuICAgIGNhc2UgMjpcbiAgICAgIHJldHVybiBjdHgudHJhbnNmb3JtKC0xLCAwLCAwLCAxLCB3aWR0aCwgMCk7XG4gICAgY2FzZSAzOlxuICAgICAgcmV0dXJuIGN0eC50cmFuc2Zvcm0oLTEsIDAsIDAsIC0xLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICBjYXNlIDQ6XG4gICAgICByZXR1cm4gY3R4LnRyYW5zZm9ybSgxLCAwLCAwLCAtMSwgMCwgaGVpZ2h0KTtcbiAgICBjYXNlIDU6XG4gICAgICByZXR1cm4gY3R4LnRyYW5zZm9ybSgwLCAxLCAxLCAwLCAwLCAwKTtcbiAgICBjYXNlIDY6XG4gICAgICByZXR1cm4gY3R4LnRyYW5zZm9ybSgwLCAxLCAtMSwgMCwgaGVpZ2h0LCAwKTtcbiAgICBjYXNlIDc6XG4gICAgICByZXR1cm4gY3R4LnRyYW5zZm9ybSgwLCAtMSwgLTEsIDAsIGhlaWdodCwgd2lkdGgpO1xuICAgIGNhc2UgODpcbiAgICAgIHJldHVybiBjdHgudHJhbnNmb3JtKDAsIC0xLCAxLCAwLCAwLCB3aWR0aCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpeEZpbGVPcmllbnRhdGlvbkJ5TWV0YShcbiAgZmlsZTpGaWxlLCByZXN1bHQ6b3JpZW50YXRpb25NZXRhXG4pOlByb21pc2U8RmlsZT57XG4gIHJldHVybiBkYXRhVXJsKGZpbGUsIHRydWUpXG4gIC50aGVuKHVybD0+e1xuICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICB2YXIgaW1nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7XG5cbiAgICByZXR1cm4gPFByb21pc2U8RmlsZT4+bmV3IFByb21pc2UoZnVuY3Rpb24ocmVzLHJlail7XG4gICAgICBpbWcub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNhbnZhcy53aWR0aCA9IHJlc3VsdC5vcmllbnRhdGlvbiA+IDQgPyBpbWcuaGVpZ2h0IDogaW1nLndpZHRoXG4gICAgICAgICAgY2FudmFzLmhlaWdodCA9IHJlc3VsdC5vcmllbnRhdGlvbiA+IDQgPyBpbWcud2lkdGggOiBpbWcuaGVpZ2h0XG4gICAgICAgICAgdmFyIGN0eCA9IDxDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ+Y2FudmFzLmdldENvbnRleHQoJzJkJylcbiAgICAgICAgICBhcHBseVRyYW5zZm9ybShjdHgsIHJlc3VsdC5vcmllbnRhdGlvbiwgaW1nLndpZHRoLCBpbWcuaGVpZ2h0KVxuICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoaW1nLCAwLCAwKTtcbiAgICAgICAgICB2YXIgZGF0YVVybCA9IGNhbnZhcy50b0RhdGFVUkwoZmlsZS50eXBlIHx8ICdpbWFnZS9XZWJQJywgMC45MzQpXG4gICAgICAgICAgY29uc3QgYmFzZSA9IGFycmF5QnVmZmVyVG9CYXNlNjQocmVzdWx0LmZpeGVkQXJyYXlCdWZmZXIpXG4gICAgICAgICAgZGF0YVVybCA9IHJlc3RvcmVFeGlmKGJhc2UsIGRhdGFVcmwpXG4gICAgICAgICAgdmFyIGJsb2IgPSBkYXRhVXJsdG9CbG9iKGRhdGFVcmwsIGZpbGUubmFtZSlcbiAgICAgICAgICBjb25zdCBuZXdGaWxlID0gYmxvYlRvRmlsZShibG9iLCBmaWxlLm5hbWUpO1xuICAgICAgICAgIHJlcyhuZXdGaWxlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJlaihlKVxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgaW1nLm9uZXJyb3IgPSByZWo7XG4gICAgICBpbWcuc3JjID0gdXJsOyAgICBcbiAgICB9KVxuICB9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlFeGlmUm90YXRpb24oXG4gIGZpbGU6RmlsZVxuKTpQcm9taXNlPEZpbGU+e1xuICBpZiAoZmlsZS50eXBlLmluZGV4T2YoJ2ltYWdlL2pwZWcnKSAhPT0gMCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmlsZSk7XG4gIH1cblxuICByZXR1cm4gcmVhZE9yaWVudGF0aW9uKGZpbGUpXG4gIC50aGVuKChyZXN1bHQ6b3JpZW50YXRpb25NZXRhKT0+e1xuICAgIGlmIChyZXN1bHQub3JpZW50YXRpb24gPCAyIHx8IHJlc3VsdC5vcmllbnRhdGlvbiA+IDgpIHtcbiAgICAgIHJldHVybiBmaWxlXG4gICAgfVxuICAgIFxuICAgIHJldHVybiBmaXhGaWxlT3JpZW50YXRpb25CeU1ldGEoZmlsZSxyZXN1bHQpXG4gIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkT3JpZW50YXRpb24oXG4gIGZpbGU6RmlsZVxuKTpQcm9taXNlPG9yaWVudGF0aW9uTWV0YT57XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzLHJlaik9PntcbiAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICB2YXIgc2xpY2VkRmlsZSA9IGZpbGUuc2xpY2UgPyBmaWxlLnNsaWNlKDAsIDY0ICogMTAyNCkgOiBmaWxlO1xuICAgIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihzbGljZWRGaWxlKTtcbiAgICByZWFkZXIub25lcnJvciA9IHJlalxuICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoZTphbnkpIHtcbiAgICAgIHZhciByZXN1bHQ6b3JpZW50YXRpb25NZXRhID0ge29yaWVudGF0aW9uOiAxfTtcbiAgICAgIHZhciB2aWV3ID0gbmV3IERhdGFWaWV3KCA8QXJyYXlCdWZmZXI+dGhpcy5yZXN1bHQgKTtcbiAgICAgIGlmICh2aWV3LmdldFVpbnQxNigwLCBmYWxzZSkgIT09IDB4RkZEOCkgcmV0dXJuIHJlcyhyZXN1bHQpO1xuXG4gICAgICB2YXIgbGVuZ3RoID0gdmlldy5ieXRlTGVuZ3RoLFxuICAgICAgICBvZmZzZXQgPSAyO1xuICAgICAgd2hpbGUgKG9mZnNldCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgbWFya2VyID0gdmlldy5nZXRVaW50MTYob2Zmc2V0LCBmYWxzZSk7XG4gICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICBpZiAobWFya2VyID09PSAweEZGRTEpIHtcbiAgICAgICAgICBpZiAodmlldy5nZXRVaW50MzIob2Zmc2V0ICs9IDIsIGZhbHNlKSAhPT0gMHg0NTc4Njk2NikgcmV0dXJuIHJlcyhyZXN1bHQpO1xuXG4gICAgICAgICAgdmFyIGxpdHRsZSA9IHZpZXcuZ2V0VWludDE2KG9mZnNldCArPSA2LCBmYWxzZSkgPT09IDB4NDk0OTtcbiAgICAgICAgICBvZmZzZXQgKz0gdmlldy5nZXRVaW50MzIob2Zmc2V0ICsgNCwgbGl0dGxlKTtcbiAgICAgICAgICB2YXIgdGFncyA9IHZpZXcuZ2V0VWludDE2KG9mZnNldCwgbGl0dGxlKTtcbiAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRhZ3M7IGkrKylcbiAgICAgICAgICAgIGlmICh2aWV3LmdldFVpbnQxNihvZmZzZXQgKyAoaSAqIDEyKSwgbGl0dGxlKSA9PT0gMHgwMTEyKSB7XG4gICAgICAgICAgICAgIHZhciBvcmllbnRhdGlvbiA9IHZpZXcuZ2V0VWludDE2KG9mZnNldCArIChpICogMTIpICsgOCwgbGl0dGxlKTtcbiAgICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uID49IDIgJiYgb3JpZW50YXRpb24gPD0gOCkge1xuICAgICAgICAgICAgICAgIHZpZXcuc2V0VWludDE2KG9mZnNldCArIChpICogMTIpICsgOCwgMSwgbGl0dGxlKTtcbiAgICAgICAgICAgICAgICByZXN1bHQuZml4ZWRBcnJheUJ1ZmZlciA9IGUudGFyZ2V0LnJlc3VsdDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXN1bHQub3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlcyhyZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKChtYXJrZXIgJiAweEZGMDApICE9PSAweEZGMDApIGJyZWFrO1xuICAgICAgICBlbHNlIG9mZnNldCArPSB2aWV3LmdldFVpbnQxNihvZmZzZXQsIGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMocmVzdWx0KTtcbiAgICB9O1xuICB9KVxufVxuXG4vKiogY29udmVydHMgZmlsZS1pbnB1dCBmaWxlIGludG8gYmFzZTY0IGRhdGFVcmkgKi9cbmV4cG9ydCBmdW5jdGlvbiBkYXRhVXJsKFxuICBmaWxlOmFueSxcbiAgZGlzYWxsb3dPYmplY3RVcmw/OmFueVxuKTpQcm9taXNlPHN0cmluZz57XG4gIGlmICghZmlsZSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmaWxlKVxuICBcbiAgaWYgKChkaXNhbGxvd09iamVjdFVybCAmJiBmaWxlLiRuZ2ZEYXRhVXJsICE9IG51bGwpIHx8ICghZGlzYWxsb3dPYmplY3RVcmwgJiYgZmlsZS4kbmdmQmxvYlVybCAhPSBudWxsKSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoIGRpc2FsbG93T2JqZWN0VXJsID8gZmlsZS4kbmdmRGF0YVVybCA6IGZpbGUuJG5nZkJsb2JVcmwgKVxuICB9XG5cbiAgdmFyIHAgPSBkaXNhbGxvd09iamVjdFVybCA/IGZpbGUuJCRuZ2ZEYXRhVXJsUHJvbWlzZSA6IGZpbGUuJCRuZ2ZCbG9iVXJsUHJvbWlzZTtcbiAgaWYgKHApIHJldHVybiBwO1xuXG4gIGNvbnN0IHdpbiA9IGdldFdpbmRvdygpXG4gIGxldCBkZWZlcnJlZDpQcm9taXNlPHN0cmluZz5cbiAgaWYgKHdpbi5GaWxlUmVhZGVyICYmIGZpbGUgJiZcbiAgICAoIXdpbi5GaWxlQVBJIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignTVNJRSA4JykgPT09IC0xIHx8IGZpbGUuc2l6ZSA8IDIwMDAwKSAmJlxuICAgICghd2luLkZpbGVBUEkgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdNU0lFIDknKSA9PT0gLTEgfHwgZmlsZS5zaXplIDwgNDAwMDAwMCkpIHtcbiAgICAvL3ByZWZlciBVUkwuY3JlYXRlT2JqZWN0VVJMIGZvciBoYW5kbGluZyByZWZyZW5jZXMgdG8gZmlsZXMgb2YgYWxsIHNpemVzXG4gICAgLy9zaW5jZSBpdCBkb2VzbsK0dCBidWlsZCBhIGxhcmdlIHN0cmluZyBpbiBtZW1vcnlcbiAgICB2YXIgVVJMID0gd2luLlVSTCB8fCB3aW4ud2Via2l0VVJMO1xuICAgIGlmIChGaWxlUmVhZGVyKSB7XG4gICAgICBkZWZlcnJlZCA9IG5ldyBQcm9taXNlKChyZXMscmVqKT0+e1xuICAgICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24gKGV2ZW50OmFueSkge1xuICAgICAgICAgIGZpbGUuJG5nZkRhdGFVcmwgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgICAgIGRlbGV0ZSBmaWxlLiRuZ2ZEYXRhVXJsO1xuICAgICAgICAgIHJlcyggZXZlbnQudGFyZ2V0LnJlc3VsdCApXG4gICAgICAgIH07XG4gICAgICAgIGZpbGVSZWFkZXIub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgZmlsZS4kbmdmRGF0YVVybCA9ICcnO1xuICAgICAgICAgIHJlaihlKVxuICAgICAgICB9O1xuICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdXJsOmFueTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgZGVmZXJyZWQgPSBQcm9taXNlLnJlc29sdmUoIHVybCApXG4gICAgICBmaWxlLiRuZ2ZCbG9iVXJsID0gdXJsO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmaWxlW2Rpc2FsbG93T2JqZWN0VXJsID8gJyRuZ2ZEYXRhVXJsJyA6ICckbmdmQmxvYlVybCddID0gJyc7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCBuZXcgRXJyb3IoJ0Jyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCB3aW5kb3cuRmlsZVJlYWRlciwgd2luZG93LkZpbGVSZWFkZXIsIG9yIHdpbmRvdy5GaWxlQVBJJykgKS8vZGVmZXJyZWQucmVqZWN0KCk7XG4gIH1cblxuICBpZiAoZGlzYWxsb3dPYmplY3RVcmwpIHtcbiAgICBwID0gZmlsZS4kJG5nZkRhdGFVcmxQcm9taXNlID0gZGVmZXJyZWQ7XG4gIH0gZWxzZSB7XG4gICAgcCA9IGZpbGUuJCRuZ2ZCbG9iVXJsUHJvbWlzZSA9IGRlZmVycmVkO1xuICB9XG5cbiAgcCA9IHAudGhlbigoeDphbnkpPT57XG4gICAgZGVsZXRlIGZpbGVbZGlzYWxsb3dPYmplY3RVcmwgPyAnJCRuZ2ZEYXRhVXJsUHJvbWlzZScgOiAnJCRuZ2ZCbG9iVXJsUHJvbWlzZSddO1xuICAgIHJldHVybiB4XG4gIH0pXG5cbiAgcmV0dXJuIHA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXN0b3JlRXhpZihvcmlnOmFueSwgcmVzaXplZDphbnkpIHtcbiAgdmFyIEV4aWZSZXN0b3JlcjphbnkgPSB7XG4gICAgS0VZX1NUUjonQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz0nXG4gIH1cblxuICBFeGlmUmVzdG9yZXIuZW5jb2RlNjQgPSBmdW5jdGlvbiAoaW5wdXQ6YW55KSB7XG4gICAgdmFyIG91dHB1dCA9ICcnLFxuICAgICAgY2hyMSwgY2hyMiwgY2hyMzphbnkgPSAnJyxcbiAgICAgIGVuYzEsIGVuYzIsIGVuYzMsIGVuYzQ6YW55ID0gJycsXG4gICAgICBpID0gMDtcblxuICAgIGRvIHtcbiAgICAgIGNocjEgPSBpbnB1dFtpKytdO1xuICAgICAgY2hyMiA9IGlucHV0W2krK107XG4gICAgICBjaHIzID0gaW5wdXRbaSsrXTtcblxuICAgICAgZW5jMSA9IGNocjEgPj4gMjtcbiAgICAgIGVuYzIgPSAoKGNocjEgJiAzKSA8PCA0KSB8IChjaHIyID4+IDQpO1xuICAgICAgZW5jMyA9ICgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpO1xuICAgICAgZW5jNCA9IGNocjMgJiA2MztcblxuICAgICAgaWYgKGlzTmFOKGNocjIpKSB7XG4gICAgICAgIGVuYzMgPSBlbmM0ID0gNjQ7XG4gICAgICB9IGVsc2UgaWYgKGlzTmFOKGNocjMpKSB7XG4gICAgICAgIGVuYzQgPSA2NDtcbiAgICAgIH1cblxuICAgICAgb3V0cHV0ID0gb3V0cHV0ICtcbiAgICAgICAgdGhpcy5LRVlfU1RSLmNoYXJBdChlbmMxKSArXG4gICAgICAgIHRoaXMuS0VZX1NUUi5jaGFyQXQoZW5jMikgK1xuICAgICAgICB0aGlzLktFWV9TVFIuY2hhckF0KGVuYzMpICtcbiAgICAgICAgdGhpcy5LRVlfU1RSLmNoYXJBdChlbmM0KTtcbiAgICAgIGNocjEgPSBjaHIyID0gY2hyMyA9ICcnO1xuICAgICAgZW5jMSA9IGVuYzIgPSBlbmMzID0gZW5jNCA9ICcnO1xuICAgIH0gd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpO1xuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfTtcblxuICBFeGlmUmVzdG9yZXIucmVzdG9yZSA9IGZ1bmN0aW9uIChvcmlnRmlsZUJhc2U2NDphbnksIHJlc2l6ZWRGaWxlQmFzZTY0OmFueSkge1xuICAgIGlmIChvcmlnRmlsZUJhc2U2NC5tYXRjaCgnZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwnKSkge1xuICAgICAgb3JpZ0ZpbGVCYXNlNjQgPSBvcmlnRmlsZUJhc2U2NC5yZXBsYWNlKCdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcsICcnKTtcbiAgICB9XG5cbiAgICB2YXIgcmF3SW1hZ2U6bnVtYmVyW10gPSB0aGlzLmRlY29kZTY0KG9yaWdGaWxlQmFzZTY0KTtcbiAgICB2YXIgc2VnbWVudHMgPSB0aGlzLnNsaWNlMlNlZ21lbnRzKHJhd0ltYWdlKTtcblxuICAgIHZhciBpbWFnZSA9IHRoaXMuZXhpZk1hbmlwdWxhdGlvbihyZXNpemVkRmlsZUJhc2U2NCwgc2VnbWVudHMpO1xuXG4gICAgcmV0dXJuICdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcgKyB0aGlzLmVuY29kZTY0KGltYWdlKTtcbiAgfTtcblxuXG4gIEV4aWZSZXN0b3Jlci5leGlmTWFuaXB1bGF0aW9uID0gZnVuY3Rpb24gKHJlc2l6ZWRGaWxlQmFzZTY0OmFueSwgc2VnbWVudHM6YW55KSB7XG4gICAgdmFyIGV4aWZBcnJheSA9IHRoaXMuZ2V0RXhpZkFycmF5KHNlZ21lbnRzKSxcbiAgICAgIG5ld0ltYWdlQXJyYXkgPSB0aGlzLmluc2VydEV4aWYocmVzaXplZEZpbGVCYXNlNjQsIGV4aWZBcnJheSk7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG5ld0ltYWdlQXJyYXkpO1xuICB9O1xuXG4gIEV4aWZSZXN0b3Jlci5nZXRFeGlmQXJyYXkgPSBmdW5jdGlvbiAoc2VnbWVudHM6bnVtYmVyW11bXSkge1xuICAgIHZhciBzZWc7XG4gICAgZm9yICh2YXIgeCA9IDA7IHggPCBzZWdtZW50cy5sZW5ndGg7IHgrKykge1xuICAgICAgc2VnID0gc2VnbWVudHNbeF07XG4gICAgICBpZiAoc2VnWzBdID09PSAyNTUgJiYgc2VnWzFdID09PSAyMjUpIC8vKGZmIGUxKVxuICAgICAge1xuICAgICAgICByZXR1cm4gc2VnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH07XG5cblxuICBFeGlmUmVzdG9yZXIuaW5zZXJ0RXhpZiA9IGZ1bmN0aW9uIChyZXNpemVkRmlsZUJhc2U2NDphbnksIGV4aWZBcnJheTphbnkpIHtcbiAgICB2YXIgaW1hZ2VEYXRhID0gcmVzaXplZEZpbGVCYXNlNjQucmVwbGFjZSgnZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwnLCAnJyksXG4gICAgICBidWYgPSB0aGlzLmRlY29kZTY0KGltYWdlRGF0YSksXG4gICAgICBzZXBhcmF0ZVBvaW50ID0gYnVmLmluZGV4T2YoMjU1LCAzKSxcbiAgICAgIG1hZSA9IGJ1Zi5zbGljZSgwLCBzZXBhcmF0ZVBvaW50KSxcbiAgICAgIGF0byA9IGJ1Zi5zbGljZShzZXBhcmF0ZVBvaW50KSxcbiAgICAgIGFycmF5ID0gbWFlO1xuXG4gICAgYXJyYXkgPSBhcnJheS5jb25jYXQoZXhpZkFycmF5KTtcbiAgICBhcnJheSA9IGFycmF5LmNvbmNhdChhdG8pO1xuICAgIHJldHVybiBhcnJheTtcbiAgfTtcblxuXG4gIEV4aWZSZXN0b3Jlci5zbGljZTJTZWdtZW50cyA9IGZ1bmN0aW9uKFxuICAgIHJhd0ltYWdlQXJyYXk6bnVtYmVyW11cbiAgKSB7XG4gICAgdmFyIGhlYWQ6bnVtYmVyID0gMCxcbiAgICAgIHNlZ21lbnRzOm51bWJlcltdW10gPSBbXTtcblxuICAgIHdoaWxlICgxKSB7XG4gICAgICBpZiAocmF3SW1hZ2VBcnJheVtoZWFkXSA9PT0gMjU1ICYmIHJhd0ltYWdlQXJyYXlbaGVhZCArIDFdID09PSAyMTgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAocmF3SW1hZ2VBcnJheVtoZWFkXSA9PT0gMjU1ICYmIHJhd0ltYWdlQXJyYXlbaGVhZCArIDFdID09PSAyMTYpIHtcbiAgICAgICAgaGVhZCArPSAyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHZhciBsZW5ndGggPSByYXdJbWFnZUFycmF5W2hlYWQgKyAyXSAqIDI1NiArIHJhd0ltYWdlQXJyYXlbaGVhZCArIDNdXG4gICAgICAgIHZhciBlbmRQb2ludCA9IGhlYWQgKyBsZW5ndGggKyAyXG4gICAgICAgIHZhciBzZWc6bnVtYmVyW10gPSByYXdJbWFnZUFycmF5LnNsaWNlKGhlYWQsIGVuZFBvaW50KVxuICAgICAgICBzZWdtZW50cy5wdXNoKHNlZyk7XG4gICAgICAgIGhlYWQgPSBlbmRQb2ludDtcbiAgICAgIH1cbiAgICAgIGlmIChoZWFkID4gcmF3SW1hZ2VBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlZ21lbnRzO1xuICB9O1xuXG5cbiAgRXhpZlJlc3RvcmVyLmRlY29kZTY0ID0gZnVuY3Rpb24gKFxuICAgIGlucHV0OmFueVxuICApOm51bWJlcltde1xuICAgIHZhciBjaHIxLCBjaHIyLCBjaHIzOmFueSA9ICcnLFxuICAgICAgZW5jMSwgZW5jMiwgZW5jMywgZW5jNDphbnkgPSAnJyxcbiAgICAgIGkgPSAwLFxuICAgICAgYnVmOm51bWJlcltdID0gW107XG5cbiAgICAvLyByZW1vdmUgYWxsIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IEEtWiwgYS16LCAwLTksICssIC8sIG9yID1cbiAgICB2YXIgYmFzZTY0dGVzdCA9IC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZztcbiAgICBpZiAoYmFzZTY0dGVzdC5leGVjKGlucHV0KSkge1xuICAgICAgY29uc29sZS5sb2coJ1RoZXJlIHdlcmUgaW52YWxpZCBiYXNlNjQgY2hhcmFjdGVycyBpbiB0aGUgaW5wdXQgdGV4dC4nKTtcbiAgICB9XG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZywgJycpO1xuXG4gICAgZG8ge1xuICAgICAgZW5jMSA9IHRoaXMuS0VZX1NUUi5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgIGVuYzIgPSB0aGlzLktFWV9TVFIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICBlbmMzID0gdGhpcy5LRVlfU1RSLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgZW5jNCA9IHRoaXMuS0VZX1NUUi5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcblxuICAgICAgY2hyMSA9IChlbmMxIDw8IDIpIHwgKGVuYzIgPj4gNCk7XG4gICAgICBjaHIyID0gKChlbmMyICYgMTUpIDw8IDQpIHwgKGVuYzMgPj4gMik7XG4gICAgICBjaHIzID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0O1xuXG4gICAgICBidWYucHVzaChjaHIxKTtcblxuICAgICAgaWYgKGVuYzMgIT09IDY0KSB7XG4gICAgICAgIGJ1Zi5wdXNoKGNocjIpO1xuICAgICAgfVxuICAgICAgaWYgKGVuYzQgIT09IDY0KSB7XG4gICAgICAgIGJ1Zi5wdXNoKGNocjMpO1xuICAgICAgfVxuXG4gICAgICBjaHIxID0gY2hyMiA9IGNocjMgPSAnJztcbiAgICAgIGVuYzEgPSBlbmMyID0gZW5jMyA9IGVuYzQgPSAnJztcblxuICAgIH0gd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpO1xuXG4gICAgcmV0dXJuIGJ1ZjtcbiAgfTtcblxuICByZXR1cm4gRXhpZlJlc3RvcmVyLnJlc3RvcmUob3JpZywgcmVzaXplZCk7ICAvLzw9IEVYSUZcbn07XG5cbmZ1bmN0aW9uIGJsb2JUb0ZpbGUodGhlQmxvYjogQmxvYiwgZmlsZU5hbWU6c3RyaW5nKTogRmlsZSB7XG4gIHZhciBiOiBhbnkgPSB0aGVCbG9iO1xuICAvL0EgQmxvYigpIGlzIGFsbW9zdCBhIEZpbGUoKSAtIGl0J3MganVzdCBtaXNzaW5nIHRoZSB0d28gcHJvcGVydGllcyBiZWxvdyB3aGljaCB3ZSB3aWxsIGFkZFxuICBiLmxhc3RNb2RpZmllZERhdGUgPSBuZXcgRGF0ZSgpO1xuICBiLm5hbWUgPSBmaWxlTmFtZTtcblxuICAvL0Nhc3QgdG8gYSBGaWxlKCkgdHlwZVxuICByZXR1cm4gPEZpbGU+dGhlQmxvYjtcbn1cbiJdfQ== |
| import { Directive, EventEmitter, Input, Output, HostListener } from '@angular/core'; | ||
| import { createInvisibleFileInputWrap, isFileInput, detectSwipe } from "./doc-event-help.functions"; | ||
| import { acceptType, applyExifRotation, dataUrl } from "./fileTools"; | ||
| import * as i0 from "@angular/core"; | ||
| /** A master base set of logic intended to support file select/drag/drop operations | ||
| NOTE: Use ngfDrop for full drag/drop. Use ngfSelect for selecting | ||
| */ | ||
| export class ngf { | ||
| constructor(element) { | ||
| this.element = element; | ||
| this.filters = []; | ||
| this.lastFileCount = 0; | ||
| this.ngfFixOrientation = true; | ||
| this.fileDropDisabled = false; | ||
| this.selectable = false; | ||
| this.directiveInit = new EventEmitter(); | ||
| this.lastInvalids = []; | ||
| this.lastInvalidsChange = new EventEmitter(); | ||
| this.lastBaseUrlChange = new EventEmitter(); | ||
| this.fileChange = new EventEmitter(); | ||
| this.files = []; | ||
| this.filesChange = new EventEmitter(); | ||
| this.fileSelectStart = new EventEmitter(); | ||
| this.initFilters(); | ||
| } | ||
| initFilters() { | ||
| // the order is important | ||
| this.filters.push({ name: 'accept', fn: this._acceptFilter }); | ||
| this.filters.push({ name: 'fileSize', fn: this._fileSizeFilter }); | ||
| //this.filters.push({name: 'fileType', fn: this._fileTypeFilter}) | ||
| //this.filters.push({name: 'queueLimit', fn: this._queueLimitFilter}) | ||
| //this.filters.push({name: 'mimeType', fn: this._mimeTypeFilter}) | ||
| } | ||
| ngOnDestroy() { | ||
| delete this.fileElm; //faster memory release of dom element | ||
| this.destroyPasteListener(); | ||
| } | ||
| ngOnInit() { | ||
| const selectable = (this.selectable || this.selectable === '') && !['false', 'null', '0'].includes(this.selectable); | ||
| if (selectable) { | ||
| this.enableSelecting(); | ||
| } | ||
| if (this.multiple) { | ||
| this.paramFileElm().setAttribute('multiple', this.multiple); | ||
| } | ||
| this.evalCapturePaste(); | ||
| // create reference to this class with one cycle delay to avoid ExpressionChangedAfterItHasBeenCheckedError | ||
| setTimeout(() => { | ||
| this.directiveInit.emit(this); | ||
| }, 0); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.accept) { | ||
| this.paramFileElm().setAttribute('accept', changes.accept.currentValue || '*'); | ||
| } | ||
| if (changes.capturePaste) { | ||
| this.evalCapturePaste(); | ||
| } | ||
| // Did we go from having a file to not having a file? Clear file element then | ||
| if (changes.file && changes.file.previousValue && !changes.file.currentValue) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| // Did we go from having files to not having files? Clear file element then | ||
| if (changes.files) { | ||
| const filesWentToZero = changes.files.previousValue?.length && !changes.files.currentValue?.length; | ||
| if (filesWentToZero) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| } | ||
| } | ||
| evalCapturePaste() { | ||
| const isActive = this.capturePaste || this.capturePaste === '' || ['false', '0', 'null'].includes(this.capturePaste); | ||
| if (isActive) { | ||
| if (this.pasteCapturer) { | ||
| return; // already listening | ||
| } | ||
| this.pasteCapturer = (e) => { | ||
| const clip = e.clipboardData; | ||
| if (clip && clip.files && clip.files.length) { | ||
| this.handleFiles(clip.files); | ||
| e.preventDefault(); | ||
| } | ||
| }; | ||
| window.addEventListener('paste', this.pasteCapturer); | ||
| return; | ||
| } | ||
| this.destroyPasteListener(); | ||
| } | ||
| destroyPasteListener() { | ||
| if (this.pasteCapturer) { | ||
| window.removeEventListener('paste', this.pasteCapturer); | ||
| delete this.pasteCapturer; | ||
| } | ||
| } | ||
| paramFileElm() { | ||
| if (this.fileElm) | ||
| return this.fileElm; // already defined | ||
| // elm already is a file input | ||
| const isFile = isFileInput(this.element.nativeElement); | ||
| if (isFile) { | ||
| return this.fileElm = this.element.nativeElement; | ||
| } | ||
| // the host elm is NOT a file input | ||
| return this.fileElm = this.createFileElm({ | ||
| change: this.changeFn.bind(this) | ||
| }); | ||
| } | ||
| /** Only used when host element we are attached to is NOT a fileElement */ | ||
| createFileElm({ change }) { | ||
| // use specific technique to hide file element within | ||
| const label = createInvisibleFileInputWrap(); | ||
| const fileElm = label.getElementsByTagName('input')[0]; | ||
| fileElm.addEventListener('change', change); | ||
| this.element.nativeElement.appendChild(label); // put on html stage | ||
| return fileElm; | ||
| } | ||
| enableSelecting() { | ||
| let elm = this.element.nativeElement; | ||
| if (isFileInput(elm)) { | ||
| const bindedHandler = event => this.beforeSelect(event); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| return; | ||
| } | ||
| const bindedHandler = ev => this.clickHandler(ev); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| elm.addEventListener('touchend', bindedHandler); | ||
| } | ||
| getValidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (this.isFileValid(files[x])) { | ||
| rtn.push(files[x]); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| getInvalidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| let failReason = this.getFileFilterFailName(files[x]); | ||
| if (failReason) { | ||
| rtn.push({ | ||
| file: files[x], | ||
| type: failReason | ||
| }); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| // Primary handler of files coming in | ||
| handleFiles(files) { | ||
| const valids = this.getValidFiles(files); | ||
| if (files.length != valids.length) { | ||
| this.lastInvalids = this.getInvalidFiles(files); | ||
| } | ||
| else { | ||
| delete this.lastInvalids; | ||
| } | ||
| this.lastInvalidsChange.emit(this.lastInvalids); | ||
| if (valids.length) { | ||
| if (this.ngfFixOrientation) { | ||
| this.applyExifRotations(valids) | ||
| .then(fixedFiles => this.que(fixedFiles)); | ||
| } | ||
| else { | ||
| this.que(valids); | ||
| } | ||
| } | ||
| if (this.isEmptyAfterSelection()) { | ||
| this.element.nativeElement.value = ''; | ||
| } | ||
| } | ||
| que(files) { | ||
| this.files = this.files || []; | ||
| Array.prototype.push.apply(this.files, files); | ||
| //below break memory ref and doesnt act like a que | ||
| //this.files = files//causes memory change which triggers bindings like <ngfFormData [files]="files"></ngfFormData> | ||
| this.filesChange.emit(this.files); | ||
| if (files.length) { | ||
| this.fileChange.emit(this.file = files[0]); | ||
| if (this.lastBaseUrlChange.observers.length) { | ||
| dataUrl(files[0]) | ||
| .then(url => this.lastBaseUrlChange.emit(url)); | ||
| } | ||
| } | ||
| //will be checked for input value clearing | ||
| this.lastFileCount = this.files.length; | ||
| } | ||
| /** called when input has files */ | ||
| changeFn(event) { | ||
| var fileList = event.__files_ || (event.target && event.target.files); | ||
| if (!fileList) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(fileList); | ||
| } | ||
| clickHandler(evt) { | ||
| const elm = this.element.nativeElement; | ||
| if (elm.getAttribute('disabled') || this.fileDropDisabled) { | ||
| return false; | ||
| } | ||
| var r = detectSwipe(evt); | ||
| // prevent the click if it is a swipe | ||
| if (r !== false) | ||
| return r; | ||
| const fileElm = this.paramFileElm(); | ||
| fileElm.click(); | ||
| //fileElm.dispatchEvent( new Event('click') ); | ||
| this.beforeSelect(evt); | ||
| return false; | ||
| } | ||
| beforeSelect(event) { | ||
| this.fileSelectStart.emit(event); | ||
| if (this.files && this.lastFileCount === this.files.length) | ||
| return; | ||
| // if no files in array, be sure browser does not prevent reselect of same file (see github issue 27) | ||
| this.clearFileElmValue(); | ||
| } | ||
| clearFileElmValue() { | ||
| if (!this.fileElm) | ||
| return; | ||
| this.fileElm.value = null; | ||
| } | ||
| isEmptyAfterSelection() { | ||
| return !!this.element.nativeElement.attributes.multiple; | ||
| } | ||
| stopEvent(event) { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| } | ||
| transferHasFiles(transfer) { | ||
| if (!transfer.types) { | ||
| return false; | ||
| } | ||
| if (transfer.types.indexOf) { | ||
| return transfer.types.indexOf('Files') !== -1; | ||
| } | ||
| else if (transfer.types.contains) { | ||
| return transfer.types.contains('Files'); | ||
| } | ||
| else { | ||
| return false; | ||
| } | ||
| } | ||
| eventToFiles(event) { | ||
| const transfer = eventToTransfer(event); | ||
| if (transfer) { | ||
| if (transfer.files && transfer.files.length) { | ||
| return transfer.files; | ||
| } | ||
| if (transfer.items && transfer.items.length) { | ||
| return transfer.items; | ||
| } | ||
| } | ||
| return []; | ||
| } | ||
| applyExifRotations(files) { | ||
| const mapper = (file, index) => { | ||
| return applyExifRotation(file) | ||
| .then(fixedFile => files.splice(index, 1, fixedFile)); | ||
| }; | ||
| const proms = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| proms[x] = mapper(files[x], x); | ||
| } | ||
| return Promise.all(proms).then(() => files); | ||
| } | ||
| onChange(event) { | ||
| let files = this.element.nativeElement.files || this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| getFileFilterFailName(file) { | ||
| for (let i = 0; i < this.filters.length; i++) { | ||
| if (!this.filters[i].fn.call(this, file)) { | ||
| return this.filters[i].name; | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| isFileValid(file) { | ||
| const noFilters = !this.accept && (!this.filters || !this.filters.length); | ||
| if (noFilters) { | ||
| return true; //we have no filters so all files are valid | ||
| } | ||
| return this.getFileFilterFailName(file) ? false : true; | ||
| } | ||
| isFilesValid(files) { | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (!this.isFileValid(files[x])) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| _acceptFilter(item) { | ||
| return acceptType(this.accept, item.type, item.name); | ||
| } | ||
| _fileSizeFilter(item) { | ||
| return !(this.maxSize && item.size > this.maxSize); | ||
| } | ||
| } | ||
| ngf.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngf.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngf, selector: "[ngf]", inputs: { multiple: "multiple", accept: "accept", maxSize: "maxSize", ngfFixOrientation: "ngfFixOrientation", fileDropDisabled: "fileDropDisabled", selectable: "selectable", lastInvalids: "lastInvalids", lastBaseUrl: "lastBaseUrl", file: "file", files: "files", capturePaste: "capturePaste" }, outputs: { directiveInit: "init", lastInvalidsChange: "lastInvalidsChange", lastBaseUrlChange: "lastBaseUrlChange", fileChange: "fileChange", filesChange: "filesChange", fileSelectStart: "fileSelectStart" }, host: { listeners: { "change": "onChange($event)" } }, exportAs: ["ngf"], usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngf]", | ||
| exportAs: "ngf" | ||
| }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { multiple: [{ | ||
| type: Input | ||
| }], accept: [{ | ||
| type: Input | ||
| }], maxSize: [{ | ||
| type: Input | ||
| }], ngfFixOrientation: [{ | ||
| type: Input | ||
| }], fileDropDisabled: [{ | ||
| type: Input | ||
| }], selectable: [{ | ||
| type: Input | ||
| }], directiveInit: [{ | ||
| type: Output, | ||
| args: ['init'] | ||
| }], lastInvalids: [{ | ||
| type: Input | ||
| }], lastInvalidsChange: [{ | ||
| type: Output | ||
| }], lastBaseUrl: [{ | ||
| type: Input | ||
| }], lastBaseUrlChange: [{ | ||
| type: Output | ||
| }], file: [{ | ||
| type: Input | ||
| }], fileChange: [{ | ||
| type: Output | ||
| }], files: [{ | ||
| type: Input | ||
| }], filesChange: [{ | ||
| type: Output | ||
| }], fileSelectStart: [{ | ||
| type: Output | ||
| }], capturePaste: [{ | ||
| type: Input | ||
| }], onChange: [{ | ||
| type: HostListener, | ||
| args: ['change', ['$event']] | ||
| }] } }); | ||
| /** browsers try hard to conceal data about file drags, this tends to undo that */ | ||
| export function filesToWriteableObject(files) { | ||
| const jsonFiles = []; | ||
| for (let x = 0; x < files.length; ++x) { | ||
| jsonFiles.push({ | ||
| type: files[x].type, | ||
| kind: files[x]["kind"] | ||
| }); | ||
| } | ||
| return jsonFiles; | ||
| } | ||
| export function eventToTransfer(event) { | ||
| if (event.dataTransfer) | ||
| return event.dataTransfer; | ||
| return event.originalEvent ? event.originalEvent.dataTransfer : null; | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2YuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFjLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQUNoSCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFBO0FBQ25HLE9BQU8sRUFDTCxVQUFVLEVBQ1YsaUJBQWlCLEVBQUUsT0FBTyxFQUMzQixNQUFNLGFBQWEsQ0FBQTs7QUFPcEI7O0VBRUU7QUFLRixNQUFNLE9BQU8sR0FBRztJQWdDZCxZQUFtQixPQUFrQjtRQUFsQixZQUFPLEdBQVAsT0FBTyxDQUFXO1FBOUJyQyxZQUFPLEdBQStDLEVBQUUsQ0FBQTtRQUN4RCxrQkFBYSxHQUFXLENBQUMsQ0FBQTtRQUtoQixzQkFBaUIsR0FBWSxJQUFJLENBQUE7UUFFakMscUJBQWdCLEdBQVksS0FBSyxDQUFBO1FBQ2pDLGVBQVUsR0FBcUIsS0FBSyxDQUFBO1FBQzdCLGtCQUFhLEdBQXFCLElBQUksWUFBWSxFQUFFLENBQUE7UUFFM0QsaUJBQVksR0FBcUIsRUFBRSxDQUFBO1FBQ2xDLHVCQUFrQixHQUEyQyxJQUFJLFlBQVksRUFBRSxDQUFBO1FBRy9FLHNCQUFpQixHQUF3QixJQUFJLFlBQVksRUFBRSxDQUFBO1FBRzNELGVBQVUsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQUVwRCxVQUFLLEdBQVUsRUFBRSxDQUFBO1FBQ2hCLGdCQUFXLEdBQXdCLElBQUksWUFBWSxFQUFVLENBQUM7UUFFOUQsb0JBQWUsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQU9oRSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDcEIsQ0FBQztJQUVELFdBQVc7UUFDVCx5QkFBeUI7UUFDekIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFDLENBQUMsQ0FBQTtRQUMzRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUMsQ0FBQyxDQUFBO1FBRS9ELGlFQUFpRTtRQUNqRSxxRUFBcUU7UUFDckUsaUVBQWlFO0lBQ25FLENBQUM7SUFFRCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFBLENBQUEsc0NBQXNDO1FBQ3pELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRCxRQUFRO1FBQ04sTUFBTSxVQUFVLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFvQixDQUFDLENBQUM7UUFDNUgsSUFBSSxVQUFVLEVBQUU7WUFDZCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7U0FDdkI7UUFFRCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDakIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1NBQzVEO1FBRUQsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFeEIsMkdBQTJHO1FBQzNHLFVBQVUsQ0FBQyxHQUFFLEVBQUU7WUFDYixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMvQixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7SUFDUCxDQUFDO0lBRUQsV0FBVyxDQUFFLE9BQXNCO1FBQ2pDLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRTtZQUNsQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxHQUFHLENBQUMsQ0FBQTtTQUMvRTtRQUVELElBQUksT0FBTyxDQUFDLFlBQVksRUFBRTtZQUN4QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUN6QjtRQUVELDZFQUE2RTtRQUM3RSxJQUFJLE9BQU8sQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUM1RSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtTQUN6QjtRQUVELDJFQUEyRTtRQUMzRSxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUU7WUFDakIsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFBO1lBRWxHLElBQUksZUFBZSxFQUFFO2dCQUNuQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTthQUN6QjtTQUNGO0lBQ0gsQ0FBQztJQUVELGdCQUFnQjtRQUNkLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLElBQUssSUFBSSxDQUFDLFlBQW9CLEtBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFlBQW1CLENBQUMsQ0FBQztRQUVuSSxJQUFJLFFBQVEsRUFBRTtZQUNaLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtnQkFDdEIsT0FBTyxDQUFDLG9CQUFvQjthQUM3QjtZQUVELElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFRLEVBQUUsRUFBRTtnQkFDaEMsTUFBTSxJQUFJLEdBQUksQ0FBUyxDQUFDLGFBQWEsQ0FBQztnQkFDdEMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRTtvQkFDM0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzdCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztpQkFDcEI7WUFDSCxDQUFDLENBQUE7WUFFRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUVyRCxPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQsb0JBQW9CO1FBQ2xCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN0QixNQUFNLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN4RCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7U0FDM0I7SUFDSCxDQUFDO0lBRUQsWUFBWTtRQUNWLElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUEsQ0FBQyxrQkFBa0I7UUFFeEQsOEJBQThCO1FBQzlCLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBRSxDQUFBO1FBQ3hELElBQUcsTUFBTSxFQUFDO1lBQ1IsT0FBTyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFBO1NBQ2pEO1FBRUQsbUNBQW1DO1FBQ25DLE9BQU8sSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQ3ZDLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDakMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVELDBFQUEwRTtJQUMxRSxhQUFhLENBQUMsRUFBQyxNQUFNLEVBQXFCO1FBQ3hDLHFEQUFxRDtRQUNyRCxNQUFNLEtBQUssR0FBRyw0QkFBNEIsRUFBRSxDQUFBO1FBQzVDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUV0RCxPQUFPLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBRSxLQUFLLENBQUUsQ0FBQSxDQUFDLG9CQUFvQjtRQUVwRSxPQUFPLE9BQU8sQ0FBQTtJQUNoQixDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFBO1FBRXBDLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ3BCLE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUN2RCxHQUFHLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFBO1lBQzVDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsYUFBYSxDQUFDLENBQUE7WUFDakQsT0FBTTtTQUNQO1FBRUQsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ2pELEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFDLENBQUE7UUFDNUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQTtRQUNqRCxHQUFHLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxDQUFBO0lBQ2pELENBQUM7SUFFRCxhQUFhLENBQUUsS0FBWTtRQUN6QixNQUFNLEdBQUcsR0FBVSxFQUFFLENBQUE7UUFDckIsS0FBSSxJQUFJLENBQUMsR0FBQyxLQUFLLENBQUMsTUFBTSxHQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFDO1lBQ3BDLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDOUIsR0FBRyxDQUFDLElBQUksQ0FBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUUsQ0FBQTthQUNyQjtTQUNGO1FBQ0QsT0FBTyxHQUFHLENBQUE7SUFDWixDQUFDO0lBRUQsZUFBZSxDQUFDLEtBQVk7UUFDMUIsTUFBTSxHQUFHLEdBQXFCLEVBQUUsQ0FBQTtRQUNoQyxLQUFJLElBQUksQ0FBQyxHQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUM7WUFDcEMsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQ3JELElBQUksVUFBVSxFQUFFO2dCQUNkLEdBQUcsQ0FBQyxJQUFJLENBQUM7b0JBQ1AsSUFBSSxFQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQ2YsSUFBSSxFQUFHLFVBQVU7aUJBQ2xCLENBQUMsQ0FBQTthQUNIO1NBQ0Y7UUFDRCxPQUFPLEdBQUcsQ0FBQTtJQUNaLENBQUM7SUFFRCxxQ0FBcUM7SUFDckMsV0FBVyxDQUFDLEtBQVk7UUFDdEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUV4QyxJQUFHLEtBQUssQ0FBQyxNQUFNLElBQUUsTUFBTSxDQUFDLE1BQU0sRUFBQztZQUM3QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUE7U0FDaEQ7YUFBSTtZQUNILE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQTtTQUN6QjtRQUVELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBRS9DLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRTtZQUNqQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDMUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQztxQkFDOUIsSUFBSSxDQUFFLFVBQVUsQ0FBQSxFQUFFLENBQUEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBRSxDQUFBO2FBQzFDO2lCQUFJO2dCQUNILElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUE7YUFDakI7U0FDRjtRQUVELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLEVBQUU7WUFDaEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQTtTQUN0QztJQUNILENBQUM7SUFFRCxHQUFHLENBQUUsS0FBWTtRQUNmLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUE7UUFDN0IsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFFN0Msa0RBQWtEO1FBQ2xELG1IQUFtSDtRQUVuSCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsS0FBSyxDQUFFLENBQUE7UUFFbkMsSUFBRyxLQUFLLENBQUMsTUFBTSxFQUFDO1lBQ2QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUUsSUFBSSxDQUFDLElBQUksR0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUUsQ0FBQTtZQUUxQyxJQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFDO2dCQUN6QyxPQUFPLENBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFFO3FCQUNsQixJQUFJLENBQUUsR0FBRyxDQUFBLEVBQUUsQ0FBQSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFFLENBQUE7YUFDL0M7U0FDRjtRQUVELDBDQUEwQztRQUMxQyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFBO0lBQ3hDLENBQUM7SUFFRCxrQ0FBa0M7SUFDbEMsUUFBUSxDQUFDLEtBQVM7UUFDaEIsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUVyRSxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFFdEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQzVCLENBQUM7SUFFRCxZQUFZLENBQUMsR0FBVTtRQUNyQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQTtRQUN0QyxJQUFJLEdBQUcsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFDO1lBQ3hELE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFFRCxJQUFJLENBQUMsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekIscUNBQXFDO1FBQ3JDLElBQUssQ0FBQyxLQUFHLEtBQUs7WUFBRyxPQUFPLENBQUMsQ0FBQztRQUUxQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUE7UUFDbkMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQ2YsOENBQThDO1FBQzlDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUE7UUFFdEIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsWUFBWSxDQUFDLEtBQVk7UUFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFaEMsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNO1lBQUUsT0FBTTtRQUVoRSxxR0FBcUc7UUFDckcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUE7SUFDMUIsQ0FBQztJQUVELGlCQUFpQjtRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU07UUFFekIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO0lBQzNCLENBQUM7SUFFRCxxQkFBcUI7UUFDbkIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztJQUMxRCxDQUFDO0lBRUQsU0FBUyxDQUFDLEtBQVM7UUFDakIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsZ0JBQWdCLENBQUMsUUFBWTtRQUMzQixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtZQUNuQixPQUFPLEtBQUssQ0FBQztTQUNkO1FBRUQsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUMxQixPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQy9DO2FBQU0sSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRTtZQUNsQyxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3pDO2FBQU07WUFDTCxPQUFPLEtBQUssQ0FBQztTQUNkO0lBQ0gsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFXO1FBQ3RCLE1BQU0sUUFBUSxHQUFHLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN4QyxJQUFJLFFBQVEsRUFBRTtZQUNaLElBQUcsUUFBUSxDQUFDLEtBQUssSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBQztnQkFDekMsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFBO2FBQ3RCO1lBQ0QsSUFBRyxRQUFRLENBQUMsS0FBSyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFDO2dCQUN6QyxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUE7YUFDdEI7U0FDRjtRQUNELE9BQU8sRUFBRSxDQUFBO0lBQ1gsQ0FBQztJQUVELGtCQUFrQixDQUNoQixLQUFZO1FBRVosTUFBTSxNQUFNLEdBQUcsQ0FDYixJQUFTLEVBQUMsS0FBWSxFQUNWLEVBQUU7WUFDZCxPQUFPLGlCQUFpQixDQUFDLElBQUksQ0FBQztpQkFDN0IsSUFBSSxDQUFFLFNBQVMsQ0FBQSxFQUFFLENBQUEsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFFLENBQUE7UUFDdkQsQ0FBQyxDQUFBO1FBRUQsTUFBTSxLQUFLLEdBQWtCLEVBQUUsQ0FBQTtRQUMvQixLQUFJLElBQUksQ0FBQyxHQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUM7WUFDcEMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFFLENBQUE7U0FDakM7UUFDRCxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUUsS0FBSyxDQUFFLENBQUMsSUFBSSxDQUFFLEdBQUUsRUFBRSxDQUFBLEtBQUssQ0FBRSxDQUFBO0lBQy9DLENBQUM7SUFHRCxRQUFRLENBQUMsS0FBVztRQUNsQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUV4RSxJQUFHLENBQUMsS0FBSyxDQUFDLE1BQU07WUFBQyxPQUFNO1FBRXZCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUN6QixDQUFDO0lBRUQscUJBQXFCLENBQ25CLElBQVM7UUFFVCxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUM7WUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUU7Z0JBQ3hDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7YUFDNUI7U0FDRjtRQUNELE9BQU8sU0FBUyxDQUFBO0lBQ2xCLENBQUM7SUFFRCxXQUFXLENBQUMsSUFBUztRQUNuQixNQUFNLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3pFLElBQUksU0FBUyxFQUFFO1lBQ2IsT0FBTyxJQUFJLENBQUEsQ0FBQSwyQ0FBMkM7U0FDdkQ7UUFFRCxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7SUFDeEQsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFZO1FBQ3ZCLEtBQUksSUFBSSxDQUFDLEdBQUMsS0FBSyxDQUFDLE1BQU0sR0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBQztZQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDL0IsT0FBTyxLQUFLLENBQUE7YUFDYjtTQUNGO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRVMsYUFBYSxDQUFDLElBQVM7UUFDL0IsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUN0RCxDQUFDO0lBRVMsZUFBZSxDQUFDLElBQVM7UUFDakMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyRCxDQUFDOztpR0E1WFUsR0FBRztxRkFBSCxHQUFHOzRGQUFILEdBQUc7a0JBSmYsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsT0FBTztvQkFDakIsUUFBUSxFQUFDLEtBQUs7aUJBQ2Y7aUdBTVUsUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFFRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDVSxhQUFhO3NCQUE1QixNQUFNO3VCQUFDLE1BQU07Z0JBRUwsWUFBWTtzQkFBcEIsS0FBSztnQkFDSSxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBRUUsV0FBVztzQkFBbkIsS0FBSztnQkFDSSxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBRUUsSUFBSTtzQkFBWixLQUFLO2dCQUNJLFVBQVU7c0JBQW5CLE1BQU07Z0JBRUUsS0FBSztzQkFBYixLQUFLO2dCQUNJLFdBQVc7c0JBQXBCLE1BQU07Z0JBRUcsZUFBZTtzQkFBeEIsTUFBTTtnQkFFRSxZQUFZO3NCQUFwQixLQUFLO2dCQW9UTixRQUFRO3NCQURQLFlBQVk7dUJBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDOztBQWlEcEMsa0ZBQWtGO0FBQ2xGLE1BQU0sVUFBVSxzQkFBc0IsQ0FBRSxLQUFZO0lBQ2xELE1BQU0sU0FBUyxHQUFjLEVBQUUsQ0FBQTtJQUMvQixLQUFJLElBQUksQ0FBQyxHQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBQztRQUNqQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2IsSUFBSSxFQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJO1lBQ2xCLElBQUksRUFBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1NBQ3RCLENBQUMsQ0FBQTtLQUNIO0lBQ0QsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQztBQUVELE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBVTtJQUN4QyxJQUFHLEtBQUssQ0FBQyxZQUFZO1FBQUMsT0FBTyxLQUFLLENBQUMsWUFBWSxDQUFBO0lBQy9DLE9BQVEsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtBQUN2RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIEVsZW1lbnRSZWYsIElucHV0LCBPdXRwdXQsIEhvc3RMaXN0ZW5lciwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgY3JlYXRlSW52aXNpYmxlRmlsZUlucHV0V3JhcCwgaXNGaWxlSW5wdXQsIGRldGVjdFN3aXBlIH0gZnJvbSBcIi4vZG9jLWV2ZW50LWhlbHAuZnVuY3Rpb25zXCJcbmltcG9ydCB7XG4gIGFjY2VwdFR5cGUsIEludmFsaWRGaWxlSXRlbSxcbiAgYXBwbHlFeGlmUm90YXRpb24sIGRhdGFVcmxcbn0gZnJvbSBcIi4vZmlsZVRvb2xzXCJcblxuZXhwb3J0IGludGVyZmFjZSBkcmFnTWV0YXtcbiAgdHlwZTpzdHJpbmdcbiAga2luZDpzdHJpbmdcbn1cblxuLyoqIEEgbWFzdGVyIGJhc2Ugc2V0IG9mIGxvZ2ljIGludGVuZGVkIHRvIHN1cHBvcnQgZmlsZSBzZWxlY3QvZHJhZy9kcm9wIG9wZXJhdGlvbnNcbiBOT1RFOiBVc2UgbmdmRHJvcCBmb3IgZnVsbCBkcmFnL2Ryb3AuIFVzZSBuZ2ZTZWxlY3QgZm9yIHNlbGVjdGluZ1xuKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogXCJbbmdmXVwiLFxuICBleHBvcnRBczpcIm5nZlwiXG59KVxuZXhwb3J0IGNsYXNzIG5nZiB7XG4gIGZpbGVFbG06IGFueVxuICBmaWx0ZXJzOiB7bmFtZTogc3RyaW5nLCBmbjogKGZpbGU6RmlsZSk9PmJvb2xlYW59W10gPSBbXVxuICBsYXN0RmlsZUNvdW50OiBudW1iZXIgPSAwXG5cbiAgQElucHV0KCkgbXVsdGlwbGUgITpzdHJpbmdcbiAgQElucHV0KCkgYWNjZXB0ICAgITpzdHJpbmdcbiAgQElucHV0KCkgbWF4U2l6ZSAgITpudW1iZXJcbiAgQElucHV0KCkgbmdmRml4T3JpZW50YXRpb246IGJvb2xlYW4gPSB0cnVlXG5cbiAgQElucHV0KCkgZmlsZURyb3BEaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlXG4gIEBJbnB1dCgpIHNlbGVjdGFibGU6IGJvb2xlYW4gfCBzdHJpbmcgPSBmYWxzZVxuICBAT3V0cHV0KCdpbml0JykgZGlyZWN0aXZlSW5pdDpFdmVudEVtaXR0ZXI8bmdmPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGxhc3RJbnZhbGlkczpJbnZhbGlkRmlsZUl0ZW1bXSA9IFtdXG4gIEBPdXRwdXQoKSBsYXN0SW52YWxpZHNDaGFuZ2U6RXZlbnRFbWl0dGVyPHtmaWxlOkZpbGUsdHlwZTpzdHJpbmd9W10+ID0gbmV3IEV2ZW50RW1pdHRlcigpXG5cbiAgQElucHV0KCkgbGFzdEJhc2VVcmwhOiBzdHJpbmcvL2Jhc2U2NCBsYXN0IGZpbGUgdXBsb2FkZWQgdXJsXG4gIEBPdXRwdXQoKSBsYXN0QmFzZVVybENoYW5nZTpFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGZpbGU/OiBGaWxlLy9sYXN0IGZpbGUgdXBsb2FkZWRcbiAgQE91dHB1dCgpIGZpbGVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxGaWxlPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGZpbGVzOkZpbGVbXSA9IFtdXG4gIEBPdXRwdXQoKSBmaWxlc0NoYW5nZTpFdmVudEVtaXR0ZXI8RmlsZVtdPiA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZVtdPigpO1xuXG4gIEBPdXRwdXQoKSBmaWxlU2VsZWN0U3RhcnQ6RXZlbnRFbWl0dGVyPEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGNhcHR1cmVQYXN0ZTogYm9vbGVhbiAvLyB3aW5kb3cgcGFzdGUgZmlsZSB3YXRjaGluZyAoZW1wdHkgc3RyaW5nIHR1cm5zIG9uKVxuXG4gIHBhc3RlQ2FwdHVyZXIhOiAoZTogRXZlbnQpID0+IHZvaWQgLy8gZ29lcyB3aXRoIGNhcHR1cmVQYXN0ZVxuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBlbGVtZW50OkVsZW1lbnRSZWYpe1xuICAgIHRoaXMuaW5pdEZpbHRlcnMoKVxuICB9XG5cbiAgaW5pdEZpbHRlcnMoKXtcbiAgICAvLyB0aGUgb3JkZXIgaXMgaW1wb3J0YW50XG4gICAgdGhpcy5maWx0ZXJzLnB1c2goe25hbWU6ICdhY2NlcHQnLCBmbjogdGhpcy5fYWNjZXB0RmlsdGVyfSlcbiAgICB0aGlzLmZpbHRlcnMucHVzaCh7bmFtZTogJ2ZpbGVTaXplJywgZm46IHRoaXMuX2ZpbGVTaXplRmlsdGVyfSlcblxuICAgIC8vdGhpcy5maWx0ZXJzLnB1c2goe25hbWU6ICdmaWxlVHlwZScsIGZuOiB0aGlzLl9maWxlVHlwZUZpbHRlcn0pXG4gICAgLy90aGlzLmZpbHRlcnMucHVzaCh7bmFtZTogJ3F1ZXVlTGltaXQnLCBmbjogdGhpcy5fcXVldWVMaW1pdEZpbHRlcn0pXG4gICAgLy90aGlzLmZpbHRlcnMucHVzaCh7bmFtZTogJ21pbWVUeXBlJywgZm46IHRoaXMuX21pbWVUeXBlRmlsdGVyfSlcbiAgfVxuXG4gIG5nT25EZXN0cm95KCl7XG4gICAgZGVsZXRlIHRoaXMuZmlsZUVsbS8vZmFzdGVyIG1lbW9yeSByZWxlYXNlIG9mIGRvbSBlbGVtZW50XG4gICAgdGhpcy5kZXN0cm95UGFzdGVMaXN0ZW5lcigpO1xuICB9XG5cbiAgbmdPbkluaXQoKXtcbiAgICBjb25zdCBzZWxlY3RhYmxlID0gKHRoaXMuc2VsZWN0YWJsZSB8fCB0aGlzLnNlbGVjdGFibGU9PT0nJykgJiYgIVsnZmFsc2UnLCAnbnVsbCcsICcwJ10uaW5jbHVkZXModGhpcy5zZWxlY3RhYmxlIGFzIHN0cmluZyk7XG4gICAgaWYoIHNlbGVjdGFibGUgKXtcbiAgICAgIHRoaXMuZW5hYmxlU2VsZWN0aW5nKClcbiAgICB9XG5cbiAgICBpZiggdGhpcy5tdWx0aXBsZSApe1xuICAgICAgdGhpcy5wYXJhbUZpbGVFbG0oKS5zZXRBdHRyaWJ1dGUoJ211bHRpcGxlJywgdGhpcy5tdWx0aXBsZSlcbiAgICB9XG5cbiAgICB0aGlzLmV2YWxDYXB0dXJlUGFzdGUoKTtcblxuICAgIC8vIGNyZWF0ZSByZWZlcmVuY2UgdG8gdGhpcyBjbGFzcyB3aXRoIG9uZSBjeWNsZSBkZWxheSB0byBhdm9pZCBFeHByZXNzaW9uQ2hhbmdlZEFmdGVySXRIYXNCZWVuQ2hlY2tlZEVycm9yXG4gICAgc2V0VGltZW91dCgoKT0+e1xuICAgICAgdGhpcy5kaXJlY3RpdmVJbml0LmVtaXQodGhpcylcbiAgICB9LCAwKVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoIGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMgKXtcbiAgICBpZiggY2hhbmdlcy5hY2NlcHQgKXtcbiAgICAgIHRoaXMucGFyYW1GaWxlRWxtKCkuc2V0QXR0cmlidXRlKCdhY2NlcHQnLCBjaGFuZ2VzLmFjY2VwdC5jdXJyZW50VmFsdWUgfHwgJyonKVxuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzLmNhcHR1cmVQYXN0ZSkge1xuICAgICAgdGhpcy5ldmFsQ2FwdHVyZVBhc3RlKCk7XG4gICAgfVxuXG4gICAgLy8gRGlkIHdlIGdvIGZyb20gaGF2aW5nIGEgZmlsZSB0byBub3QgaGF2aW5nIGEgZmlsZT8gQ2xlYXIgZmlsZSBlbGVtZW50IHRoZW5cbiAgICBpZiAoY2hhbmdlcy5maWxlICYmIGNoYW5nZXMuZmlsZS5wcmV2aW91c1ZhbHVlICYmICFjaGFuZ2VzLmZpbGUuY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLmNsZWFyRmlsZUVsbVZhbHVlKClcbiAgICB9XG5cbiAgICAvLyBEaWQgd2UgZ28gZnJvbSBoYXZpbmcgZmlsZXMgdG8gbm90IGhhdmluZyBmaWxlcz8gQ2xlYXIgZmlsZSBlbGVtZW50IHRoZW5cbiAgICBpZiAoY2hhbmdlcy5maWxlcykge1xuICAgICAgY29uc3QgZmlsZXNXZW50VG9aZXJvID0gY2hhbmdlcy5maWxlcy5wcmV2aW91c1ZhbHVlPy5sZW5ndGggJiYgIWNoYW5nZXMuZmlsZXMuY3VycmVudFZhbHVlPy5sZW5ndGhcblxuICAgICAgaWYgKGZpbGVzV2VudFRvWmVybykge1xuICAgICAgICB0aGlzLmNsZWFyRmlsZUVsbVZhbHVlKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBldmFsQ2FwdHVyZVBhc3RlKCkge1xuICAgIGNvbnN0IGlzQWN0aXZlID0gdGhpcy5jYXB0dXJlUGFzdGUgfHwgKHRoaXMuY2FwdHVyZVBhc3RlIGFzIGFueSk9PT0nJyB8fCBbJ2ZhbHNlJywgJzAnLCAnbnVsbCddLmluY2x1ZGVzKHRoaXMuY2FwdHVyZVBhc3RlIGFzIGFueSk7XG5cbiAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgIGlmICh0aGlzLnBhc3RlQ2FwdHVyZXIpIHtcbiAgICAgICAgcmV0dXJuOyAvLyBhbHJlYWR5IGxpc3RlbmluZ1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBhc3RlQ2FwdHVyZXIgPSAoZTogRXZlbnQpID0+IHtcbiAgICAgICAgY29uc3QgY2xpcCA9IChlIGFzIGFueSkuY2xpcGJvYXJkRGF0YTtcbiAgICAgICAgaWYgKGNsaXAgJiYgY2xpcC5maWxlcyAmJiBjbGlwLmZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuaGFuZGxlRmlsZXMoY2xpcC5maWxlcyk7XG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwYXN0ZScsIHRoaXMucGFzdGVDYXB0dXJlcik7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmRlc3Ryb3lQYXN0ZUxpc3RlbmVyKCk7XG4gIH1cblxuICBkZXN0cm95UGFzdGVMaXN0ZW5lcigpIHtcbiAgICBpZiAodGhpcy5wYXN0ZUNhcHR1cmVyKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncGFzdGUnLCB0aGlzLnBhc3RlQ2FwdHVyZXIpO1xuICAgICAgZGVsZXRlIHRoaXMucGFzdGVDYXB0dXJlcjtcbiAgICB9XG4gIH1cblxuICBwYXJhbUZpbGVFbG0oKXtcbiAgICBpZiggdGhpcy5maWxlRWxtIClyZXR1cm4gdGhpcy5maWxlRWxtIC8vIGFscmVhZHkgZGVmaW5lZFxuXG4gICAgLy8gZWxtIGFscmVhZHkgaXMgYSBmaWxlIGlucHV0XG4gICAgY29uc3QgaXNGaWxlID0gaXNGaWxlSW5wdXQoIHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50IClcbiAgICBpZihpc0ZpbGUpe1xuICAgICAgcmV0dXJuIHRoaXMuZmlsZUVsbSA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50XG4gICAgfVxuXG4gICAgLy8gdGhlIGhvc3QgZWxtIGlzIE5PVCBhIGZpbGUgaW5wdXRcbiAgICByZXR1cm4gdGhpcy5maWxlRWxtID0gdGhpcy5jcmVhdGVGaWxlRWxtKHtcbiAgICAgIGNoYW5nZTogdGhpcy5jaGFuZ2VGbi5iaW5kKHRoaXMpXG4gICAgfSlcbiAgfVxuXG4gIC8qKiBPbmx5IHVzZWQgd2hlbiBob3N0IGVsZW1lbnQgd2UgYXJlIGF0dGFjaGVkIHRvIGlzIE5PVCBhIGZpbGVFbGVtZW50ICovXG4gIGNyZWF0ZUZpbGVFbG0oe2NoYW5nZX06IHtjaGFuZ2U6KCkgPT4gYW55fSkge1xuICAgIC8vIHVzZSBzcGVjaWZpYyB0ZWNobmlxdWUgdG8gaGlkZSBmaWxlIGVsZW1lbnQgd2l0aGluXG4gICAgY29uc3QgbGFiZWwgPSBjcmVhdGVJbnZpc2libGVGaWxlSW5wdXRXcmFwKClcbiAgICBjb25zdCBmaWxlRWxtID0gbGFiZWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0JylbMF1cblxuICAgIGZpbGVFbG0uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgY2hhbmdlKTtcbiAgICB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZCggbGFiZWwgKSAvLyBwdXQgb24gaHRtbCBzdGFnZVxuXG4gICAgcmV0dXJuIGZpbGVFbG1cbiAgfVxuXG4gIGVuYWJsZVNlbGVjdGluZygpe1xuICAgIGxldCBlbG0gPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudFxuXG4gICAgaWYoIGlzRmlsZUlucHV0KGVsbSkgKXtcbiAgICAgIGNvbnN0IGJpbmRlZEhhbmRsZXIgPSBldmVudCA9PiB0aGlzLmJlZm9yZVNlbGVjdChldmVudClcbiAgICAgIGVsbS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGJpbmRlZEhhbmRsZXIpXG4gICAgICBlbG0uYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGJpbmRlZEhhbmRsZXIpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBiaW5kZWRIYW5kbGVyID0gZXYgPT4gdGhpcy5jbGlja0hhbmRsZXIoZXYpXG4gICAgZWxtLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYmluZGVkSGFuZGxlcilcbiAgICBlbG0uYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGJpbmRlZEhhbmRsZXIpXG4gICAgZWxtLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgYmluZGVkSGFuZGxlcilcbiAgfVxuXG4gIGdldFZhbGlkRmlsZXMoIGZpbGVzOkZpbGVbXSApOkZpbGVbXXtcbiAgICBjb25zdCBydG46RmlsZVtdID0gW11cbiAgICBmb3IobGV0IHg9ZmlsZXMubGVuZ3RoLTE7IHggPj0gMDsgLS14KXtcbiAgICAgIGlmKCB0aGlzLmlzRmlsZVZhbGlkKGZpbGVzW3hdKSApe1xuICAgICAgICBydG4ucHVzaCggZmlsZXNbeF0gKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcnRuXG4gIH1cblxuICBnZXRJbnZhbGlkRmlsZXMoZmlsZXM6RmlsZVtdKTpJbnZhbGlkRmlsZUl0ZW1bXXtcbiAgICBjb25zdCBydG46SW52YWxpZEZpbGVJdGVtW10gPSBbXVxuICAgIGZvcihsZXQgeD1maWxlcy5sZW5ndGgtMTsgeCA+PSAwOyAtLXgpe1xuICAgICAgbGV0IGZhaWxSZWFzb24gPSB0aGlzLmdldEZpbGVGaWx0ZXJGYWlsTmFtZShmaWxlc1t4XSlcbiAgICAgIGlmKCBmYWlsUmVhc29uICl7XG4gICAgICAgIHJ0bi5wdXNoKHtcbiAgICAgICAgICBmaWxlIDogZmlsZXNbeF0sXG4gICAgICAgICAgdHlwZSA6IGZhaWxSZWFzb25cbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJ0blxuICB9XG5cbiAgLy8gUHJpbWFyeSBoYW5kbGVyIG9mIGZpbGVzIGNvbWluZyBpblxuICBoYW5kbGVGaWxlcyhmaWxlczpGaWxlW10pe1xuICAgIGNvbnN0IHZhbGlkcyA9IHRoaXMuZ2V0VmFsaWRGaWxlcyhmaWxlcylcblxuICAgIGlmKGZpbGVzLmxlbmd0aCE9dmFsaWRzLmxlbmd0aCl7XG4gICAgICB0aGlzLmxhc3RJbnZhbGlkcyA9IHRoaXMuZ2V0SW52YWxpZEZpbGVzKGZpbGVzKVxuICAgIH1lbHNle1xuICAgICAgZGVsZXRlIHRoaXMubGFzdEludmFsaWRzXG4gICAgfVxuXG4gICAgdGhpcy5sYXN0SW52YWxpZHNDaGFuZ2UuZW1pdCh0aGlzLmxhc3RJbnZhbGlkcylcblxuICAgIGlmKCB2YWxpZHMubGVuZ3RoICl7XG4gICAgICBpZiggdGhpcy5uZ2ZGaXhPcmllbnRhdGlvbiApe1xuICAgICAgICB0aGlzLmFwcGx5RXhpZlJvdGF0aW9ucyh2YWxpZHMpXG4gICAgICAgIC50aGVuKCBmaXhlZEZpbGVzPT50aGlzLnF1ZShmaXhlZEZpbGVzKSApXG4gICAgICB9ZWxzZXtcbiAgICAgICAgdGhpcy5xdWUodmFsaWRzKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmlzRW1wdHlBZnRlclNlbGVjdGlvbigpKSB7XG4gICAgICB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnXG4gICAgfVxuICB9XG5cbiAgcXVlKCBmaWxlczpGaWxlW10gKXtcbiAgICB0aGlzLmZpbGVzID0gdGhpcy5maWxlcyB8fCBbXVxuICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRoaXMuZmlsZXMsIGZpbGVzKVxuXG4gICAgLy9iZWxvdyBicmVhayBtZW1vcnkgcmVmIGFuZCBkb2VzbnQgYWN0IGxpa2UgYSBxdWVcbiAgICAvL3RoaXMuZmlsZXMgPSBmaWxlcy8vY2F1c2VzIG1lbW9yeSBjaGFuZ2Ugd2hpY2ggdHJpZ2dlcnMgYmluZGluZ3MgbGlrZSA8bmdmRm9ybURhdGEgW2ZpbGVzXT1cImZpbGVzXCI+PC9uZ2ZGb3JtRGF0YT5cblxuICAgIHRoaXMuZmlsZXNDaGFuZ2UuZW1pdCggdGhpcy5maWxlcyApXG5cbiAgICBpZihmaWxlcy5sZW5ndGgpe1xuICAgICAgdGhpcy5maWxlQ2hhbmdlLmVtaXQoIHRoaXMuZmlsZT1maWxlc1swXSApXG5cbiAgICAgIGlmKHRoaXMubGFzdEJhc2VVcmxDaGFuZ2Uub2JzZXJ2ZXJzLmxlbmd0aCl7XG4gICAgICAgIGRhdGFVcmwoIGZpbGVzWzBdIClcbiAgICAgICAgLnRoZW4oIHVybD0+dGhpcy5sYXN0QmFzZVVybENoYW5nZS5lbWl0KHVybCkgKVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vd2lsbCBiZSBjaGVja2VkIGZvciBpbnB1dCB2YWx1ZSBjbGVhcmluZ1xuICAgIHRoaXMubGFzdEZpbGVDb3VudCA9IHRoaXMuZmlsZXMubGVuZ3RoXG4gIH1cblxuICAvKiogY2FsbGVkIHdoZW4gaW5wdXQgaGFzIGZpbGVzICovXG4gIGNoYW5nZUZuKGV2ZW50OmFueSkge1xuICAgIHZhciBmaWxlTGlzdCA9IGV2ZW50Ll9fZmlsZXNfIHx8IChldmVudC50YXJnZXQgJiYgZXZlbnQudGFyZ2V0LmZpbGVzKVxuXG4gICAgaWYgKCFmaWxlTGlzdCkgcmV0dXJuO1xuXG4gICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgIHRoaXMuaGFuZGxlRmlsZXMoZmlsZUxpc3QpXG4gIH1cblxuICBjbGlja0hhbmRsZXIoZXZ0OiBFdmVudCl7XG4gICAgY29uc3QgZWxtID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnRcbiAgICBpZiAoZWxtLmdldEF0dHJpYnV0ZSgnZGlzYWJsZWQnKSB8fCB0aGlzLmZpbGVEcm9wRGlzYWJsZWQpe1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciByID0gZGV0ZWN0U3dpcGUoZXZ0KTtcbiAgICAvLyBwcmV2ZW50IHRoZSBjbGljayBpZiBpdCBpcyBhIHN3aXBlXG4gICAgaWYgKCByIT09ZmFsc2UgKSByZXR1cm4gcjtcblxuICAgIGNvbnN0IGZpbGVFbG0gPSB0aGlzLnBhcmFtRmlsZUVsbSgpXG4gICAgZmlsZUVsbS5jbGljaygpXG4gICAgLy9maWxlRWxtLmRpc3BhdGNoRXZlbnQoIG5ldyBFdmVudCgnY2xpY2snKSApO1xuICAgIHRoaXMuYmVmb3JlU2VsZWN0KGV2dClcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGJlZm9yZVNlbGVjdChldmVudDogRXZlbnQpe1xuICAgIHRoaXMuZmlsZVNlbGVjdFN0YXJ0LmVtaXQoZXZlbnQpXG5cbiAgICBpZiggdGhpcy5maWxlcyAmJiB0aGlzLmxhc3RGaWxlQ291bnQ9PT10aGlzLmZpbGVzLmxlbmd0aCApcmV0dXJuXG5cbiAgICAvLyBpZiBubyBmaWxlcyBpbiBhcnJheSwgYmUgc3VyZSBicm93c2VyIGRvZXMgbm90IHByZXZlbnQgcmVzZWxlY3Qgb2Ygc2FtZSBmaWxlIChzZWUgZ2l0aHViIGlzc3VlIDI3KVxuICAgIHRoaXMuY2xlYXJGaWxlRWxtVmFsdWUoKVxuICB9XG5cbiAgY2xlYXJGaWxlRWxtVmFsdWUoKSB7XG4gICAgaWYgKCF0aGlzLmZpbGVFbG0pIHJldHVyblxuXG4gICAgdGhpcy5maWxlRWxtLnZhbHVlID0gbnVsbFxuICB9XG5cbiAgaXNFbXB0eUFmdGVyU2VsZWN0aW9uKCk6Ym9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuYXR0cmlidXRlcy5tdWx0aXBsZTtcbiAgfVxuXG4gIHN0b3BFdmVudChldmVudDphbnkpOmFueSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHRyYW5zZmVySGFzRmlsZXModHJhbnNmZXI6YW55KTphbnkge1xuICAgIGlmICghdHJhbnNmZXIudHlwZXMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodHJhbnNmZXIudHlwZXMuaW5kZXhPZikge1xuICAgICAgcmV0dXJuIHRyYW5zZmVyLnR5cGVzLmluZGV4T2YoJ0ZpbGVzJykgIT09IC0xO1xuICAgIH0gZWxzZSBpZiAodHJhbnNmZXIudHlwZXMuY29udGFpbnMpIHtcbiAgICAgIHJldHVybiB0cmFuc2Zlci50eXBlcy5jb250YWlucygnRmlsZXMnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGV2ZW50VG9GaWxlcyhldmVudDpFdmVudCl7XG4gICAgY29uc3QgdHJhbnNmZXIgPSBldmVudFRvVHJhbnNmZXIoZXZlbnQpO1xuICAgIGlmKCB0cmFuc2ZlciApe1xuICAgICAgaWYodHJhbnNmZXIuZmlsZXMgJiYgdHJhbnNmZXIuZmlsZXMubGVuZ3RoKXtcbiAgICAgICAgcmV0dXJuIHRyYW5zZmVyLmZpbGVzXG4gICAgICB9XG4gICAgICBpZih0cmFuc2Zlci5pdGVtcyAmJiB0cmFuc2Zlci5pdGVtcy5sZW5ndGgpe1xuICAgICAgICByZXR1cm4gdHJhbnNmZXIuaXRlbXNcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFtdXG4gIH1cblxuICBhcHBseUV4aWZSb3RhdGlvbnMoXG4gICAgZmlsZXM6RmlsZVtdXG4gICk6UHJvbWlzZTxGaWxlW10+e1xuICAgIGNvbnN0IG1hcHBlciA9IChcbiAgICAgIGZpbGU6RmlsZSxpbmRleDpudW1iZXJcbiAgICApOlByb21pc2U8YW55Pj0+e1xuICAgICAgcmV0dXJuIGFwcGx5RXhpZlJvdGF0aW9uKGZpbGUpXG4gICAgICAudGhlbiggZml4ZWRGaWxlPT5maWxlcy5zcGxpY2UoaW5kZXgsIDEsIGZpeGVkRmlsZSkgKVxuICAgIH1cblxuICAgIGNvbnN0IHByb21zOlByb21pc2U8YW55PltdID0gW11cbiAgICBmb3IobGV0IHg9ZmlsZXMubGVuZ3RoLTE7IHggPj0gMDsgLS14KXtcbiAgICAgIHByb21zW3hdID0gbWFwcGVyKCBmaWxlc1t4XSwgeCApXG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLmFsbCggcHJvbXMgKS50aGVuKCAoKT0+ZmlsZXMgKVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignY2hhbmdlJywgWyckZXZlbnQnXSlcbiAgb25DaGFuZ2UoZXZlbnQ6RXZlbnQpOnZvaWQge1xuICAgIGxldCBmaWxlcyA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmZpbGVzIHx8IHRoaXMuZXZlbnRUb0ZpbGVzKGV2ZW50KVxuXG4gICAgaWYoIWZpbGVzLmxlbmd0aClyZXR1cm5cblxuICAgIHRoaXMuc3RvcEV2ZW50KGV2ZW50KTtcbiAgICB0aGlzLmhhbmRsZUZpbGVzKGZpbGVzKVxuICB9XG5cbiAgZ2V0RmlsZUZpbHRlckZhaWxOYW1lKFxuICAgIGZpbGU6RmlsZVxuICApOnN0cmluZyB8IHVuZGVmaW5lZHtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5maWx0ZXJzLmxlbmd0aDsgaSsrKXtcbiAgICAgIGlmKCAhdGhpcy5maWx0ZXJzW2ldLmZuLmNhbGwodGhpcywgZmlsZSkgKXtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyc1tpXS5uYW1lXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIGlzRmlsZVZhbGlkKGZpbGU6RmlsZSk6Ym9vbGVhbntcbiAgICBjb25zdCBub0ZpbHRlcnMgPSAhdGhpcy5hY2NlcHQgJiYgKCF0aGlzLmZpbHRlcnMgfHwgIXRoaXMuZmlsdGVycy5sZW5ndGgpXG4gICAgaWYoIG5vRmlsdGVycyApe1xuICAgICAgcmV0dXJuIHRydWUvL3dlIGhhdmUgbm8gZmlsdGVycyBzbyBhbGwgZmlsZXMgYXJlIHZhbGlkXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ2V0RmlsZUZpbHRlckZhaWxOYW1lKGZpbGUpID8gZmFsc2UgOiB0cnVlXG4gIH1cblxuICBpc0ZpbGVzVmFsaWQoZmlsZXM6RmlsZVtdKXtcbiAgICBmb3IobGV0IHg9ZmlsZXMubGVuZ3RoLTE7IHggPj0gMDsgLS14KXtcbiAgICAgIGlmKCAhdGhpcy5pc0ZpbGVWYWxpZChmaWxlc1t4XSkgKXtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBwcm90ZWN0ZWQgX2FjY2VwdEZpbHRlcihpdGVtOkZpbGUpOmJvb2xlYW4ge1xuICAgIHJldHVybiBhY2NlcHRUeXBlKHRoaXMuYWNjZXB0LCBpdGVtLnR5cGUsIGl0ZW0ubmFtZSlcbiAgfVxuXG4gIHByb3RlY3RlZCBfZmlsZVNpemVGaWx0ZXIoaXRlbTpGaWxlKTpib29sZWFuIHtcbiAgICByZXR1cm4gISh0aGlzLm1heFNpemUgJiYgaXRlbS5zaXplID4gdGhpcy5tYXhTaXplKTtcbiAgfVxufVxuXG5cbi8qKiBicm93c2VycyB0cnkgaGFyZCB0byBjb25jZWFsIGRhdGEgYWJvdXQgZmlsZSBkcmFncywgdGhpcyB0ZW5kcyB0byB1bmRvIHRoYXQgKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWxlc1RvV3JpdGVhYmxlT2JqZWN0KCBmaWxlczpGaWxlW10gKTpkcmFnTWV0YVtde1xuICBjb25zdCBqc29uRmlsZXM6ZHJhZ01ldGFbXSA9IFtdXG4gIGZvcihsZXQgeD0wOyB4IDwgZmlsZXMubGVuZ3RoOyArK3gpe1xuICAgIGpzb25GaWxlcy5wdXNoKHtcbiAgICAgIHR5cGU6ZmlsZXNbeF0udHlwZSxcbiAgICAgIGtpbmQ6ZmlsZXNbeF1bXCJraW5kXCJdXG4gICAgfSlcbiAgfVxuICByZXR1cm4ganNvbkZpbGVzXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldmVudFRvVHJhbnNmZXIoZXZlbnQ6IGFueSk6IFRyYW5zZmVyT2JqZWN0IHtcbiAgaWYoZXZlbnQuZGF0YVRyYW5zZmVyKXJldHVybiBldmVudC5kYXRhVHJhbnNmZXJcbiAgcmV0dXJuICBldmVudC5vcmlnaW5hbEV2ZW50ID8gZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXIgOiBudWxsXG59XG5cblxuaW50ZXJmYWNlIFRyYW5zZmVyT2JqZWN0IHtcbiAgaXRlbXM/OiBhbnlbXVxuICBmaWxlcz86IGFueVtdXG4gIGRyb3BFZmZlY3Q/OiAnY29weScgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0RhdGFUcmFuc2Zlci9kcm9wRWZmZWN0XG59XG4iXX0= |
| import { CommonModule } from '@angular/common'; | ||
| import { NgModule } from '@angular/core'; | ||
| import { ngfBackground } from './ngfBackground.directive'; | ||
| import { ngfDrop } from './ngfDrop.directive'; | ||
| import { ngf } from './ngf.directive'; | ||
| import { ngfSelect } from './ngfSelect.directive'; | ||
| import { ngfUploadStatus } from './ngfUploadStatus.directive'; | ||
| import { ngfFormData } from './ngfFormData.directive'; | ||
| import { ngfSrc } from './ngfSrc.directive'; | ||
| import * as i0 from "@angular/core"; | ||
| //import{ HttpModule } from '@angular/http'; | ||
| const declarations = [ | ||
| ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf | ||
| ]; | ||
| export class ngfModule { | ||
| } | ||
| ngfModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); | ||
| ngfModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, declarations: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf], imports: [CommonModule | ||
| //,HttpModule | ||
| ], exports: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf] }); | ||
| ngfModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, imports: [[ | ||
| CommonModule | ||
| //,HttpModule | ||
| ]] }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, decorators: [{ | ||
| type: NgModule, | ||
| args: [{ | ||
| imports: [ | ||
| CommonModule | ||
| //,HttpModule | ||
| ], | ||
| declarations: declarations, | ||
| exports: declarations //[HttpModule, ...declarations] | ||
| }] | ||
| }] }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2YubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXpDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7QUFDNUMsNENBQTRDO0FBRTVDLE1BQU0sWUFBWSxHQUFHO0lBQ25CLE9BQU87SUFDUCxTQUFTO0lBQ1QsYUFBYTtJQUNiLE1BQU07SUFDTixlQUFlO0lBQ2YsV0FBVztJQUNYLEdBQUc7Q0FDSixDQUFBO0FBU0UsTUFBTSxPQUFPLFNBQVM7O3VHQUFULFNBQVM7d0dBQVQsU0FBUyxpQkFoQnZCLE9BQU87UUFDUCxTQUFTO1FBQ1QsYUFBYTtRQUNiLE1BQU07UUFDTixlQUFlO1FBQ2YsV0FBVztRQUNYLEdBQUcsYUFLRCxZQUFZO1FBQ1osYUFBYTtpQkFaZixPQUFPO1FBQ1AsU0FBUztRQUNULGFBQWE7UUFDYixNQUFNO1FBQ04sZUFBZTtRQUNmLFdBQVc7UUFDWCxHQUFHO3dHQVVXLFNBQVMsWUFOZDtZQUNQLFlBQVk7WUFDWixhQUFhO1NBQ2Q7NEZBR2EsU0FBUztrQkFQeEIsUUFBUTttQkFBQztvQkFDUixPQUFPLEVBQUU7d0JBQ1AsWUFBWTt3QkFDWixhQUFhO3FCQUNkO29CQUNELFlBQVksRUFBRSxZQUFZO29CQUMxQixPQUFPLEVBQUUsWUFBWSxDQUFBLCtCQUErQjtpQkFDckQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgbmdmQmFja2dyb3VuZCB9IGZyb20gJy4vbmdmQmFja2dyb3VuZC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgbmdmRHJvcCB9IGZyb20gJy4vbmdmRHJvcC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgbmdmIH0gZnJvbSAnLi9uZ2YuZGlyZWN0aXZlJztcbmltcG9ydCB7IG5nZlNlbGVjdCB9IGZyb20gJy4vbmdmU2VsZWN0LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBuZ2ZVcGxvYWRTdGF0dXMgfSBmcm9tICcuL25nZlVwbG9hZFN0YXR1cy5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgbmdmRm9ybURhdGEgfSBmcm9tICcuL25nZkZvcm1EYXRhLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBuZ2ZTcmMgfSBmcm9tICcuL25nZlNyYy5kaXJlY3RpdmUnO1xuLy9pbXBvcnR7IEh0dHBNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9odHRwJztcblxuY29uc3QgZGVjbGFyYXRpb25zID0gW1xuICBuZ2ZEcm9wLFxuICBuZ2ZTZWxlY3QsXG4gIG5nZkJhY2tncm91bmQsXG4gIG5nZlNyYyxcbiAgbmdmVXBsb2FkU3RhdHVzLFxuICBuZ2ZGb3JtRGF0YSxcbiAgbmdmXG5dXG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGVcbiAgICAvLyxIdHRwTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogZGVjbGFyYXRpb25zLFxuICBleHBvcnRzOiBkZWNsYXJhdGlvbnMvL1tIdHRwTW9kdWxlLCAuLi5kZWNsYXJhdGlvbnNdXG59KSBleHBvcnQgY2xhc3MgbmdmTW9kdWxlIHt9Il19 |
| import { Directive, Input } from '@angular/core'; | ||
| import { dataUrl } from './fileTools'; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfBackground { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => { | ||
| const urlString = 'url(\'' + (src || '') + '\')'; | ||
| this.ElementRef.nativeElement.style.backgroundImage = urlString; | ||
| }); | ||
| } | ||
| } | ||
| ngfBackground.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfBackground.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfBackground, selector: "[ngfBackground]", inputs: { file: ["ngfBackground", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfBackground]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfBackground'] | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmQmFja2dyb3VuZC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZmlsZS11cGxvYWQvbmdmQmFja2dyb3VuZC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGFBQWEsQ0FBQzs7QUFHdEMsTUFBTSxPQUFPLGFBQWE7SUFHeEIsWUFBbUIsVUFBcUI7UUFBckIsZUFBVSxHQUFWLFVBQVUsQ0FBVztJQUFFLENBQUM7SUFFM0MsV0FBVyxDQUFFLFFBQVk7UUFDdkIsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDakIsSUFBSSxDQUFDLEdBQUcsQ0FBQSxFQUFFO1lBQ1QsTUFBTSxTQUFTLEdBQUcsUUFBUSxHQUFHLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQTtZQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLFNBQVMsQ0FBQTtRQUNqRSxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7OzJHQVhVLGFBQWE7K0ZBQWIsYUFBYTs0RkFBYixhQUFhO2tCQUR6QixTQUFTO21CQUFDLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDO2lHQUVkLElBQUk7c0JBQTNCLEtBQUs7dUJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGRhdGFVcmwgfSBmcm9tICcuL2ZpbGVUb29scyc7XG5cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnW25nZkJhY2tncm91bmRdJ30pXG5leHBvcnQgY2xhc3MgbmdmQmFja2dyb3VuZCB7XG4gIEBJbnB1dCgnbmdmQmFja2dyb3VuZCcpIGZpbGU6YW55XG5cbiAgY29uc3RydWN0b3IocHVibGljIEVsZW1lbnRSZWY6RWxlbWVudFJlZil7fVxuXG4gIG5nT25DaGFuZ2VzKCBfY2hhbmdlczphbnkgKXtcbiAgICBkYXRhVXJsKHRoaXMuZmlsZSlcbiAgICAudGhlbihzcmM9PntcbiAgICAgIGNvbnN0IHVybFN0cmluZyA9ICd1cmwoXFwnJyArIChzcmMgfHwgJycpICsgJ1xcJyknXG4gICAgICB0aGlzLkVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSB1cmxTdHJpbmdcbiAgICB9KVxuICB9XG59XG4iXX0= |
| import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core'; | ||
| import { ngf, eventToTransfer, filesToWriteableObject } from "./ngf.directive"; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfDrop extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.fileOver = new EventEmitter(); | ||
| this.validDrag = false; | ||
| this.validDragChange = new EventEmitter(); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange = new EventEmitter(); | ||
| this.dragFilesChange = new EventEmitter(); | ||
| } | ||
| onDrop(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| let files = this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| handleFiles(files) { | ||
| this.fileOver.emit(false); //turn-off dragover | ||
| super.handleFiles(files); | ||
| } | ||
| onDragOver(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| const transfer = eventToTransfer(event); | ||
| let files = this.eventToFiles(event); | ||
| let jsonFiles = filesToWriteableObject(files); | ||
| this.dragFilesChange.emit(this.dragFiles = jsonFiles); | ||
| if (files.length) { | ||
| this.validDrag = this.isFilesValid(files); | ||
| } | ||
| else { | ||
| //Safari, IE11 & some browsers do NOT tell you about dragged files until dropped. Always consider a valid drag | ||
| this.validDrag = true; | ||
| } | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = !this.validDrag; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| transfer.dropEffect = 'copy'; // change cursor and visual display | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(true); | ||
| } | ||
| closeDrags() { | ||
| delete this.validDrag; | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| delete this.dragFiles; | ||
| this.dragFilesChange.emit(this.dragFiles); | ||
| } | ||
| onDragLeave(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| if (this.element) { | ||
| if (event.currentTarget === this.element[0]) { | ||
| return; | ||
| } | ||
| } | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(false); | ||
| } | ||
| } | ||
| ngfDrop.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfDrop.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfDrop, selector: "[ngfDrop]", inputs: { validDrag: "validDrag", invalidDrag: "invalidDrag", dragFiles: "dragFiles" }, outputs: { fileOver: "fileOver", validDragChange: "validDragChange", invalidDragChange: "invalidDragChange", dragFilesChange: "dragFilesChange" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)" } }, exportAs: ["ngfDrop"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfDrop]", | ||
| exportAs: "ngfDrop" | ||
| }] | ||
| }], propDecorators: { fileOver: [{ | ||
| type: Output | ||
| }], validDrag: [{ | ||
| type: Input | ||
| }], validDragChange: [{ | ||
| type: Output | ||
| }], invalidDrag: [{ | ||
| type: Input | ||
| }], invalidDragChange: [{ | ||
| type: Output | ||
| }], dragFiles: [{ | ||
| type: Input | ||
| }], dragFilesChange: [{ | ||
| type: Output | ||
| }], onDrop: [{ | ||
| type: HostListener, | ||
| args: ['drop', ['$event']] | ||
| }], onDragOver: [{ | ||
| type: HostListener, | ||
| args: ['dragover', ['$event']] | ||
| }], onDragLeave: [{ | ||
| type: HostListener, | ||
| args: ['dragleave', ['$event']] | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmRHJvcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZmlsZS11cGxvYWQvbmdmRHJvcC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFBRSxZQUFZLEVBQ3ZCLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUM1QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsR0FBRyxFQUFZLGVBQWUsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlCQUFpQixDQUFBOztBQU14RixNQUFNLE9BQU8sT0FBUSxTQUFRLEdBQUc7SUFKaEM7O1FBS1ksYUFBUSxHQUFxQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBRWpELGNBQVMsR0FBVyxLQUFLLENBQUE7UUFDeEIsb0JBQWUsR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQUUzRCxnQkFBVyxHQUFHLEtBQUssQ0FBQTtRQUNsQixzQkFBaUIsR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQTtRQUc1RCxvQkFBZSxHQUE0QixJQUFJLFlBQVksRUFBRSxDQUFBO0tBaUZ4RTtJQTlFQyxNQUFNLENBQUMsS0FBVztRQUNoQixJQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBQztZQUN2QixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RCLE9BQU07U0FDUDtRQUVELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUNqQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRXBDLElBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTTtZQUFDLE9BQU07UUFFdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3pCLENBQUM7SUFFRCxXQUFXLENBQUMsS0FBWTtRQUN0QixJ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QUFNO2dCQUVFLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0ksZUFBZTtzQkFBeEIsTUFBTTtnQkFHUCxNQUFNO3NCQURMLFlBQVk7dUJBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQXNCaEMsVUFBVTtzQkFEVCxZQUFZO3VCQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkF5Q3BDLFdBQVc7c0JBRFYsWUFBWTt1QkFBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBEaXJlY3RpdmUsIEV2ZW50RW1pdHRlcixcbiAgSG9zdExpc3RlbmVyLCBJbnB1dCwgT3V0cHV0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgbmdmLCBkcmFnTWV0YSwgZXZlbnRUb1RyYW5zZmVyLCBmaWxlc1RvV3JpdGVhYmxlT2JqZWN0IH0gZnJvbSBcIi4vbmdmLmRpcmVjdGl2ZVwiXG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogXCJbbmdmRHJvcF1cIixcbiAgZXhwb3J0QXM6IFwibmdmRHJvcFwiXG59KVxuZXhwb3J0IGNsYXNzIG5nZkRyb3AgZXh0ZW5kcyBuZ2Yge1xuICBAT3V0cHV0KCkgZmlsZU92ZXI6RXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgQElucHV0KCkgdmFsaWREcmFnOmJvb2xlYW4gPSBmYWxzZVxuICBAT3V0cHV0KCkgdmFsaWREcmFnQ2hhbmdlOkV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGludmFsaWREcmFnID0gZmFsc2VcbiAgQE91dHB1dCgpIGludmFsaWREcmFnQ2hhbmdlOkV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG4gIEBJbnB1dCgpIGRyYWdGaWxlcyAhOiBkcmFnTWV0YVtdXG4gIEBPdXRwdXQoKSBkcmFnRmlsZXNDaGFuZ2U6RXZlbnRFbWl0dGVyPGRyYWdNZXRhW10+ID0gbmV3IEV2ZW50RW1pdHRlcigpXG5cbiAgQEhvc3RMaXN0ZW5lcignZHJvcCcsIFsnJGV2ZW50J10pXG4gIG9uRHJvcChldmVudDpFdmVudCk6dm9pZCB7XG4gICAgaWYodGhpcy5maWxlRHJvcERpc2FibGVkKXtcbiAgICAgIHRoaXMuc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuY2xvc2VEcmFncygpXG4gICAgbGV0IGZpbGVzID0gdGhpcy5ldmVudFRvRmlsZXMoZXZlbnQpXG5cbiAgICBpZighZmlsZXMubGVuZ3RoKXJldHVyblxuXG4gICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgIHRoaXMuaGFuZGxlRmlsZXMoZmlsZXMpXG4gIH1cblxuICBoYW5kbGVGaWxlcyhmaWxlczpGaWxlW10pe1xuICAgIHRoaXMuZmlsZU92ZXIuZW1pdChmYWxzZSkvL3R1cm4tb2ZmIGRyYWdvdmVyXG4gICAgc3VwZXIuaGFuZGxlRmlsZXMoZmlsZXMpXG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkcmFnb3ZlcicsIFsnJGV2ZW50J10pXG4gIG9uRHJhZ092ZXIoZXZlbnQ6RXZlbnQpOnZvaWQge1xuICAgIGlmKHRoaXMuZmlsZURyb3BEaXNhYmxlZCl7XG4gICAgICB0aGlzLnN0b3BFdmVudChldmVudCk7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc2ZlciA9IGV2ZW50VG9UcmFuc2ZlcihldmVudClcblxuICAgIGxldCBmaWxlcyA9IHRoaXMuZXZlbnRUb0ZpbGVzKGV2ZW50KVxuXG4gICAgbGV0IGpzb25GaWxlcyA9IGZpbGVzVG9Xcml0ZWFibGVPYmplY3QoZmlsZXMpXG4gICAgdGhpcy5kcmFnRmlsZXNDaGFuZ2UuZW1pdCggdGhpcy5kcmFnRmlsZXM9anNvbkZpbGVzIClcblxuICAgIGlmKCBmaWxlcy5sZW5ndGggKXtcbiAgICAgIHRoaXMudmFsaWREcmFnID0gdGhpcy5pc0ZpbGVzVmFsaWQoZmlsZXMpXG4gICAgfWVsc2V7XG4gICAgICAvL1NhZmFyaSwgSUUxMSAmIHNvbWUgYnJvd3NlcnMgZG8gTk9UIHRlbGwgeW91IGFib3V0IGRyYWdnZWQgZmlsZXMgdW50aWwgZHJvcHBlZC4gQWx3YXlzIGNvbnNpZGVyIGEgdmFsaWQgZHJhZ1xuICAgICAgdGhpcy52YWxpZERyYWcgPSB0cnVlXG4gICAgfVxuXG4gICAgdGhpcy52YWxpZERyYWdDaGFuZ2UuZW1pdCh0aGlzLnZhbGlkRHJhZylcblxuICAgIHRoaXMuaW52YWxpZERyYWcgPSAhdGhpcy52YWxpZERyYWdcbiAgICB0aGlzLmludmFsaWREcmFnQ2hhbmdlLmVtaXQodGhpcy5pbnZhbGlkRHJhZylcblxuICAgIHRyYW5zZmVyLmRyb3BFZmZlY3QgPSAnY29weScgLy8gY2hhbmdlIGN1cnNvciBhbmQgdmlzdWFsIGRpc3BsYXlcbiAgICB0aGlzLnN0b3BFdmVudChldmVudClcbiAgICB0aGlzLmZpbGVPdmVyLmVtaXQodHJ1ZSlcbiAgfVxuXG4gIGNsb3NlRHJhZ3MoKXtcbiAgICBkZWxldGUgdGhpcy52YWxpZERyYWdcbiAgICB0aGlzLnZhbGlkRHJhZ0NoYW5nZS5lbWl0KHRoaXMudmFsaWREcmFnKVxuICAgIHRoaXMuaW52YWxpZERyYWcgPSBmYWxzZVxuICAgIHRoaXMuaW52YWxpZERyYWdDaGFuZ2UuZW1pdCh0aGlzLmludmFsaWREcmFnKVxuICAgIGRlbGV0ZSB0aGlzLmRyYWdGaWxlc1xuICAgIHRoaXMuZHJhZ0ZpbGVzQ2hhbmdlLmVtaXQoIHRoaXMuZHJhZ0ZpbGVzIClcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIFsnJGV2ZW50J10pXG4gIG9uRHJhZ0xlYXZlKGV2ZW50OkV2ZW50KTphbnkge1xuICAgIGlmKHRoaXMuZmlsZURyb3BEaXNhYmxlZCl7XG4gICAgICB0aGlzLnN0b3BFdmVudChldmVudCk7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlRHJhZ3MoKVxuXG4gICAgaWYgKCh0aGlzIGFzIGFueSkuZWxlbWVudCkge1xuICAgICAgaWYgKGV2ZW50LmN1cnJlbnRUYXJnZXQgPT09ICh0aGlzIGFzIGFueSkuZWxlbWVudFswXSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgIHRoaXMuZmlsZU92ZXIuZW1pdChmYWxzZSk7XG4gIH1cbn0iXX0= |
| import { Directive, EventEmitter, Output, Input } from '@angular/core'; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfFormData { | ||
| constructor(IterableDiffers) { | ||
| this.postName = "file"; | ||
| this.FormData = new FormData(); | ||
| this.FormDataChange = new EventEmitter(); | ||
| this.differ = IterableDiffers.find([]).create(); | ||
| } | ||
| ngDoCheck() { | ||
| var changes = this.differ.diff(this.files); | ||
| if (changes) { | ||
| setTimeout(() => this.buildFormData(), 0); | ||
| } | ||
| } | ||
| buildFormData() { | ||
| const isArray = typeof (this.files) === 'object' && this.files.constructor === Array; | ||
| if (isArray) { | ||
| this.FormData = new FormData(); | ||
| const files = this.files || []; | ||
| files.forEach(file => this.FormData.append(this.postName, file, this.fileName || file.name)); | ||
| this.FormDataChange.emit(this.FormData); | ||
| } | ||
| else { | ||
| delete this.FormData; | ||
| } | ||
| } | ||
| } | ||
| ngfFormData.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, deps: [{ token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfFormData.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfFormData, selector: "ngfFormData", inputs: { files: "files", postName: "postName", fileName: "fileName", FormData: "FormData" }, outputs: { FormDataChange: "FormDataChange" }, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfFormData' }] | ||
| }], ctorParameters: function () { return [{ type: i0.IterableDiffers }]; }, propDecorators: { files: [{ | ||
| type: Input | ||
| }], postName: [{ | ||
| type: Input | ||
| }], fileName: [{ | ||
| type: Input | ||
| }], FormData: [{ | ||
| type: Input | ||
| }], FormDataChange: [{ | ||
| type: Output | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmRm9ybURhdGEuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2ZpbGUtdXBsb2FkL25nZkZvcm1EYXRhLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0wsU0FBUyxFQUFFLFlBQVksRUFDdkIsTUFBTSxFQUFFLEtBQUssRUFDZCxNQUFNLGVBQWUsQ0FBQzs7QUFHdkIsTUFBTSxPQUFPLFdBQVc7SUFVdEIsWUFBWSxlQUFnQztRQVJuQyxhQUFRLEdBQVUsTUFBTSxDQUFBO1FBR3hCLGFBQVEsR0FBWSxJQUFJLFFBQVEsRUFBRSxDQUFBO1FBQ2pDLG1CQUFjLEdBQTBCLElBQUksWUFBWSxFQUFFLENBQUE7UUFLbEUsSUFBSSxDQUFDLE1BQU0sR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFBO0lBQ2pELENBQUM7SUFFRCxTQUFTO1FBQ1AsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUUsSUFBSSxDQUFDLEtBQUssQ0FBRSxDQUFDO1FBRTdDLElBQUksT0FBTyxFQUFFO1lBQ1gsVUFBVSxDQUFDLEdBQUUsRUFBRSxDQUFBLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQTtTQUN4QztJQUNILENBQUM7SUFFRCxhQUFhO1FBQ1gsTUFBTSxPQUFPLEdBQUcsT0FBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBRyxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUcsS0FBSyxDQUFBO1FBRS9FLElBQUksT0FBTyxFQUFFO1lBQ1gsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFBO1lBQzlCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFBO1lBQzlCLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFBLEVBQUUsQ0FDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsSUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQ3BFLENBQUE7WUFDRCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsUUFBUSxDQUFFLENBQUE7U0FDMUM7YUFBSTtZQUNILE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQTtTQUNyQjtJQUNILENBQUM7O3lHQW5DVSxXQUFXOzZGQUFYLFdBQVc7NEZBQVgsV0FBVztrQkFEdkIsU0FBUzttQkFBQyxFQUFDLFFBQVEsRUFBRSxhQUFhLEVBQUM7c0dBRXpCLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFDSSxjQUFjO3NCQUF2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSXRlcmFibGVEaWZmZXIsXG4gIEl0ZXJhYmxlRGlmZmVycyxcbiAgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsXG4gIE91dHB1dCwgSW5wdXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnbmdmRm9ybURhdGEnfSlcbmV4cG9ydCBjbGFzcyBuZ2ZGb3JtRGF0YSB7XG4gIEBJbnB1dCgpIGZpbGVzICE6IEZpbGVbXVxuICBASW5wdXQoKSBwb3N0TmFtZTpzdHJpbmcgPSBcImZpbGVcIlxuICBASW5wdXQoKSBmaWxlTmFtZSAhOiBzdHJpbmcvL2ZvcmNlIGZpbGUgbmFtZVxuXG4gIEBJbnB1dCgpIEZvcm1EYXRhOkZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKClcbiAgQE91dHB1dCgpIEZvcm1EYXRhQ2hhbmdlOkV2ZW50RW1pdHRlcjxGb3JtRGF0YT4gPSBuZXcgRXZlbnRFbWl0dGVyKClcblxuICBkaWZmZXI6SXRlcmFibGVEaWZmZXI8e30+XG5cbiAgY29uc3RydWN0b3IoSXRlcmFibGVEaWZmZXJzOiBJdGVyYWJsZURpZmZlcnMpe1xuICAgIHRoaXMuZGlmZmVyID0gSXRlcmFibGVEaWZmZXJzLmZpbmQoW10pLmNyZWF0ZSgpXG4gIH1cblxuICBuZ0RvQ2hlY2soKXtcbiAgICB2YXIgY2hhbmdlcyA9IHRoaXMuZGlmZmVyLmRpZmYoIHRoaXMuZmlsZXMgKTtcblxuICAgIGlmIChjaGFuZ2VzKSB7XG4gICAgICBzZXRUaW1lb3V0KCgpPT50aGlzLmJ1aWxkRm9ybURhdGEoKSwgMClcbiAgICB9XG4gIH1cblxuICBidWlsZEZvcm1EYXRhKCl7XG4gICAgY29uc3QgaXNBcnJheSA9IHR5cGVvZih0aGlzLmZpbGVzKT09PSdvYmplY3QnICYmIHRoaXMuZmlsZXMuY29uc3RydWN0b3I9PT1BcnJheVxuXG4gICAgaWYoIGlzQXJyYXkgKXtcbiAgICAgIHRoaXMuRm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKVxuICAgICAgY29uc3QgZmlsZXMgPSB0aGlzLmZpbGVzIHx8IFtdXG4gICAgICBmaWxlcy5mb3JFYWNoKGZpbGU9PlxuICAgICAgICB0aGlzLkZvcm1EYXRhLmFwcGVuZCh0aGlzLnBvc3ROYW1lLCBmaWxlLCB0aGlzLmZpbGVOYW1lfHxmaWxlLm5hbWUpXG4gICAgICApXG4gICAgICB0aGlzLkZvcm1EYXRhQ2hhbmdlLmVtaXQoIHRoaXMuRm9ybURhdGEgKVxuICAgIH1lbHNle1xuICAgICAgZGVsZXRlIHRoaXMuRm9ybURhdGFcbiAgICB9XG4gIH1cbn0iXX0= |
| import { Directive, Input } from "@angular/core"; | ||
| import { ngf } from "./ngf.directive"; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfSelect extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.selectable = true; | ||
| } | ||
| } | ||
| ngfSelect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSelect.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSelect, selector: "[ngfSelect]", inputs: { selectable: "selectable" }, exportAs: ["ngfSelect"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfSelect]", | ||
| exportAs: "ngfSelect" | ||
| }] | ||
| }], propDecorators: { selectable: [{ | ||
| type: Input | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmU2VsZWN0LmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2ZTZWxlY3QuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2hELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTs7QUFNckMsTUFBTSxPQUFPLFNBQVUsU0FBUSxHQUFHO0lBSmxDOztRQUtXLGVBQVUsR0FBTyxJQUFJLENBQUE7S0FDL0I7O3VHQUZZLFNBQVM7MkZBQVQsU0FBUzs0RkFBVCxTQUFTO2tCQUpyQixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxhQUFhO29CQUN2QixRQUFRLEVBQUUsV0FBVztpQkFDdEI7OEJBRVUsVUFBVTtzQkFBbEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgSW5wdXQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiXG5pbXBvcnQgeyBuZ2YgfSBmcm9tIFwiLi9uZ2YuZGlyZWN0aXZlXCJcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBcIltuZ2ZTZWxlY3RdXCIsXG4gIGV4cG9ydEFzOiBcIm5nZlNlbGVjdFwiXG59KVxuZXhwb3J0IGNsYXNzIG5nZlNlbGVjdCBleHRlbmRzIG5nZiB7XG4gIEBJbnB1dCgpIHNlbGVjdGFibGU6YW55ID0gdHJ1ZVxufSJdfQ== |
| import { Directive, Input } from '@angular/core'; | ||
| import { dataUrl } from './fileTools'; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfSrc { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => this.ElementRef.nativeElement.src = src); | ||
| } | ||
| } | ||
| ngfSrc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSrc.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSrc, selector: "[ngfSrc]", inputs: { file: ["ngfSrc", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfSrc]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfSrc'] | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmU3JjLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2ZTcmMuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUM7O0FBR3RDLE1BQU0sT0FBTyxNQUFNO0lBR2pCLFlBQW1CLFVBQXNCO1FBQXRCLGVBQVUsR0FBVixVQUFVLENBQVk7SUFBSSxDQUFDO0lBRTlDLFdBQVcsQ0FBQyxRQUFhO1FBQ3ZCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ2pCLElBQUksQ0FBQyxHQUFHLENBQUEsRUFBRSxDQUNULElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQ3hDLENBQUE7SUFDSCxDQUFDOztvR0FWVSxNQUFNO3dGQUFOLE1BQU07NEZBQU4sTUFBTTtrQkFEbEIsU0FBUzttQkFBQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUU7aUdBRWhCLElBQUk7c0JBQXBCLEtBQUs7dUJBQUMsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGRhdGFVcmwgfSBmcm9tICcuL2ZpbGVUb29scyc7XG5cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1tuZ2ZTcmNdJyB9KVxuZXhwb3J0IGNsYXNzIG5nZlNyYyB7XG4gIEBJbnB1dCgnbmdmU3JjJykgZmlsZTogYW55XG5cbiAgY29uc3RydWN0b3IocHVibGljIEVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHsgfVxuXG4gIG5nT25DaGFuZ2VzKF9jaGFuZ2VzOiBhbnkpIHtcbiAgICBkYXRhVXJsKHRoaXMuZmlsZSlcbiAgICAudGhlbihzcmM9PlxuICAgICAgdGhpcy5FbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc3JjID0gc3JjXG4gICAgKVxuICB9XG59XG4iXX0= |
| import { Directive, EventEmitter, Output, Input } from '@angular/core'; | ||
| import * as i0 from "@angular/core"; | ||
| export class ngfUploadStatus { | ||
| constructor() { | ||
| this.percent = 0; | ||
| this.percentChange = new EventEmitter(); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.httpEvent && changes.httpEvent.currentValue) { | ||
| const event = changes.httpEvent.currentValue; | ||
| if (event.loaded && event.total) { | ||
| setTimeout(() => { | ||
| this.percent = Math.round(100 * event.loaded / event.total); | ||
| this.percentChange.emit(this.percent); | ||
| }, 0); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ngfUploadStatus.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, deps: [], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfUploadStatus.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfUploadStatus, selector: "ngfUploadStatus", inputs: { percent: "percent", httpEvent: "httpEvent" }, outputs: { percentChange: "percentChange" }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfUploadStatus' }] | ||
| }], propDecorators: { percent: [{ | ||
| type: Input | ||
| }], percentChange: [{ | ||
| type: Output | ||
| }], httpEvent: [{ | ||
| type: Input | ||
| }] } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdmVXBsb2FkU3RhdHVzLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9maWxlLXVwbG9hZC9uZ2ZVcGxvYWRTdGF0dXMuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBR3ZFLE1BQU0sT0FBTyxlQUFlO0lBRDVCO1FBRVcsWUFBTyxHQUFVLENBQUMsQ0FBQTtRQUNqQixrQkFBYSxHQUF3QixJQUFJLFlBQVksRUFBRSxDQUFBO0tBY2xFO0lBWEMsV0FBVyxDQUFFLE9BQU87UUFDbEIsSUFBSSxPQUFPLENBQUMsU0FBUyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFO1lBQ3ZELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFBO1lBQzVDLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO2dCQUMvQixVQUFVLENBQUMsR0FBRSxFQUFFO29CQUNiLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzVELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFFLElBQUksQ0FBQyxPQUFPLENBQUUsQ0FBQTtnQkFDekMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO2FBQ047U0FDRjtJQUNILENBQUM7OzZHQWZVLGVBQWU7aUdBQWYsZUFBZTs0RkFBZixlQUFlO2tCQUQzQixTQUFTO21CQUFDLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDOzhCQUU3QixPQUFPO3NCQUFmLEtBQUs7Z0JBQ0ksYUFBYTtzQkFBdEIsTUFBTTtnQkFDRSxTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIE91dHB1dCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7c2VsZWN0b3I6ICduZ2ZVcGxvYWRTdGF0dXMnfSlcbmV4cG9ydCBjbGFzcyBuZ2ZVcGxvYWRTdGF0dXMge1xuICBASW5wdXQoKSBwZXJjZW50Om51bWJlciA9IDBcbiAgQE91dHB1dCgpIHBlcmNlbnRDaGFuZ2U6RXZlbnRFbWl0dGVyPG51bWJlcj4gPSBuZXcgRXZlbnRFbWl0dGVyKClcbiAgQElucHV0KCkgaHR0cEV2ZW50ICE6IEV2ZW50XG5cbiAgbmdPbkNoYW5nZXMoIGNoYW5nZXMgKXtcbiAgICBpZiggY2hhbmdlcy5odHRwRXZlbnQgJiYgY2hhbmdlcy5odHRwRXZlbnQuY3VycmVudFZhbHVlICl7XG4gICAgICBjb25zdCBldmVudCA9IGNoYW5nZXMuaHR0cEV2ZW50LmN1cnJlbnRWYWx1ZVxuICAgICAgaWYgKGV2ZW50LmxvYWRlZCAmJiBldmVudC50b3RhbCkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpPT57XG4gICAgICAgICAgdGhpcy5wZXJjZW50ID0gTWF0aC5yb3VuZCgxMDAgKiBldmVudC5sb2FkZWQgLyBldmVudC50b3RhbCk7XG4gICAgICAgICAgdGhpcy5wZXJjZW50Q2hhbmdlLmVtaXQoIHRoaXMucGVyY2VudCApXG4gICAgICAgIH0sIDApXG4gICAgICB9XG4gICAgfVxuICB9XG59Il19 |
| /* | ||
| * Public API Surface of angular-file | ||
| */ | ||
| export * from './file-upload/ngfSelect.directive'; | ||
| export * from './file-upload/ngfDrop.directive'; | ||
| export * from './file-upload/ngf.directive'; | ||
| export * from './file-upload/ngf.module'; | ||
| export { ngfBackground } from './file-upload/ngfBackground.directive'; | ||
| export { ngfSrc } from './file-upload/ngfSrc.directive'; | ||
| export { ngfUploadStatus } from './file-upload/ngfUploadStatus.directive'; | ||
| export { ngfFormData } from './file-upload/ngfFormData.directive'; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxtQ0FBbUMsQ0FBQztBQUNsRCxjQUFjLGlDQUFpQyxDQUFDO0FBQ2hELGNBQWMsNkJBQTZCLENBQUM7QUFDNUMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDdEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3hELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUNBQXFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIGFuZ3VsYXItZmlsZVxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vZmlsZS11cGxvYWQvbmdmU2VsZWN0LmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL2ZpbGUtdXBsb2FkL25nZkRyb3AuZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vZmlsZS11cGxvYWQvbmdmLmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL2ZpbGUtdXBsb2FkL25nZi5tb2R1bGUnO1xuZXhwb3J0IHsgbmdmQmFja2dyb3VuZCB9IGZyb20gJy4vZmlsZS11cGxvYWQvbmdmQmFja2dyb3VuZC5kaXJlY3RpdmUnO1xuZXhwb3J0IHsgbmdmU3JjIH0gZnJvbSAnLi9maWxlLXVwbG9hZC9uZ2ZTcmMuZGlyZWN0aXZlJztcbmV4cG9ydCB7IG5nZlVwbG9hZFN0YXR1cyB9IGZyb20gJy4vZmlsZS11cGxvYWQvbmdmVXBsb2FkU3RhdHVzLmRpcmVjdGl2ZSc7XG5leHBvcnQgeyBuZ2ZGb3JtRGF0YSB9IGZyb20gJy4vZmlsZS11cGxvYWQvbmdmRm9ybURhdGEuZGlyZWN0aXZlJzsiXX0= |
| import * as i0 from '@angular/core'; | ||
| import { EventEmitter, Directive, Input, Output, HostListener, NgModule } from '@angular/core'; | ||
| import { CommonModule } from '@angular/common'; | ||
| const isFileInput = function (elm) { | ||
| const ty = elm.getAttribute('type'); | ||
| return elm.tagName.toLowerCase() === 'input' && ty && ty.toLowerCase() === 'file'; | ||
| }; | ||
| let initialTouchStartY = 0; | ||
| let initialTouchStartX = 0; | ||
| const detectSwipe = function (evt) { | ||
| var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches); | ||
| if (touches) { | ||
| if (evt.type === 'touchstart') { | ||
| initialTouchStartX = touches[0].clientX; | ||
| initialTouchStartY = touches[0].clientY; | ||
| return true; // don't block event default | ||
| } | ||
| else { | ||
| // prevent scroll from triggering event | ||
| if (evt.type === 'touchend') { | ||
| var currentX = touches[0].clientX; | ||
| var currentY = touches[0].clientY; | ||
| if ((Math.abs(currentX - initialTouchStartX) > 20) || | ||
| (Math.abs(currentY - initialTouchStartY) > 20)) { | ||
| evt.stopPropagation(); | ||
| if (evt.cancelable) { | ||
| evt.preventDefault(); | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }; | ||
| const createInvisibleFileInputWrap = function () { | ||
| var fileElem = createFileInput(); | ||
| var label = document.createElement('label'); | ||
| label.innerHTML = 'upload'; | ||
| label.style.visibility = 'hidden'; | ||
| label.style.position = 'absolute'; | ||
| label.style.overflow = 'hidden'; | ||
| label.style.width = '0px'; | ||
| label.style.height = '0px'; | ||
| label.style.border = 'none'; | ||
| label.style.margin = '0px'; | ||
| label.style.padding = '0px'; | ||
| label.setAttribute('tabindex', '-1'); | ||
| //bindAttrToFileInput(fileElem, label); | ||
| //generatedElems.push({el: elem, ref: label}); | ||
| label.appendChild(fileElem); | ||
| //document.body.appendChild( label ); | ||
| return label; | ||
| }; | ||
| const createFileInput = function () { | ||
| var fileElem = document.createElement('input'); | ||
| fileElem.type = "file"; | ||
| return fileElem; | ||
| }; | ||
| function getWindow() { return window; } | ||
| function acceptType(accept, type, name) { | ||
| if (!accept) { | ||
| return true; | ||
| } | ||
| const defs = accept.split(','); | ||
| let regx; | ||
| let acceptRegString; | ||
| for (let x = defs.length - 1; x >= 0; --x) { | ||
| //Escapes dots in mimetype | ||
| acceptRegString = defs[x]; | ||
| //trim | ||
| acceptRegString = acceptRegString.replace(/(^\s+|\s+$)/g, ''); | ||
| //Escapes stars in mimetype | ||
| acceptRegString = acceptRegString.replace(/\*/g, '.*'); | ||
| //let acceptReg = '^((' + acceptRegString | ||
| //acceptReg = acceptReg.replace(/,/g,')|(') + '))$' | ||
| //try by mime | ||
| regx = new RegExp(acceptRegString, 'gi'); | ||
| if (type.search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| //try by ext | ||
| if (acceptRegString.substring(0, 1) == '.') { | ||
| acceptRegString = '\\' + acceptRegString; //.substring(1, acceptRegString.length-1)//remove dot at front | ||
| regx = new RegExp(acceptRegString + '$', 'i'); | ||
| if ((name || type).search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function arrayBufferToBase64(buffer) { | ||
| var binary = ''; | ||
| var bytes = new Uint8Array(buffer); | ||
| var len = bytes.byteLength; | ||
| for (var i = 0; i < len; i++) { | ||
| binary += String.fromCharCode(bytes[i]); | ||
| } | ||
| return window.btoa(binary); | ||
| } | ||
| function dataUrltoBlob(dataurl, name, origSize) { | ||
| var arr = dataurl.split(','); | ||
| var mimeMatch = arr[0].match(/:(.*?);/); | ||
| var mime = mimeMatch ? mimeMatch[1] : 'text/plain'; | ||
| var bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); | ||
| while (n--) { | ||
| u8arr[n] = bstr.charCodeAt(n); | ||
| } | ||
| var blob = new window.Blob([u8arr], { type: mime }); | ||
| blob["name"] = name; | ||
| blob["$ngfOrigSize"] = origSize; | ||
| return blob; | ||
| } | ||
| function applyTransform(ctx, orientation, width, height) { | ||
| switch (orientation) { | ||
| case 2: | ||
| return ctx.transform(-1, 0, 0, 1, width, 0); | ||
| case 3: | ||
| return ctx.transform(-1, 0, 0, -1, width, height); | ||
| case 4: | ||
| return ctx.transform(1, 0, 0, -1, 0, height); | ||
| case 5: | ||
| return ctx.transform(0, 1, 1, 0, 0, 0); | ||
| case 6: | ||
| return ctx.transform(0, 1, -1, 0, height, 0); | ||
| case 7: | ||
| return ctx.transform(0, -1, -1, 0, height, width); | ||
| case 8: | ||
| return ctx.transform(0, -1, 1, 0, 0, width); | ||
| } | ||
| } | ||
| function fixFileOrientationByMeta(file, result) { | ||
| return dataUrl(file, true) | ||
| .then(url => { | ||
| var canvas = document.createElement('canvas'); | ||
| var img = document.createElement('img'); | ||
| return new Promise(function (res, rej) { | ||
| img.onload = function () { | ||
| try { | ||
| canvas.width = result.orientation > 4 ? img.height : img.width; | ||
| canvas.height = result.orientation > 4 ? img.width : img.height; | ||
| var ctx = canvas.getContext('2d'); | ||
| applyTransform(ctx, result.orientation, img.width, img.height); | ||
| ctx.drawImage(img, 0, 0); | ||
| var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934); | ||
| const base = arrayBufferToBase64(result.fixedArrayBuffer); | ||
| dataUrl = restoreExif(base, dataUrl); | ||
| var blob = dataUrltoBlob(dataUrl, file.name); | ||
| const newFile = blobToFile(blob, file.name); | ||
| res(newFile); | ||
| } | ||
| catch (e) { | ||
| rej(e); | ||
| } | ||
| }; | ||
| img.onerror = rej; | ||
| img.src = url; | ||
| }); | ||
| }); | ||
| } | ||
| function applyExifRotation(file) { | ||
| if (file.type.indexOf('image/jpeg') !== 0) { | ||
| return Promise.resolve(file); | ||
| } | ||
| return readOrientation(file) | ||
| .then((result) => { | ||
| if (result.orientation < 2 || result.orientation > 8) { | ||
| return file; | ||
| } | ||
| return fixFileOrientationByMeta(file, result); | ||
| }); | ||
| } | ||
| function readOrientation(file) { | ||
| return new Promise((res, rej) => { | ||
| var reader = new FileReader(); | ||
| var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file; | ||
| reader.readAsArrayBuffer(slicedFile); | ||
| reader.onerror = rej; | ||
| reader.onload = function (e) { | ||
| var result = { orientation: 1 }; | ||
| var view = new DataView(this.result); | ||
| if (view.getUint16(0, false) !== 0xFFD8) | ||
| return res(result); | ||
| var length = view.byteLength, offset = 2; | ||
| while (offset < length) { | ||
| var marker = view.getUint16(offset, false); | ||
| offset += 2; | ||
| if (marker === 0xFFE1) { | ||
| if (view.getUint32(offset += 2, false) !== 0x45786966) | ||
| return res(result); | ||
| var little = view.getUint16(offset += 6, false) === 0x4949; | ||
| offset += view.getUint32(offset + 4, little); | ||
| var tags = view.getUint16(offset, little); | ||
| offset += 2; | ||
| for (var i = 0; i < tags; i++) | ||
| if (view.getUint16(offset + (i * 12), little) === 0x0112) { | ||
| var orientation = view.getUint16(offset + (i * 12) + 8, little); | ||
| if (orientation >= 2 && orientation <= 8) { | ||
| view.setUint16(offset + (i * 12) + 8, 1, little); | ||
| result.fixedArrayBuffer = e.target.result; | ||
| } | ||
| result.orientation = orientation; | ||
| return res(result); | ||
| } | ||
| } | ||
| else if ((marker & 0xFF00) !== 0xFF00) | ||
| break; | ||
| else | ||
| offset += view.getUint16(offset, false); | ||
| } | ||
| return res(result); | ||
| }; | ||
| }); | ||
| } | ||
| /** converts file-input file into base64 dataUri */ | ||
| function dataUrl(file, disallowObjectUrl) { | ||
| if (!file) | ||
| return Promise.resolve(file); | ||
| if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { | ||
| return Promise.resolve(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl); | ||
| } | ||
| var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; | ||
| if (p) | ||
| return p; | ||
| const win = getWindow(); | ||
| let deferred; | ||
| if (win.FileReader && file && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { | ||
| //prefer URL.createObjectURL for handling refrences to files of all sizes | ||
| //since it doesn´t build a large string in memory | ||
| var URL = win.URL || win.webkitURL; | ||
| if (FileReader) { | ||
| deferred = new Promise((res, rej) => { | ||
| var fileReader = new FileReader(); | ||
| fileReader.onload = function (event) { | ||
| file.$ngfDataUrl = event.target.result; | ||
| delete file.$ngfDataUrl; | ||
| res(event.target.result); | ||
| }; | ||
| fileReader.onerror = function (e) { | ||
| file.$ngfDataUrl = ''; | ||
| rej(e); | ||
| }; | ||
| fileReader.readAsDataURL(file); | ||
| }); | ||
| } | ||
| else { | ||
| var url; | ||
| try { | ||
| url = URL.createObjectURL(file); | ||
| } | ||
| catch (e) { | ||
| return Promise.reject(e); | ||
| } | ||
| deferred = Promise.resolve(url); | ||
| file.$ngfBlobUrl = url; | ||
| } | ||
| } | ||
| else { | ||
| file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; | ||
| return Promise.reject(new Error('Browser does not support window.FileReader, window.FileReader, or window.FileAPI')); //deferred.reject(); | ||
| } | ||
| if (disallowObjectUrl) { | ||
| p = file.$$ngfDataUrlPromise = deferred; | ||
| } | ||
| else { | ||
| p = file.$$ngfBlobUrlPromise = deferred; | ||
| } | ||
| p = p.then((x) => { | ||
| delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; | ||
| return x; | ||
| }); | ||
| return p; | ||
| } | ||
| function restoreExif(orig, resized) { | ||
| var ExifRestorer = { | ||
| KEY_STR: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' | ||
| }; | ||
| ExifRestorer.encode64 = function (input) { | ||
| var output = '', chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0; | ||
| do { | ||
| chr1 = input[i++]; | ||
| chr2 = input[i++]; | ||
| chr3 = input[i++]; | ||
| enc1 = chr1 >> 2; | ||
| enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | ||
| enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | ||
| enc4 = chr3 & 63; | ||
| if (isNaN(chr2)) { | ||
| enc3 = enc4 = 64; | ||
| } | ||
| else if (isNaN(chr3)) { | ||
| enc4 = 64; | ||
| } | ||
| output = output + | ||
| this.KEY_STR.charAt(enc1) + | ||
| this.KEY_STR.charAt(enc2) + | ||
| this.KEY_STR.charAt(enc3) + | ||
| this.KEY_STR.charAt(enc4); | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return output; | ||
| }; | ||
| ExifRestorer.restore = function (origFileBase64, resizedFileBase64) { | ||
| if (origFileBase64.match('data:image/jpeg;base64,')) { | ||
| origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', ''); | ||
| } | ||
| var rawImage = this.decode64(origFileBase64); | ||
| var segments = this.slice2Segments(rawImage); | ||
| var image = this.exifManipulation(resizedFileBase64, segments); | ||
| return 'data:image/jpeg;base64,' + this.encode64(image); | ||
| }; | ||
| ExifRestorer.exifManipulation = function (resizedFileBase64, segments) { | ||
| var exifArray = this.getExifArray(segments), newImageArray = this.insertExif(resizedFileBase64, exifArray); | ||
| return new Uint8Array(newImageArray); | ||
| }; | ||
| ExifRestorer.getExifArray = function (segments) { | ||
| var seg; | ||
| for (var x = 0; x < segments.length; x++) { | ||
| seg = segments[x]; | ||
| if (seg[0] === 255 && seg[1] === 225) //(ff e1) | ||
| { | ||
| return seg; | ||
| } | ||
| } | ||
| return []; | ||
| }; | ||
| ExifRestorer.insertExif = function (resizedFileBase64, exifArray) { | ||
| var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''), buf = this.decode64(imageData), separatePoint = buf.indexOf(255, 3), mae = buf.slice(0, separatePoint), ato = buf.slice(separatePoint), array = mae; | ||
| array = array.concat(exifArray); | ||
| array = array.concat(ato); | ||
| return array; | ||
| }; | ||
| ExifRestorer.slice2Segments = function (rawImageArray) { | ||
| var head = 0, segments = []; | ||
| while (1) { | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 218) { | ||
| break; | ||
| } | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 216) { | ||
| head += 2; | ||
| } | ||
| else { | ||
| var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3]; | ||
| var endPoint = head + length + 2; | ||
| var seg = rawImageArray.slice(head, endPoint); | ||
| segments.push(seg); | ||
| head = endPoint; | ||
| } | ||
| if (head > rawImageArray.length) { | ||
| break; | ||
| } | ||
| } | ||
| return segments; | ||
| }; | ||
| ExifRestorer.decode64 = function (input) { | ||
| var chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0, buf = []; | ||
| // remove all characters that are not A-Z, a-z, 0-9, +, /, or = | ||
| var base64test = /[^A-Za-z0-9\+\/\=]/g; | ||
| if (base64test.exec(input)) { | ||
| console.log('There were invalid base64 characters in the input text.'); | ||
| } | ||
| input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); | ||
| do { | ||
| enc1 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc2 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc3 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc4 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| chr1 = (enc1 << 2) | (enc2 >> 4); | ||
| chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); | ||
| chr3 = ((enc3 & 3) << 6) | enc4; | ||
| buf.push(chr1); | ||
| if (enc3 !== 64) { | ||
| buf.push(chr2); | ||
| } | ||
| if (enc4 !== 64) { | ||
| buf.push(chr3); | ||
| } | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return buf; | ||
| }; | ||
| return ExifRestorer.restore(orig, resized); //<= EXIF | ||
| } | ||
| ; | ||
| function blobToFile(theBlob, fileName) { | ||
| var b = theBlob; | ||
| //A Blob() is almost a File() - it's just missing the two properties below which we will add | ||
| b.lastModifiedDate = new Date(); | ||
| b.name = fileName; | ||
| //Cast to a File() type | ||
| return theBlob; | ||
| } | ||
| /** A master base set of logic intended to support file select/drag/drop operations | ||
| NOTE: Use ngfDrop for full drag/drop. Use ngfSelect for selecting | ||
| */ | ||
| class ngf { | ||
| constructor(element) { | ||
| this.element = element; | ||
| this.filters = []; | ||
| this.lastFileCount = 0; | ||
| this.ngfFixOrientation = true; | ||
| this.fileDropDisabled = false; | ||
| this.selectable = false; | ||
| this.directiveInit = new EventEmitter(); | ||
| this.lastInvalids = []; | ||
| this.lastInvalidsChange = new EventEmitter(); | ||
| this.lastBaseUrlChange = new EventEmitter(); | ||
| this.fileChange = new EventEmitter(); | ||
| this.files = []; | ||
| this.filesChange = new EventEmitter(); | ||
| this.fileSelectStart = new EventEmitter(); | ||
| this.initFilters(); | ||
| } | ||
| initFilters() { | ||
| // the order is important | ||
| this.filters.push({ name: 'accept', fn: this._acceptFilter }); | ||
| this.filters.push({ name: 'fileSize', fn: this._fileSizeFilter }); | ||
| //this.filters.push({name: 'fileType', fn: this._fileTypeFilter}) | ||
| //this.filters.push({name: 'queueLimit', fn: this._queueLimitFilter}) | ||
| //this.filters.push({name: 'mimeType', fn: this._mimeTypeFilter}) | ||
| } | ||
| ngOnDestroy() { | ||
| delete this.fileElm; //faster memory release of dom element | ||
| this.destroyPasteListener(); | ||
| } | ||
| ngOnInit() { | ||
| const selectable = (this.selectable || this.selectable === '') && !['false', 'null', '0'].includes(this.selectable); | ||
| if (selectable) { | ||
| this.enableSelecting(); | ||
| } | ||
| if (this.multiple) { | ||
| this.paramFileElm().setAttribute('multiple', this.multiple); | ||
| } | ||
| this.evalCapturePaste(); | ||
| // create reference to this class with one cycle delay to avoid ExpressionChangedAfterItHasBeenCheckedError | ||
| setTimeout(() => { | ||
| this.directiveInit.emit(this); | ||
| }, 0); | ||
| } | ||
| ngOnChanges(changes) { | ||
| var _a, _b; | ||
| if (changes.accept) { | ||
| this.paramFileElm().setAttribute('accept', changes.accept.currentValue || '*'); | ||
| } | ||
| if (changes.capturePaste) { | ||
| this.evalCapturePaste(); | ||
| } | ||
| // Did we go from having a file to not having a file? Clear file element then | ||
| if (changes.file && changes.file.previousValue && !changes.file.currentValue) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| // Did we go from having files to not having files? Clear file element then | ||
| if (changes.files) { | ||
| const filesWentToZero = ((_a = changes.files.previousValue) === null || _a === void 0 ? void 0 : _a.length) && !((_b = changes.files.currentValue) === null || _b === void 0 ? void 0 : _b.length); | ||
| if (filesWentToZero) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| } | ||
| } | ||
| evalCapturePaste() { | ||
| const isActive = this.capturePaste || this.capturePaste === '' || ['false', '0', 'null'].includes(this.capturePaste); | ||
| if (isActive) { | ||
| if (this.pasteCapturer) { | ||
| return; // already listening | ||
| } | ||
| this.pasteCapturer = (e) => { | ||
| const clip = e.clipboardData; | ||
| if (clip && clip.files && clip.files.length) { | ||
| this.handleFiles(clip.files); | ||
| e.preventDefault(); | ||
| } | ||
| }; | ||
| window.addEventListener('paste', this.pasteCapturer); | ||
| return; | ||
| } | ||
| this.destroyPasteListener(); | ||
| } | ||
| destroyPasteListener() { | ||
| if (this.pasteCapturer) { | ||
| window.removeEventListener('paste', this.pasteCapturer); | ||
| delete this.pasteCapturer; | ||
| } | ||
| } | ||
| paramFileElm() { | ||
| if (this.fileElm) | ||
| return this.fileElm; // already defined | ||
| // elm already is a file input | ||
| const isFile = isFileInput(this.element.nativeElement); | ||
| if (isFile) { | ||
| return this.fileElm = this.element.nativeElement; | ||
| } | ||
| // the host elm is NOT a file input | ||
| return this.fileElm = this.createFileElm({ | ||
| change: this.changeFn.bind(this) | ||
| }); | ||
| } | ||
| /** Only used when host element we are attached to is NOT a fileElement */ | ||
| createFileElm({ change }) { | ||
| // use specific technique to hide file element within | ||
| const label = createInvisibleFileInputWrap(); | ||
| const fileElm = label.getElementsByTagName('input')[0]; | ||
| fileElm.addEventListener('change', change); | ||
| this.element.nativeElement.appendChild(label); // put on html stage | ||
| return fileElm; | ||
| } | ||
| enableSelecting() { | ||
| let elm = this.element.nativeElement; | ||
| if (isFileInput(elm)) { | ||
| const bindedHandler = event => this.beforeSelect(event); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| return; | ||
| } | ||
| const bindedHandler = ev => this.clickHandler(ev); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| elm.addEventListener('touchend', bindedHandler); | ||
| } | ||
| getValidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (this.isFileValid(files[x])) { | ||
| rtn.push(files[x]); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| getInvalidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| let failReason = this.getFileFilterFailName(files[x]); | ||
| if (failReason) { | ||
| rtn.push({ | ||
| file: files[x], | ||
| type: failReason | ||
| }); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| // Primary handler of files coming in | ||
| handleFiles(files) { | ||
| const valids = this.getValidFiles(files); | ||
| if (files.length != valids.length) { | ||
| this.lastInvalids = this.getInvalidFiles(files); | ||
| } | ||
| else { | ||
| delete this.lastInvalids; | ||
| } | ||
| this.lastInvalidsChange.emit(this.lastInvalids); | ||
| if (valids.length) { | ||
| if (this.ngfFixOrientation) { | ||
| this.applyExifRotations(valids) | ||
| .then(fixedFiles => this.que(fixedFiles)); | ||
| } | ||
| else { | ||
| this.que(valids); | ||
| } | ||
| } | ||
| if (this.isEmptyAfterSelection()) { | ||
| this.element.nativeElement.value = ''; | ||
| } | ||
| } | ||
| que(files) { | ||
| this.files = this.files || []; | ||
| Array.prototype.push.apply(this.files, files); | ||
| //below break memory ref and doesnt act like a que | ||
| //this.files = files//causes memory change which triggers bindings like <ngfFormData [files]="files"></ngfFormData> | ||
| this.filesChange.emit(this.files); | ||
| if (files.length) { | ||
| this.fileChange.emit(this.file = files[0]); | ||
| if (this.lastBaseUrlChange.observers.length) { | ||
| dataUrl(files[0]) | ||
| .then(url => this.lastBaseUrlChange.emit(url)); | ||
| } | ||
| } | ||
| //will be checked for input value clearing | ||
| this.lastFileCount = this.files.length; | ||
| } | ||
| /** called when input has files */ | ||
| changeFn(event) { | ||
| var fileList = event.__files_ || (event.target && event.target.files); | ||
| if (!fileList) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(fileList); | ||
| } | ||
| clickHandler(evt) { | ||
| const elm = this.element.nativeElement; | ||
| if (elm.getAttribute('disabled') || this.fileDropDisabled) { | ||
| return false; | ||
| } | ||
| var r = detectSwipe(evt); | ||
| // prevent the click if it is a swipe | ||
| if (r !== false) | ||
| return r; | ||
| const fileElm = this.paramFileElm(); | ||
| fileElm.click(); | ||
| //fileElm.dispatchEvent( new Event('click') ); | ||
| this.beforeSelect(evt); | ||
| return false; | ||
| } | ||
| beforeSelect(event) { | ||
| this.fileSelectStart.emit(event); | ||
| if (this.files && this.lastFileCount === this.files.length) | ||
| return; | ||
| // if no files in array, be sure browser does not prevent reselect of same file (see github issue 27) | ||
| this.clearFileElmValue(); | ||
| } | ||
| clearFileElmValue() { | ||
| if (!this.fileElm) | ||
| return; | ||
| this.fileElm.value = null; | ||
| } | ||
| isEmptyAfterSelection() { | ||
| return !!this.element.nativeElement.attributes.multiple; | ||
| } | ||
| stopEvent(event) { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| } | ||
| transferHasFiles(transfer) { | ||
| if (!transfer.types) { | ||
| return false; | ||
| } | ||
| if (transfer.types.indexOf) { | ||
| return transfer.types.indexOf('Files') !== -1; | ||
| } | ||
| else if (transfer.types.contains) { | ||
| return transfer.types.contains('Files'); | ||
| } | ||
| else { | ||
| return false; | ||
| } | ||
| } | ||
| eventToFiles(event) { | ||
| const transfer = eventToTransfer(event); | ||
| if (transfer) { | ||
| if (transfer.files && transfer.files.length) { | ||
| return transfer.files; | ||
| } | ||
| if (transfer.items && transfer.items.length) { | ||
| return transfer.items; | ||
| } | ||
| } | ||
| return []; | ||
| } | ||
| applyExifRotations(files) { | ||
| const mapper = (file, index) => { | ||
| return applyExifRotation(file) | ||
| .then(fixedFile => files.splice(index, 1, fixedFile)); | ||
| }; | ||
| const proms = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| proms[x] = mapper(files[x], x); | ||
| } | ||
| return Promise.all(proms).then(() => files); | ||
| } | ||
| onChange(event) { | ||
| let files = this.element.nativeElement.files || this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| getFileFilterFailName(file) { | ||
| for (let i = 0; i < this.filters.length; i++) { | ||
| if (!this.filters[i].fn.call(this, file)) { | ||
| return this.filters[i].name; | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| isFileValid(file) { | ||
| const noFilters = !this.accept && (!this.filters || !this.filters.length); | ||
| if (noFilters) { | ||
| return true; //we have no filters so all files are valid | ||
| } | ||
| return this.getFileFilterFailName(file) ? false : true; | ||
| } | ||
| isFilesValid(files) { | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (!this.isFileValid(files[x])) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| _acceptFilter(item) { | ||
| return acceptType(this.accept, item.type, item.name); | ||
| } | ||
| _fileSizeFilter(item) { | ||
| return !(this.maxSize && item.size > this.maxSize); | ||
| } | ||
| } | ||
| ngf.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngf.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngf, selector: "[ngf]", inputs: { multiple: "multiple", accept: "accept", maxSize: "maxSize", ngfFixOrientation: "ngfFixOrientation", fileDropDisabled: "fileDropDisabled", selectable: "selectable", lastInvalids: "lastInvalids", lastBaseUrl: "lastBaseUrl", file: "file", files: "files", capturePaste: "capturePaste" }, outputs: { directiveInit: "init", lastInvalidsChange: "lastInvalidsChange", lastBaseUrlChange: "lastBaseUrlChange", fileChange: "fileChange", filesChange: "filesChange", fileSelectStart: "fileSelectStart" }, host: { listeners: { "change": "onChange($event)" } }, exportAs: ["ngf"], usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngf]", | ||
| exportAs: "ngf" | ||
| }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { multiple: [{ | ||
| type: Input | ||
| }], accept: [{ | ||
| type: Input | ||
| }], maxSize: [{ | ||
| type: Input | ||
| }], ngfFixOrientation: [{ | ||
| type: Input | ||
| }], fileDropDisabled: [{ | ||
| type: Input | ||
| }], selectable: [{ | ||
| type: Input | ||
| }], directiveInit: [{ | ||
| type: Output, | ||
| args: ['init'] | ||
| }], lastInvalids: [{ | ||
| type: Input | ||
| }], lastInvalidsChange: [{ | ||
| type: Output | ||
| }], lastBaseUrl: [{ | ||
| type: Input | ||
| }], lastBaseUrlChange: [{ | ||
| type: Output | ||
| }], file: [{ | ||
| type: Input | ||
| }], fileChange: [{ | ||
| type: Output | ||
| }], files: [{ | ||
| type: Input | ||
| }], filesChange: [{ | ||
| type: Output | ||
| }], fileSelectStart: [{ | ||
| type: Output | ||
| }], capturePaste: [{ | ||
| type: Input | ||
| }], onChange: [{ | ||
| type: HostListener, | ||
| args: ['change', ['$event']] | ||
| }] } }); | ||
| /** browsers try hard to conceal data about file drags, this tends to undo that */ | ||
| function filesToWriteableObject(files) { | ||
| const jsonFiles = []; | ||
| for (let x = 0; x < files.length; ++x) { | ||
| jsonFiles.push({ | ||
| type: files[x].type, | ||
| kind: files[x]["kind"] | ||
| }); | ||
| } | ||
| return jsonFiles; | ||
| } | ||
| function eventToTransfer(event) { | ||
| if (event.dataTransfer) | ||
| return event.dataTransfer; | ||
| return event.originalEvent ? event.originalEvent.dataTransfer : null; | ||
| } | ||
| class ngfSelect extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.selectable = true; | ||
| } | ||
| } | ||
| ngfSelect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSelect.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSelect, selector: "[ngfSelect]", inputs: { selectable: "selectable" }, exportAs: ["ngfSelect"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfSelect]", | ||
| exportAs: "ngfSelect" | ||
| }] | ||
| }], propDecorators: { selectable: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ngfDrop extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.fileOver = new EventEmitter(); | ||
| this.validDrag = false; | ||
| this.validDragChange = new EventEmitter(); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange = new EventEmitter(); | ||
| this.dragFilesChange = new EventEmitter(); | ||
| } | ||
| onDrop(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| let files = this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| handleFiles(files) { | ||
| this.fileOver.emit(false); //turn-off dragover | ||
| super.handleFiles(files); | ||
| } | ||
| onDragOver(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| const transfer = eventToTransfer(event); | ||
| let files = this.eventToFiles(event); | ||
| let jsonFiles = filesToWriteableObject(files); | ||
| this.dragFilesChange.emit(this.dragFiles = jsonFiles); | ||
| if (files.length) { | ||
| this.validDrag = this.isFilesValid(files); | ||
| } | ||
| else { | ||
| //Safari, IE11 & some browsers do NOT tell you about dragged files until dropped. Always consider a valid drag | ||
| this.validDrag = true; | ||
| } | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = !this.validDrag; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| transfer.dropEffect = 'copy'; // change cursor and visual display | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(true); | ||
| } | ||
| closeDrags() { | ||
| delete this.validDrag; | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| delete this.dragFiles; | ||
| this.dragFilesChange.emit(this.dragFiles); | ||
| } | ||
| onDragLeave(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| if (this.element) { | ||
| if (event.currentTarget === this.element[0]) { | ||
| return; | ||
| } | ||
| } | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(false); | ||
| } | ||
| } | ||
| ngfDrop.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfDrop.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfDrop, selector: "[ngfDrop]", inputs: { validDrag: "validDrag", invalidDrag: "invalidDrag", dragFiles: "dragFiles" }, outputs: { fileOver: "fileOver", validDragChange: "validDragChange", invalidDragChange: "invalidDragChange", dragFilesChange: "dragFilesChange" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)" } }, exportAs: ["ngfDrop"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfDrop]", | ||
| exportAs: "ngfDrop" | ||
| }] | ||
| }], propDecorators: { fileOver: [{ | ||
| type: Output | ||
| }], validDrag: [{ | ||
| type: Input | ||
| }], validDragChange: [{ | ||
| type: Output | ||
| }], invalidDrag: [{ | ||
| type: Input | ||
| }], invalidDragChange: [{ | ||
| type: Output | ||
| }], dragFiles: [{ | ||
| type: Input | ||
| }], dragFilesChange: [{ | ||
| type: Output | ||
| }], onDrop: [{ | ||
| type: HostListener, | ||
| args: ['drop', ['$event']] | ||
| }], onDragOver: [{ | ||
| type: HostListener, | ||
| args: ['dragover', ['$event']] | ||
| }], onDragLeave: [{ | ||
| type: HostListener, | ||
| args: ['dragleave', ['$event']] | ||
| }] } }); | ||
| class ngfBackground { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => { | ||
| const urlString = 'url(\'' + (src || '') + '\')'; | ||
| this.ElementRef.nativeElement.style.backgroundImage = urlString; | ||
| }); | ||
| } | ||
| } | ||
| ngfBackground.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfBackground.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfBackground, selector: "[ngfBackground]", inputs: { file: ["ngfBackground", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfBackground]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfBackground'] | ||
| }] } }); | ||
| class ngfUploadStatus { | ||
| constructor() { | ||
| this.percent = 0; | ||
| this.percentChange = new EventEmitter(); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.httpEvent && changes.httpEvent.currentValue) { | ||
| const event = changes.httpEvent.currentValue; | ||
| if (event.loaded && event.total) { | ||
| setTimeout(() => { | ||
| this.percent = Math.round(100 * event.loaded / event.total); | ||
| this.percentChange.emit(this.percent); | ||
| }, 0); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ngfUploadStatus.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, deps: [], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfUploadStatus.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfUploadStatus, selector: "ngfUploadStatus", inputs: { percent: "percent", httpEvent: "httpEvent" }, outputs: { percentChange: "percentChange" }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfUploadStatus' }] | ||
| }], propDecorators: { percent: [{ | ||
| type: Input | ||
| }], percentChange: [{ | ||
| type: Output | ||
| }], httpEvent: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ngfFormData { | ||
| constructor(IterableDiffers) { | ||
| this.postName = "file"; | ||
| this.FormData = new FormData(); | ||
| this.FormDataChange = new EventEmitter(); | ||
| this.differ = IterableDiffers.find([]).create(); | ||
| } | ||
| ngDoCheck() { | ||
| var changes = this.differ.diff(this.files); | ||
| if (changes) { | ||
| setTimeout(() => this.buildFormData(), 0); | ||
| } | ||
| } | ||
| buildFormData() { | ||
| const isArray = typeof (this.files) === 'object' && this.files.constructor === Array; | ||
| if (isArray) { | ||
| this.FormData = new FormData(); | ||
| const files = this.files || []; | ||
| files.forEach(file => this.FormData.append(this.postName, file, this.fileName || file.name)); | ||
| this.FormDataChange.emit(this.FormData); | ||
| } | ||
| else { | ||
| delete this.FormData; | ||
| } | ||
| } | ||
| } | ||
| ngfFormData.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, deps: [{ token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfFormData.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfFormData, selector: "ngfFormData", inputs: { files: "files", postName: "postName", fileName: "fileName", FormData: "FormData" }, outputs: { FormDataChange: "FormDataChange" }, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfFormData' }] | ||
| }], ctorParameters: function () { return [{ type: i0.IterableDiffers }]; }, propDecorators: { files: [{ | ||
| type: Input | ||
| }], postName: [{ | ||
| type: Input | ||
| }], fileName: [{ | ||
| type: Input | ||
| }], FormData: [{ | ||
| type: Input | ||
| }], FormDataChange: [{ | ||
| type: Output | ||
| }] } }); | ||
| class ngfSrc { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => this.ElementRef.nativeElement.src = src); | ||
| } | ||
| } | ||
| ngfSrc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSrc.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSrc, selector: "[ngfSrc]", inputs: { file: ["ngfSrc", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfSrc]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfSrc'] | ||
| }] } }); | ||
| //import{ HttpModule } from '@angular/http'; | ||
| const declarations = [ | ||
| ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf | ||
| ]; | ||
| class ngfModule { | ||
| } | ||
| ngfModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); | ||
| ngfModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, declarations: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf], imports: [CommonModule | ||
| //,HttpModule | ||
| ], exports: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf] }); | ||
| ngfModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, imports: [[ | ||
| CommonModule | ||
| //,HttpModule | ||
| ]] }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, decorators: [{ | ||
| type: NgModule, | ||
| args: [{ | ||
| imports: [ | ||
| CommonModule | ||
| //,HttpModule | ||
| ], | ||
| declarations: declarations, | ||
| exports: declarations //[HttpModule, ...declarations] | ||
| }] | ||
| }] }); | ||
| /* | ||
| * Public API Surface of angular-file | ||
| */ | ||
| /** | ||
| * Generated bundle index. Do not edit. | ||
| */ | ||
| export { eventToTransfer, filesToWriteableObject, ngf, ngfBackground, ngfDrop, ngfFormData, ngfModule, ngfSelect, ngfSrc, ngfUploadStatus }; | ||
| //# sourceMappingURL=angular-file-src.mjs.map |
Sorry, the diff of this file is too big to display
| import { CommonModule } from '@angular/common'; | ||
| import * as i0 from '@angular/core'; | ||
| import { Directive, Input, EventEmitter, Output, HostListener, NgModule } from '@angular/core'; | ||
| function getWindow() { return window; } | ||
| function acceptType(accept, type, name) { | ||
| if (!accept) { | ||
| return true; | ||
| } | ||
| const defs = accept.split(','); | ||
| let regx; | ||
| let acceptRegString; | ||
| for (let x = defs.length - 1; x >= 0; --x) { | ||
| //Escapes dots in mimetype | ||
| acceptRegString = defs[x]; | ||
| //trim | ||
| acceptRegString = acceptRegString.replace(/(^\s+|\s+$)/g, ''); | ||
| //Escapes stars in mimetype | ||
| acceptRegString = acceptRegString.replace(/\*/g, '.*'); | ||
| //let acceptReg = '^((' + acceptRegString | ||
| //acceptReg = acceptReg.replace(/,/g,')|(') + '))$' | ||
| //try by mime | ||
| regx = new RegExp(acceptRegString, 'gi'); | ||
| if (type.search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| //try by ext | ||
| if (acceptRegString.substring(0, 1) == '.') { | ||
| acceptRegString = '\\' + acceptRegString; //.substring(1, acceptRegString.length-1)//remove dot at front | ||
| regx = new RegExp(acceptRegString + '$', 'i'); | ||
| if ((name || type).search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function arrayBufferToBase64(buffer) { | ||
| var binary = ''; | ||
| var bytes = new Uint8Array(buffer); | ||
| var len = bytes.byteLength; | ||
| for (var i = 0; i < len; i++) { | ||
| binary += String.fromCharCode(bytes[i]); | ||
| } | ||
| return window.btoa(binary); | ||
| } | ||
| function dataUrltoBlob(dataurl, name, origSize) { | ||
| var arr = dataurl.split(','); | ||
| var mimeMatch = arr[0].match(/:(.*?);/); | ||
| var mime = mimeMatch ? mimeMatch[1] : 'text/plain'; | ||
| var bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); | ||
| while (n--) { | ||
| u8arr[n] = bstr.charCodeAt(n); | ||
| } | ||
| var blob = new window.Blob([u8arr], { type: mime }); | ||
| blob["name"] = name; | ||
| blob["$ngfOrigSize"] = origSize; | ||
| return blob; | ||
| } | ||
| function applyTransform(ctx, orientation, width, height) { | ||
| switch (orientation) { | ||
| case 2: | ||
| return ctx.transform(-1, 0, 0, 1, width, 0); | ||
| case 3: | ||
| return ctx.transform(-1, 0, 0, -1, width, height); | ||
| case 4: | ||
| return ctx.transform(1, 0, 0, -1, 0, height); | ||
| case 5: | ||
| return ctx.transform(0, 1, 1, 0, 0, 0); | ||
| case 6: | ||
| return ctx.transform(0, 1, -1, 0, height, 0); | ||
| case 7: | ||
| return ctx.transform(0, -1, -1, 0, height, width); | ||
| case 8: | ||
| return ctx.transform(0, -1, 1, 0, 0, width); | ||
| } | ||
| } | ||
| function fixFileOrientationByMeta(file, result) { | ||
| return dataUrl(file, true) | ||
| .then(url => { | ||
| var canvas = document.createElement('canvas'); | ||
| var img = document.createElement('img'); | ||
| return new Promise(function (res, rej) { | ||
| img.onload = function () { | ||
| try { | ||
| canvas.width = result.orientation > 4 ? img.height : img.width; | ||
| canvas.height = result.orientation > 4 ? img.width : img.height; | ||
| var ctx = canvas.getContext('2d'); | ||
| applyTransform(ctx, result.orientation, img.width, img.height); | ||
| ctx.drawImage(img, 0, 0); | ||
| var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934); | ||
| const base = arrayBufferToBase64(result.fixedArrayBuffer); | ||
| dataUrl = restoreExif(base, dataUrl); | ||
| var blob = dataUrltoBlob(dataUrl, file.name); | ||
| const newFile = blobToFile(blob, file.name); | ||
| res(newFile); | ||
| } | ||
| catch (e) { | ||
| rej(e); | ||
| } | ||
| }; | ||
| img.onerror = rej; | ||
| img.src = url; | ||
| }); | ||
| }); | ||
| } | ||
| function applyExifRotation(file) { | ||
| if (file.type.indexOf('image/jpeg') !== 0) { | ||
| return Promise.resolve(file); | ||
| } | ||
| return readOrientation(file) | ||
| .then((result) => { | ||
| if (result.orientation < 2 || result.orientation > 8) { | ||
| return file; | ||
| } | ||
| return fixFileOrientationByMeta(file, result); | ||
| }); | ||
| } | ||
| function readOrientation(file) { | ||
| return new Promise((res, rej) => { | ||
| var reader = new FileReader(); | ||
| var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file; | ||
| reader.readAsArrayBuffer(slicedFile); | ||
| reader.onerror = rej; | ||
| reader.onload = function (e) { | ||
| var result = { orientation: 1 }; | ||
| var view = new DataView(this.result); | ||
| if (view.getUint16(0, false) !== 0xFFD8) | ||
| return res(result); | ||
| var length = view.byteLength, offset = 2; | ||
| while (offset < length) { | ||
| var marker = view.getUint16(offset, false); | ||
| offset += 2; | ||
| if (marker === 0xFFE1) { | ||
| if (view.getUint32(offset += 2, false) !== 0x45786966) | ||
| return res(result); | ||
| var little = view.getUint16(offset += 6, false) === 0x4949; | ||
| offset += view.getUint32(offset + 4, little); | ||
| var tags = view.getUint16(offset, little); | ||
| offset += 2; | ||
| for (var i = 0; i < tags; i++) | ||
| if (view.getUint16(offset + (i * 12), little) === 0x0112) { | ||
| var orientation = view.getUint16(offset + (i * 12) + 8, little); | ||
| if (orientation >= 2 && orientation <= 8) { | ||
| view.setUint16(offset + (i * 12) + 8, 1, little); | ||
| result.fixedArrayBuffer = e.target.result; | ||
| } | ||
| result.orientation = orientation; | ||
| return res(result); | ||
| } | ||
| } | ||
| else if ((marker & 0xFF00) !== 0xFF00) | ||
| break; | ||
| else | ||
| offset += view.getUint16(offset, false); | ||
| } | ||
| return res(result); | ||
| }; | ||
| }); | ||
| } | ||
| /** converts file-input file into base64 dataUri */ | ||
| function dataUrl(file, disallowObjectUrl) { | ||
| if (!file) | ||
| return Promise.resolve(file); | ||
| if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { | ||
| return Promise.resolve(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl); | ||
| } | ||
| var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; | ||
| if (p) | ||
| return p; | ||
| const win = getWindow(); | ||
| let deferred; | ||
| if (win.FileReader && file && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { | ||
| //prefer URL.createObjectURL for handling refrences to files of all sizes | ||
| //since it doesn´t build a large string in memory | ||
| var URL = win.URL || win.webkitURL; | ||
| if (FileReader) { | ||
| deferred = new Promise((res, rej) => { | ||
| var fileReader = new FileReader(); | ||
| fileReader.onload = function (event) { | ||
| file.$ngfDataUrl = event.target.result; | ||
| delete file.$ngfDataUrl; | ||
| res(event.target.result); | ||
| }; | ||
| fileReader.onerror = function (e) { | ||
| file.$ngfDataUrl = ''; | ||
| rej(e); | ||
| }; | ||
| fileReader.readAsDataURL(file); | ||
| }); | ||
| } | ||
| else { | ||
| var url; | ||
| try { | ||
| url = URL.createObjectURL(file); | ||
| } | ||
| catch (e) { | ||
| return Promise.reject(e); | ||
| } | ||
| deferred = Promise.resolve(url); | ||
| file.$ngfBlobUrl = url; | ||
| } | ||
| } | ||
| else { | ||
| file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; | ||
| return Promise.reject(new Error('Browser does not support window.FileReader, window.FileReader, or window.FileAPI')); //deferred.reject(); | ||
| } | ||
| if (disallowObjectUrl) { | ||
| p = file.$$ngfDataUrlPromise = deferred; | ||
| } | ||
| else { | ||
| p = file.$$ngfBlobUrlPromise = deferred; | ||
| } | ||
| p = p.then((x) => { | ||
| delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; | ||
| return x; | ||
| }); | ||
| return p; | ||
| } | ||
| function restoreExif(orig, resized) { | ||
| var ExifRestorer = { | ||
| KEY_STR: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' | ||
| }; | ||
| ExifRestorer.encode64 = function (input) { | ||
| var output = '', chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0; | ||
| do { | ||
| chr1 = input[i++]; | ||
| chr2 = input[i++]; | ||
| chr3 = input[i++]; | ||
| enc1 = chr1 >> 2; | ||
| enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | ||
| enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | ||
| enc4 = chr3 & 63; | ||
| if (isNaN(chr2)) { | ||
| enc3 = enc4 = 64; | ||
| } | ||
| else if (isNaN(chr3)) { | ||
| enc4 = 64; | ||
| } | ||
| output = output + | ||
| this.KEY_STR.charAt(enc1) + | ||
| this.KEY_STR.charAt(enc2) + | ||
| this.KEY_STR.charAt(enc3) + | ||
| this.KEY_STR.charAt(enc4); | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return output; | ||
| }; | ||
| ExifRestorer.restore = function (origFileBase64, resizedFileBase64) { | ||
| if (origFileBase64.match('data:image/jpeg;base64,')) { | ||
| origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', ''); | ||
| } | ||
| var rawImage = this.decode64(origFileBase64); | ||
| var segments = this.slice2Segments(rawImage); | ||
| var image = this.exifManipulation(resizedFileBase64, segments); | ||
| return 'data:image/jpeg;base64,' + this.encode64(image); | ||
| }; | ||
| ExifRestorer.exifManipulation = function (resizedFileBase64, segments) { | ||
| var exifArray = this.getExifArray(segments), newImageArray = this.insertExif(resizedFileBase64, exifArray); | ||
| return new Uint8Array(newImageArray); | ||
| }; | ||
| ExifRestorer.getExifArray = function (segments) { | ||
| var seg; | ||
| for (var x = 0; x < segments.length; x++) { | ||
| seg = segments[x]; | ||
| if (seg[0] === 255 && seg[1] === 225) //(ff e1) | ||
| { | ||
| return seg; | ||
| } | ||
| } | ||
| return []; | ||
| }; | ||
| ExifRestorer.insertExif = function (resizedFileBase64, exifArray) { | ||
| var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''), buf = this.decode64(imageData), separatePoint = buf.indexOf(255, 3), mae = buf.slice(0, separatePoint), ato = buf.slice(separatePoint), array = mae; | ||
| array = array.concat(exifArray); | ||
| array = array.concat(ato); | ||
| return array; | ||
| }; | ||
| ExifRestorer.slice2Segments = function (rawImageArray) { | ||
| var head = 0, segments = []; | ||
| while (1) { | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 218) { | ||
| break; | ||
| } | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 216) { | ||
| head += 2; | ||
| } | ||
| else { | ||
| var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3]; | ||
| var endPoint = head + length + 2; | ||
| var seg = rawImageArray.slice(head, endPoint); | ||
| segments.push(seg); | ||
| head = endPoint; | ||
| } | ||
| if (head > rawImageArray.length) { | ||
| break; | ||
| } | ||
| } | ||
| return segments; | ||
| }; | ||
| ExifRestorer.decode64 = function (input) { | ||
| var chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0, buf = []; | ||
| // remove all characters that are not A-Z, a-z, 0-9, +, /, or = | ||
| var base64test = /[^A-Za-z0-9\+\/\=]/g; | ||
| if (base64test.exec(input)) { | ||
| console.log('There were invalid base64 characters in the input text.'); | ||
| } | ||
| input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); | ||
| do { | ||
| enc1 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc2 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc3 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc4 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| chr1 = (enc1 << 2) | (enc2 >> 4); | ||
| chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); | ||
| chr3 = ((enc3 & 3) << 6) | enc4; | ||
| buf.push(chr1); | ||
| if (enc3 !== 64) { | ||
| buf.push(chr2); | ||
| } | ||
| if (enc4 !== 64) { | ||
| buf.push(chr3); | ||
| } | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return buf; | ||
| }; | ||
| return ExifRestorer.restore(orig, resized); //<= EXIF | ||
| } | ||
| ; | ||
| function blobToFile(theBlob, fileName) { | ||
| var b = theBlob; | ||
| //A Blob() is almost a File() - it's just missing the two properties below which we will add | ||
| b.lastModifiedDate = new Date(); | ||
| b.name = fileName; | ||
| //Cast to a File() type | ||
| return theBlob; | ||
| } | ||
| class ngfBackground { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => { | ||
| const urlString = 'url(\'' + (src || '') + '\')'; | ||
| this.ElementRef.nativeElement.style.backgroundImage = urlString; | ||
| }); | ||
| } | ||
| } | ||
| ngfBackground.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfBackground.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfBackground, selector: "[ngfBackground]", inputs: { file: ["ngfBackground", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfBackground]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfBackground'] | ||
| }] } }); | ||
| const isFileInput = function (elm) { | ||
| const ty = elm.getAttribute('type'); | ||
| return elm.tagName.toLowerCase() === 'input' && ty && ty.toLowerCase() === 'file'; | ||
| }; | ||
| let initialTouchStartY = 0; | ||
| let initialTouchStartX = 0; | ||
| const detectSwipe = function (evt) { | ||
| var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches); | ||
| if (touches) { | ||
| if (evt.type === 'touchstart') { | ||
| initialTouchStartX = touches[0].clientX; | ||
| initialTouchStartY = touches[0].clientY; | ||
| return true; // don't block event default | ||
| } | ||
| else { | ||
| // prevent scroll from triggering event | ||
| if (evt.type === 'touchend') { | ||
| var currentX = touches[0].clientX; | ||
| var currentY = touches[0].clientY; | ||
| if ((Math.abs(currentX - initialTouchStartX) > 20) || | ||
| (Math.abs(currentY - initialTouchStartY) > 20)) { | ||
| evt.stopPropagation(); | ||
| if (evt.cancelable) { | ||
| evt.preventDefault(); | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }; | ||
| const createInvisibleFileInputWrap = function () { | ||
| var fileElem = createFileInput(); | ||
| var label = document.createElement('label'); | ||
| label.innerHTML = 'upload'; | ||
| label.style.visibility = 'hidden'; | ||
| label.style.position = 'absolute'; | ||
| label.style.overflow = 'hidden'; | ||
| label.style.width = '0px'; | ||
| label.style.height = '0px'; | ||
| label.style.border = 'none'; | ||
| label.style.margin = '0px'; | ||
| label.style.padding = '0px'; | ||
| label.setAttribute('tabindex', '-1'); | ||
| //bindAttrToFileInput(fileElem, label); | ||
| //generatedElems.push({el: elem, ref: label}); | ||
| label.appendChild(fileElem); | ||
| //document.body.appendChild( label ); | ||
| return label; | ||
| }; | ||
| const createFileInput = function () { | ||
| var fileElem = document.createElement('input'); | ||
| fileElem.type = "file"; | ||
| return fileElem; | ||
| }; | ||
| /** A master base set of logic intended to support file select/drag/drop operations | ||
| NOTE: Use ngfDrop for full drag/drop. Use ngfSelect for selecting | ||
| */ | ||
| class ngf { | ||
| constructor(element) { | ||
| this.element = element; | ||
| this.filters = []; | ||
| this.lastFileCount = 0; | ||
| this.ngfFixOrientation = true; | ||
| this.fileDropDisabled = false; | ||
| this.selectable = false; | ||
| this.directiveInit = new EventEmitter(); | ||
| this.lastInvalids = []; | ||
| this.lastInvalidsChange = new EventEmitter(); | ||
| this.lastBaseUrlChange = new EventEmitter(); | ||
| this.fileChange = new EventEmitter(); | ||
| this.files = []; | ||
| this.filesChange = new EventEmitter(); | ||
| this.fileSelectStart = new EventEmitter(); | ||
| this.initFilters(); | ||
| } | ||
| initFilters() { | ||
| // the order is important | ||
| this.filters.push({ name: 'accept', fn: this._acceptFilter }); | ||
| this.filters.push({ name: 'fileSize', fn: this._fileSizeFilter }); | ||
| //this.filters.push({name: 'fileType', fn: this._fileTypeFilter}) | ||
| //this.filters.push({name: 'queueLimit', fn: this._queueLimitFilter}) | ||
| //this.filters.push({name: 'mimeType', fn: this._mimeTypeFilter}) | ||
| } | ||
| ngOnDestroy() { | ||
| delete this.fileElm; //faster memory release of dom element | ||
| this.destroyPasteListener(); | ||
| } | ||
| ngOnInit() { | ||
| const selectable = (this.selectable || this.selectable === '') && !['false', 'null', '0'].includes(this.selectable); | ||
| if (selectable) { | ||
| this.enableSelecting(); | ||
| } | ||
| if (this.multiple) { | ||
| this.paramFileElm().setAttribute('multiple', this.multiple); | ||
| } | ||
| this.evalCapturePaste(); | ||
| // create reference to this class with one cycle delay to avoid ExpressionChangedAfterItHasBeenCheckedError | ||
| setTimeout(() => { | ||
| this.directiveInit.emit(this); | ||
| }, 0); | ||
| } | ||
| ngOnChanges(changes) { | ||
| var _a, _b; | ||
| if (changes.accept) { | ||
| this.paramFileElm().setAttribute('accept', changes.accept.currentValue || '*'); | ||
| } | ||
| if (changes.capturePaste) { | ||
| this.evalCapturePaste(); | ||
| } | ||
| // Did we go from having a file to not having a file? Clear file element then | ||
| if (changes.file && changes.file.previousValue && !changes.file.currentValue) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| // Did we go from having files to not having files? Clear file element then | ||
| if (changes.files) { | ||
| const filesWentToZero = ((_a = changes.files.previousValue) === null || _a === void 0 ? void 0 : _a.length) && !((_b = changes.files.currentValue) === null || _b === void 0 ? void 0 : _b.length); | ||
| if (filesWentToZero) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| } | ||
| } | ||
| evalCapturePaste() { | ||
| const isActive = this.capturePaste || this.capturePaste === '' || ['false', '0', 'null'].includes(this.capturePaste); | ||
| if (isActive) { | ||
| if (this.pasteCapturer) { | ||
| return; // already listening | ||
| } | ||
| this.pasteCapturer = (e) => { | ||
| const clip = e.clipboardData; | ||
| if (clip && clip.files && clip.files.length) { | ||
| this.handleFiles(clip.files); | ||
| e.preventDefault(); | ||
| } | ||
| }; | ||
| window.addEventListener('paste', this.pasteCapturer); | ||
| return; | ||
| } | ||
| this.destroyPasteListener(); | ||
| } | ||
| destroyPasteListener() { | ||
| if (this.pasteCapturer) { | ||
| window.removeEventListener('paste', this.pasteCapturer); | ||
| delete this.pasteCapturer; | ||
| } | ||
| } | ||
| paramFileElm() { | ||
| if (this.fileElm) | ||
| return this.fileElm; // already defined | ||
| // elm already is a file input | ||
| const isFile = isFileInput(this.element.nativeElement); | ||
| if (isFile) { | ||
| return this.fileElm = this.element.nativeElement; | ||
| } | ||
| // the host elm is NOT a file input | ||
| return this.fileElm = this.createFileElm({ | ||
| change: this.changeFn.bind(this) | ||
| }); | ||
| } | ||
| /** Only used when host element we are attached to is NOT a fileElement */ | ||
| createFileElm({ change }) { | ||
| // use specific technique to hide file element within | ||
| const label = createInvisibleFileInputWrap(); | ||
| const fileElm = label.getElementsByTagName('input')[0]; | ||
| fileElm.addEventListener('change', change); | ||
| this.element.nativeElement.appendChild(label); // put on html stage | ||
| return fileElm; | ||
| } | ||
| enableSelecting() { | ||
| let elm = this.element.nativeElement; | ||
| if (isFileInput(elm)) { | ||
| const bindedHandler = event => this.beforeSelect(event); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| return; | ||
| } | ||
| const bindedHandler = ev => this.clickHandler(ev); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| elm.addEventListener('touchend', bindedHandler); | ||
| } | ||
| getValidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (this.isFileValid(files[x])) { | ||
| rtn.push(files[x]); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| getInvalidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| let failReason = this.getFileFilterFailName(files[x]); | ||
| if (failReason) { | ||
| rtn.push({ | ||
| file: files[x], | ||
| type: failReason | ||
| }); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| // Primary handler of files coming in | ||
| handleFiles(files) { | ||
| const valids = this.getValidFiles(files); | ||
| if (files.length != valids.length) { | ||
| this.lastInvalids = this.getInvalidFiles(files); | ||
| } | ||
| else { | ||
| delete this.lastInvalids; | ||
| } | ||
| this.lastInvalidsChange.emit(this.lastInvalids); | ||
| if (valids.length) { | ||
| if (this.ngfFixOrientation) { | ||
| this.applyExifRotations(valids) | ||
| .then(fixedFiles => this.que(fixedFiles)); | ||
| } | ||
| else { | ||
| this.que(valids); | ||
| } | ||
| } | ||
| if (this.isEmptyAfterSelection()) { | ||
| this.element.nativeElement.value = ''; | ||
| } | ||
| } | ||
| que(files) { | ||
| this.files = this.files || []; | ||
| Array.prototype.push.apply(this.files, files); | ||
| //below break memory ref and doesnt act like a que | ||
| //this.files = files//causes memory change which triggers bindings like <ngfFormData [files]="files"></ngfFormData> | ||
| this.filesChange.emit(this.files); | ||
| if (files.length) { | ||
| this.fileChange.emit(this.file = files[0]); | ||
| if (this.lastBaseUrlChange.observers.length) { | ||
| dataUrl(files[0]) | ||
| .then(url => this.lastBaseUrlChange.emit(url)); | ||
| } | ||
| } | ||
| //will be checked for input value clearing | ||
| this.lastFileCount = this.files.length; | ||
| } | ||
| /** called when input has files */ | ||
| changeFn(event) { | ||
| var fileList = event.__files_ || (event.target && event.target.files); | ||
| if (!fileList) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(fileList); | ||
| } | ||
| clickHandler(evt) { | ||
| const elm = this.element.nativeElement; | ||
| if (elm.getAttribute('disabled') || this.fileDropDisabled) { | ||
| return false; | ||
| } | ||
| var r = detectSwipe(evt); | ||
| // prevent the click if it is a swipe | ||
| if (r !== false) | ||
| return r; | ||
| const fileElm = this.paramFileElm(); | ||
| fileElm.click(); | ||
| //fileElm.dispatchEvent( new Event('click') ); | ||
| this.beforeSelect(evt); | ||
| return false; | ||
| } | ||
| beforeSelect(event) { | ||
| this.fileSelectStart.emit(event); | ||
| if (this.files && this.lastFileCount === this.files.length) | ||
| return; | ||
| // if no files in array, be sure browser does not prevent reselect of same file (see github issue 27) | ||
| this.clearFileElmValue(); | ||
| } | ||
| clearFileElmValue() { | ||
| if (!this.fileElm) | ||
| return; | ||
| this.fileElm.value = null; | ||
| } | ||
| isEmptyAfterSelection() { | ||
| return !!this.element.nativeElement.attributes.multiple; | ||
| } | ||
| stopEvent(event) { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| } | ||
| transferHasFiles(transfer) { | ||
| if (!transfer.types) { | ||
| return false; | ||
| } | ||
| if (transfer.types.indexOf) { | ||
| return transfer.types.indexOf('Files') !== -1; | ||
| } | ||
| else if (transfer.types.contains) { | ||
| return transfer.types.contains('Files'); | ||
| } | ||
| else { | ||
| return false; | ||
| } | ||
| } | ||
| eventToFiles(event) { | ||
| const transfer = eventToTransfer(event); | ||
| if (transfer) { | ||
| if (transfer.files && transfer.files.length) { | ||
| return transfer.files; | ||
| } | ||
| if (transfer.items && transfer.items.length) { | ||
| return transfer.items; | ||
| } | ||
| } | ||
| return []; | ||
| } | ||
| applyExifRotations(files) { | ||
| const mapper = (file, index) => { | ||
| return applyExifRotation(file) | ||
| .then(fixedFile => files.splice(index, 1, fixedFile)); | ||
| }; | ||
| const proms = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| proms[x] = mapper(files[x], x); | ||
| } | ||
| return Promise.all(proms).then(() => files); | ||
| } | ||
| onChange(event) { | ||
| let files = this.element.nativeElement.files || this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| getFileFilterFailName(file) { | ||
| for (let i = 0; i < this.filters.length; i++) { | ||
| if (!this.filters[i].fn.call(this, file)) { | ||
| return this.filters[i].name; | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| isFileValid(file) { | ||
| const noFilters = !this.accept && (!this.filters || !this.filters.length); | ||
| if (noFilters) { | ||
| return true; //we have no filters so all files are valid | ||
| } | ||
| return this.getFileFilterFailName(file) ? false : true; | ||
| } | ||
| isFilesValid(files) { | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (!this.isFileValid(files[x])) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| _acceptFilter(item) { | ||
| return acceptType(this.accept, item.type, item.name); | ||
| } | ||
| _fileSizeFilter(item) { | ||
| return !(this.maxSize && item.size > this.maxSize); | ||
| } | ||
| } | ||
| ngf.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngf.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngf, selector: "[ngf]", inputs: { multiple: "multiple", accept: "accept", maxSize: "maxSize", ngfFixOrientation: "ngfFixOrientation", fileDropDisabled: "fileDropDisabled", selectable: "selectable", lastInvalids: "lastInvalids", lastBaseUrl: "lastBaseUrl", file: "file", files: "files", capturePaste: "capturePaste" }, outputs: { directiveInit: "init", lastInvalidsChange: "lastInvalidsChange", lastBaseUrlChange: "lastBaseUrlChange", fileChange: "fileChange", filesChange: "filesChange", fileSelectStart: "fileSelectStart" }, host: { listeners: { "change": "onChange($event)" } }, exportAs: ["ngf"], usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngf]", | ||
| exportAs: "ngf" | ||
| }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { multiple: [{ | ||
| type: Input | ||
| }], accept: [{ | ||
| type: Input | ||
| }], maxSize: [{ | ||
| type: Input | ||
| }], ngfFixOrientation: [{ | ||
| type: Input | ||
| }], fileDropDisabled: [{ | ||
| type: Input | ||
| }], selectable: [{ | ||
| type: Input | ||
| }], directiveInit: [{ | ||
| type: Output, | ||
| args: ['init'] | ||
| }], lastInvalids: [{ | ||
| type: Input | ||
| }], lastInvalidsChange: [{ | ||
| type: Output | ||
| }], lastBaseUrl: [{ | ||
| type: Input | ||
| }], lastBaseUrlChange: [{ | ||
| type: Output | ||
| }], file: [{ | ||
| type: Input | ||
| }], fileChange: [{ | ||
| type: Output | ||
| }], files: [{ | ||
| type: Input | ||
| }], filesChange: [{ | ||
| type: Output | ||
| }], fileSelectStart: [{ | ||
| type: Output | ||
| }], capturePaste: [{ | ||
| type: Input | ||
| }], onChange: [{ | ||
| type: HostListener, | ||
| args: ['change', ['$event']] | ||
| }] } }); | ||
| /** browsers try hard to conceal data about file drags, this tends to undo that */ | ||
| function filesToWriteableObject(files) { | ||
| const jsonFiles = []; | ||
| for (let x = 0; x < files.length; ++x) { | ||
| jsonFiles.push({ | ||
| type: files[x].type, | ||
| kind: files[x]["kind"] | ||
| }); | ||
| } | ||
| return jsonFiles; | ||
| } | ||
| function eventToTransfer(event) { | ||
| if (event.dataTransfer) | ||
| return event.dataTransfer; | ||
| return event.originalEvent ? event.originalEvent.dataTransfer : null; | ||
| } | ||
| class ngfDrop extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.fileOver = new EventEmitter(); | ||
| this.validDrag = false; | ||
| this.validDragChange = new EventEmitter(); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange = new EventEmitter(); | ||
| this.dragFilesChange = new EventEmitter(); | ||
| } | ||
| onDrop(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| let files = this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| handleFiles(files) { | ||
| this.fileOver.emit(false); //turn-off dragover | ||
| super.handleFiles(files); | ||
| } | ||
| onDragOver(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| const transfer = eventToTransfer(event); | ||
| let files = this.eventToFiles(event); | ||
| let jsonFiles = filesToWriteableObject(files); | ||
| this.dragFilesChange.emit(this.dragFiles = jsonFiles); | ||
| if (files.length) { | ||
| this.validDrag = this.isFilesValid(files); | ||
| } | ||
| else { | ||
| //Safari, IE11 & some browsers do NOT tell you about dragged files until dropped. Always consider a valid drag | ||
| this.validDrag = true; | ||
| } | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = !this.validDrag; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| transfer.dropEffect = 'copy'; // change cursor and visual display | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(true); | ||
| } | ||
| closeDrags() { | ||
| delete this.validDrag; | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| delete this.dragFiles; | ||
| this.dragFilesChange.emit(this.dragFiles); | ||
| } | ||
| onDragLeave(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| if (this.element) { | ||
| if (event.currentTarget === this.element[0]) { | ||
| return; | ||
| } | ||
| } | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(false); | ||
| } | ||
| } | ||
| ngfDrop.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfDrop.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfDrop, selector: "[ngfDrop]", inputs: { validDrag: "validDrag", invalidDrag: "invalidDrag", dragFiles: "dragFiles" }, outputs: { fileOver: "fileOver", validDragChange: "validDragChange", invalidDragChange: "invalidDragChange", dragFilesChange: "dragFilesChange" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)" } }, exportAs: ["ngfDrop"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfDrop]", | ||
| exportAs: "ngfDrop" | ||
| }] | ||
| }], propDecorators: { fileOver: [{ | ||
| type: Output | ||
| }], validDrag: [{ | ||
| type: Input | ||
| }], validDragChange: [{ | ||
| type: Output | ||
| }], invalidDrag: [{ | ||
| type: Input | ||
| }], invalidDragChange: [{ | ||
| type: Output | ||
| }], dragFiles: [{ | ||
| type: Input | ||
| }], dragFilesChange: [{ | ||
| type: Output | ||
| }], onDrop: [{ | ||
| type: HostListener, | ||
| args: ['drop', ['$event']] | ||
| }], onDragOver: [{ | ||
| type: HostListener, | ||
| args: ['dragover', ['$event']] | ||
| }], onDragLeave: [{ | ||
| type: HostListener, | ||
| args: ['dragleave', ['$event']] | ||
| }] } }); | ||
| class ngfSelect extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.selectable = true; | ||
| } | ||
| } | ||
| ngfSelect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSelect.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSelect, selector: "[ngfSelect]", inputs: { selectable: "selectable" }, exportAs: ["ngfSelect"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfSelect]", | ||
| exportAs: "ngfSelect" | ||
| }] | ||
| }], propDecorators: { selectable: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ngfUploadStatus { | ||
| constructor() { | ||
| this.percent = 0; | ||
| this.percentChange = new EventEmitter(); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.httpEvent && changes.httpEvent.currentValue) { | ||
| const event = changes.httpEvent.currentValue; | ||
| if (event.loaded && event.total) { | ||
| setTimeout(() => { | ||
| this.percent = Math.round(100 * event.loaded / event.total); | ||
| this.percentChange.emit(this.percent); | ||
| }, 0); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ngfUploadStatus.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, deps: [], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfUploadStatus.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfUploadStatus, selector: "ngfUploadStatus", inputs: { percent: "percent", httpEvent: "httpEvent" }, outputs: { percentChange: "percentChange" }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfUploadStatus' }] | ||
| }], propDecorators: { percent: [{ | ||
| type: Input | ||
| }], percentChange: [{ | ||
| type: Output | ||
| }], httpEvent: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ngfFormData { | ||
| constructor(IterableDiffers) { | ||
| this.postName = "file"; | ||
| this.FormData = new FormData(); | ||
| this.FormDataChange = new EventEmitter(); | ||
| this.differ = IterableDiffers.find([]).create(); | ||
| } | ||
| ngDoCheck() { | ||
| var changes = this.differ.diff(this.files); | ||
| if (changes) { | ||
| setTimeout(() => this.buildFormData(), 0); | ||
| } | ||
| } | ||
| buildFormData() { | ||
| const isArray = typeof (this.files) === 'object' && this.files.constructor === Array; | ||
| if (isArray) { | ||
| this.FormData = new FormData(); | ||
| const files = this.files || []; | ||
| files.forEach(file => this.FormData.append(this.postName, file, this.fileName || file.name)); | ||
| this.FormDataChange.emit(this.FormData); | ||
| } | ||
| else { | ||
| delete this.FormData; | ||
| } | ||
| } | ||
| } | ||
| ngfFormData.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, deps: [{ token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfFormData.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfFormData, selector: "ngfFormData", inputs: { files: "files", postName: "postName", fileName: "fileName", FormData: "FormData" }, outputs: { FormDataChange: "FormDataChange" }, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfFormData' }] | ||
| }], ctorParameters: function () { return [{ type: i0.IterableDiffers }]; }, propDecorators: { files: [{ | ||
| type: Input | ||
| }], postName: [{ | ||
| type: Input | ||
| }], fileName: [{ | ||
| type: Input | ||
| }], FormData: [{ | ||
| type: Input | ||
| }], FormDataChange: [{ | ||
| type: Output | ||
| }] } }); | ||
| class ngfSrc { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => this.ElementRef.nativeElement.src = src); | ||
| } | ||
| } | ||
| ngfSrc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSrc.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSrc, selector: "[ngfSrc]", inputs: { file: ["ngfSrc", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfSrc]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfSrc'] | ||
| }] } }); | ||
| //import{ HttpModule } from '@angular/http'; | ||
| const declarations = [ | ||
| ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf | ||
| ]; | ||
| class ngfModule { | ||
| } | ||
| ngfModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); | ||
| ngfModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, declarations: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf], imports: [CommonModule | ||
| //,HttpModule | ||
| ], exports: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf] }); | ||
| ngfModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, imports: [[ | ||
| CommonModule | ||
| //,HttpModule | ||
| ]] }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, decorators: [{ | ||
| type: NgModule, | ||
| args: [{ | ||
| imports: [ | ||
| CommonModule | ||
| //,HttpModule | ||
| ], | ||
| declarations: declarations, | ||
| exports: declarations //[HttpModule, ...declarations] | ||
| }] | ||
| }] }); | ||
| /** | ||
| * Generated bundle index. Do not edit. | ||
| */ | ||
| export { ngf, ngfBackground, ngfDrop, ngfFormData, ngfModule, ngfSelect, ngfSrc, ngfUploadStatus }; | ||
| //# sourceMappingURL=angular-file.mjs.map |
Sorry, the diff of this file is too big to display
| import * as i0 from '@angular/core'; | ||
| import { EventEmitter, Directive, Input, Output, HostListener, NgModule } from '@angular/core'; | ||
| import { CommonModule } from '@angular/common'; | ||
| const isFileInput = function (elm) { | ||
| const ty = elm.getAttribute('type'); | ||
| return elm.tagName.toLowerCase() === 'input' && ty && ty.toLowerCase() === 'file'; | ||
| }; | ||
| let initialTouchStartY = 0; | ||
| let initialTouchStartX = 0; | ||
| const detectSwipe = function (evt) { | ||
| var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches); | ||
| if (touches) { | ||
| if (evt.type === 'touchstart') { | ||
| initialTouchStartX = touches[0].clientX; | ||
| initialTouchStartY = touches[0].clientY; | ||
| return true; // don't block event default | ||
| } | ||
| else { | ||
| // prevent scroll from triggering event | ||
| if (evt.type === 'touchend') { | ||
| var currentX = touches[0].clientX; | ||
| var currentY = touches[0].clientY; | ||
| if ((Math.abs(currentX - initialTouchStartX) > 20) || | ||
| (Math.abs(currentY - initialTouchStartY) > 20)) { | ||
| evt.stopPropagation(); | ||
| if (evt.cancelable) { | ||
| evt.preventDefault(); | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }; | ||
| const createInvisibleFileInputWrap = function () { | ||
| var fileElem = createFileInput(); | ||
| var label = document.createElement('label'); | ||
| label.innerHTML = 'upload'; | ||
| label.style.visibility = 'hidden'; | ||
| label.style.position = 'absolute'; | ||
| label.style.overflow = 'hidden'; | ||
| label.style.width = '0px'; | ||
| label.style.height = '0px'; | ||
| label.style.border = 'none'; | ||
| label.style.margin = '0px'; | ||
| label.style.padding = '0px'; | ||
| label.setAttribute('tabindex', '-1'); | ||
| //bindAttrToFileInput(fileElem, label); | ||
| //generatedElems.push({el: elem, ref: label}); | ||
| label.appendChild(fileElem); | ||
| //document.body.appendChild( label ); | ||
| return label; | ||
| }; | ||
| const createFileInput = function () { | ||
| var fileElem = document.createElement('input'); | ||
| fileElem.type = "file"; | ||
| return fileElem; | ||
| }; | ||
| function getWindow() { return window; } | ||
| function acceptType(accept, type, name) { | ||
| if (!accept) { | ||
| return true; | ||
| } | ||
| const defs = accept.split(','); | ||
| let regx; | ||
| let acceptRegString; | ||
| for (let x = defs.length - 1; x >= 0; --x) { | ||
| //Escapes dots in mimetype | ||
| acceptRegString = defs[x]; | ||
| //trim | ||
| acceptRegString = acceptRegString.replace(/(^\s+|\s+$)/g, ''); | ||
| //Escapes stars in mimetype | ||
| acceptRegString = acceptRegString.replace(/\*/g, '.*'); | ||
| //let acceptReg = '^((' + acceptRegString | ||
| //acceptReg = acceptReg.replace(/,/g,')|(') + '))$' | ||
| //try by mime | ||
| regx = new RegExp(acceptRegString, 'gi'); | ||
| if (type.search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| //try by ext | ||
| if (acceptRegString.substring(0, 1) == '.') { | ||
| acceptRegString = '\\' + acceptRegString; //.substring(1, acceptRegString.length-1)//remove dot at front | ||
| regx = new RegExp(acceptRegString + '$', 'i'); | ||
| if ((name || type).search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function arrayBufferToBase64(buffer) { | ||
| var binary = ''; | ||
| var bytes = new Uint8Array(buffer); | ||
| var len = bytes.byteLength; | ||
| for (var i = 0; i < len; i++) { | ||
| binary += String.fromCharCode(bytes[i]); | ||
| } | ||
| return window.btoa(binary); | ||
| } | ||
| function dataUrltoBlob(dataurl, name, origSize) { | ||
| var arr = dataurl.split(','); | ||
| var mimeMatch = arr[0].match(/:(.*?);/); | ||
| var mime = mimeMatch ? mimeMatch[1] : 'text/plain'; | ||
| var bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); | ||
| while (n--) { | ||
| u8arr[n] = bstr.charCodeAt(n); | ||
| } | ||
| var blob = new window.Blob([u8arr], { type: mime }); | ||
| blob["name"] = name; | ||
| blob["$ngfOrigSize"] = origSize; | ||
| return blob; | ||
| } | ||
| function applyTransform(ctx, orientation, width, height) { | ||
| switch (orientation) { | ||
| case 2: | ||
| return ctx.transform(-1, 0, 0, 1, width, 0); | ||
| case 3: | ||
| return ctx.transform(-1, 0, 0, -1, width, height); | ||
| case 4: | ||
| return ctx.transform(1, 0, 0, -1, 0, height); | ||
| case 5: | ||
| return ctx.transform(0, 1, 1, 0, 0, 0); | ||
| case 6: | ||
| return ctx.transform(0, 1, -1, 0, height, 0); | ||
| case 7: | ||
| return ctx.transform(0, -1, -1, 0, height, width); | ||
| case 8: | ||
| return ctx.transform(0, -1, 1, 0, 0, width); | ||
| } | ||
| } | ||
| function fixFileOrientationByMeta(file, result) { | ||
| return dataUrl(file, true) | ||
| .then(url => { | ||
| var canvas = document.createElement('canvas'); | ||
| var img = document.createElement('img'); | ||
| return new Promise(function (res, rej) { | ||
| img.onload = function () { | ||
| try { | ||
| canvas.width = result.orientation > 4 ? img.height : img.width; | ||
| canvas.height = result.orientation > 4 ? img.width : img.height; | ||
| var ctx = canvas.getContext('2d'); | ||
| applyTransform(ctx, result.orientation, img.width, img.height); | ||
| ctx.drawImage(img, 0, 0); | ||
| var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934); | ||
| const base = arrayBufferToBase64(result.fixedArrayBuffer); | ||
| dataUrl = restoreExif(base, dataUrl); | ||
| var blob = dataUrltoBlob(dataUrl, file.name); | ||
| const newFile = blobToFile(blob, file.name); | ||
| res(newFile); | ||
| } | ||
| catch (e) { | ||
| rej(e); | ||
| } | ||
| }; | ||
| img.onerror = rej; | ||
| img.src = url; | ||
| }); | ||
| }); | ||
| } | ||
| function applyExifRotation(file) { | ||
| if (file.type.indexOf('image/jpeg') !== 0) { | ||
| return Promise.resolve(file); | ||
| } | ||
| return readOrientation(file) | ||
| .then((result) => { | ||
| if (result.orientation < 2 || result.orientation > 8) { | ||
| return file; | ||
| } | ||
| return fixFileOrientationByMeta(file, result); | ||
| }); | ||
| } | ||
| function readOrientation(file) { | ||
| return new Promise((res, rej) => { | ||
| var reader = new FileReader(); | ||
| var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file; | ||
| reader.readAsArrayBuffer(slicedFile); | ||
| reader.onerror = rej; | ||
| reader.onload = function (e) { | ||
| var result = { orientation: 1 }; | ||
| var view = new DataView(this.result); | ||
| if (view.getUint16(0, false) !== 0xFFD8) | ||
| return res(result); | ||
| var length = view.byteLength, offset = 2; | ||
| while (offset < length) { | ||
| var marker = view.getUint16(offset, false); | ||
| offset += 2; | ||
| if (marker === 0xFFE1) { | ||
| if (view.getUint32(offset += 2, false) !== 0x45786966) | ||
| return res(result); | ||
| var little = view.getUint16(offset += 6, false) === 0x4949; | ||
| offset += view.getUint32(offset + 4, little); | ||
| var tags = view.getUint16(offset, little); | ||
| offset += 2; | ||
| for (var i = 0; i < tags; i++) | ||
| if (view.getUint16(offset + (i * 12), little) === 0x0112) { | ||
| var orientation = view.getUint16(offset + (i * 12) + 8, little); | ||
| if (orientation >= 2 && orientation <= 8) { | ||
| view.setUint16(offset + (i * 12) + 8, 1, little); | ||
| result.fixedArrayBuffer = e.target.result; | ||
| } | ||
| result.orientation = orientation; | ||
| return res(result); | ||
| } | ||
| } | ||
| else if ((marker & 0xFF00) !== 0xFF00) | ||
| break; | ||
| else | ||
| offset += view.getUint16(offset, false); | ||
| } | ||
| return res(result); | ||
| }; | ||
| }); | ||
| } | ||
| /** converts file-input file into base64 dataUri */ | ||
| function dataUrl(file, disallowObjectUrl) { | ||
| if (!file) | ||
| return Promise.resolve(file); | ||
| if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { | ||
| return Promise.resolve(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl); | ||
| } | ||
| var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; | ||
| if (p) | ||
| return p; | ||
| const win = getWindow(); | ||
| let deferred; | ||
| if (win.FileReader && file && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { | ||
| //prefer URL.createObjectURL for handling refrences to files of all sizes | ||
| //since it doesn´t build a large string in memory | ||
| var URL = win.URL || win.webkitURL; | ||
| if (FileReader) { | ||
| deferred = new Promise((res, rej) => { | ||
| var fileReader = new FileReader(); | ||
| fileReader.onload = function (event) { | ||
| file.$ngfDataUrl = event.target.result; | ||
| delete file.$ngfDataUrl; | ||
| res(event.target.result); | ||
| }; | ||
| fileReader.onerror = function (e) { | ||
| file.$ngfDataUrl = ''; | ||
| rej(e); | ||
| }; | ||
| fileReader.readAsDataURL(file); | ||
| }); | ||
| } | ||
| else { | ||
| var url; | ||
| try { | ||
| url = URL.createObjectURL(file); | ||
| } | ||
| catch (e) { | ||
| return Promise.reject(e); | ||
| } | ||
| deferred = Promise.resolve(url); | ||
| file.$ngfBlobUrl = url; | ||
| } | ||
| } | ||
| else { | ||
| file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; | ||
| return Promise.reject(new Error('Browser does not support window.FileReader, window.FileReader, or window.FileAPI')); //deferred.reject(); | ||
| } | ||
| if (disallowObjectUrl) { | ||
| p = file.$$ngfDataUrlPromise = deferred; | ||
| } | ||
| else { | ||
| p = file.$$ngfBlobUrlPromise = deferred; | ||
| } | ||
| p = p.then((x) => { | ||
| delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; | ||
| return x; | ||
| }); | ||
| return p; | ||
| } | ||
| function restoreExif(orig, resized) { | ||
| var ExifRestorer = { | ||
| KEY_STR: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' | ||
| }; | ||
| ExifRestorer.encode64 = function (input) { | ||
| var output = '', chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0; | ||
| do { | ||
| chr1 = input[i++]; | ||
| chr2 = input[i++]; | ||
| chr3 = input[i++]; | ||
| enc1 = chr1 >> 2; | ||
| enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | ||
| enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | ||
| enc4 = chr3 & 63; | ||
| if (isNaN(chr2)) { | ||
| enc3 = enc4 = 64; | ||
| } | ||
| else if (isNaN(chr3)) { | ||
| enc4 = 64; | ||
| } | ||
| output = output + | ||
| this.KEY_STR.charAt(enc1) + | ||
| this.KEY_STR.charAt(enc2) + | ||
| this.KEY_STR.charAt(enc3) + | ||
| this.KEY_STR.charAt(enc4); | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return output; | ||
| }; | ||
| ExifRestorer.restore = function (origFileBase64, resizedFileBase64) { | ||
| if (origFileBase64.match('data:image/jpeg;base64,')) { | ||
| origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', ''); | ||
| } | ||
| var rawImage = this.decode64(origFileBase64); | ||
| var segments = this.slice2Segments(rawImage); | ||
| var image = this.exifManipulation(resizedFileBase64, segments); | ||
| return 'data:image/jpeg;base64,' + this.encode64(image); | ||
| }; | ||
| ExifRestorer.exifManipulation = function (resizedFileBase64, segments) { | ||
| var exifArray = this.getExifArray(segments), newImageArray = this.insertExif(resizedFileBase64, exifArray); | ||
| return new Uint8Array(newImageArray); | ||
| }; | ||
| ExifRestorer.getExifArray = function (segments) { | ||
| var seg; | ||
| for (var x = 0; x < segments.length; x++) { | ||
| seg = segments[x]; | ||
| if (seg[0] === 255 && seg[1] === 225) //(ff e1) | ||
| { | ||
| return seg; | ||
| } | ||
| } | ||
| return []; | ||
| }; | ||
| ExifRestorer.insertExif = function (resizedFileBase64, exifArray) { | ||
| var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''), buf = this.decode64(imageData), separatePoint = buf.indexOf(255, 3), mae = buf.slice(0, separatePoint), ato = buf.slice(separatePoint), array = mae; | ||
| array = array.concat(exifArray); | ||
| array = array.concat(ato); | ||
| return array; | ||
| }; | ||
| ExifRestorer.slice2Segments = function (rawImageArray) { | ||
| var head = 0, segments = []; | ||
| while (1) { | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 218) { | ||
| break; | ||
| } | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 216) { | ||
| head += 2; | ||
| } | ||
| else { | ||
| var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3]; | ||
| var endPoint = head + length + 2; | ||
| var seg = rawImageArray.slice(head, endPoint); | ||
| segments.push(seg); | ||
| head = endPoint; | ||
| } | ||
| if (head > rawImageArray.length) { | ||
| break; | ||
| } | ||
| } | ||
| return segments; | ||
| }; | ||
| ExifRestorer.decode64 = function (input) { | ||
| var chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0, buf = []; | ||
| // remove all characters that are not A-Z, a-z, 0-9, +, /, or = | ||
| var base64test = /[^A-Za-z0-9\+\/\=]/g; | ||
| if (base64test.exec(input)) { | ||
| console.log('There were invalid base64 characters in the input text.'); | ||
| } | ||
| input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); | ||
| do { | ||
| enc1 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc2 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc3 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc4 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| chr1 = (enc1 << 2) | (enc2 >> 4); | ||
| chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); | ||
| chr3 = ((enc3 & 3) << 6) | enc4; | ||
| buf.push(chr1); | ||
| if (enc3 !== 64) { | ||
| buf.push(chr2); | ||
| } | ||
| if (enc4 !== 64) { | ||
| buf.push(chr3); | ||
| } | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return buf; | ||
| }; | ||
| return ExifRestorer.restore(orig, resized); //<= EXIF | ||
| } | ||
| ; | ||
| function blobToFile(theBlob, fileName) { | ||
| var b = theBlob; | ||
| //A Blob() is almost a File() - it's just missing the two properties below which we will add | ||
| b.lastModifiedDate = new Date(); | ||
| b.name = fileName; | ||
| //Cast to a File() type | ||
| return theBlob; | ||
| } | ||
| /** A master base set of logic intended to support file select/drag/drop operations | ||
| NOTE: Use ngfDrop for full drag/drop. Use ngfSelect for selecting | ||
| */ | ||
| class ngf { | ||
| constructor(element) { | ||
| this.element = element; | ||
| this.filters = []; | ||
| this.lastFileCount = 0; | ||
| this.ngfFixOrientation = true; | ||
| this.fileDropDisabled = false; | ||
| this.selectable = false; | ||
| this.directiveInit = new EventEmitter(); | ||
| this.lastInvalids = []; | ||
| this.lastInvalidsChange = new EventEmitter(); | ||
| this.lastBaseUrlChange = new EventEmitter(); | ||
| this.fileChange = new EventEmitter(); | ||
| this.files = []; | ||
| this.filesChange = new EventEmitter(); | ||
| this.fileSelectStart = new EventEmitter(); | ||
| this.initFilters(); | ||
| } | ||
| initFilters() { | ||
| // the order is important | ||
| this.filters.push({ name: 'accept', fn: this._acceptFilter }); | ||
| this.filters.push({ name: 'fileSize', fn: this._fileSizeFilter }); | ||
| //this.filters.push({name: 'fileType', fn: this._fileTypeFilter}) | ||
| //this.filters.push({name: 'queueLimit', fn: this._queueLimitFilter}) | ||
| //this.filters.push({name: 'mimeType', fn: this._mimeTypeFilter}) | ||
| } | ||
| ngOnDestroy() { | ||
| delete this.fileElm; //faster memory release of dom element | ||
| this.destroyPasteListener(); | ||
| } | ||
| ngOnInit() { | ||
| const selectable = (this.selectable || this.selectable === '') && !['false', 'null', '0'].includes(this.selectable); | ||
| if (selectable) { | ||
| this.enableSelecting(); | ||
| } | ||
| if (this.multiple) { | ||
| this.paramFileElm().setAttribute('multiple', this.multiple); | ||
| } | ||
| this.evalCapturePaste(); | ||
| // create reference to this class with one cycle delay to avoid ExpressionChangedAfterItHasBeenCheckedError | ||
| setTimeout(() => { | ||
| this.directiveInit.emit(this); | ||
| }, 0); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.accept) { | ||
| this.paramFileElm().setAttribute('accept', changes.accept.currentValue || '*'); | ||
| } | ||
| if (changes.capturePaste) { | ||
| this.evalCapturePaste(); | ||
| } | ||
| // Did we go from having a file to not having a file? Clear file element then | ||
| if (changes.file && changes.file.previousValue && !changes.file.currentValue) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| // Did we go from having files to not having files? Clear file element then | ||
| if (changes.files) { | ||
| const filesWentToZero = changes.files.previousValue?.length && !changes.files.currentValue?.length; | ||
| if (filesWentToZero) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| } | ||
| } | ||
| evalCapturePaste() { | ||
| const isActive = this.capturePaste || this.capturePaste === '' || ['false', '0', 'null'].includes(this.capturePaste); | ||
| if (isActive) { | ||
| if (this.pasteCapturer) { | ||
| return; // already listening | ||
| } | ||
| this.pasteCapturer = (e) => { | ||
| const clip = e.clipboardData; | ||
| if (clip && clip.files && clip.files.length) { | ||
| this.handleFiles(clip.files); | ||
| e.preventDefault(); | ||
| } | ||
| }; | ||
| window.addEventListener('paste', this.pasteCapturer); | ||
| return; | ||
| } | ||
| this.destroyPasteListener(); | ||
| } | ||
| destroyPasteListener() { | ||
| if (this.pasteCapturer) { | ||
| window.removeEventListener('paste', this.pasteCapturer); | ||
| delete this.pasteCapturer; | ||
| } | ||
| } | ||
| paramFileElm() { | ||
| if (this.fileElm) | ||
| return this.fileElm; // already defined | ||
| // elm already is a file input | ||
| const isFile = isFileInput(this.element.nativeElement); | ||
| if (isFile) { | ||
| return this.fileElm = this.element.nativeElement; | ||
| } | ||
| // the host elm is NOT a file input | ||
| return this.fileElm = this.createFileElm({ | ||
| change: this.changeFn.bind(this) | ||
| }); | ||
| } | ||
| /** Only used when host element we are attached to is NOT a fileElement */ | ||
| createFileElm({ change }) { | ||
| // use specific technique to hide file element within | ||
| const label = createInvisibleFileInputWrap(); | ||
| const fileElm = label.getElementsByTagName('input')[0]; | ||
| fileElm.addEventListener('change', change); | ||
| this.element.nativeElement.appendChild(label); // put on html stage | ||
| return fileElm; | ||
| } | ||
| enableSelecting() { | ||
| let elm = this.element.nativeElement; | ||
| if (isFileInput(elm)) { | ||
| const bindedHandler = event => this.beforeSelect(event); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| return; | ||
| } | ||
| const bindedHandler = ev => this.clickHandler(ev); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| elm.addEventListener('touchend', bindedHandler); | ||
| } | ||
| getValidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (this.isFileValid(files[x])) { | ||
| rtn.push(files[x]); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| getInvalidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| let failReason = this.getFileFilterFailName(files[x]); | ||
| if (failReason) { | ||
| rtn.push({ | ||
| file: files[x], | ||
| type: failReason | ||
| }); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| // Primary handler of files coming in | ||
| handleFiles(files) { | ||
| const valids = this.getValidFiles(files); | ||
| if (files.length != valids.length) { | ||
| this.lastInvalids = this.getInvalidFiles(files); | ||
| } | ||
| else { | ||
| delete this.lastInvalids; | ||
| } | ||
| this.lastInvalidsChange.emit(this.lastInvalids); | ||
| if (valids.length) { | ||
| if (this.ngfFixOrientation) { | ||
| this.applyExifRotations(valids) | ||
| .then(fixedFiles => this.que(fixedFiles)); | ||
| } | ||
| else { | ||
| this.que(valids); | ||
| } | ||
| } | ||
| if (this.isEmptyAfterSelection()) { | ||
| this.element.nativeElement.value = ''; | ||
| } | ||
| } | ||
| que(files) { | ||
| this.files = this.files || []; | ||
| Array.prototype.push.apply(this.files, files); | ||
| //below break memory ref and doesnt act like a que | ||
| //this.files = files//causes memory change which triggers bindings like <ngfFormData [files]="files"></ngfFormData> | ||
| this.filesChange.emit(this.files); | ||
| if (files.length) { | ||
| this.fileChange.emit(this.file = files[0]); | ||
| if (this.lastBaseUrlChange.observers.length) { | ||
| dataUrl(files[0]) | ||
| .then(url => this.lastBaseUrlChange.emit(url)); | ||
| } | ||
| } | ||
| //will be checked for input value clearing | ||
| this.lastFileCount = this.files.length; | ||
| } | ||
| /** called when input has files */ | ||
| changeFn(event) { | ||
| var fileList = event.__files_ || (event.target && event.target.files); | ||
| if (!fileList) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(fileList); | ||
| } | ||
| clickHandler(evt) { | ||
| const elm = this.element.nativeElement; | ||
| if (elm.getAttribute('disabled') || this.fileDropDisabled) { | ||
| return false; | ||
| } | ||
| var r = detectSwipe(evt); | ||
| // prevent the click if it is a swipe | ||
| if (r !== false) | ||
| return r; | ||
| const fileElm = this.paramFileElm(); | ||
| fileElm.click(); | ||
| //fileElm.dispatchEvent( new Event('click') ); | ||
| this.beforeSelect(evt); | ||
| return false; | ||
| } | ||
| beforeSelect(event) { | ||
| this.fileSelectStart.emit(event); | ||
| if (this.files && this.lastFileCount === this.files.length) | ||
| return; | ||
| // if no files in array, be sure browser does not prevent reselect of same file (see github issue 27) | ||
| this.clearFileElmValue(); | ||
| } | ||
| clearFileElmValue() { | ||
| if (!this.fileElm) | ||
| return; | ||
| this.fileElm.value = null; | ||
| } | ||
| isEmptyAfterSelection() { | ||
| return !!this.element.nativeElement.attributes.multiple; | ||
| } | ||
| stopEvent(event) { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| } | ||
| transferHasFiles(transfer) { | ||
| if (!transfer.types) { | ||
| return false; | ||
| } | ||
| if (transfer.types.indexOf) { | ||
| return transfer.types.indexOf('Files') !== -1; | ||
| } | ||
| else if (transfer.types.contains) { | ||
| return transfer.types.contains('Files'); | ||
| } | ||
| else { | ||
| return false; | ||
| } | ||
| } | ||
| eventToFiles(event) { | ||
| const transfer = eventToTransfer(event); | ||
| if (transfer) { | ||
| if (transfer.files && transfer.files.length) { | ||
| return transfer.files; | ||
| } | ||
| if (transfer.items && transfer.items.length) { | ||
| return transfer.items; | ||
| } | ||
| } | ||
| return []; | ||
| } | ||
| applyExifRotations(files) { | ||
| const mapper = (file, index) => { | ||
| return applyExifRotation(file) | ||
| .then(fixedFile => files.splice(index, 1, fixedFile)); | ||
| }; | ||
| const proms = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| proms[x] = mapper(files[x], x); | ||
| } | ||
| return Promise.all(proms).then(() => files); | ||
| } | ||
| onChange(event) { | ||
| let files = this.element.nativeElement.files || this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| getFileFilterFailName(file) { | ||
| for (let i = 0; i < this.filters.length; i++) { | ||
| if (!this.filters[i].fn.call(this, file)) { | ||
| return this.filters[i].name; | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| isFileValid(file) { | ||
| const noFilters = !this.accept && (!this.filters || !this.filters.length); | ||
| if (noFilters) { | ||
| return true; //we have no filters so all files are valid | ||
| } | ||
| return this.getFileFilterFailName(file) ? false : true; | ||
| } | ||
| isFilesValid(files) { | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (!this.isFileValid(files[x])) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| _acceptFilter(item) { | ||
| return acceptType(this.accept, item.type, item.name); | ||
| } | ||
| _fileSizeFilter(item) { | ||
| return !(this.maxSize && item.size > this.maxSize); | ||
| } | ||
| } | ||
| ngf.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngf.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngf, selector: "[ngf]", inputs: { multiple: "multiple", accept: "accept", maxSize: "maxSize", ngfFixOrientation: "ngfFixOrientation", fileDropDisabled: "fileDropDisabled", selectable: "selectable", lastInvalids: "lastInvalids", lastBaseUrl: "lastBaseUrl", file: "file", files: "files", capturePaste: "capturePaste" }, outputs: { directiveInit: "init", lastInvalidsChange: "lastInvalidsChange", lastBaseUrlChange: "lastBaseUrlChange", fileChange: "fileChange", filesChange: "filesChange", fileSelectStart: "fileSelectStart" }, host: { listeners: { "change": "onChange($event)" } }, exportAs: ["ngf"], usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngf]", | ||
| exportAs: "ngf" | ||
| }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { multiple: [{ | ||
| type: Input | ||
| }], accept: [{ | ||
| type: Input | ||
| }], maxSize: [{ | ||
| type: Input | ||
| }], ngfFixOrientation: [{ | ||
| type: Input | ||
| }], fileDropDisabled: [{ | ||
| type: Input | ||
| }], selectable: [{ | ||
| type: Input | ||
| }], directiveInit: [{ | ||
| type: Output, | ||
| args: ['init'] | ||
| }], lastInvalids: [{ | ||
| type: Input | ||
| }], lastInvalidsChange: [{ | ||
| type: Output | ||
| }], lastBaseUrl: [{ | ||
| type: Input | ||
| }], lastBaseUrlChange: [{ | ||
| type: Output | ||
| }], file: [{ | ||
| type: Input | ||
| }], fileChange: [{ | ||
| type: Output | ||
| }], files: [{ | ||
| type: Input | ||
| }], filesChange: [{ | ||
| type: Output | ||
| }], fileSelectStart: [{ | ||
| type: Output | ||
| }], capturePaste: [{ | ||
| type: Input | ||
| }], onChange: [{ | ||
| type: HostListener, | ||
| args: ['change', ['$event']] | ||
| }] } }); | ||
| /** browsers try hard to conceal data about file drags, this tends to undo that */ | ||
| function filesToWriteableObject(files) { | ||
| const jsonFiles = []; | ||
| for (let x = 0; x < files.length; ++x) { | ||
| jsonFiles.push({ | ||
| type: files[x].type, | ||
| kind: files[x]["kind"] | ||
| }); | ||
| } | ||
| return jsonFiles; | ||
| } | ||
| function eventToTransfer(event) { | ||
| if (event.dataTransfer) | ||
| return event.dataTransfer; | ||
| return event.originalEvent ? event.originalEvent.dataTransfer : null; | ||
| } | ||
| class ngfSelect extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.selectable = true; | ||
| } | ||
| } | ||
| ngfSelect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSelect.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSelect, selector: "[ngfSelect]", inputs: { selectable: "selectable" }, exportAs: ["ngfSelect"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfSelect]", | ||
| exportAs: "ngfSelect" | ||
| }] | ||
| }], propDecorators: { selectable: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ngfDrop extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.fileOver = new EventEmitter(); | ||
| this.validDrag = false; | ||
| this.validDragChange = new EventEmitter(); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange = new EventEmitter(); | ||
| this.dragFilesChange = new EventEmitter(); | ||
| } | ||
| onDrop(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| let files = this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| handleFiles(files) { | ||
| this.fileOver.emit(false); //turn-off dragover | ||
| super.handleFiles(files); | ||
| } | ||
| onDragOver(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| const transfer = eventToTransfer(event); | ||
| let files = this.eventToFiles(event); | ||
| let jsonFiles = filesToWriteableObject(files); | ||
| this.dragFilesChange.emit(this.dragFiles = jsonFiles); | ||
| if (files.length) { | ||
| this.validDrag = this.isFilesValid(files); | ||
| } | ||
| else { | ||
| //Safari, IE11 & some browsers do NOT tell you about dragged files until dropped. Always consider a valid drag | ||
| this.validDrag = true; | ||
| } | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = !this.validDrag; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| transfer.dropEffect = 'copy'; // change cursor and visual display | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(true); | ||
| } | ||
| closeDrags() { | ||
| delete this.validDrag; | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| delete this.dragFiles; | ||
| this.dragFilesChange.emit(this.dragFiles); | ||
| } | ||
| onDragLeave(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| if (this.element) { | ||
| if (event.currentTarget === this.element[0]) { | ||
| return; | ||
| } | ||
| } | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(false); | ||
| } | ||
| } | ||
| ngfDrop.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfDrop.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfDrop, selector: "[ngfDrop]", inputs: { validDrag: "validDrag", invalidDrag: "invalidDrag", dragFiles: "dragFiles" }, outputs: { fileOver: "fileOver", validDragChange: "validDragChange", invalidDragChange: "invalidDragChange", dragFilesChange: "dragFilesChange" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)" } }, exportAs: ["ngfDrop"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfDrop]", | ||
| exportAs: "ngfDrop" | ||
| }] | ||
| }], propDecorators: { fileOver: [{ | ||
| type: Output | ||
| }], validDrag: [{ | ||
| type: Input | ||
| }], validDragChange: [{ | ||
| type: Output | ||
| }], invalidDrag: [{ | ||
| type: Input | ||
| }], invalidDragChange: [{ | ||
| type: Output | ||
| }], dragFiles: [{ | ||
| type: Input | ||
| }], dragFilesChange: [{ | ||
| type: Output | ||
| }], onDrop: [{ | ||
| type: HostListener, | ||
| args: ['drop', ['$event']] | ||
| }], onDragOver: [{ | ||
| type: HostListener, | ||
| args: ['dragover', ['$event']] | ||
| }], onDragLeave: [{ | ||
| type: HostListener, | ||
| args: ['dragleave', ['$event']] | ||
| }] } }); | ||
| class ngfBackground { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => { | ||
| const urlString = 'url(\'' + (src || '') + '\')'; | ||
| this.ElementRef.nativeElement.style.backgroundImage = urlString; | ||
| }); | ||
| } | ||
| } | ||
| ngfBackground.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfBackground.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfBackground, selector: "[ngfBackground]", inputs: { file: ["ngfBackground", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfBackground]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfBackground'] | ||
| }] } }); | ||
| class ngfUploadStatus { | ||
| constructor() { | ||
| this.percent = 0; | ||
| this.percentChange = new EventEmitter(); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.httpEvent && changes.httpEvent.currentValue) { | ||
| const event = changes.httpEvent.currentValue; | ||
| if (event.loaded && event.total) { | ||
| setTimeout(() => { | ||
| this.percent = Math.round(100 * event.loaded / event.total); | ||
| this.percentChange.emit(this.percent); | ||
| }, 0); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ngfUploadStatus.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, deps: [], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfUploadStatus.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfUploadStatus, selector: "ngfUploadStatus", inputs: { percent: "percent", httpEvent: "httpEvent" }, outputs: { percentChange: "percentChange" }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfUploadStatus' }] | ||
| }], propDecorators: { percent: [{ | ||
| type: Input | ||
| }], percentChange: [{ | ||
| type: Output | ||
| }], httpEvent: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ngfFormData { | ||
| constructor(IterableDiffers) { | ||
| this.postName = "file"; | ||
| this.FormData = new FormData(); | ||
| this.FormDataChange = new EventEmitter(); | ||
| this.differ = IterableDiffers.find([]).create(); | ||
| } | ||
| ngDoCheck() { | ||
| var changes = this.differ.diff(this.files); | ||
| if (changes) { | ||
| setTimeout(() => this.buildFormData(), 0); | ||
| } | ||
| } | ||
| buildFormData() { | ||
| const isArray = typeof (this.files) === 'object' && this.files.constructor === Array; | ||
| if (isArray) { | ||
| this.FormData = new FormData(); | ||
| const files = this.files || []; | ||
| files.forEach(file => this.FormData.append(this.postName, file, this.fileName || file.name)); | ||
| this.FormDataChange.emit(this.FormData); | ||
| } | ||
| else { | ||
| delete this.FormData; | ||
| } | ||
| } | ||
| } | ||
| ngfFormData.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, deps: [{ token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfFormData.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfFormData, selector: "ngfFormData", inputs: { files: "files", postName: "postName", fileName: "fileName", FormData: "FormData" }, outputs: { FormDataChange: "FormDataChange" }, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfFormData' }] | ||
| }], ctorParameters: function () { return [{ type: i0.IterableDiffers }]; }, propDecorators: { files: [{ | ||
| type: Input | ||
| }], postName: [{ | ||
| type: Input | ||
| }], fileName: [{ | ||
| type: Input | ||
| }], FormData: [{ | ||
| type: Input | ||
| }], FormDataChange: [{ | ||
| type: Output | ||
| }] } }); | ||
| class ngfSrc { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => this.ElementRef.nativeElement.src = src); | ||
| } | ||
| } | ||
| ngfSrc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSrc.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSrc, selector: "[ngfSrc]", inputs: { file: ["ngfSrc", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfSrc]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfSrc'] | ||
| }] } }); | ||
| //import{ HttpModule } from '@angular/http'; | ||
| const declarations = [ | ||
| ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf | ||
| ]; | ||
| class ngfModule { | ||
| } | ||
| ngfModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); | ||
| ngfModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, declarations: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf], imports: [CommonModule | ||
| //,HttpModule | ||
| ], exports: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf] }); | ||
| ngfModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, imports: [[ | ||
| CommonModule | ||
| //,HttpModule | ||
| ]] }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, decorators: [{ | ||
| type: NgModule, | ||
| args: [{ | ||
| imports: [ | ||
| CommonModule | ||
| //,HttpModule | ||
| ], | ||
| declarations: declarations, | ||
| exports: declarations //[HttpModule, ...declarations] | ||
| }] | ||
| }] }); | ||
| /* | ||
| * Public API Surface of angular-file | ||
| */ | ||
| /** | ||
| * Generated bundle index. Do not edit. | ||
| */ | ||
| export { eventToTransfer, filesToWriteableObject, ngf, ngfBackground, ngfDrop, ngfFormData, ngfModule, ngfSelect, ngfSrc, ngfUploadStatus }; | ||
| //# sourceMappingURL=angular-file-src.mjs.map |
Sorry, the diff of this file is too big to display
| import { CommonModule } from '@angular/common'; | ||
| import * as i0 from '@angular/core'; | ||
| import { Directive, Input, EventEmitter, Output, HostListener, NgModule } from '@angular/core'; | ||
| function getWindow() { return window; } | ||
| function acceptType(accept, type, name) { | ||
| if (!accept) { | ||
| return true; | ||
| } | ||
| const defs = accept.split(','); | ||
| let regx; | ||
| let acceptRegString; | ||
| for (let x = defs.length - 1; x >= 0; --x) { | ||
| //Escapes dots in mimetype | ||
| acceptRegString = defs[x]; | ||
| //trim | ||
| acceptRegString = acceptRegString.replace(/(^\s+|\s+$)/g, ''); | ||
| //Escapes stars in mimetype | ||
| acceptRegString = acceptRegString.replace(/\*/g, '.*'); | ||
| //let acceptReg = '^((' + acceptRegString | ||
| //acceptReg = acceptReg.replace(/,/g,')|(') + '))$' | ||
| //try by mime | ||
| regx = new RegExp(acceptRegString, 'gi'); | ||
| if (type.search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| //try by ext | ||
| if (acceptRegString.substring(0, 1) == '.') { | ||
| acceptRegString = '\\' + acceptRegString; //.substring(1, acceptRegString.length-1)//remove dot at front | ||
| regx = new RegExp(acceptRegString + '$', 'i'); | ||
| if ((name || type).search(regx) >= 0) { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function arrayBufferToBase64(buffer) { | ||
| var binary = ''; | ||
| var bytes = new Uint8Array(buffer); | ||
| var len = bytes.byteLength; | ||
| for (var i = 0; i < len; i++) { | ||
| binary += String.fromCharCode(bytes[i]); | ||
| } | ||
| return window.btoa(binary); | ||
| } | ||
| function dataUrltoBlob(dataurl, name, origSize) { | ||
| var arr = dataurl.split(','); | ||
| var mimeMatch = arr[0].match(/:(.*?);/); | ||
| var mime = mimeMatch ? mimeMatch[1] : 'text/plain'; | ||
| var bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); | ||
| while (n--) { | ||
| u8arr[n] = bstr.charCodeAt(n); | ||
| } | ||
| var blob = new window.Blob([u8arr], { type: mime }); | ||
| blob["name"] = name; | ||
| blob["$ngfOrigSize"] = origSize; | ||
| return blob; | ||
| } | ||
| function applyTransform(ctx, orientation, width, height) { | ||
| switch (orientation) { | ||
| case 2: | ||
| return ctx.transform(-1, 0, 0, 1, width, 0); | ||
| case 3: | ||
| return ctx.transform(-1, 0, 0, -1, width, height); | ||
| case 4: | ||
| return ctx.transform(1, 0, 0, -1, 0, height); | ||
| case 5: | ||
| return ctx.transform(0, 1, 1, 0, 0, 0); | ||
| case 6: | ||
| return ctx.transform(0, 1, -1, 0, height, 0); | ||
| case 7: | ||
| return ctx.transform(0, -1, -1, 0, height, width); | ||
| case 8: | ||
| return ctx.transform(0, -1, 1, 0, 0, width); | ||
| } | ||
| } | ||
| function fixFileOrientationByMeta(file, result) { | ||
| return dataUrl(file, true) | ||
| .then(url => { | ||
| var canvas = document.createElement('canvas'); | ||
| var img = document.createElement('img'); | ||
| return new Promise(function (res, rej) { | ||
| img.onload = function () { | ||
| try { | ||
| canvas.width = result.orientation > 4 ? img.height : img.width; | ||
| canvas.height = result.orientation > 4 ? img.width : img.height; | ||
| var ctx = canvas.getContext('2d'); | ||
| applyTransform(ctx, result.orientation, img.width, img.height); | ||
| ctx.drawImage(img, 0, 0); | ||
| var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934); | ||
| const base = arrayBufferToBase64(result.fixedArrayBuffer); | ||
| dataUrl = restoreExif(base, dataUrl); | ||
| var blob = dataUrltoBlob(dataUrl, file.name); | ||
| const newFile = blobToFile(blob, file.name); | ||
| res(newFile); | ||
| } | ||
| catch (e) { | ||
| rej(e); | ||
| } | ||
| }; | ||
| img.onerror = rej; | ||
| img.src = url; | ||
| }); | ||
| }); | ||
| } | ||
| function applyExifRotation(file) { | ||
| if (file.type.indexOf('image/jpeg') !== 0) { | ||
| return Promise.resolve(file); | ||
| } | ||
| return readOrientation(file) | ||
| .then((result) => { | ||
| if (result.orientation < 2 || result.orientation > 8) { | ||
| return file; | ||
| } | ||
| return fixFileOrientationByMeta(file, result); | ||
| }); | ||
| } | ||
| function readOrientation(file) { | ||
| return new Promise((res, rej) => { | ||
| var reader = new FileReader(); | ||
| var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file; | ||
| reader.readAsArrayBuffer(slicedFile); | ||
| reader.onerror = rej; | ||
| reader.onload = function (e) { | ||
| var result = { orientation: 1 }; | ||
| var view = new DataView(this.result); | ||
| if (view.getUint16(0, false) !== 0xFFD8) | ||
| return res(result); | ||
| var length = view.byteLength, offset = 2; | ||
| while (offset < length) { | ||
| var marker = view.getUint16(offset, false); | ||
| offset += 2; | ||
| if (marker === 0xFFE1) { | ||
| if (view.getUint32(offset += 2, false) !== 0x45786966) | ||
| return res(result); | ||
| var little = view.getUint16(offset += 6, false) === 0x4949; | ||
| offset += view.getUint32(offset + 4, little); | ||
| var tags = view.getUint16(offset, little); | ||
| offset += 2; | ||
| for (var i = 0; i < tags; i++) | ||
| if (view.getUint16(offset + (i * 12), little) === 0x0112) { | ||
| var orientation = view.getUint16(offset + (i * 12) + 8, little); | ||
| if (orientation >= 2 && orientation <= 8) { | ||
| view.setUint16(offset + (i * 12) + 8, 1, little); | ||
| result.fixedArrayBuffer = e.target.result; | ||
| } | ||
| result.orientation = orientation; | ||
| return res(result); | ||
| } | ||
| } | ||
| else if ((marker & 0xFF00) !== 0xFF00) | ||
| break; | ||
| else | ||
| offset += view.getUint16(offset, false); | ||
| } | ||
| return res(result); | ||
| }; | ||
| }); | ||
| } | ||
| /** converts file-input file into base64 dataUri */ | ||
| function dataUrl(file, disallowObjectUrl) { | ||
| if (!file) | ||
| return Promise.resolve(file); | ||
| if ((disallowObjectUrl && file.$ngfDataUrl != null) || (!disallowObjectUrl && file.$ngfBlobUrl != null)) { | ||
| return Promise.resolve(disallowObjectUrl ? file.$ngfDataUrl : file.$ngfBlobUrl); | ||
| } | ||
| var p = disallowObjectUrl ? file.$$ngfDataUrlPromise : file.$$ngfBlobUrlPromise; | ||
| if (p) | ||
| return p; | ||
| const win = getWindow(); | ||
| let deferred; | ||
| if (win.FileReader && file && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 8') === -1 || file.size < 20000) && | ||
| (!win.FileAPI || navigator.userAgent.indexOf('MSIE 9') === -1 || file.size < 4000000)) { | ||
| //prefer URL.createObjectURL for handling refrences to files of all sizes | ||
| //since it doesn´t build a large string in memory | ||
| var URL = win.URL || win.webkitURL; | ||
| if (FileReader) { | ||
| deferred = new Promise((res, rej) => { | ||
| var fileReader = new FileReader(); | ||
| fileReader.onload = function (event) { | ||
| file.$ngfDataUrl = event.target.result; | ||
| delete file.$ngfDataUrl; | ||
| res(event.target.result); | ||
| }; | ||
| fileReader.onerror = function (e) { | ||
| file.$ngfDataUrl = ''; | ||
| rej(e); | ||
| }; | ||
| fileReader.readAsDataURL(file); | ||
| }); | ||
| } | ||
| else { | ||
| var url; | ||
| try { | ||
| url = URL.createObjectURL(file); | ||
| } | ||
| catch (e) { | ||
| return Promise.reject(e); | ||
| } | ||
| deferred = Promise.resolve(url); | ||
| file.$ngfBlobUrl = url; | ||
| } | ||
| } | ||
| else { | ||
| file[disallowObjectUrl ? '$ngfDataUrl' : '$ngfBlobUrl'] = ''; | ||
| return Promise.reject(new Error('Browser does not support window.FileReader, window.FileReader, or window.FileAPI')); //deferred.reject(); | ||
| } | ||
| if (disallowObjectUrl) { | ||
| p = file.$$ngfDataUrlPromise = deferred; | ||
| } | ||
| else { | ||
| p = file.$$ngfBlobUrlPromise = deferred; | ||
| } | ||
| p = p.then((x) => { | ||
| delete file[disallowObjectUrl ? '$$ngfDataUrlPromise' : '$$ngfBlobUrlPromise']; | ||
| return x; | ||
| }); | ||
| return p; | ||
| } | ||
| function restoreExif(orig, resized) { | ||
| var ExifRestorer = { | ||
| KEY_STR: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' | ||
| }; | ||
| ExifRestorer.encode64 = function (input) { | ||
| var output = '', chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0; | ||
| do { | ||
| chr1 = input[i++]; | ||
| chr2 = input[i++]; | ||
| chr3 = input[i++]; | ||
| enc1 = chr1 >> 2; | ||
| enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | ||
| enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | ||
| enc4 = chr3 & 63; | ||
| if (isNaN(chr2)) { | ||
| enc3 = enc4 = 64; | ||
| } | ||
| else if (isNaN(chr3)) { | ||
| enc4 = 64; | ||
| } | ||
| output = output + | ||
| this.KEY_STR.charAt(enc1) + | ||
| this.KEY_STR.charAt(enc2) + | ||
| this.KEY_STR.charAt(enc3) + | ||
| this.KEY_STR.charAt(enc4); | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return output; | ||
| }; | ||
| ExifRestorer.restore = function (origFileBase64, resizedFileBase64) { | ||
| if (origFileBase64.match('data:image/jpeg;base64,')) { | ||
| origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', ''); | ||
| } | ||
| var rawImage = this.decode64(origFileBase64); | ||
| var segments = this.slice2Segments(rawImage); | ||
| var image = this.exifManipulation(resizedFileBase64, segments); | ||
| return 'data:image/jpeg;base64,' + this.encode64(image); | ||
| }; | ||
| ExifRestorer.exifManipulation = function (resizedFileBase64, segments) { | ||
| var exifArray = this.getExifArray(segments), newImageArray = this.insertExif(resizedFileBase64, exifArray); | ||
| return new Uint8Array(newImageArray); | ||
| }; | ||
| ExifRestorer.getExifArray = function (segments) { | ||
| var seg; | ||
| for (var x = 0; x < segments.length; x++) { | ||
| seg = segments[x]; | ||
| if (seg[0] === 255 && seg[1] === 225) //(ff e1) | ||
| { | ||
| return seg; | ||
| } | ||
| } | ||
| return []; | ||
| }; | ||
| ExifRestorer.insertExif = function (resizedFileBase64, exifArray) { | ||
| var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''), buf = this.decode64(imageData), separatePoint = buf.indexOf(255, 3), mae = buf.slice(0, separatePoint), ato = buf.slice(separatePoint), array = mae; | ||
| array = array.concat(exifArray); | ||
| array = array.concat(ato); | ||
| return array; | ||
| }; | ||
| ExifRestorer.slice2Segments = function (rawImageArray) { | ||
| var head = 0, segments = []; | ||
| while (1) { | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 218) { | ||
| break; | ||
| } | ||
| if (rawImageArray[head] === 255 && rawImageArray[head + 1] === 216) { | ||
| head += 2; | ||
| } | ||
| else { | ||
| var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3]; | ||
| var endPoint = head + length + 2; | ||
| var seg = rawImageArray.slice(head, endPoint); | ||
| segments.push(seg); | ||
| head = endPoint; | ||
| } | ||
| if (head > rawImageArray.length) { | ||
| break; | ||
| } | ||
| } | ||
| return segments; | ||
| }; | ||
| ExifRestorer.decode64 = function (input) { | ||
| var chr1, chr2, chr3 = '', enc1, enc2, enc3, enc4 = '', i = 0, buf = []; | ||
| // remove all characters that are not A-Z, a-z, 0-9, +, /, or = | ||
| var base64test = /[^A-Za-z0-9\+\/\=]/g; | ||
| if (base64test.exec(input)) { | ||
| console.log('There were invalid base64 characters in the input text.'); | ||
| } | ||
| input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); | ||
| do { | ||
| enc1 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc2 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc3 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| enc4 = this.KEY_STR.indexOf(input.charAt(i++)); | ||
| chr1 = (enc1 << 2) | (enc2 >> 4); | ||
| chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); | ||
| chr3 = ((enc3 & 3) << 6) | enc4; | ||
| buf.push(chr1); | ||
| if (enc3 !== 64) { | ||
| buf.push(chr2); | ||
| } | ||
| if (enc4 !== 64) { | ||
| buf.push(chr3); | ||
| } | ||
| chr1 = chr2 = chr3 = ''; | ||
| enc1 = enc2 = enc3 = enc4 = ''; | ||
| } while (i < input.length); | ||
| return buf; | ||
| }; | ||
| return ExifRestorer.restore(orig, resized); //<= EXIF | ||
| } | ||
| ; | ||
| function blobToFile(theBlob, fileName) { | ||
| var b = theBlob; | ||
| //A Blob() is almost a File() - it's just missing the two properties below which we will add | ||
| b.lastModifiedDate = new Date(); | ||
| b.name = fileName; | ||
| //Cast to a File() type | ||
| return theBlob; | ||
| } | ||
| class ngfBackground { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => { | ||
| const urlString = 'url(\'' + (src || '') + '\')'; | ||
| this.ElementRef.nativeElement.style.backgroundImage = urlString; | ||
| }); | ||
| } | ||
| } | ||
| ngfBackground.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfBackground.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfBackground, selector: "[ngfBackground]", inputs: { file: ["ngfBackground", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfBackground, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfBackground]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfBackground'] | ||
| }] } }); | ||
| const isFileInput = function (elm) { | ||
| const ty = elm.getAttribute('type'); | ||
| return elm.tagName.toLowerCase() === 'input' && ty && ty.toLowerCase() === 'file'; | ||
| }; | ||
| let initialTouchStartY = 0; | ||
| let initialTouchStartX = 0; | ||
| const detectSwipe = function (evt) { | ||
| var touches = evt.changedTouches || (evt.originalEvent && evt.originalEvent.changedTouches); | ||
| if (touches) { | ||
| if (evt.type === 'touchstart') { | ||
| initialTouchStartX = touches[0].clientX; | ||
| initialTouchStartY = touches[0].clientY; | ||
| return true; // don't block event default | ||
| } | ||
| else { | ||
| // prevent scroll from triggering event | ||
| if (evt.type === 'touchend') { | ||
| var currentX = touches[0].clientX; | ||
| var currentY = touches[0].clientY; | ||
| if ((Math.abs(currentX - initialTouchStartX) > 20) || | ||
| (Math.abs(currentY - initialTouchStartY) > 20)) { | ||
| evt.stopPropagation(); | ||
| if (evt.cancelable) { | ||
| evt.preventDefault(); | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }; | ||
| const createInvisibleFileInputWrap = function () { | ||
| var fileElem = createFileInput(); | ||
| var label = document.createElement('label'); | ||
| label.innerHTML = 'upload'; | ||
| label.style.visibility = 'hidden'; | ||
| label.style.position = 'absolute'; | ||
| label.style.overflow = 'hidden'; | ||
| label.style.width = '0px'; | ||
| label.style.height = '0px'; | ||
| label.style.border = 'none'; | ||
| label.style.margin = '0px'; | ||
| label.style.padding = '0px'; | ||
| label.setAttribute('tabindex', '-1'); | ||
| //bindAttrToFileInput(fileElem, label); | ||
| //generatedElems.push({el: elem, ref: label}); | ||
| label.appendChild(fileElem); | ||
| //document.body.appendChild( label ); | ||
| return label; | ||
| }; | ||
| const createFileInput = function () { | ||
| var fileElem = document.createElement('input'); | ||
| fileElem.type = "file"; | ||
| return fileElem; | ||
| }; | ||
| /** A master base set of logic intended to support file select/drag/drop operations | ||
| NOTE: Use ngfDrop for full drag/drop. Use ngfSelect for selecting | ||
| */ | ||
| class ngf { | ||
| constructor(element) { | ||
| this.element = element; | ||
| this.filters = []; | ||
| this.lastFileCount = 0; | ||
| this.ngfFixOrientation = true; | ||
| this.fileDropDisabled = false; | ||
| this.selectable = false; | ||
| this.directiveInit = new EventEmitter(); | ||
| this.lastInvalids = []; | ||
| this.lastInvalidsChange = new EventEmitter(); | ||
| this.lastBaseUrlChange = new EventEmitter(); | ||
| this.fileChange = new EventEmitter(); | ||
| this.files = []; | ||
| this.filesChange = new EventEmitter(); | ||
| this.fileSelectStart = new EventEmitter(); | ||
| this.initFilters(); | ||
| } | ||
| initFilters() { | ||
| // the order is important | ||
| this.filters.push({ name: 'accept', fn: this._acceptFilter }); | ||
| this.filters.push({ name: 'fileSize', fn: this._fileSizeFilter }); | ||
| //this.filters.push({name: 'fileType', fn: this._fileTypeFilter}) | ||
| //this.filters.push({name: 'queueLimit', fn: this._queueLimitFilter}) | ||
| //this.filters.push({name: 'mimeType', fn: this._mimeTypeFilter}) | ||
| } | ||
| ngOnDestroy() { | ||
| delete this.fileElm; //faster memory release of dom element | ||
| this.destroyPasteListener(); | ||
| } | ||
| ngOnInit() { | ||
| const selectable = (this.selectable || this.selectable === '') && !['false', 'null', '0'].includes(this.selectable); | ||
| if (selectable) { | ||
| this.enableSelecting(); | ||
| } | ||
| if (this.multiple) { | ||
| this.paramFileElm().setAttribute('multiple', this.multiple); | ||
| } | ||
| this.evalCapturePaste(); | ||
| // create reference to this class with one cycle delay to avoid ExpressionChangedAfterItHasBeenCheckedError | ||
| setTimeout(() => { | ||
| this.directiveInit.emit(this); | ||
| }, 0); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.accept) { | ||
| this.paramFileElm().setAttribute('accept', changes.accept.currentValue || '*'); | ||
| } | ||
| if (changes.capturePaste) { | ||
| this.evalCapturePaste(); | ||
| } | ||
| // Did we go from having a file to not having a file? Clear file element then | ||
| if (changes.file && changes.file.previousValue && !changes.file.currentValue) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| // Did we go from having files to not having files? Clear file element then | ||
| if (changes.files) { | ||
| const filesWentToZero = changes.files.previousValue?.length && !changes.files.currentValue?.length; | ||
| if (filesWentToZero) { | ||
| this.clearFileElmValue(); | ||
| } | ||
| } | ||
| } | ||
| evalCapturePaste() { | ||
| const isActive = this.capturePaste || this.capturePaste === '' || ['false', '0', 'null'].includes(this.capturePaste); | ||
| if (isActive) { | ||
| if (this.pasteCapturer) { | ||
| return; // already listening | ||
| } | ||
| this.pasteCapturer = (e) => { | ||
| const clip = e.clipboardData; | ||
| if (clip && clip.files && clip.files.length) { | ||
| this.handleFiles(clip.files); | ||
| e.preventDefault(); | ||
| } | ||
| }; | ||
| window.addEventListener('paste', this.pasteCapturer); | ||
| return; | ||
| } | ||
| this.destroyPasteListener(); | ||
| } | ||
| destroyPasteListener() { | ||
| if (this.pasteCapturer) { | ||
| window.removeEventListener('paste', this.pasteCapturer); | ||
| delete this.pasteCapturer; | ||
| } | ||
| } | ||
| paramFileElm() { | ||
| if (this.fileElm) | ||
| return this.fileElm; // already defined | ||
| // elm already is a file input | ||
| const isFile = isFileInput(this.element.nativeElement); | ||
| if (isFile) { | ||
| return this.fileElm = this.element.nativeElement; | ||
| } | ||
| // the host elm is NOT a file input | ||
| return this.fileElm = this.createFileElm({ | ||
| change: this.changeFn.bind(this) | ||
| }); | ||
| } | ||
| /** Only used when host element we are attached to is NOT a fileElement */ | ||
| createFileElm({ change }) { | ||
| // use specific technique to hide file element within | ||
| const label = createInvisibleFileInputWrap(); | ||
| const fileElm = label.getElementsByTagName('input')[0]; | ||
| fileElm.addEventListener('change', change); | ||
| this.element.nativeElement.appendChild(label); // put on html stage | ||
| return fileElm; | ||
| } | ||
| enableSelecting() { | ||
| let elm = this.element.nativeElement; | ||
| if (isFileInput(elm)) { | ||
| const bindedHandler = event => this.beforeSelect(event); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| return; | ||
| } | ||
| const bindedHandler = ev => this.clickHandler(ev); | ||
| elm.addEventListener('click', bindedHandler); | ||
| elm.addEventListener('touchstart', bindedHandler); | ||
| elm.addEventListener('touchend', bindedHandler); | ||
| } | ||
| getValidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (this.isFileValid(files[x])) { | ||
| rtn.push(files[x]); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| getInvalidFiles(files) { | ||
| const rtn = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| let failReason = this.getFileFilterFailName(files[x]); | ||
| if (failReason) { | ||
| rtn.push({ | ||
| file: files[x], | ||
| type: failReason | ||
| }); | ||
| } | ||
| } | ||
| return rtn; | ||
| } | ||
| // Primary handler of files coming in | ||
| handleFiles(files) { | ||
| const valids = this.getValidFiles(files); | ||
| if (files.length != valids.length) { | ||
| this.lastInvalids = this.getInvalidFiles(files); | ||
| } | ||
| else { | ||
| delete this.lastInvalids; | ||
| } | ||
| this.lastInvalidsChange.emit(this.lastInvalids); | ||
| if (valids.length) { | ||
| if (this.ngfFixOrientation) { | ||
| this.applyExifRotations(valids) | ||
| .then(fixedFiles => this.que(fixedFiles)); | ||
| } | ||
| else { | ||
| this.que(valids); | ||
| } | ||
| } | ||
| if (this.isEmptyAfterSelection()) { | ||
| this.element.nativeElement.value = ''; | ||
| } | ||
| } | ||
| que(files) { | ||
| this.files = this.files || []; | ||
| Array.prototype.push.apply(this.files, files); | ||
| //below break memory ref and doesnt act like a que | ||
| //this.files = files//causes memory change which triggers bindings like <ngfFormData [files]="files"></ngfFormData> | ||
| this.filesChange.emit(this.files); | ||
| if (files.length) { | ||
| this.fileChange.emit(this.file = files[0]); | ||
| if (this.lastBaseUrlChange.observers.length) { | ||
| dataUrl(files[0]) | ||
| .then(url => this.lastBaseUrlChange.emit(url)); | ||
| } | ||
| } | ||
| //will be checked for input value clearing | ||
| this.lastFileCount = this.files.length; | ||
| } | ||
| /** called when input has files */ | ||
| changeFn(event) { | ||
| var fileList = event.__files_ || (event.target && event.target.files); | ||
| if (!fileList) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(fileList); | ||
| } | ||
| clickHandler(evt) { | ||
| const elm = this.element.nativeElement; | ||
| if (elm.getAttribute('disabled') || this.fileDropDisabled) { | ||
| return false; | ||
| } | ||
| var r = detectSwipe(evt); | ||
| // prevent the click if it is a swipe | ||
| if (r !== false) | ||
| return r; | ||
| const fileElm = this.paramFileElm(); | ||
| fileElm.click(); | ||
| //fileElm.dispatchEvent( new Event('click') ); | ||
| this.beforeSelect(evt); | ||
| return false; | ||
| } | ||
| beforeSelect(event) { | ||
| this.fileSelectStart.emit(event); | ||
| if (this.files && this.lastFileCount === this.files.length) | ||
| return; | ||
| // if no files in array, be sure browser does not prevent reselect of same file (see github issue 27) | ||
| this.clearFileElmValue(); | ||
| } | ||
| clearFileElmValue() { | ||
| if (!this.fileElm) | ||
| return; | ||
| this.fileElm.value = null; | ||
| } | ||
| isEmptyAfterSelection() { | ||
| return !!this.element.nativeElement.attributes.multiple; | ||
| } | ||
| stopEvent(event) { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| } | ||
| transferHasFiles(transfer) { | ||
| if (!transfer.types) { | ||
| return false; | ||
| } | ||
| if (transfer.types.indexOf) { | ||
| return transfer.types.indexOf('Files') !== -1; | ||
| } | ||
| else if (transfer.types.contains) { | ||
| return transfer.types.contains('Files'); | ||
| } | ||
| else { | ||
| return false; | ||
| } | ||
| } | ||
| eventToFiles(event) { | ||
| const transfer = eventToTransfer(event); | ||
| if (transfer) { | ||
| if (transfer.files && transfer.files.length) { | ||
| return transfer.files; | ||
| } | ||
| if (transfer.items && transfer.items.length) { | ||
| return transfer.items; | ||
| } | ||
| } | ||
| return []; | ||
| } | ||
| applyExifRotations(files) { | ||
| const mapper = (file, index) => { | ||
| return applyExifRotation(file) | ||
| .then(fixedFile => files.splice(index, 1, fixedFile)); | ||
| }; | ||
| const proms = []; | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| proms[x] = mapper(files[x], x); | ||
| } | ||
| return Promise.all(proms).then(() => files); | ||
| } | ||
| onChange(event) { | ||
| let files = this.element.nativeElement.files || this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| getFileFilterFailName(file) { | ||
| for (let i = 0; i < this.filters.length; i++) { | ||
| if (!this.filters[i].fn.call(this, file)) { | ||
| return this.filters[i].name; | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| isFileValid(file) { | ||
| const noFilters = !this.accept && (!this.filters || !this.filters.length); | ||
| if (noFilters) { | ||
| return true; //we have no filters so all files are valid | ||
| } | ||
| return this.getFileFilterFailName(file) ? false : true; | ||
| } | ||
| isFilesValid(files) { | ||
| for (let x = files.length - 1; x >= 0; --x) { | ||
| if (!this.isFileValid(files[x])) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| _acceptFilter(item) { | ||
| return acceptType(this.accept, item.type, item.name); | ||
| } | ||
| _fileSizeFilter(item) { | ||
| return !(this.maxSize && item.size > this.maxSize); | ||
| } | ||
| } | ||
| ngf.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngf.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngf, selector: "[ngf]", inputs: { multiple: "multiple", accept: "accept", maxSize: "maxSize", ngfFixOrientation: "ngfFixOrientation", fileDropDisabled: "fileDropDisabled", selectable: "selectable", lastInvalids: "lastInvalids", lastBaseUrl: "lastBaseUrl", file: "file", files: "files", capturePaste: "capturePaste" }, outputs: { directiveInit: "init", lastInvalidsChange: "lastInvalidsChange", lastBaseUrlChange: "lastBaseUrlChange", fileChange: "fileChange", filesChange: "filesChange", fileSelectStart: "fileSelectStart" }, host: { listeners: { "change": "onChange($event)" } }, exportAs: ["ngf"], usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngf, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngf]", | ||
| exportAs: "ngf" | ||
| }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { multiple: [{ | ||
| type: Input | ||
| }], accept: [{ | ||
| type: Input | ||
| }], maxSize: [{ | ||
| type: Input | ||
| }], ngfFixOrientation: [{ | ||
| type: Input | ||
| }], fileDropDisabled: [{ | ||
| type: Input | ||
| }], selectable: [{ | ||
| type: Input | ||
| }], directiveInit: [{ | ||
| type: Output, | ||
| args: ['init'] | ||
| }], lastInvalids: [{ | ||
| type: Input | ||
| }], lastInvalidsChange: [{ | ||
| type: Output | ||
| }], lastBaseUrl: [{ | ||
| type: Input | ||
| }], lastBaseUrlChange: [{ | ||
| type: Output | ||
| }], file: [{ | ||
| type: Input | ||
| }], fileChange: [{ | ||
| type: Output | ||
| }], files: [{ | ||
| type: Input | ||
| }], filesChange: [{ | ||
| type: Output | ||
| }], fileSelectStart: [{ | ||
| type: Output | ||
| }], capturePaste: [{ | ||
| type: Input | ||
| }], onChange: [{ | ||
| type: HostListener, | ||
| args: ['change', ['$event']] | ||
| }] } }); | ||
| /** browsers try hard to conceal data about file drags, this tends to undo that */ | ||
| function filesToWriteableObject(files) { | ||
| const jsonFiles = []; | ||
| for (let x = 0; x < files.length; ++x) { | ||
| jsonFiles.push({ | ||
| type: files[x].type, | ||
| kind: files[x]["kind"] | ||
| }); | ||
| } | ||
| return jsonFiles; | ||
| } | ||
| function eventToTransfer(event) { | ||
| if (event.dataTransfer) | ||
| return event.dataTransfer; | ||
| return event.originalEvent ? event.originalEvent.dataTransfer : null; | ||
| } | ||
| class ngfDrop extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.fileOver = new EventEmitter(); | ||
| this.validDrag = false; | ||
| this.validDragChange = new EventEmitter(); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange = new EventEmitter(); | ||
| this.dragFilesChange = new EventEmitter(); | ||
| } | ||
| onDrop(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| let files = this.eventToFiles(event); | ||
| if (!files.length) | ||
| return; | ||
| this.stopEvent(event); | ||
| this.handleFiles(files); | ||
| } | ||
| handleFiles(files) { | ||
| this.fileOver.emit(false); //turn-off dragover | ||
| super.handleFiles(files); | ||
| } | ||
| onDragOver(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| const transfer = eventToTransfer(event); | ||
| let files = this.eventToFiles(event); | ||
| let jsonFiles = filesToWriteableObject(files); | ||
| this.dragFilesChange.emit(this.dragFiles = jsonFiles); | ||
| if (files.length) { | ||
| this.validDrag = this.isFilesValid(files); | ||
| } | ||
| else { | ||
| //Safari, IE11 & some browsers do NOT tell you about dragged files until dropped. Always consider a valid drag | ||
| this.validDrag = true; | ||
| } | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = !this.validDrag; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| transfer.dropEffect = 'copy'; // change cursor and visual display | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(true); | ||
| } | ||
| closeDrags() { | ||
| delete this.validDrag; | ||
| this.validDragChange.emit(this.validDrag); | ||
| this.invalidDrag = false; | ||
| this.invalidDragChange.emit(this.invalidDrag); | ||
| delete this.dragFiles; | ||
| this.dragFilesChange.emit(this.dragFiles); | ||
| } | ||
| onDragLeave(event) { | ||
| if (this.fileDropDisabled) { | ||
| this.stopEvent(event); | ||
| return; | ||
| } | ||
| this.closeDrags(); | ||
| if (this.element) { | ||
| if (event.currentTarget === this.element[0]) { | ||
| return; | ||
| } | ||
| } | ||
| this.stopEvent(event); | ||
| this.fileOver.emit(false); | ||
| } | ||
| } | ||
| ngfDrop.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfDrop.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfDrop, selector: "[ngfDrop]", inputs: { validDrag: "validDrag", invalidDrag: "invalidDrag", dragFiles: "dragFiles" }, outputs: { fileOver: "fileOver", validDragChange: "validDragChange", invalidDragChange: "invalidDragChange", dragFilesChange: "dragFilesChange" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)" } }, exportAs: ["ngfDrop"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfDrop, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfDrop]", | ||
| exportAs: "ngfDrop" | ||
| }] | ||
| }], propDecorators: { fileOver: [{ | ||
| type: Output | ||
| }], validDrag: [{ | ||
| type: Input | ||
| }], validDragChange: [{ | ||
| type: Output | ||
| }], invalidDrag: [{ | ||
| type: Input | ||
| }], invalidDragChange: [{ | ||
| type: Output | ||
| }], dragFiles: [{ | ||
| type: Input | ||
| }], dragFilesChange: [{ | ||
| type: Output | ||
| }], onDrop: [{ | ||
| type: HostListener, | ||
| args: ['drop', ['$event']] | ||
| }], onDragOver: [{ | ||
| type: HostListener, | ||
| args: ['dragover', ['$event']] | ||
| }], onDragLeave: [{ | ||
| type: HostListener, | ||
| args: ['dragleave', ['$event']] | ||
| }] } }); | ||
| class ngfSelect extends ngf { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.selectable = true; | ||
| } | ||
| } | ||
| ngfSelect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, deps: null, target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSelect.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSelect, selector: "[ngfSelect]", inputs: { selectable: "selectable" }, exportAs: ["ngfSelect"], usesInheritance: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSelect, decorators: [{ | ||
| type: Directive, | ||
| args: [{ | ||
| selector: "[ngfSelect]", | ||
| exportAs: "ngfSelect" | ||
| }] | ||
| }], propDecorators: { selectable: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ngfUploadStatus { | ||
| constructor() { | ||
| this.percent = 0; | ||
| this.percentChange = new EventEmitter(); | ||
| } | ||
| ngOnChanges(changes) { | ||
| if (changes.httpEvent && changes.httpEvent.currentValue) { | ||
| const event = changes.httpEvent.currentValue; | ||
| if (event.loaded && event.total) { | ||
| setTimeout(() => { | ||
| this.percent = Math.round(100 * event.loaded / event.total); | ||
| this.percentChange.emit(this.percent); | ||
| }, 0); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ngfUploadStatus.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, deps: [], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfUploadStatus.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfUploadStatus, selector: "ngfUploadStatus", inputs: { percent: "percent", httpEvent: "httpEvent" }, outputs: { percentChange: "percentChange" }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfUploadStatus, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfUploadStatus' }] | ||
| }], propDecorators: { percent: [{ | ||
| type: Input | ||
| }], percentChange: [{ | ||
| type: Output | ||
| }], httpEvent: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ngfFormData { | ||
| constructor(IterableDiffers) { | ||
| this.postName = "file"; | ||
| this.FormData = new FormData(); | ||
| this.FormDataChange = new EventEmitter(); | ||
| this.differ = IterableDiffers.find([]).create(); | ||
| } | ||
| ngDoCheck() { | ||
| var changes = this.differ.diff(this.files); | ||
| if (changes) { | ||
| setTimeout(() => this.buildFormData(), 0); | ||
| } | ||
| } | ||
| buildFormData() { | ||
| const isArray = typeof (this.files) === 'object' && this.files.constructor === Array; | ||
| if (isArray) { | ||
| this.FormData = new FormData(); | ||
| const files = this.files || []; | ||
| files.forEach(file => this.FormData.append(this.postName, file, this.fileName || file.name)); | ||
| this.FormDataChange.emit(this.FormData); | ||
| } | ||
| else { | ||
| delete this.FormData; | ||
| } | ||
| } | ||
| } | ||
| ngfFormData.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, deps: [{ token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfFormData.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfFormData, selector: "ngfFormData", inputs: { files: "files", postName: "postName", fileName: "fileName", FormData: "FormData" }, outputs: { FormDataChange: "FormDataChange" }, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfFormData, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: 'ngfFormData' }] | ||
| }], ctorParameters: function () { return [{ type: i0.IterableDiffers }]; }, propDecorators: { files: [{ | ||
| type: Input | ||
| }], postName: [{ | ||
| type: Input | ||
| }], fileName: [{ | ||
| type: Input | ||
| }], FormData: [{ | ||
| type: Input | ||
| }], FormDataChange: [{ | ||
| type: Output | ||
| }] } }); | ||
| class ngfSrc { | ||
| constructor(ElementRef) { | ||
| this.ElementRef = ElementRef; | ||
| } | ||
| ngOnChanges(_changes) { | ||
| dataUrl(this.file) | ||
| .then(src => this.ElementRef.nativeElement.src = src); | ||
| } | ||
| } | ||
| ngfSrc.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); | ||
| ngfSrc.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ngfSrc, selector: "[ngfSrc]", inputs: { file: ["ngfSrc", "file"] }, usesOnChanges: true, ngImport: i0 }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfSrc, decorators: [{ | ||
| type: Directive, | ||
| args: [{ selector: '[ngfSrc]' }] | ||
| }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { file: [{ | ||
| type: Input, | ||
| args: ['ngfSrc'] | ||
| }] } }); | ||
| //import{ HttpModule } from '@angular/http'; | ||
| const declarations = [ | ||
| ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf | ||
| ]; | ||
| class ngfModule { | ||
| } | ||
| ngfModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); | ||
| ngfModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, declarations: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf], imports: [CommonModule | ||
| //,HttpModule | ||
| ], exports: [ngfDrop, | ||
| ngfSelect, | ||
| ngfBackground, | ||
| ngfSrc, | ||
| ngfUploadStatus, | ||
| ngfFormData, | ||
| ngf] }); | ||
| ngfModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, imports: [[ | ||
| CommonModule | ||
| //,HttpModule | ||
| ]] }); | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ngfModule, decorators: [{ | ||
| type: NgModule, | ||
| args: [{ | ||
| imports: [ | ||
| CommonModule | ||
| //,HttpModule | ||
| ], | ||
| declarations: declarations, | ||
| exports: declarations //[HttpModule, ...declarations] | ||
| }] | ||
| }] }); | ||
| /** | ||
| * Generated bundle index. Do not edit. | ||
| */ | ||
| export { ngf, ngfBackground, ngfDrop, ngfFormData, ngfModule, ngfSelect, ngfSrc, ngfUploadStatus }; | ||
| //# sourceMappingURL=angular-file.mjs.map |
Sorry, the diff of this file is too big to display
| /** | ||
| * Generated bundle index. Do not edit. | ||
| */ | ||
| /// <amd-module name="angular-file" /> | ||
| export * from './index'; | ||
| export { ngf as ɵb } from './file-upload/ngf.directive'; | ||
| export { ngfBackground as ɵd } from './file-upload/ngfBackground.directive'; | ||
| export { ngfDrop as ɵa } from './file-upload/ngfDrop.directive'; | ||
| export { ngfFormData as ɵg } from './file-upload/ngfFormData.directive'; | ||
| export { ngfSelect as ɵc } from './file-upload/ngfSelect.directive'; | ||
| export { ngfSrc as ɵe } from './file-upload/ngfSrc.directive'; | ||
| export { ngfUploadStatus as ɵf } from './file-upload/ngfUploadStatus.directive'; |
+3
-0
| # angular-file - Change Log | ||
| All notable changes to this project will be documented here. | ||
| ## 3.9.0 - (2023-05-03) | ||
| - Built on Angular 13 | ||
| ## 3.8.0 - (2023-05-03) | ||
@@ -5,0 +8,0 @@ - Built on Angular 12 |
| import { EventEmitter, ElementRef, SimpleChanges } from '@angular/core'; | ||
| import { InvalidFileItem } from "./fileTools"; | ||
| import * as i0 from "@angular/core"; | ||
| export interface dragMeta { | ||
@@ -72,2 +73,4 @@ type: string; | ||
| protected _fileSizeFilter(item: File): boolean; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ngf, never>; | ||
| static ɵdir: i0.ɵɵDirectiveDeclaration<ngf, "[ngf]", ["ngf"], { "multiple": "multiple"; "accept": "accept"; "maxSize": "maxSize"; "ngfFixOrientation": "ngfFixOrientation"; "fileDropDisabled": "fileDropDisabled"; "selectable": "selectable"; "lastInvalids": "lastInvalids"; "lastBaseUrl": "lastBaseUrl"; "file": "file"; "files": "files"; "capturePaste": "capturePaste"; }, { "directiveInit": "init"; "lastInvalidsChange": "lastInvalidsChange"; "lastBaseUrlChange": "lastBaseUrlChange"; "fileChange": "fileChange"; "filesChange": "filesChange"; "fileSelectStart": "fileSelectStart"; }, never>; | ||
| } | ||
@@ -74,0 +77,0 @@ /** browsers try hard to conceal data about file drags, this tends to undo that */ |
@@ -0,2 +1,14 @@ | ||
| import * as i0 from "@angular/core"; | ||
| import * as i1 from "./ngfDrop.directive"; | ||
| import * as i2 from "./ngfSelect.directive"; | ||
| import * as i3 from "./ngfBackground.directive"; | ||
| import * as i4 from "./ngfSrc.directive"; | ||
| import * as i5 from "./ngfUploadStatus.directive"; | ||
| import * as i6 from "./ngfFormData.directive"; | ||
| import * as i7 from "./ngf.directive"; | ||
| import * as i8 from "@angular/common"; | ||
| export declare class ngfModule { | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ngfModule, never>; | ||
| static ɵmod: i0.ɵɵNgModuleDeclaration<ngfModule, [typeof i1.ngfDrop, typeof i2.ngfSelect, typeof i3.ngfBackground, typeof i4.ngfSrc, typeof i5.ngfUploadStatus, typeof i6.ngfFormData, typeof i7.ngf], [typeof i8.CommonModule], [typeof i1.ngfDrop, typeof i2.ngfSelect, typeof i3.ngfBackground, typeof i4.ngfSrc, typeof i5.ngfUploadStatus, typeof i6.ngfFormData, typeof i7.ngf]>; | ||
| static ɵinj: i0.ɵɵInjectorDeclaration<ngfModule>; | ||
| } |
| import { ElementRef } from '@angular/core'; | ||
| import * as i0 from "@angular/core"; | ||
| export declare class ngfBackground { | ||
@@ -7,2 +8,4 @@ ElementRef: ElementRef; | ||
| ngOnChanges(_changes: any): void; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ngfBackground, never>; | ||
| static ɵdir: i0.ɵɵDirectiveDeclaration<ngfBackground, "[ngfBackground]", never, { "file": "ngfBackground"; }, {}, never>; | ||
| } |
| import { EventEmitter } from '@angular/core'; | ||
| import { ngf, dragMeta } from "./ngf.directive"; | ||
| import * as i0 from "@angular/core"; | ||
| export declare class ngfDrop extends ngf { | ||
@@ -16,2 +17,4 @@ fileOver: EventEmitter<any>; | ||
| onDragLeave(event: Event): any; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ngfDrop, never>; | ||
| static ɵdir: i0.ɵɵDirectiveDeclaration<ngfDrop, "[ngfDrop]", ["ngfDrop"], { "validDrag": "validDrag"; "invalidDrag": "invalidDrag"; "dragFiles": "dragFiles"; }, { "fileOver": "fileOver"; "validDragChange": "validDragChange"; "invalidDragChange": "invalidDragChange"; "dragFilesChange": "dragFilesChange"; }, never>; | ||
| } |
| import { IterableDiffer, IterableDiffers, EventEmitter } from '@angular/core'; | ||
| import * as i0 from "@angular/core"; | ||
| export declare class ngfFormData { | ||
@@ -12,2 +13,4 @@ files: File[]; | ||
| buildFormData(): void; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ngfFormData, never>; | ||
| static ɵdir: i0.ɵɵDirectiveDeclaration<ngfFormData, "ngfFormData", never, { "files": "files"; "postName": "postName"; "fileName": "fileName"; "FormData": "FormData"; }, { "FormDataChange": "FormDataChange"; }, never>; | ||
| } |
| import { ngf } from "./ngf.directive"; | ||
| import * as i0 from "@angular/core"; | ||
| export declare class ngfSelect extends ngf { | ||
| selectable: any; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ngfSelect, never>; | ||
| static ɵdir: i0.ɵɵDirectiveDeclaration<ngfSelect, "[ngfSelect]", ["ngfSelect"], { "selectable": "selectable"; }, {}, never>; | ||
| } |
| import { ElementRef } from '@angular/core'; | ||
| import * as i0 from "@angular/core"; | ||
| export declare class ngfSrc { | ||
@@ -7,2 +8,4 @@ ElementRef: ElementRef; | ||
| ngOnChanges(_changes: any): void; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ngfSrc, never>; | ||
| static ɵdir: i0.ɵɵDirectiveDeclaration<ngfSrc, "[ngfSrc]", never, { "file": "ngfSrc"; }, {}, never>; | ||
| } |
| import { EventEmitter } from '@angular/core'; | ||
| import * as i0 from "@angular/core"; | ||
| export declare class ngfUploadStatus { | ||
@@ -7,2 +8,4 @@ percent: number; | ||
| ngOnChanges(changes: any): void; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ngfUploadStatus, never>; | ||
| static ɵdir: i0.ɵɵDirectiveDeclaration<ngfUploadStatus, "ngfUploadStatus", never, { "percent": "percent"; "httpEvent": "httpEvent"; }, { "percentChange": "percentChange"; }, never>; | ||
| } |
+7
-0
| export * from './file-upload/ngf.module'; | ||
| export { ngfSrc } from './file-upload/ngfSrc.directive'; | ||
| export { ngfFormData } from './file-upload/ngfFormData.directive'; | ||
| export { ngfSelect } from './file-upload/ngfSelect.directive'; | ||
| export { ngfUploadStatus } from './file-upload/ngfUploadStatus.directive'; | ||
| export { ngfDrop } from './file-upload/ngfDrop.directive'; | ||
| export { ngf } from './file-upload/ngf.directive'; | ||
| export { ngfBackground } from './file-upload/ngfBackground.directive'; |
+31
-10
| { | ||
| "name": "angular-file", | ||
| "version": "3.8.2", | ||
| "version": "3.9.1", | ||
| "description": "Easy to use Angular directives for user file selections", | ||
| "main": "bundles/angular-file.umd.js", | ||
| "module": "fesm2015/angular-file.js", | ||
| "main": "dist/index.js", | ||
| "module": "fesm2015/angular-file.mjs", | ||
| "typings": "angular-file.d.ts", | ||
@@ -52,10 +52,31 @@ "keywords": [ | ||
| ], | ||
| "es2020": "fesm2020/angular-file.mjs", | ||
| "esm2020": "esm2020/angular-file.mjs", | ||
| "fesm2020": "fesm2020/angular-file.mjs", | ||
| "fesm2015": "fesm2015/angular-file.mjs", | ||
| "exports": { | ||
| "./package.json": { | ||
| "default": "./package.json" | ||
| }, | ||
| ".": { | ||
| "types": "./angular-file.d.ts", | ||
| "esm2020": "./esm2020/angular-file.mjs", | ||
| "es2020": "./fesm2020/angular-file.mjs", | ||
| "es2015": "./fesm2015/angular-file.mjs", | ||
| "node": "./fesm2015/angular-file.mjs", | ||
| "default": "./fesm2020/angular-file.mjs" | ||
| }, | ||
| "./src": { | ||
| "types": "./src/angular-file-src.d.ts", | ||
| "esm2020": "./esm2020/src/angular-file-src.mjs", | ||
| "es2020": "./fesm2020/angular-file-src.mjs", | ||
| "es2015": "./fesm2015/angular-file-src.mjs", | ||
| "node": "./fesm2015/angular-file-src.mjs", | ||
| "default": "./fesm2020/angular-file-src.mjs" | ||
| } | ||
| }, | ||
| "sideEffects": false, | ||
| "dependencies": { | ||
| "tslib": "^2.5.0" | ||
| }, | ||
| "es2015": "fesm2015/angular-file.js", | ||
| "esm2015": "esm2015/angular-file.js", | ||
| "fesm2015": "fesm2015/angular-file.js", | ||
| "metadata": "angular-file.metadata.json", | ||
| "sideEffects": false | ||
| "tslib": "^2.3.0" | ||
| } | ||
| } |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
1657844
78.57%85
60.38%13443
90.84%41
115.79%Updated