@innovastudio/contentbox 1.1.15 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -3
- package/public/contentbox/contentbox.esm.js +2744 -1170
- package/public/contentbox/contentbox.min.js +10 -16
|
@@ -2849,9 +2849,9 @@ class EditSection {
|
|
|
2849
2849
|
|
|
2850
2850
|
}
|
|
2851
2851
|
|
|
2852
|
-
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
2852
|
+
var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
2853
2853
|
|
|
2854
|
-
var js$
|
|
2854
|
+
var js$2 = {exports: {}};
|
|
2855
2855
|
|
|
2856
2856
|
var src$1 = {};
|
|
2857
2857
|
|
|
@@ -8046,9 +8046,9 @@ function get_beautify(js_beautify, css_beautify, html_beautify) {
|
|
|
8046
8046
|
|
|
8047
8047
|
})(module);
|
|
8048
8048
|
}
|
|
8049
|
-
}(js$
|
|
8049
|
+
}(js$2));
|
|
8050
8050
|
|
|
8051
|
-
var JsBeautify$1 = js$
|
|
8051
|
+
var JsBeautify$1 = js$2.exports;
|
|
8052
8052
|
|
|
8053
8053
|
const dom$K = new Dom$1();
|
|
8054
8054
|
|
|
@@ -8058,7 +8058,7 @@ class EditBox {
|
|
|
8058
8058
|
this.builderStuff = this.builder.builderStuff;
|
|
8059
8059
|
const builderStuff = this.builderStuff;
|
|
8060
8060
|
let html = '' + '<div id="divBoxTool">' + '<form id="form-upload-cover" data-tooltip-top data-title="' + out('Background Image') + '" target="frame-upload-cover" method="post" action="' + this.builder.coverImageHandler + '" enctype="multipart/form-data" style="position:relative;width:40px;height:40px;display:inline-block;float:left;background: rgb(90, 156, 38);">' + '<div style="width:40px;height:40px;overflow:hidden;">' + '<div style="position:absolute;width:100%;height:100%;"><svg class="is-icon-flex" style="position: absolute;top: 12px;left: 12px;fill:rgb(255,255,255);"><use xlink:href="#ion-image"></use></svg></div>' + '<input type="file" title="' + out('Background Image') + '" id="fileCover" name="fileCover" accept="image/*" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;"/>' + '</div>' + '<input id="hidcustomval" name="hidcustomval" type="hidden" value="" />' + '<iframe id="frame-upload-cover" name="frame-upload-cover" src="about:blank" style="width:1px;height:1px;position:absolute;top:0;right:-100000px"></iframe>' + '</form>' + '<button id="btnEditBox" data-tooltip-top data-title="' + out('Box Settings') + '" title="' + out('Box Settings') + '"><svg class="is-icon-flex"><use xlink:href="#ion-wrench"></use></svg></button>' + '<button id="btnEditModule" data-tooltip-top data-title="' + out('Module Settings') + '" title="' + out('Module Settings') + '"><svg class="is-icon-flex"><use xlink:href="#ion-ios-gear"></use></svg></button>' + '</div>' + '' + '<div class="is-modal editmodule">' + '<div style="max-width:900px;height:570px;padding:0;box-sizing:border-box;position:relative;">' + '<div class="is-modal-bar is-draggable" style="position: absolute;top: 0;left: 0;width: 100%;z-index:1;">' + out('Module Settings') + '</div>' + '<iframe style="position: absolute;top: 0;left: 0;width:100%;height:100%;border:none;border-bottom:60px solid transparent;border-top:40px solid transparent;margin:0;box-sizing:border-box;" src="about:blank"></iframe>' + '<input id="hidModuleCode" type="hidden" />' + '<input id="hidModuleSettings" type="hidden" />' + '<button class="input-ok classic" style="height:60px;position:absolute;left:0;bottom:0;">' + out('Ok') + '</button>' + '</div>' + '</div>' + '' + '<div class="is-modal editcustomcode">' + '<div style="max-width:900px;height:570px;padding:0;box-sizing:border-box;position:relative;">' + '<div class="is-modal-bar is-draggable" style="position: absolute;top: 0;left: 0;width: 100%;z-index:1;">' + out('Custom Code (Javascript Allowed)') + '</div>' + '<textarea id="txtBoxCustomCode" class="inptxt" style="background: #fff;position: absolute;top: 0;left: 0;width:100%;height:100%;border:none;border-bottom:60px solid transparent;border-top:40px solid transparent;box-sizing:border-box;"></textarea>' + '<input id="hidBoxCustomCode" type="hidden" />' + '<button class="cell-html-larger" style="width:35px;height:35px;position:absolute;right:0;top:0;background:transparent;z-index:2;"><svg class="is-icon-flex" style="width:19px;height:19px;fill:rgb(170, 170, 170);"><use xlink:href="#ion-arrow-expand"></use></svg></button>' + '<button class="input-ok classic" style="height:60px;position:absolute;left:0;bottom:0;">' + out('Ok') + '</button>' + '</div>' + '</div>' + '<div class="is-modal editbox">' + '<div class="is-modal-content" style="max-width:380px;min-height:300px;padding:0">' + '<div class="is-modal-bar is-draggable">' + out('Box Settings') + '</div>' + '<div class="is-tabs clearfix" style="padding-top:37px;">' + '<a id="tabBoxGeneral" href="" data-content="divBoxGeneral" class="active">' + out('General') + '</a>' + '<a id="tabBoxContentContainer" href="" data-content="divBoxContentContainer">' + out('Content') + '</a>' + '<a id="tabBoxContentText" href="" data-content="divBoxContentText">' + out('Text') + '</a>' + '<a id="tabBoxImage" href="" data-content="divBoxImage">' + out('Image') + '</a>' + '<a id="tabBoxAnimate" href="" data-content="divBoxAnimate">' + out('Animate') + '</a>' + '<a id="tabBoxClick" href="" data-content="divBoxClick">' + out('On Click') + '</a>' + '</div>' + '<div id="divBoxGeneral" class="is-tab-content" data-group="boxsettings" style="display:flex;padding-top:0">' + '<div id="divBoxSize">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Box Size') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Decrease') + '" class="cmd-box-smaller" style="width:40px;">-</button>' + '<button title="' + out('Increase') + '" class="cmd-box-larger" style="width:40px;border-left:none">+</button>' + '<br style="clear:both">' + '</div>' + '</div>' + '<div id="divContentSize">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Content Size') + ': <span class="val-box-size" style="font-size:12px"></span></div>' + '<div style="display: flex;flex-direction: row;flex-wrap: wrap;">' + '<input class="inp-box-size" type="text" style="display:none;width:80px;height:35px;text-align:center;font-size:12px;" />' + '<button class="cmd-box-size" data-value="500" style="width:40px;border-left:none">500</button>' + '<button class="cmd-box-size" data-value="600" style="width:40px;border-left:none">600</button>' + '<button class="cmd-box-size" data-value="700" style="width:40px;border-left:none">700</button>' + '<button class="cmd-box-size" data-value="800" style="width:40px;border-top:none">800</button>' + '<button class="cmd-box-size" data-value="900" style="width:40px;border-top:none">900</button>' + '<button class="cmd-box-size" data-value="1000" style="width:40px;border-top:none;border-left:none">1000</button>' + '<button class="cmd-box-size" data-value="1100" style="width:40px;border-top:none;border-left:none">1100</button>' + '<button class="cmd-box-size" data-value="1200" style="width:40px;border-top:none;border-left:none">1200</button>' + '<button class="cmd-box-size" data-value="1300" style="width:40px;border-top:none;border-left:none">1300</button>' + '<button class="cmd-box-size" data-value="1400" style="width:40px;border-top:none;border-left:none">1400</button>' + '<button class="cmd-box-size" data-value="1500" style="width:40px;border-top:none;border-left:none">1500</button>' + '<button class="cmd-box-size" data-value="1600" style="width:40px;border-top:none;border-left:none">1600</button>' + '<button class="cmd-box-size" data-value="1800" style="width:40px;border-top:none;border-left:none">1800</button>' + '<button title="' + out('Clear') + '" class="cmd-box-size" data-value=""><svg class="is-icon-flex" style="width:10px;height:10px;"><use xlink:href="#icon-clean"></use></svg></button>' + '<button title="' + out('Decrease') + '" class="cmd-box-size" data-value="-" style="width:40px;border-top:none;border-left:none">-</button>' + '<button title="' + out('Increase') + '"class="cmd-box-size" data-value="+" style="width:40px;border-top:none;border-left:none">+</button>' + '<br style="clear:both">' + '</div>' + '</div>' + '<div id="divBoxBackgroundColor">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Background Color') + ':</div>' + '<div style="display:flex;">' + '<button title="' + out('Background Color') + '" class="input-box-bgcolor is-btn-color" style="margin-right:15px"></button>' + '<button title="' + out('Gradient') + '" class="input-box-gradient classic" data-value="+">' + out('Gradient') + '</button>' + '</div>' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Background Image') + ':</div>' + '<div style="height:auto">' + '<div style="display:flex;align-items:flex-end;">' + '<div class="box-bgimage-preview"></div>' + '<label class="label-box-bgimage-grayscale label-checkbox" for="chkBoxBgImageGrayscale" style="margin:0;margin-left:8px;margin-bottom:5px;"><input id="chkBoxBgImageGrayscale" class="chk-box-bgimage-grayscale" type="checkbox" /> ' + out('Grayscale') + '</label>' + '</div>' + '<div style="display:flex;align-items: flex-end;">' + '<button title="' + out('Image') + '" class="input-box-bgimage">' + '<svg class="is-icon-flex"><use xlink:href="#ion-image"></use></svg>' + '<span>' + out('Image') + '</span>' + '</button>' + '<button title="' + out('Remove') + '" class="input-box-bgremove"><svg class="is-icon-flex" style="width:11px;height:11px;"><use xlink:href="#icon-clean"></use></svg></button>' + '<button title="' + out('Adjust') + '" class="input-box-bgimageadjust"><svg class="is-icon-flex"><use xlink:href="#ion-wrench"></use></svg></button>' + '</div>' + '</div>' + '</div>' + '<div id="divBoxPickPhoto" class="is-settings" style="padding-top:20px">' + '<button class="cmd-box-pickphoto" data-value="" style="width:100%"><svg class="is-icon-flex" style=""><use xlink:href="#ion-image"></use></svg></button>' + '</div>' + '<div style="display:flex;justify-content:flex-end;">' + '<button title="' + out('Add Text') + '" class="cmd-box-addtext" style="display:none;margin-top:20px;"><svg class="is-icon-flex" style="width:11px;height:11px;"><use xlink:href="#ion-android-add"></use></svg> <span>' + out('Text') + '</span></button>' + '<button title="' + out('Remove Text') + '" class="cmd-box-removetext" style="display:none;margin-top:20px;"><svg class="is-icon-flex" style="width:11px;height:11px;"><use xlink:href="#icon-clean"></use></svg> <span>' + out('Clear') + '</span></button>' + '</div>' + '<p id="divNoBoxSettings" style="text-align: center;display:none;">' + out('This box has no available settings.') + '</p>' + '</div>' + '<div id="divBoxClick" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + '<label for="inpBoxLinkSource" style="display:block;padding-top:20px;">' + out('Open') + ':</label>' + '<div class="image-src" style="display:flex">' + '<input id="inpBoxLinkSource" class="input-src" type="text" style="height:38px">' + '<button title="' + out('Select') + '" class="input-select" style="flex:none;width:40px;height:38px;background:transparent;"><svg class="is-icon-flex"><use xlink:href="#ion-more"></use></svg></button>' + '<div class="image-larger5" style="position: relative; flex: 0 0 auto; width: 40px; height: 38px; box-shadow: rgba(0, 0, 0, 0.32) 0px 3px 6px -6px;">' + '<form class="form-upload-larger" target="frameTargetBoxLinkUpload" method="post" action="' + this.builder.largerImageHandler + '" enctype="multipart/form-data" style="position:absolute;top:0;left:0;width:100%;height:100%;">' + '<input id="hidRefId5" name="hidRefId" type="hidden" value="">' + '<svg class="is-icon-flex" style="position: absolute;top: 10px;left: 15px;"><use xlink:href="#ion-image"></use></svg>' + '<input title="' + out('Select') + '" id="fileImage5" name="fileImage" type="file" accept="image/*,video/mp4" style="position:absolute;top:-30px;left:0;width:100%;height:80px;opacity: 0;cursor: pointer;">' + '</form>' + '<iframe id="frameTargetBoxLinkUpload" name="frameTargetBoxLinkUpload" src="about:blank" style="width:1px;height:1px;position:absolute;top:0;right:-100000px"></iframe>' + '</div>' + '</div>' + '<div style="padding-top:20px">' + '<button class="cmd-box-testclick">' + out('Test') + '</button>' + '</div>' + '</div>';
|
|
8061
|
-
html += '<div id="divBoxContentText" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Text Style') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Light') + '" class="cmd-box-textcolor" data-value="light">' + out('Light') + '</button>' + '<button title="' + out('Dark') + '" class="cmd-box-textcolor" data-value="dark" style="border-left:none;">' + out('Dark') + '</button>' + '<br style="clear:both">' + '</div>' + '</div>' + '<div style="padding-top:20px;">' + '<label for="chkOptimizeTextSize" style="margin:0;"><input id="chkOptimizeTextSize" type="checkbox" /> ' + out('Optimize text sizes on large screen.') + '</label>' + '</div>' + '<div id="divContainerTransparency" style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Transparency') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Increase') + '" class="cmd-box-textopacity" data-value="+" style="width:40px"> + </button>' + '<button title="' + out('Decrease') + '" class="cmd-box-textopacity" data-value="-" style="width:40px;border-left:none;"> - </button>' + '<button title="' + out('Not Set') + '" class="cmd-box-textopacity" data-value="" style="border-left:none;">' + out('Not Set') + '</button>' + '<br style="clear:both">' + '</div>' + '</div>' + '<div id="divContainerTextAlign" style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">Align:</div>' + '<div style="display:flex">' + '<button title="' + out('Align Left') + '" class="cmd-box-textalign" data-value="left" style="width:40px"><svg class="is-icon-flex" style="fill:rgba(0, 0, 0, 0.8);width:13px;height:13px;"><use xlink:href="#icon-align-left"></use></svg></button>' + '<button title="' + out('Align Center') + '" class="cmd-box-textalign" data-value="center" style="width:40px;border-left:none;"><svg class="is-icon-flex" style="fill:rgba(0, 0, 0, 0.8);width:13px;height:13px;"><use xlink:href="#icon-align-center"></use></svg></button>' + '<button title="' + out('Align Right') + '" class="cmd-box-textalign" data-value="right" style="width:40px;border-left:none;"><svg class="is-icon-flex" style="fill:rgba(0, 0, 0, 0.8);width:13px;height:13px;"><use xlink:href="#icon-align-right"></use></svg></button>' + '<button title="' + out('Align Full') + '" class="cmd-box-textalign" data-value="justify" style="width:40px;border-left:none;"><svg class="is-icon-flex" style="fill:rgba(0, 0, 0, 0.8);width:13px;height:13px;"><use xlink:href="#icon-align-full"></use></svg></button>' + '<br style="clear:both">' + '</div>' + '</div>' + (this.builder.settings.enableContentStyle ? '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Typography') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Change Style') + '" class="cmd-box-typography" data-value="+"> ' + out('Change Style') + ' </button>' + '<br style="clear:both">' + '</div>' + '</div>' : '') + '</div>' + '<div id="divBoxContentContainer" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + '<div style="padding-top:10px;">' + '<label for="chkParallaxContent" style="margin:0;"><input id="chkParallaxContent" type="checkbox" /> ' + out('Parallax') + '</label>' + '</div>' + '<div style="padding-top:10px;">' + '<label for="chkFadeContent" style="margin:0;"><input id="chkFadeContent" type="checkbox" /> ' + out('Fade') + '</label>' + '</div>' + '<div style="display:flex;flex-direction: row;">' + '<div style="display:flex;flex-direction: column;margin-right:20px;">' + '<div style="padding-top:13px;padding-bottom: 3px;">' + out('Position') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Top Left') + '" class="cmd-box-content-pos" data-value="topleft" style="width:40px;">↖</button>' + '<button title="' + out('Top Center') + '" class="cmd-box-content-pos" data-value="topcenter" style="width:40px;border-left:none;">↑</button>' + '<button title="' + out('Top Right') + '" class="cmd-box-content-pos" data-value="topright" style="width:40px;border-left:none;">↗</button>' + '</div>' + '<div style="display:flex">' + '<button title="' + out('Middle Left') + '" class="cmd-box-content-pos" data-value="middleleft" style="width:40px;border-top:none;">←</button>' + '<button title="' + out('Middle Center') + '" class="cmd-box-content-pos" data-value="middlecenter" style="width:40px;border-left:none;border-top:none;">☉</button>' + '<button title="' + out('Middle Right') + '" class="cmd-box-content-pos" data-value="middleright" style="width:40px;border-left:none;border-top:none;">→</button>' + '</div>' + '<div style="display:flex">' + '<button title="' + out('Bottom Left') + '" class="cmd-box-content-pos" data-value="bottomleft" style="width:40px;border-top:none;">↙</button>' + '<button title="' + out('Bottom Center') + '" class="cmd-box-content-pos" data-value="bottomcenter" style="width:40px;border-left:none;border-top:none;">↓</button>' + '<button title="' + out('Bottom Right') + '" class="cmd-box-content-pos" data-value="bottomright" style="width:40px;border-left:none;border-top:none;">↘</button>' + '</div>' + '</div>' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 1px;">' + out('Height') + ':</div>' + '<div style="display: flex;flex-direction: row;flex-wrap: wrap;">' + '<button title="' + out('Auto') + '" class="cmd-content-height" data-value="" style="width:60px">Auto</button>' + '<button title="' + out('Full') + '" class="cmd-content-height" data-value="100" style="width:40px">Full</button>' + '</div>' + '<div class="div-content-justify">' + '<div style="padding-top:10px;padding-bottom: 1px;">' + out('Justify') + ':</div>' + '<div style="display: flex;flex-direction: row;flex-wrap: wrap;">' + '<button title="' + out('Top') + '" class="cmd-content-justify" data-value="flex-start" style="width:40px"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-arrow-bar-to-up"></use></svg></button>' + '<button title="' + out('Bottom') + '" class="cmd-content-justify" data-value="flex-end" style="width:40px"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-arrow-bar-to-down"></use></svg></button>' + '<button title="' + out('Space Between') + '" class="cmd-content-justify" data-value="space-between" style="width:40px"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-space-between"></use></svg></button>' + '</div>' + '</div>' + '</div>' + '</div>' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Vertical Adjustment') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Decrease') + '" class="cmd-box-content-edge-y" data-value="-" style="width:40px;">-</button>' + '<button title="' + out('Increase') + '" class="cmd-box-content-edge-y" data-value="+" style="width:40px;border-left:none;">+</button>' + '<button title="' + out('Not Set') + '" class="cmd-box-content-edge-y" data-value="" style="display:none;width:40px;border-left:none;min-width:100px;">' + out('Not Set') + '</button>' + '</div>' + '</div>' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Horizontal Adjustment') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Decrease') + '" class="cmd-box-content-edge-x" data-value="-" style="width:40px;">-</button>' + '<button title="' + out('Increase') + '" class="cmd-box-content-edge-x" data-value="+" style="width:40px;border-left:none;">+</button>' + '<button title="' + out('Not Set') + '" class="cmd-box-content-edge-x" data-value="" style="display:none;width:40px;border-left:none;min-width:100px;">' + out('Not Set') + '</button>' + '</div>' + '</div>' + '<div style="padding-top:13px;">' + '<label for="chkAutofitContent" style="margin:0;"><input id="chkAutofitContent" type="checkbox" /> ' + out('Autofit Content on Mobile') + '</label>' + '</div>' + '</div>' + '<div id="divBoxImage" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + (this.builder.settings.onCoverImageSelectClick != null ? '<div style="padding-top:20px;">' + '<button class="cmd-box-selectasset" style="width:120px;">' + out('Select Image') + '</button>' + '</div>' + '<div style="padding-top:20px;">' + '<label for="chkAnimateBg" style="margin:0;"><input id="chkAnimateBg" type="checkbox" /> ' + out('Ken Burns Effect') + '</label>' + '</div>' : '<div style="padding-top:20px;">' + '<label for="chkAnimateBg" style="margin:0;"><input id="chkAnimateBg" type="checkbox" /> ' + out('Ken Burns Effect') + '</label>' + '</div>') + '<div style="padding-top:10px;">' + '<label for="chkParallaxBg" style="margin:0;"><input id="chkParallaxBg" type="checkbox" /> ' + out('Parallax') + ' & ' + out('Scale') + '</label>' + '</div>' + '<div style="padding-top:10px;">' + '<label for="chkParallaxBg2" style="margin:0;"><input id="chkParallaxBg2" type="checkbox" /> ' + out('Parallax') + '</label>' + '</div>' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Overlay Color') + ':</div>' + '<div style="display:flex;">' + '<button title="' + out('Overlay Color') + '" class="input-box-overlaycolor is-btn-color" style="margin-right:15px"></button>' + '</div>' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Overlay Transparency') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Increase') + '" class="cmd-box-overlayopacity" data-value="+" style="width:40px;">+</button>' + '<button title="' + out('Decrease') + '" class="cmd-box-overlayopacity" data-value="-" style="width:40px;border-left:none;">-</button>' + '<button title="' + out('None') + '" class="cmd-box-overlayopacity" data-value="0" style="border-left:none;min-width:100px;">' + out('None') + '</button>' + '</div>' + '</div>' + '</div>' + '<div id="divBoxAnimate" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + '<div style="display:flex;flex-direction: column;">' + '<select class="cmd-box-animate">' + '<option value="">' + out('None') + '</option>' + '<option value="is-pulse">pulse</option>' + '<option value="is-bounceIn">bounceIn</option>' + '<option value="is-fadeIn">fadeIn</option>' + '<option value="is-fadeInDown">fadeInDown</option>' + '<option value="is-fadeInLeft">fadeInLeft</option>' + '<option value="is-fadeInRight">fadeInRight</option>' + '<option value="is-fadeInUp">fadeInUp</option>' + '<option value="is-flipInX">flipInX</option>' + '<option value="is-flipInY">flipInY</option>' + '<option value="is-slideInUp">slideInUp</option>' + '<option value="is-slideInDown">slideInDown</option>' + '<option value="is-slideInLeft">slideInLeft</option>' + '<option value="is-slideInRight">slideInRight</option>' + '<option value="is-zoomIn">zoomIn</option>' + '</select>' + '<label for="chkAnimOnce" style="margin:10px 0 0;"><input id="chkAnimOnce" type="checkbox" /> ' + out('Once') + '</label>' + '</div>' + '<div>' + '<label style="padding-top:20px;">' + out('Delay') + ': ' + '<select class="cmd-box-animatedelay" style="margin-top:3px;">' + '<option value="">' + out('None') + '</option>' + '<option value="delay-0ms">0s</option>' + '<option value="delay-100ms">100ms</option>' + '<option value="delay-200ms">200ms</option>' + '<option value="delay-300ms">300ms</option>' + '<option value="delay-400ms">400ms</option>' + '<option value="delay-500ms">500ms</option>' + '<option value="delay-600ms">600ms</option>' + '<option value="delay-700ms">700ms</option>' + '<option value="delay-800ms">800ms</option>' + '<option value="delay-900ms">900ms</option>' + '<option value="delay-1000ms">1000ms</option>' + '<option value="delay-1100ms">1100ms</option>' + '<option value="delay-1200ms">1200ms</option>' + '<option value="delay-1300ms">1300ms</option>' + '<option value="delay-1400ms">1400ms</option>' + '<option value="delay-1500ms">1500ms</option>' + '<option value="delay-1600ms">1600ms</option>' + '<option value="delay-1700ms">1700ms</option>' + '<option value="delay-1800ms">1800ms</option>' + '<option value="delay-1900ms">1900ms</option>' + '<option value="delay-2000ms">2000ms</option>' + '<option value="delay-2100ms">2100ms</option>' + '<option value="delay-2200ms">2200ms</option>' + '<option value="delay-2300ms">2300ms</option>' + '<option value="delay-2400ms">2400ms</option>' + '<option value="delay-2500ms">2500ms</option>' + '<option value="delay-2600ms">2600ms</option>' + '<option value="delay-2700ms">2700ms</option>' + '<option value="delay-2800ms">2800ms</option>' + '<option value="delay-2900ms">2900ms</option>' + '<option value="delay-3000ms">3000ms</option>' + '</select></label>' + '</div>' + '<div style="padding-top:20px">' + '<button class="cmd-box-animate-test" style="width:100%">' + out('Test') + '</button>' + '</div>' + '</div>' + '</div>' + '</div>' + '' + '<div class="is-modal pickphoto">' + '<div style="max-width:1000px;height:570px;padding:0;box-sizing:border-box;position:relative;">' + '<div class="is-modal-bar is-draggable" style="position: absolute;top: 0;left: 0;width: 100%;z-index:1;">' + out('Photos') + '</div>' + '<iframe style="position: absolute;top: 0;left: 0;width:100%;height:100%;border:none;border-top:40px solid transparent;margin:0;box-sizing:border-box;" src="about:blank"></iframe>' + '</div>' + '</div>' + '';
|
|
8061
|
+
html += '<div id="divBoxContentText" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Text Style') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Light') + '" class="cmd-box-textcolor" data-value="light">' + out('Light') + '</button>' + '<button title="' + out('Dark') + '" class="cmd-box-textcolor" data-value="dark" style="border-left:none;">' + out('Dark') + '</button>' + '<button title="' + out('Not Set') + '" class="cmd-box-textcolor" data-value="" style="border-left:none;">' + out('Not Set') + '</button>' + '<br style="clear:both">' + '</div>' + '</div>' + '<div style="padding-top:20px;">' + '<label for="chkOptimizeTextSize" style="margin:0;"><input id="chkOptimizeTextSize" type="checkbox" /> ' + out('Optimize text sizes on large screen.') + '</label>' + '</div>' + '<div id="divContainerTransparency" style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Transparency') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Increase') + '" class="cmd-box-textopacity" data-value="+" style="width:40px"> + </button>' + '<button title="' + out('Decrease') + '" class="cmd-box-textopacity" data-value="-" style="width:40px;border-left:none;"> - </button>' + '<button title="' + out('Not Set') + '" class="cmd-box-textopacity" data-value="" style="border-left:none;">' + out('Not Set') + '</button>' + '<br style="clear:both">' + '</div>' + '</div>' + '<div id="divContainerTextAlign" style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">Align:</div>' + '<div style="display:flex">' + '<button title="' + out('Align Left') + '" class="cmd-box-textalign" data-value="left" style="width:40px"><svg class="is-icon-flex" style="fill:rgba(0, 0, 0, 0.8);width:13px;height:13px;"><use xlink:href="#icon-align-left"></use></svg></button>' + '<button title="' + out('Align Center') + '" class="cmd-box-textalign" data-value="center" style="width:40px;border-left:none;"><svg class="is-icon-flex" style="fill:rgba(0, 0, 0, 0.8);width:13px;height:13px;"><use xlink:href="#icon-align-center"></use></svg></button>' + '<button title="' + out('Align Right') + '" class="cmd-box-textalign" data-value="right" style="width:40px;border-left:none;"><svg class="is-icon-flex" style="fill:rgba(0, 0, 0, 0.8);width:13px;height:13px;"><use xlink:href="#icon-align-right"></use></svg></button>' + '<button title="' + out('Align Full') + '" class="cmd-box-textalign" data-value="justify" style="width:40px;border-left:none;"><svg class="is-icon-flex" style="fill:rgba(0, 0, 0, 0.8);width:13px;height:13px;"><use xlink:href="#icon-align-full"></use></svg></button>' + '<button title="' + out('Not Set') + '" class="cmd-box-textalign" data-value="" style="border-left:none;">' + out('Not Set') + '</button>' + '<br style="clear:both">' + '</div>' + '</div>' + (this.builder.settings.enableContentStyle ? '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Typography') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Change Style') + '" class="cmd-box-typography" data-value="+"> ' + out('Change Style') + ' </button>' + '<br style="clear:both">' + '</div>' + '</div>' : '') + '</div>' + '<div id="divBoxContentContainer" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + '<div style="padding-top:10px;">' + '<label for="chkParallaxContent" style="margin:0;"><input id="chkParallaxContent" type="checkbox" /> ' + out('Parallax') + '</label>' + '</div>' + '<div style="padding-top:10px;">' + '<label for="chkFadeContent" style="margin:0;"><input id="chkFadeContent" type="checkbox" /> ' + out('Fade') + '</label>' + '</div>' + '<div style="display:flex;flex-direction: row;">' + '<div style="display:flex;flex-direction: column;margin-right:20px;">' + '<div style="padding-top:13px;padding-bottom: 3px;">' + out('Position') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Top Left') + '" class="cmd-box-content-pos" data-value="topleft" style="width:40px;">↖</button>' + '<button title="' + out('Top Center') + '" class="cmd-box-content-pos" data-value="topcenter" style="width:40px;border-left:none;">↑</button>' + '<button title="' + out('Top Right') + '" class="cmd-box-content-pos" data-value="topright" style="width:40px;border-left:none;">↗</button>' + '</div>' + '<div style="display:flex">' + '<button title="' + out('Middle Left') + '" class="cmd-box-content-pos" data-value="middleleft" style="width:40px;border-top:none;">←</button>' + '<button title="' + out('Middle Center') + '" class="cmd-box-content-pos" data-value="middlecenter" style="width:40px;border-left:none;border-top:none;">☉</button>' + '<button title="' + out('Middle Right') + '" class="cmd-box-content-pos" data-value="middleright" style="width:40px;border-left:none;border-top:none;">→</button>' + '</div>' + '<div style="display:flex">' + '<button title="' + out('Bottom Left') + '" class="cmd-box-content-pos" data-value="bottomleft" style="width:40px;border-top:none;">↙</button>' + '<button title="' + out('Bottom Center') + '" class="cmd-box-content-pos" data-value="bottomcenter" style="width:40px;border-left:none;border-top:none;">↓</button>' + '<button title="' + out('Bottom Right') + '" class="cmd-box-content-pos" data-value="bottomright" style="width:40px;border-left:none;border-top:none;">↘</button>' + '</div>' + '</div>' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 1px;">' + out('Height') + ':</div>' + '<div style="display: flex;flex-direction: row;flex-wrap: wrap;">' + '<button title="' + out('Auto') + '" class="cmd-content-height" data-value="" style="width:60px">Auto</button>' + '<button title="' + out('Full') + '" class="cmd-content-height" data-value="100" style="width:40px">Full</button>' + '</div>' + '<div class="div-content-justify">' + '<div style="padding-top:10px;padding-bottom: 1px;">' + out('Justify') + ':</div>' + '<div style="display: flex;flex-direction: row;flex-wrap: wrap;">' + '<button title="' + out('Top') + '" class="cmd-content-justify" data-value="flex-start" style="width:40px"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-arrow-bar-to-up"></use></svg></button>' + '<button title="' + out('Bottom') + '" class="cmd-content-justify" data-value="flex-end" style="width:40px"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-arrow-bar-to-down"></use></svg></button>' + '<button title="' + out('Space Between') + '" class="cmd-content-justify" data-value="space-between" style="width:40px"><svg class="is-icon-flex" style="width:14px;height:14px;"><use xlink:href="#icon-space-between"></use></svg></button>' + '</div>' + '</div>' + '</div>' + '</div>' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Vertical Adjustment') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Decrease') + '" class="cmd-box-content-edge-y" data-value="-" style="width:40px;">-</button>' + '<button title="' + out('Increase') + '" class="cmd-box-content-edge-y" data-value="+" style="width:40px;border-left:none;">+</button>' + '<button title="' + out('Not Set') + '" class="cmd-box-content-edge-y" data-value="" style="display:none;width:40px;border-left:none;min-width:100px;">' + out('Not Set') + '</button>' + '</div>' + '</div>' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Horizontal Adjustment') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Decrease') + '" class="cmd-box-content-edge-x" data-value="-" style="width:40px;">-</button>' + '<button title="' + out('Increase') + '" class="cmd-box-content-edge-x" data-value="+" style="width:40px;border-left:none;">+</button>' + '<button title="' + out('Not Set') + '" class="cmd-box-content-edge-x" data-value="" style="display:none;width:40px;border-left:none;min-width:100px;">' + out('Not Set') + '</button>' + '</div>' + '</div>' + '<div style="padding-top:13px;">' + '<label for="chkAutofitContent" style="margin:0;"><input id="chkAutofitContent" type="checkbox" /> ' + out('Autofit Content on Mobile') + '</label>' + '</div>' + '</div>' + '<div id="divBoxImage" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + (this.builder.settings.onCoverImageSelectClick != null ? '<div style="padding-top:20px;">' + '<button class="cmd-box-selectasset" style="width:120px;">' + out('Select Image') + '</button>' + '</div>' + '<div style="padding-top:20px;">' + '<label for="chkAnimateBg" style="margin:0;"><input id="chkAnimateBg" type="checkbox" /> ' + out('Ken Burns Effect') + '</label>' + '</div>' : '<div style="padding-top:20px;">' + '<label for="chkAnimateBg" style="margin:0;"><input id="chkAnimateBg" type="checkbox" /> ' + out('Ken Burns Effect') + '</label>' + '</div>') + '<div style="padding-top:10px;">' + '<label for="chkParallaxBg" style="margin:0;"><input id="chkParallaxBg" type="checkbox" /> ' + out('Parallax') + ' & ' + out('Scale') + '</label>' + '</div>' + '<div style="padding-top:10px;">' + '<label for="chkParallaxBg2" style="margin:0;"><input id="chkParallaxBg2" type="checkbox" /> ' + out('Parallax') + '</label>' + '</div>' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Overlay Color') + ':</div>' + '<div style="display:flex;">' + '<button title="' + out('Overlay Color') + '" class="input-box-overlaycolor is-btn-color" style="margin-right:15px"></button>' + '</div>' + '<div style="display:flex;flex-direction: column;">' + '<div style="padding-top:20px;padding-bottom: 3px;">' + out('Overlay Transparency') + ':</div>' + '<div style="display:flex">' + '<button title="' + out('Increase') + '" class="cmd-box-overlayopacity" data-value="+" style="width:40px;">+</button>' + '<button title="' + out('Decrease') + '" class="cmd-box-overlayopacity" data-value="-" style="width:40px;border-left:none;">-</button>' + '<button title="' + out('None') + '" class="cmd-box-overlayopacity" data-value="0" style="border-left:none;min-width:100px;">' + out('None') + '</button>' + '</div>' + '</div>' + '</div>' + '<div id="divBoxAnimate" class="is-tab-content" data-group="boxsettings" style="padding-top:0">' + '<div style="display:flex;flex-direction: column;">' + '<select class="cmd-box-animate">' + '<option value="">' + out('None') + '</option>' + '<option value="is-pulse">pulse</option>' + '<option value="is-bounceIn">bounceIn</option>' + '<option value="is-fadeIn">fadeIn</option>' + '<option value="is-fadeInDown">fadeInDown</option>' + '<option value="is-fadeInLeft">fadeInLeft</option>' + '<option value="is-fadeInRight">fadeInRight</option>' + '<option value="is-fadeInUp">fadeInUp</option>' + '<option value="is-flipInX">flipInX</option>' + '<option value="is-flipInY">flipInY</option>' + '<option value="is-slideInUp">slideInUp</option>' + '<option value="is-slideInDown">slideInDown</option>' + '<option value="is-slideInLeft">slideInLeft</option>' + '<option value="is-slideInRight">slideInRight</option>' + '<option value="is-zoomIn">zoomIn</option>' + '</select>' + '<label for="chkAnimOnce" style="margin:10px 0 0;"><input id="chkAnimOnce" type="checkbox" /> ' + out('Once') + '</label>' + '</div>' + '<div>' + '<label style="padding-top:20px;">' + out('Delay') + ': ' + '<select class="cmd-box-animatedelay" style="margin-top:3px;">' + '<option value="">' + out('None') + '</option>' + '<option value="delay-0ms">0s</option>' + '<option value="delay-100ms">100ms</option>' + '<option value="delay-200ms">200ms</option>' + '<option value="delay-300ms">300ms</option>' + '<option value="delay-400ms">400ms</option>' + '<option value="delay-500ms">500ms</option>' + '<option value="delay-600ms">600ms</option>' + '<option value="delay-700ms">700ms</option>' + '<option value="delay-800ms">800ms</option>' + '<option value="delay-900ms">900ms</option>' + '<option value="delay-1000ms">1000ms</option>' + '<option value="delay-1100ms">1100ms</option>' + '<option value="delay-1200ms">1200ms</option>' + '<option value="delay-1300ms">1300ms</option>' + '<option value="delay-1400ms">1400ms</option>' + '<option value="delay-1500ms">1500ms</option>' + '<option value="delay-1600ms">1600ms</option>' + '<option value="delay-1700ms">1700ms</option>' + '<option value="delay-1800ms">1800ms</option>' + '<option value="delay-1900ms">1900ms</option>' + '<option value="delay-2000ms">2000ms</option>' + '<option value="delay-2100ms">2100ms</option>' + '<option value="delay-2200ms">2200ms</option>' + '<option value="delay-2300ms">2300ms</option>' + '<option value="delay-2400ms">2400ms</option>' + '<option value="delay-2500ms">2500ms</option>' + '<option value="delay-2600ms">2600ms</option>' + '<option value="delay-2700ms">2700ms</option>' + '<option value="delay-2800ms">2800ms</option>' + '<option value="delay-2900ms">2900ms</option>' + '<option value="delay-3000ms">3000ms</option>' + '</select></label>' + '</div>' + '<div style="padding-top:20px">' + '<button class="cmd-box-animate-test" style="width:100%">' + out('Test') + '</button>' + '</div>' + '</div>' + '</div>' + '</div>' + '' + '<div class="is-modal pickphoto">' + '<div style="max-width:1000px;height:570px;padding:0;box-sizing:border-box;position:relative;">' + '<div class="is-modal-bar is-draggable" style="position: absolute;top: 0;left: 0;width: 100%;z-index:1;">' + out('Photos') + '</div>' + '<iframe style="position: absolute;top: 0;left: 0;width:100%;height:100%;border:none;border-top:40px solid transparent;margin:0;box-sizing:border-box;" src="about:blank"></iframe>' + '</div>' + '</div>' + '';
|
|
8062
8062
|
dom$K.appendHtml(builderStuff, html); // Box Tool
|
|
8063
8063
|
|
|
8064
8064
|
this.builder.boxTool = builderStuff.querySelector('#divBoxTool');
|
|
@@ -8356,7 +8356,19 @@ class EditBox {
|
|
|
8356
8356
|
let s = btn.getAttribute('data-value');
|
|
8357
8357
|
let activeBox = this.builder.activeBox;
|
|
8358
8358
|
let container = activeBox.querySelector('.is-container');
|
|
8359
|
-
container.style.justifyContent =
|
|
8359
|
+
container.style.justifyContent = '';
|
|
8360
|
+
dom$K.removeClass(container, 'justify-start');
|
|
8361
|
+
dom$K.removeClass(container, 'justify-end');
|
|
8362
|
+
dom$K.removeClass(container, 'justify-between');
|
|
8363
|
+
|
|
8364
|
+
if (s === 'flex-start') {
|
|
8365
|
+
dom$K.addClass(container, 'justify-start');
|
|
8366
|
+
} else if (s === 'flex-end') {
|
|
8367
|
+
dom$K.addClass(container, 'justify-end');
|
|
8368
|
+
} else if (s === 'space-between') {
|
|
8369
|
+
dom$K.addClass(container, 'justify-between');
|
|
8370
|
+
}
|
|
8371
|
+
|
|
8360
8372
|
let btnPos = modalEditBox.querySelectorAll('.cmd-content-justify');
|
|
8361
8373
|
btnPos.forEach(btn => {
|
|
8362
8374
|
dom$K.removeClass(btn, 'on');
|
|
@@ -8377,17 +8389,22 @@ class EditBox {
|
|
|
8377
8389
|
|
|
8378
8390
|
if (s === '') {
|
|
8379
8391
|
container.style.height = '';
|
|
8380
|
-
container
|
|
8381
|
-
container
|
|
8382
|
-
container
|
|
8392
|
+
dom$K.removeClass(container, 'h-full');
|
|
8393
|
+
dom$K.removeClass(container, 'flex');
|
|
8394
|
+
dom$K.removeClass(container, 'flex-col');
|
|
8395
|
+
dom$K.removeClass(container, 'justify-start');
|
|
8396
|
+
dom$K.removeClass(container, 'justify-end');
|
|
8397
|
+
dom$K.removeClass(container, 'justify-between');
|
|
8383
8398
|
divContentJustify.style.display = 'none';
|
|
8384
8399
|
}
|
|
8385
8400
|
|
|
8386
8401
|
if (s === '100') {
|
|
8387
|
-
container
|
|
8388
|
-
container
|
|
8389
|
-
container
|
|
8390
|
-
container
|
|
8402
|
+
dom$K.addClass(container, 'h-full');
|
|
8403
|
+
dom$K.addClass(container, 'flex');
|
|
8404
|
+
dom$K.addClass(container, 'flex-col');
|
|
8405
|
+
dom$K.removeClass(container, 'justify-start');
|
|
8406
|
+
dom$K.removeClass(container, 'justify-end');
|
|
8407
|
+
dom$K.addClass(container, 'justify-between');
|
|
8391
8408
|
divContentJustify.style.display = 'block';
|
|
8392
8409
|
let btnPos = modalEditBox.querySelectorAll('.cmd-content-justify');
|
|
8393
8410
|
btnPos.forEach(btn => {
|
|
@@ -9714,22 +9731,19 @@ class EditBox {
|
|
|
9714
9731
|
});
|
|
9715
9732
|
|
|
9716
9733
|
if (container) {
|
|
9717
|
-
if (container.style.height) {
|
|
9718
|
-
|
|
9719
|
-
dom$K.addClass(modalEditBox.querySelector('.cmd-content-height[data-value="100"]'), 'on');
|
|
9720
|
-
}
|
|
9721
|
-
|
|
9734
|
+
if (container.style.height === '100%' || dom$K.hasClass(container, 'h-full')) {
|
|
9735
|
+
dom$K.addClass(modalEditBox.querySelector('.cmd-content-height[data-value="100"]'), 'on');
|
|
9722
9736
|
divContentJustify.style.display = 'block';
|
|
9723
9737
|
|
|
9724
|
-
if (container.style.justifyContent === 'flex-start') {
|
|
9738
|
+
if (container.style.justifyContent === 'flex-start' || dom$K.hasClass(container, 'justify-start')) {
|
|
9725
9739
|
dom$K.addClass(modalEditBox.querySelector('.cmd-content-justify[data-value="flex-start"]'), 'on');
|
|
9726
9740
|
}
|
|
9727
9741
|
|
|
9728
|
-
if (container.style.justifyContent === 'flex-end') {
|
|
9742
|
+
if (container.style.justifyContent === 'flex-end' || dom$K.hasClass(container, 'justify-end')) {
|
|
9729
9743
|
dom$K.addClass(modalEditBox.querySelector('.cmd-content-justify[data-value="flex-end"]'), 'on');
|
|
9730
9744
|
}
|
|
9731
9745
|
|
|
9732
|
-
if (container.style.justifyContent === 'space-between') {
|
|
9746
|
+
if (container.style.justifyContent === 'space-between' || dom$K.hasClass(container, 'justify-between')) {
|
|
9733
9747
|
dom$K.addClass(modalEditBox.querySelector('.cmd-content-justify[data-value="space-between"]'), 'on');
|
|
9734
9748
|
}
|
|
9735
9749
|
} else {
|
|
@@ -9985,27 +9999,26 @@ class EditBox {
|
|
|
9985
9999
|
dom$K.removeClass(activeBox, 'is-align-center');
|
|
9986
10000
|
dom$K.removeClass(activeBox, 'is-align-justify');
|
|
9987
10001
|
dom$K.addClass(activeBox, 'is-align-right');
|
|
9988
|
-
}
|
|
9989
|
-
|
|
9990
|
-
if (s == 'center') {
|
|
10002
|
+
} else if (s == 'center') {
|
|
9991
10003
|
dom$K.removeClass(activeBox, 'is-align-left');
|
|
9992
10004
|
dom$K.removeClass(activeBox, 'is-align-right');
|
|
9993
10005
|
dom$K.removeClass(activeBox, 'is-align-justify');
|
|
9994
10006
|
dom$K.addClass(activeBox, 'is-align-center');
|
|
9995
|
-
}
|
|
9996
|
-
|
|
9997
|
-
if (s == 'left') {
|
|
10007
|
+
} else if (s == 'left') {
|
|
9998
10008
|
dom$K.removeClass(activeBox, 'is-align-right');
|
|
9999
10009
|
dom$K.removeClass(activeBox, 'is-align-center');
|
|
10000
10010
|
dom$K.removeClass(activeBox, 'is-align-justify');
|
|
10001
10011
|
dom$K.addClass(activeBox, 'is-align-left');
|
|
10002
|
-
}
|
|
10003
|
-
|
|
10004
|
-
if (s == 'justify') {
|
|
10012
|
+
} else if (s == 'justify') {
|
|
10005
10013
|
dom$K.removeClass(activeBox, 'is-align-left');
|
|
10006
10014
|
dom$K.removeClass(activeBox, 'is-align-right');
|
|
10007
10015
|
dom$K.removeClass(activeBox, 'is-align-center');
|
|
10008
10016
|
dom$K.addClass(activeBox, 'is-align-justify');
|
|
10017
|
+
} else if (s == '') {
|
|
10018
|
+
dom$K.removeClass(activeBox, 'is-align-left');
|
|
10019
|
+
dom$K.removeClass(activeBox, 'is-align-right');
|
|
10020
|
+
dom$K.removeClass(activeBox, 'is-align-center');
|
|
10021
|
+
dom$K.removeClass(activeBox, 'is-align-justify');
|
|
10009
10022
|
}
|
|
10010
10023
|
}
|
|
10011
10024
|
|
|
@@ -10439,6 +10452,8 @@ class EditBox {
|
|
|
10439
10452
|
|
|
10440
10453
|
}
|
|
10441
10454
|
|
|
10455
|
+
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
10456
|
+
|
|
10442
10457
|
var rangyCore = {exports: {}};
|
|
10443
10458
|
|
|
10444
10459
|
/**
|
|
@@ -18330,7 +18345,7 @@ class Dom {
|
|
|
18330
18345
|
|
|
18331
18346
|
}
|
|
18332
18347
|
|
|
18333
|
-
var js = {exports: {}};
|
|
18348
|
+
var js$1 = {exports: {}};
|
|
18334
18349
|
|
|
18335
18350
|
var src = {};
|
|
18336
18351
|
|
|
@@ -23525,9 +23540,9 @@ function get_beautify(js_beautify, css_beautify, html_beautify) {
|
|
|
23525
23540
|
|
|
23526
23541
|
})(module);
|
|
23527
23542
|
}
|
|
23528
|
-
}(js));
|
|
23543
|
+
}(js$1));
|
|
23529
23544
|
|
|
23530
|
-
var JsBeautify = js.exports;
|
|
23545
|
+
var JsBeautify = js$1.exports;
|
|
23531
23546
|
|
|
23532
23547
|
const dom$I = new Dom();
|
|
23533
23548
|
let hash$1 = {};
|
|
@@ -26081,18 +26096,31 @@ const renderQuickAdd = builder => {
|
|
|
26081
26096
|
elm = quickadd.querySelector('.add-button');
|
|
26082
26097
|
if (elm) dom$F.addEventListener(elm, 'click', () => {
|
|
26083
26098
|
const mode = quickadd.getAttribute('data-mode');
|
|
26084
|
-
|
|
26099
|
+
let html = `<div>
|
|
26085
26100
|
<a href="#" class="transition-all inline-block cursor-pointer no-underline border-2 border-solid border-transparent ml-1 mr-1 hover:border-transparent rounded bg-gray-200 hover:bg-gray-300 tracking-75 uppercase py-2 size-14 px-8 font-semibold text-gray-600">Read More</a>
|
|
26086
26101
|
</div>`;
|
|
26102
|
+
|
|
26103
|
+
if (builder.opts.emailMode) {
|
|
26104
|
+
html = '<div><a href="#" style="margin-top: ;margin-right: ;margin-bottom: ;margin-left: ;display: inline-block; text-decoration: none; transition: all 0.16s ease 0s; border-style: solid; cursor: pointer; background-color: rgb(220, 220, 220); color: rgb(0, 0, 0); border-color: rgb(220, 220, 220); border-width: 2px; border-radius: 0px; padding: 13px 28px; line-height: 21px; text-transform: uppercase; font-weight: 400; font-size: 14px; letter-spacing: 3px;">Read More</a></div>';
|
|
26105
|
+
}
|
|
26106
|
+
|
|
26087
26107
|
util.addContent(html, mode);
|
|
26088
26108
|
});
|
|
26089
26109
|
elm = quickadd.querySelector('.add-twobutton');
|
|
26090
26110
|
if (elm) dom$F.addEventListener(elm, 'click', () => {
|
|
26091
26111
|
const mode = quickadd.getAttribute('data-mode');
|
|
26092
|
-
|
|
26112
|
+
let html = `<div>
|
|
26093
26113
|
<a href="#" class="transition-all inline-block cursor-pointer no-underline border-2 border-solid border-transparent ml-1 mr-1 hover:border-transparent rounded bg-gray-200 hover:bg-gray-300 tracking-75 uppercase py-2 size-14 px-8 font-semibold text-gray-600">Read More</a>
|
|
26094
26114
|
<a href="#" class="transition-all inline-block cursor-pointer no-underline border-2 border-solid ml-1 mr-1 rounded tracking-75 uppercase py-2 size-14 px-8 border-current hover:border-transparent hover:text-white font-semibold text-indigo-500 hover:bg-indigo-500">Get Started</a>
|
|
26095
26115
|
</div>`;
|
|
26116
|
+
|
|
26117
|
+
if (builder.opts.emailMode) {
|
|
26118
|
+
html = `<div>
|
|
26119
|
+
<a href="#" style="margin-top: ;margin-right: ;margin-bottom: ;margin-left: ;display: inline-block; text-decoration: none; transition: all 0.16s ease 0s; border-style: solid; cursor: pointer; background-color: rgb(220, 220, 220); color: rgb(0, 0, 0); border-color: rgb(220, 220, 220); border-width: 2px; border-radius: 0px; padding: 13px 28px; line-height: 21px; text-transform: uppercase; font-weight: 400; font-size: 14px; letter-spacing: 3px;">Read More</a>
|
|
26120
|
+
<a href="#" style="display: inline-block; text-decoration: none; transition: all 0.16s ease 0s; border-style: solid; cursor: pointer; background-color: rgba(0, 0, 0, 0); border-color: rgb(53, 53, 53); border-width: 2px; border-radius: 0px; padding: 13px 28px; line-height: 21px; text-transform: uppercase; font-weight: 600; font-size: 14px; letter-spacing: 3px; color: rgb(53, 53, 53);">Get Started</a>
|
|
26121
|
+
</div>`;
|
|
26122
|
+
}
|
|
26123
|
+
|
|
26096
26124
|
util.addContent(html, mode);
|
|
26097
26125
|
});
|
|
26098
26126
|
elm = quickadd.querySelector('.add-spacer');
|
|
@@ -53829,6 +53857,2655 @@ function (_super) {
|
|
|
53829
53857
|
|
|
53830
53858
|
var Moveable$1 = Moveable;
|
|
53831
53859
|
|
|
53860
|
+
var loadImage = {exports: {}};
|
|
53861
|
+
|
|
53862
|
+
/*
|
|
53863
|
+
* JavaScript Load Image
|
|
53864
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
53865
|
+
*
|
|
53866
|
+
* Copyright 2011, Sebastian Tschan
|
|
53867
|
+
* https://blueimp.net
|
|
53868
|
+
*
|
|
53869
|
+
* Licensed under the MIT license:
|
|
53870
|
+
* https://opensource.org/licenses/MIT
|
|
53871
|
+
*/
|
|
53872
|
+
|
|
53873
|
+
(function (module) {
|
|
53874
|
+
(function ($) {
|
|
53875
|
+
|
|
53876
|
+
var urlAPI = $.URL || $.webkitURL;
|
|
53877
|
+
|
|
53878
|
+
/**
|
|
53879
|
+
* Creates an object URL for a given File object.
|
|
53880
|
+
*
|
|
53881
|
+
* @param {Blob} blob Blob object
|
|
53882
|
+
* @returns {string|boolean} Returns object URL if API exists, else false.
|
|
53883
|
+
*/
|
|
53884
|
+
function createObjectURL(blob) {
|
|
53885
|
+
return urlAPI ? urlAPI.createObjectURL(blob) : false
|
|
53886
|
+
}
|
|
53887
|
+
|
|
53888
|
+
/**
|
|
53889
|
+
* Revokes a given object URL.
|
|
53890
|
+
*
|
|
53891
|
+
* @param {string} url Blob object URL
|
|
53892
|
+
* @returns {undefined|boolean} Returns undefined if API exists, else false.
|
|
53893
|
+
*/
|
|
53894
|
+
function revokeObjectURL(url) {
|
|
53895
|
+
return urlAPI ? urlAPI.revokeObjectURL(url) : false
|
|
53896
|
+
}
|
|
53897
|
+
|
|
53898
|
+
/**
|
|
53899
|
+
* Helper function to revoke an object URL
|
|
53900
|
+
*
|
|
53901
|
+
* @param {string} url Blob Object URL
|
|
53902
|
+
* @param {object} [options] Options object
|
|
53903
|
+
*/
|
|
53904
|
+
function revokeHelper(url, options) {
|
|
53905
|
+
if (url && url.slice(0, 5) === 'blob:' && !(options && options.noRevoke)) {
|
|
53906
|
+
revokeObjectURL(url);
|
|
53907
|
+
}
|
|
53908
|
+
}
|
|
53909
|
+
|
|
53910
|
+
/**
|
|
53911
|
+
* Loads a given File object via FileReader interface.
|
|
53912
|
+
*
|
|
53913
|
+
* @param {Blob} file Blob object
|
|
53914
|
+
* @param {Function} onload Load event callback
|
|
53915
|
+
* @param {Function} [onerror] Error/Abort event callback
|
|
53916
|
+
* @param {string} [method=readAsDataURL] FileReader method
|
|
53917
|
+
* @returns {FileReader|boolean} Returns FileReader if API exists, else false.
|
|
53918
|
+
*/
|
|
53919
|
+
function readFile(file, onload, onerror, method) {
|
|
53920
|
+
if (!$.FileReader) return false
|
|
53921
|
+
var reader = new FileReader();
|
|
53922
|
+
reader.onload = function () {
|
|
53923
|
+
onload.call(reader, this.result);
|
|
53924
|
+
};
|
|
53925
|
+
if (onerror) {
|
|
53926
|
+
reader.onabort = reader.onerror = function () {
|
|
53927
|
+
onerror.call(reader, this.error);
|
|
53928
|
+
};
|
|
53929
|
+
}
|
|
53930
|
+
var readerMethod = reader[method || 'readAsDataURL'];
|
|
53931
|
+
if (readerMethod) {
|
|
53932
|
+
readerMethod.call(reader, file);
|
|
53933
|
+
return reader
|
|
53934
|
+
}
|
|
53935
|
+
}
|
|
53936
|
+
|
|
53937
|
+
/**
|
|
53938
|
+
* Cross-frame instanceof check.
|
|
53939
|
+
*
|
|
53940
|
+
* @param {string} type Instance type
|
|
53941
|
+
* @param {object} obj Object instance
|
|
53942
|
+
* @returns {boolean} Returns true if the object is of the given instance.
|
|
53943
|
+
*/
|
|
53944
|
+
function isInstanceOf(type, obj) {
|
|
53945
|
+
// Cross-frame instanceof check
|
|
53946
|
+
return Object.prototype.toString.call(obj) === '[object ' + type + ']'
|
|
53947
|
+
}
|
|
53948
|
+
|
|
53949
|
+
/**
|
|
53950
|
+
* @typedef { HTMLImageElement|HTMLCanvasElement } Result
|
|
53951
|
+
*/
|
|
53952
|
+
|
|
53953
|
+
/**
|
|
53954
|
+
* Loads an image for a given File object.
|
|
53955
|
+
*
|
|
53956
|
+
* @param {Blob|string} file Blob object or image URL
|
|
53957
|
+
* @param {Function|object} [callback] Image load event callback or options
|
|
53958
|
+
* @param {object} [options] Options object
|
|
53959
|
+
* @returns {HTMLImageElement|FileReader|Promise<Result>} Object
|
|
53960
|
+
*/
|
|
53961
|
+
function loadImage(file, callback, options) {
|
|
53962
|
+
/**
|
|
53963
|
+
* Promise executor
|
|
53964
|
+
*
|
|
53965
|
+
* @param {Function} resolve Resolution function
|
|
53966
|
+
* @param {Function} reject Rejection function
|
|
53967
|
+
* @returns {HTMLImageElement|FileReader} Object
|
|
53968
|
+
*/
|
|
53969
|
+
function executor(resolve, reject) {
|
|
53970
|
+
var img = document.createElement('img');
|
|
53971
|
+
var url;
|
|
53972
|
+
/**
|
|
53973
|
+
* Callback for the fetchBlob call.
|
|
53974
|
+
*
|
|
53975
|
+
* @param {HTMLImageElement|HTMLCanvasElement} img Error object
|
|
53976
|
+
* @param {object} data Data object
|
|
53977
|
+
* @returns {undefined} Undefined
|
|
53978
|
+
*/
|
|
53979
|
+
function resolveWrapper(img, data) {
|
|
53980
|
+
if (resolve === reject) {
|
|
53981
|
+
// Not using Promises
|
|
53982
|
+
if (resolve) resolve(img, data);
|
|
53983
|
+
return
|
|
53984
|
+
} else if (img instanceof Error) {
|
|
53985
|
+
reject(img);
|
|
53986
|
+
return
|
|
53987
|
+
}
|
|
53988
|
+
data = data || {}; // eslint-disable-line no-param-reassign
|
|
53989
|
+
data.image = img;
|
|
53990
|
+
resolve(data);
|
|
53991
|
+
}
|
|
53992
|
+
/**
|
|
53993
|
+
* Callback for the fetchBlob call.
|
|
53994
|
+
*
|
|
53995
|
+
* @param {Blob} blob Blob object
|
|
53996
|
+
* @param {Error} err Error object
|
|
53997
|
+
*/
|
|
53998
|
+
function fetchBlobCallback(blob, err) {
|
|
53999
|
+
if (err && $.console) console.log(err); // eslint-disable-line no-console
|
|
54000
|
+
if (blob && isInstanceOf('Blob', blob)) {
|
|
54001
|
+
file = blob; // eslint-disable-line no-param-reassign
|
|
54002
|
+
url = createObjectURL(file);
|
|
54003
|
+
} else {
|
|
54004
|
+
url = file;
|
|
54005
|
+
if (options && options.crossOrigin) {
|
|
54006
|
+
img.crossOrigin = options.crossOrigin;
|
|
54007
|
+
}
|
|
54008
|
+
}
|
|
54009
|
+
img.src = url;
|
|
54010
|
+
}
|
|
54011
|
+
img.onerror = function (event) {
|
|
54012
|
+
revokeHelper(url, options);
|
|
54013
|
+
if (reject) reject.call(img, event);
|
|
54014
|
+
};
|
|
54015
|
+
img.onload = function () {
|
|
54016
|
+
revokeHelper(url, options);
|
|
54017
|
+
var data = {
|
|
54018
|
+
originalWidth: img.naturalWidth || img.width,
|
|
54019
|
+
originalHeight: img.naturalHeight || img.height
|
|
54020
|
+
};
|
|
54021
|
+
try {
|
|
54022
|
+
loadImage.transform(img, options, resolveWrapper, file, data);
|
|
54023
|
+
} catch (error) {
|
|
54024
|
+
if (reject) reject(error);
|
|
54025
|
+
}
|
|
54026
|
+
};
|
|
54027
|
+
if (typeof file === 'string') {
|
|
54028
|
+
if (loadImage.requiresMetaData(options)) {
|
|
54029
|
+
loadImage.fetchBlob(file, fetchBlobCallback, options);
|
|
54030
|
+
} else {
|
|
54031
|
+
fetchBlobCallback();
|
|
54032
|
+
}
|
|
54033
|
+
return img
|
|
54034
|
+
} else if (isInstanceOf('Blob', file) || isInstanceOf('File', file)) {
|
|
54035
|
+
url = createObjectURL(file);
|
|
54036
|
+
if (url) {
|
|
54037
|
+
img.src = url;
|
|
54038
|
+
return img
|
|
54039
|
+
}
|
|
54040
|
+
return readFile(
|
|
54041
|
+
file,
|
|
54042
|
+
function (url) {
|
|
54043
|
+
img.src = url;
|
|
54044
|
+
},
|
|
54045
|
+
reject
|
|
54046
|
+
)
|
|
54047
|
+
}
|
|
54048
|
+
}
|
|
54049
|
+
if ($.Promise && typeof callback !== 'function') {
|
|
54050
|
+
options = callback; // eslint-disable-line no-param-reassign
|
|
54051
|
+
return new Promise(executor)
|
|
54052
|
+
}
|
|
54053
|
+
return executor(callback, callback)
|
|
54054
|
+
}
|
|
54055
|
+
|
|
54056
|
+
// Determines if metadata should be loaded automatically.
|
|
54057
|
+
// Requires the load image meta extension to load metadata.
|
|
54058
|
+
loadImage.requiresMetaData = function (options) {
|
|
54059
|
+
return options && options.meta
|
|
54060
|
+
};
|
|
54061
|
+
|
|
54062
|
+
// If the callback given to this function returns a blob, it is used as image
|
|
54063
|
+
// source instead of the original url and overrides the file argument used in
|
|
54064
|
+
// the onload and onerror event callbacks:
|
|
54065
|
+
loadImage.fetchBlob = function (url, callback) {
|
|
54066
|
+
callback();
|
|
54067
|
+
};
|
|
54068
|
+
|
|
54069
|
+
loadImage.transform = function (img, options, callback, file, data) {
|
|
54070
|
+
callback(img, data);
|
|
54071
|
+
};
|
|
54072
|
+
|
|
54073
|
+
loadImage.global = $;
|
|
54074
|
+
loadImage.readFile = readFile;
|
|
54075
|
+
loadImage.isInstanceOf = isInstanceOf;
|
|
54076
|
+
loadImage.createObjectURL = createObjectURL;
|
|
54077
|
+
loadImage.revokeObjectURL = revokeObjectURL;
|
|
54078
|
+
|
|
54079
|
+
if (module.exports) {
|
|
54080
|
+
module.exports = loadImage;
|
|
54081
|
+
} else {
|
|
54082
|
+
$.loadImage = loadImage;
|
|
54083
|
+
}
|
|
54084
|
+
})((typeof window !== 'undefined' && window) || commonjsGlobal);
|
|
54085
|
+
}(loadImage));
|
|
54086
|
+
|
|
54087
|
+
var loadImageScale = {exports: {}};
|
|
54088
|
+
|
|
54089
|
+
/*
|
|
54090
|
+
* JavaScript Load Image Scaling
|
|
54091
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
54092
|
+
*
|
|
54093
|
+
* Copyright 2011, Sebastian Tschan
|
|
54094
|
+
* https://blueimp.net
|
|
54095
|
+
*
|
|
54096
|
+
* Licensed under the MIT license:
|
|
54097
|
+
* https://opensource.org/licenses/MIT
|
|
54098
|
+
*/
|
|
54099
|
+
|
|
54100
|
+
(function (module) {
|
|
54101
|
+
(function (factory) {
|
|
54102
|
+
if (module.exports) {
|
|
54103
|
+
factory(loadImage.exports);
|
|
54104
|
+
} else {
|
|
54105
|
+
// Browser globals:
|
|
54106
|
+
factory(window.loadImage);
|
|
54107
|
+
}
|
|
54108
|
+
})(function (loadImage) {
|
|
54109
|
+
|
|
54110
|
+
var originalTransform = loadImage.transform;
|
|
54111
|
+
|
|
54112
|
+
loadImage.createCanvas = function (width, height, offscreen) {
|
|
54113
|
+
if (offscreen && loadImage.global.OffscreenCanvas) {
|
|
54114
|
+
return new OffscreenCanvas(width, height)
|
|
54115
|
+
}
|
|
54116
|
+
var canvas = document.createElement('canvas');
|
|
54117
|
+
canvas.width = width;
|
|
54118
|
+
canvas.height = height;
|
|
54119
|
+
return canvas
|
|
54120
|
+
};
|
|
54121
|
+
|
|
54122
|
+
loadImage.transform = function (img, options, callback, file, data) {
|
|
54123
|
+
originalTransform.call(
|
|
54124
|
+
loadImage,
|
|
54125
|
+
loadImage.scale(img, options, data),
|
|
54126
|
+
options,
|
|
54127
|
+
callback,
|
|
54128
|
+
file,
|
|
54129
|
+
data
|
|
54130
|
+
);
|
|
54131
|
+
};
|
|
54132
|
+
|
|
54133
|
+
// Transform image coordinates, allows to override e.g.
|
|
54134
|
+
// the canvas orientation based on the orientation option,
|
|
54135
|
+
// gets canvas, options and data passed as arguments:
|
|
54136
|
+
loadImage.transformCoordinates = function () {};
|
|
54137
|
+
|
|
54138
|
+
// Returns transformed options, allows to override e.g.
|
|
54139
|
+
// maxWidth, maxHeight and crop options based on the aspectRatio.
|
|
54140
|
+
// gets img, options, data passed as arguments:
|
|
54141
|
+
loadImage.getTransformedOptions = function (img, options) {
|
|
54142
|
+
var aspectRatio = options.aspectRatio;
|
|
54143
|
+
var newOptions;
|
|
54144
|
+
var i;
|
|
54145
|
+
var width;
|
|
54146
|
+
var height;
|
|
54147
|
+
if (!aspectRatio) {
|
|
54148
|
+
return options
|
|
54149
|
+
}
|
|
54150
|
+
newOptions = {};
|
|
54151
|
+
for (i in options) {
|
|
54152
|
+
if (Object.prototype.hasOwnProperty.call(options, i)) {
|
|
54153
|
+
newOptions[i] = options[i];
|
|
54154
|
+
}
|
|
54155
|
+
}
|
|
54156
|
+
newOptions.crop = true;
|
|
54157
|
+
width = img.naturalWidth || img.width;
|
|
54158
|
+
height = img.naturalHeight || img.height;
|
|
54159
|
+
if (width / height > aspectRatio) {
|
|
54160
|
+
newOptions.maxWidth = height * aspectRatio;
|
|
54161
|
+
newOptions.maxHeight = height;
|
|
54162
|
+
} else {
|
|
54163
|
+
newOptions.maxWidth = width;
|
|
54164
|
+
newOptions.maxHeight = width / aspectRatio;
|
|
54165
|
+
}
|
|
54166
|
+
return newOptions
|
|
54167
|
+
};
|
|
54168
|
+
|
|
54169
|
+
// Canvas render method, allows to implement a different rendering algorithm:
|
|
54170
|
+
loadImage.drawImage = function (
|
|
54171
|
+
img,
|
|
54172
|
+
canvas,
|
|
54173
|
+
sourceX,
|
|
54174
|
+
sourceY,
|
|
54175
|
+
sourceWidth,
|
|
54176
|
+
sourceHeight,
|
|
54177
|
+
destWidth,
|
|
54178
|
+
destHeight,
|
|
54179
|
+
options
|
|
54180
|
+
) {
|
|
54181
|
+
var ctx = canvas.getContext('2d');
|
|
54182
|
+
if (options.imageSmoothingEnabled === false) {
|
|
54183
|
+
ctx.msImageSmoothingEnabled = false;
|
|
54184
|
+
ctx.imageSmoothingEnabled = false;
|
|
54185
|
+
} else if (options.imageSmoothingQuality) {
|
|
54186
|
+
ctx.imageSmoothingQuality = options.imageSmoothingQuality;
|
|
54187
|
+
}
|
|
54188
|
+
ctx.drawImage(
|
|
54189
|
+
img,
|
|
54190
|
+
sourceX,
|
|
54191
|
+
sourceY,
|
|
54192
|
+
sourceWidth,
|
|
54193
|
+
sourceHeight,
|
|
54194
|
+
0,
|
|
54195
|
+
0,
|
|
54196
|
+
destWidth,
|
|
54197
|
+
destHeight
|
|
54198
|
+
);
|
|
54199
|
+
return ctx
|
|
54200
|
+
};
|
|
54201
|
+
|
|
54202
|
+
// Determines if the target image should be a canvas element:
|
|
54203
|
+
loadImage.requiresCanvas = function (options) {
|
|
54204
|
+
return options.canvas || options.crop || !!options.aspectRatio
|
|
54205
|
+
};
|
|
54206
|
+
|
|
54207
|
+
// Scales and/or crops the given image (img or canvas HTML element)
|
|
54208
|
+
// using the given options:
|
|
54209
|
+
loadImage.scale = function (img, options, data) {
|
|
54210
|
+
// eslint-disable-next-line no-param-reassign
|
|
54211
|
+
options = options || {};
|
|
54212
|
+
// eslint-disable-next-line no-param-reassign
|
|
54213
|
+
data = data || {};
|
|
54214
|
+
var useCanvas =
|
|
54215
|
+
img.getContext ||
|
|
54216
|
+
(loadImage.requiresCanvas(options) &&
|
|
54217
|
+
!!loadImage.global.HTMLCanvasElement);
|
|
54218
|
+
var width = img.naturalWidth || img.width;
|
|
54219
|
+
var height = img.naturalHeight || img.height;
|
|
54220
|
+
var destWidth = width;
|
|
54221
|
+
var destHeight = height;
|
|
54222
|
+
var maxWidth;
|
|
54223
|
+
var maxHeight;
|
|
54224
|
+
var minWidth;
|
|
54225
|
+
var minHeight;
|
|
54226
|
+
var sourceWidth;
|
|
54227
|
+
var sourceHeight;
|
|
54228
|
+
var sourceX;
|
|
54229
|
+
var sourceY;
|
|
54230
|
+
var pixelRatio;
|
|
54231
|
+
var downsamplingRatio;
|
|
54232
|
+
var tmp;
|
|
54233
|
+
var canvas;
|
|
54234
|
+
/**
|
|
54235
|
+
* Scales up image dimensions
|
|
54236
|
+
*/
|
|
54237
|
+
function scaleUp() {
|
|
54238
|
+
var scale = Math.max(
|
|
54239
|
+
(minWidth || destWidth) / destWidth,
|
|
54240
|
+
(minHeight || destHeight) / destHeight
|
|
54241
|
+
);
|
|
54242
|
+
if (scale > 1) {
|
|
54243
|
+
destWidth *= scale;
|
|
54244
|
+
destHeight *= scale;
|
|
54245
|
+
}
|
|
54246
|
+
}
|
|
54247
|
+
/**
|
|
54248
|
+
* Scales down image dimensions
|
|
54249
|
+
*/
|
|
54250
|
+
function scaleDown() {
|
|
54251
|
+
var scale = Math.min(
|
|
54252
|
+
(maxWidth || destWidth) / destWidth,
|
|
54253
|
+
(maxHeight || destHeight) / destHeight
|
|
54254
|
+
);
|
|
54255
|
+
if (scale < 1) {
|
|
54256
|
+
destWidth *= scale;
|
|
54257
|
+
destHeight *= scale;
|
|
54258
|
+
}
|
|
54259
|
+
}
|
|
54260
|
+
if (useCanvas) {
|
|
54261
|
+
// eslint-disable-next-line no-param-reassign
|
|
54262
|
+
options = loadImage.getTransformedOptions(img, options, data);
|
|
54263
|
+
sourceX = options.left || 0;
|
|
54264
|
+
sourceY = options.top || 0;
|
|
54265
|
+
if (options.sourceWidth) {
|
|
54266
|
+
sourceWidth = options.sourceWidth;
|
|
54267
|
+
if (options.right !== undefined && options.left === undefined) {
|
|
54268
|
+
sourceX = width - sourceWidth - options.right;
|
|
54269
|
+
}
|
|
54270
|
+
} else {
|
|
54271
|
+
sourceWidth = width - sourceX - (options.right || 0);
|
|
54272
|
+
}
|
|
54273
|
+
if (options.sourceHeight) {
|
|
54274
|
+
sourceHeight = options.sourceHeight;
|
|
54275
|
+
if (options.bottom !== undefined && options.top === undefined) {
|
|
54276
|
+
sourceY = height - sourceHeight - options.bottom;
|
|
54277
|
+
}
|
|
54278
|
+
} else {
|
|
54279
|
+
sourceHeight = height - sourceY - (options.bottom || 0);
|
|
54280
|
+
}
|
|
54281
|
+
destWidth = sourceWidth;
|
|
54282
|
+
destHeight = sourceHeight;
|
|
54283
|
+
}
|
|
54284
|
+
maxWidth = options.maxWidth;
|
|
54285
|
+
maxHeight = options.maxHeight;
|
|
54286
|
+
minWidth = options.minWidth;
|
|
54287
|
+
minHeight = options.minHeight;
|
|
54288
|
+
if (useCanvas && maxWidth && maxHeight && options.crop) {
|
|
54289
|
+
destWidth = maxWidth;
|
|
54290
|
+
destHeight = maxHeight;
|
|
54291
|
+
tmp = sourceWidth / sourceHeight - maxWidth / maxHeight;
|
|
54292
|
+
if (tmp < 0) {
|
|
54293
|
+
sourceHeight = (maxHeight * sourceWidth) / maxWidth;
|
|
54294
|
+
if (options.top === undefined && options.bottom === undefined) {
|
|
54295
|
+
sourceY = (height - sourceHeight) / 2;
|
|
54296
|
+
}
|
|
54297
|
+
} else if (tmp > 0) {
|
|
54298
|
+
sourceWidth = (maxWidth * sourceHeight) / maxHeight;
|
|
54299
|
+
if (options.left === undefined && options.right === undefined) {
|
|
54300
|
+
sourceX = (width - sourceWidth) / 2;
|
|
54301
|
+
}
|
|
54302
|
+
}
|
|
54303
|
+
} else {
|
|
54304
|
+
if (options.contain || options.cover) {
|
|
54305
|
+
minWidth = maxWidth = maxWidth || minWidth;
|
|
54306
|
+
minHeight = maxHeight = maxHeight || minHeight;
|
|
54307
|
+
}
|
|
54308
|
+
if (options.cover) {
|
|
54309
|
+
scaleDown();
|
|
54310
|
+
scaleUp();
|
|
54311
|
+
} else {
|
|
54312
|
+
scaleUp();
|
|
54313
|
+
scaleDown();
|
|
54314
|
+
}
|
|
54315
|
+
}
|
|
54316
|
+
if (useCanvas) {
|
|
54317
|
+
pixelRatio = options.pixelRatio;
|
|
54318
|
+
if (
|
|
54319
|
+
pixelRatio > 1 &&
|
|
54320
|
+
// Check if the image has not yet had the device pixel ratio applied:
|
|
54321
|
+
!(
|
|
54322
|
+
img.style.width &&
|
|
54323
|
+
Math.floor(parseFloat(img.style.width, 10)) ===
|
|
54324
|
+
Math.floor(width / pixelRatio)
|
|
54325
|
+
)
|
|
54326
|
+
) {
|
|
54327
|
+
destWidth *= pixelRatio;
|
|
54328
|
+
destHeight *= pixelRatio;
|
|
54329
|
+
}
|
|
54330
|
+
// Check if workaround for Chromium orientation crop bug is required:
|
|
54331
|
+
// https://bugs.chromium.org/p/chromium/issues/detail?id=1074354
|
|
54332
|
+
if (
|
|
54333
|
+
loadImage.orientationCropBug &&
|
|
54334
|
+
!img.getContext &&
|
|
54335
|
+
(sourceX || sourceY || sourceWidth !== width || sourceHeight !== height)
|
|
54336
|
+
) {
|
|
54337
|
+
// Write the complete source image to an intermediate canvas first:
|
|
54338
|
+
tmp = img;
|
|
54339
|
+
// eslint-disable-next-line no-param-reassign
|
|
54340
|
+
img = loadImage.createCanvas(width, height, true);
|
|
54341
|
+
loadImage.drawImage(
|
|
54342
|
+
tmp,
|
|
54343
|
+
img,
|
|
54344
|
+
0,
|
|
54345
|
+
0,
|
|
54346
|
+
width,
|
|
54347
|
+
height,
|
|
54348
|
+
width,
|
|
54349
|
+
height,
|
|
54350
|
+
options
|
|
54351
|
+
);
|
|
54352
|
+
}
|
|
54353
|
+
downsamplingRatio = options.downsamplingRatio;
|
|
54354
|
+
if (
|
|
54355
|
+
downsamplingRatio > 0 &&
|
|
54356
|
+
downsamplingRatio < 1 &&
|
|
54357
|
+
destWidth < sourceWidth &&
|
|
54358
|
+
destHeight < sourceHeight
|
|
54359
|
+
) {
|
|
54360
|
+
while (sourceWidth * downsamplingRatio > destWidth) {
|
|
54361
|
+
canvas = loadImage.createCanvas(
|
|
54362
|
+
sourceWidth * downsamplingRatio,
|
|
54363
|
+
sourceHeight * downsamplingRatio,
|
|
54364
|
+
true
|
|
54365
|
+
);
|
|
54366
|
+
loadImage.drawImage(
|
|
54367
|
+
img,
|
|
54368
|
+
canvas,
|
|
54369
|
+
sourceX,
|
|
54370
|
+
sourceY,
|
|
54371
|
+
sourceWidth,
|
|
54372
|
+
sourceHeight,
|
|
54373
|
+
canvas.width,
|
|
54374
|
+
canvas.height,
|
|
54375
|
+
options
|
|
54376
|
+
);
|
|
54377
|
+
sourceX = 0;
|
|
54378
|
+
sourceY = 0;
|
|
54379
|
+
sourceWidth = canvas.width;
|
|
54380
|
+
sourceHeight = canvas.height;
|
|
54381
|
+
// eslint-disable-next-line no-param-reassign
|
|
54382
|
+
img = canvas;
|
|
54383
|
+
}
|
|
54384
|
+
}
|
|
54385
|
+
canvas = loadImage.createCanvas(destWidth, destHeight);
|
|
54386
|
+
loadImage.transformCoordinates(canvas, options, data);
|
|
54387
|
+
if (pixelRatio > 1) {
|
|
54388
|
+
canvas.style.width = canvas.width / pixelRatio + 'px';
|
|
54389
|
+
}
|
|
54390
|
+
loadImage
|
|
54391
|
+
.drawImage(
|
|
54392
|
+
img,
|
|
54393
|
+
canvas,
|
|
54394
|
+
sourceX,
|
|
54395
|
+
sourceY,
|
|
54396
|
+
sourceWidth,
|
|
54397
|
+
sourceHeight,
|
|
54398
|
+
destWidth,
|
|
54399
|
+
destHeight,
|
|
54400
|
+
options
|
|
54401
|
+
)
|
|
54402
|
+
.setTransform(1, 0, 0, 1, 0, 0); // reset to the identity matrix
|
|
54403
|
+
return canvas
|
|
54404
|
+
}
|
|
54405
|
+
img.width = destWidth;
|
|
54406
|
+
img.height = destHeight;
|
|
54407
|
+
return img
|
|
54408
|
+
};
|
|
54409
|
+
});
|
|
54410
|
+
}(loadImageScale));
|
|
54411
|
+
|
|
54412
|
+
var loadImageMeta = {exports: {}};
|
|
54413
|
+
|
|
54414
|
+
/*
|
|
54415
|
+
* JavaScript Load Image Meta
|
|
54416
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
54417
|
+
*
|
|
54418
|
+
* Copyright 2013, Sebastian Tschan
|
|
54419
|
+
* https://blueimp.net
|
|
54420
|
+
*
|
|
54421
|
+
* Image metadata handling implementation
|
|
54422
|
+
* based on the help and contribution of
|
|
54423
|
+
* Achim Stöhr.
|
|
54424
|
+
*
|
|
54425
|
+
* Licensed under the MIT license:
|
|
54426
|
+
* https://opensource.org/licenses/MIT
|
|
54427
|
+
*/
|
|
54428
|
+
|
|
54429
|
+
(function (module) {
|
|
54430
|
+
(function (factory) {
|
|
54431
|
+
if (module.exports) {
|
|
54432
|
+
factory(loadImage.exports);
|
|
54433
|
+
} else {
|
|
54434
|
+
// Browser globals:
|
|
54435
|
+
factory(window.loadImage);
|
|
54436
|
+
}
|
|
54437
|
+
})(function (loadImage) {
|
|
54438
|
+
|
|
54439
|
+
var global = loadImage.global;
|
|
54440
|
+
var originalTransform = loadImage.transform;
|
|
54441
|
+
|
|
54442
|
+
var blobSlice =
|
|
54443
|
+
global.Blob &&
|
|
54444
|
+
(Blob.prototype.slice ||
|
|
54445
|
+
Blob.prototype.webkitSlice ||
|
|
54446
|
+
Blob.prototype.mozSlice);
|
|
54447
|
+
|
|
54448
|
+
var bufferSlice =
|
|
54449
|
+
(global.ArrayBuffer && ArrayBuffer.prototype.slice) ||
|
|
54450
|
+
function (begin, end) {
|
|
54451
|
+
// Polyfill for IE10, which does not support ArrayBuffer.slice
|
|
54452
|
+
// eslint-disable-next-line no-param-reassign
|
|
54453
|
+
end = end || this.byteLength - begin;
|
|
54454
|
+
var arr1 = new Uint8Array(this, begin, end);
|
|
54455
|
+
var arr2 = new Uint8Array(end);
|
|
54456
|
+
arr2.set(arr1);
|
|
54457
|
+
return arr2.buffer
|
|
54458
|
+
};
|
|
54459
|
+
|
|
54460
|
+
var metaDataParsers = {
|
|
54461
|
+
jpeg: {
|
|
54462
|
+
0xffe1: [], // APP1 marker
|
|
54463
|
+
0xffed: [] // APP13 marker
|
|
54464
|
+
}
|
|
54465
|
+
};
|
|
54466
|
+
|
|
54467
|
+
/**
|
|
54468
|
+
* Parses image metadata and calls the callback with an object argument
|
|
54469
|
+
* with the following property:
|
|
54470
|
+
* - imageHead: The complete image head as ArrayBuffer
|
|
54471
|
+
* The options argument accepts an object and supports the following
|
|
54472
|
+
* properties:
|
|
54473
|
+
* - maxMetaDataSize: Defines the maximum number of bytes to parse.
|
|
54474
|
+
* - disableImageHead: Disables creating the imageHead property.
|
|
54475
|
+
*
|
|
54476
|
+
* @param {Blob} file Blob object
|
|
54477
|
+
* @param {Function} [callback] Callback function
|
|
54478
|
+
* @param {object} [options] Parsing options
|
|
54479
|
+
* @param {object} [data] Result data object
|
|
54480
|
+
* @returns {Promise<object>|undefined} Returns Promise if no callback given.
|
|
54481
|
+
*/
|
|
54482
|
+
function parseMetaData(file, callback, options, data) {
|
|
54483
|
+
var that = this;
|
|
54484
|
+
/**
|
|
54485
|
+
* Promise executor
|
|
54486
|
+
*
|
|
54487
|
+
* @param {Function} resolve Resolution function
|
|
54488
|
+
* @param {Function} reject Rejection function
|
|
54489
|
+
* @returns {undefined} Undefined
|
|
54490
|
+
*/
|
|
54491
|
+
function executor(resolve, reject) {
|
|
54492
|
+
if (
|
|
54493
|
+
!(
|
|
54494
|
+
global.DataView &&
|
|
54495
|
+
blobSlice &&
|
|
54496
|
+
file &&
|
|
54497
|
+
file.size >= 12 &&
|
|
54498
|
+
file.type === 'image/jpeg'
|
|
54499
|
+
)
|
|
54500
|
+
) {
|
|
54501
|
+
// Nothing to parse
|
|
54502
|
+
return resolve(data)
|
|
54503
|
+
}
|
|
54504
|
+
// 256 KiB should contain all EXIF/ICC/IPTC segments:
|
|
54505
|
+
var maxMetaDataSize = options.maxMetaDataSize || 262144;
|
|
54506
|
+
if (
|
|
54507
|
+
!loadImage.readFile(
|
|
54508
|
+
blobSlice.call(file, 0, maxMetaDataSize),
|
|
54509
|
+
function (buffer) {
|
|
54510
|
+
// Note on endianness:
|
|
54511
|
+
// Since the marker and length bytes in JPEG files are always
|
|
54512
|
+
// stored in big endian order, we can leave the endian parameter
|
|
54513
|
+
// of the DataView methods undefined, defaulting to big endian.
|
|
54514
|
+
var dataView = new DataView(buffer);
|
|
54515
|
+
// Check for the JPEG marker (0xffd8):
|
|
54516
|
+
if (dataView.getUint16(0) !== 0xffd8) {
|
|
54517
|
+
return reject(
|
|
54518
|
+
new Error('Invalid JPEG file: Missing JPEG marker.')
|
|
54519
|
+
)
|
|
54520
|
+
}
|
|
54521
|
+
var offset = 2;
|
|
54522
|
+
var maxOffset = dataView.byteLength - 4;
|
|
54523
|
+
var headLength = offset;
|
|
54524
|
+
var markerBytes;
|
|
54525
|
+
var markerLength;
|
|
54526
|
+
var parsers;
|
|
54527
|
+
var i;
|
|
54528
|
+
while (offset < maxOffset) {
|
|
54529
|
+
markerBytes = dataView.getUint16(offset);
|
|
54530
|
+
// Search for APPn (0xffeN) and COM (0xfffe) markers,
|
|
54531
|
+
// which contain application-specific metadata like
|
|
54532
|
+
// Exif, ICC and IPTC data and text comments:
|
|
54533
|
+
if (
|
|
54534
|
+
(markerBytes >= 0xffe0 && markerBytes <= 0xffef) ||
|
|
54535
|
+
markerBytes === 0xfffe
|
|
54536
|
+
) {
|
|
54537
|
+
// The marker bytes (2) are always followed by
|
|
54538
|
+
// the length bytes (2), indicating the length of the
|
|
54539
|
+
// marker segment, which includes the length bytes,
|
|
54540
|
+
// but not the marker bytes, so we add 2:
|
|
54541
|
+
markerLength = dataView.getUint16(offset + 2) + 2;
|
|
54542
|
+
if (offset + markerLength > dataView.byteLength) {
|
|
54543
|
+
// eslint-disable-next-line no-console
|
|
54544
|
+
console.log('Invalid JPEG metadata: Invalid segment size.');
|
|
54545
|
+
break
|
|
54546
|
+
}
|
|
54547
|
+
parsers = metaDataParsers.jpeg[markerBytes];
|
|
54548
|
+
if (parsers && !options.disableMetaDataParsers) {
|
|
54549
|
+
for (i = 0; i < parsers.length; i += 1) {
|
|
54550
|
+
parsers[i].call(
|
|
54551
|
+
that,
|
|
54552
|
+
dataView,
|
|
54553
|
+
offset,
|
|
54554
|
+
markerLength,
|
|
54555
|
+
data,
|
|
54556
|
+
options
|
|
54557
|
+
);
|
|
54558
|
+
}
|
|
54559
|
+
}
|
|
54560
|
+
offset += markerLength;
|
|
54561
|
+
headLength = offset;
|
|
54562
|
+
} else {
|
|
54563
|
+
// Not an APPn or COM marker, probably safe to
|
|
54564
|
+
// assume that this is the end of the metadata
|
|
54565
|
+
break
|
|
54566
|
+
}
|
|
54567
|
+
}
|
|
54568
|
+
// Meta length must be longer than JPEG marker (2)
|
|
54569
|
+
// plus APPn marker (2), followed by length bytes (2):
|
|
54570
|
+
if (!options.disableImageHead && headLength > 6) {
|
|
54571
|
+
data.imageHead = bufferSlice.call(buffer, 0, headLength);
|
|
54572
|
+
}
|
|
54573
|
+
resolve(data);
|
|
54574
|
+
},
|
|
54575
|
+
reject,
|
|
54576
|
+
'readAsArrayBuffer'
|
|
54577
|
+
)
|
|
54578
|
+
) {
|
|
54579
|
+
// No support for the FileReader interface, nothing to parse
|
|
54580
|
+
resolve(data);
|
|
54581
|
+
}
|
|
54582
|
+
}
|
|
54583
|
+
options = options || {}; // eslint-disable-line no-param-reassign
|
|
54584
|
+
if (global.Promise && typeof callback !== 'function') {
|
|
54585
|
+
options = callback || {}; // eslint-disable-line no-param-reassign
|
|
54586
|
+
data = options; // eslint-disable-line no-param-reassign
|
|
54587
|
+
return new Promise(executor)
|
|
54588
|
+
}
|
|
54589
|
+
data = data || {}; // eslint-disable-line no-param-reassign
|
|
54590
|
+
return executor(callback, callback)
|
|
54591
|
+
}
|
|
54592
|
+
|
|
54593
|
+
/**
|
|
54594
|
+
* Replaces the head of a JPEG Blob
|
|
54595
|
+
*
|
|
54596
|
+
* @param {Blob} blob Blob object
|
|
54597
|
+
* @param {ArrayBuffer} oldHead Old JPEG head
|
|
54598
|
+
* @param {ArrayBuffer} newHead New JPEG head
|
|
54599
|
+
* @returns {Blob} Combined Blob
|
|
54600
|
+
*/
|
|
54601
|
+
function replaceJPEGHead(blob, oldHead, newHead) {
|
|
54602
|
+
if (!blob || !oldHead || !newHead) return null
|
|
54603
|
+
return new Blob([newHead, blobSlice.call(blob, oldHead.byteLength)], {
|
|
54604
|
+
type: 'image/jpeg'
|
|
54605
|
+
})
|
|
54606
|
+
}
|
|
54607
|
+
|
|
54608
|
+
/**
|
|
54609
|
+
* Replaces the image head of a JPEG blob with the given one.
|
|
54610
|
+
* Returns a Promise or calls the callback with the new Blob.
|
|
54611
|
+
*
|
|
54612
|
+
* @param {Blob} blob Blob object
|
|
54613
|
+
* @param {ArrayBuffer} head New JPEG head
|
|
54614
|
+
* @param {Function} [callback] Callback function
|
|
54615
|
+
* @returns {Promise<Blob|null>|undefined} Combined Blob
|
|
54616
|
+
*/
|
|
54617
|
+
function replaceHead(blob, head, callback) {
|
|
54618
|
+
var options = { maxMetaDataSize: 1024, disableMetaDataParsers: true };
|
|
54619
|
+
if (!callback && global.Promise) {
|
|
54620
|
+
return parseMetaData(blob, options).then(function (data) {
|
|
54621
|
+
return replaceJPEGHead(blob, data.imageHead, head)
|
|
54622
|
+
})
|
|
54623
|
+
}
|
|
54624
|
+
parseMetaData(
|
|
54625
|
+
blob,
|
|
54626
|
+
function (data) {
|
|
54627
|
+
callback(replaceJPEGHead(blob, data.imageHead, head));
|
|
54628
|
+
},
|
|
54629
|
+
options
|
|
54630
|
+
);
|
|
54631
|
+
}
|
|
54632
|
+
|
|
54633
|
+
loadImage.transform = function (img, options, callback, file, data) {
|
|
54634
|
+
if (loadImage.requiresMetaData(options)) {
|
|
54635
|
+
data = data || {}; // eslint-disable-line no-param-reassign
|
|
54636
|
+
parseMetaData(
|
|
54637
|
+
file,
|
|
54638
|
+
function (result) {
|
|
54639
|
+
if (result !== data) {
|
|
54640
|
+
// eslint-disable-next-line no-console
|
|
54641
|
+
if (global.console) console.log(result);
|
|
54642
|
+
result = data; // eslint-disable-line no-param-reassign
|
|
54643
|
+
}
|
|
54644
|
+
originalTransform.call(
|
|
54645
|
+
loadImage,
|
|
54646
|
+
img,
|
|
54647
|
+
options,
|
|
54648
|
+
callback,
|
|
54649
|
+
file,
|
|
54650
|
+
result
|
|
54651
|
+
);
|
|
54652
|
+
},
|
|
54653
|
+
options,
|
|
54654
|
+
data
|
|
54655
|
+
);
|
|
54656
|
+
} else {
|
|
54657
|
+
originalTransform.apply(loadImage, arguments);
|
|
54658
|
+
}
|
|
54659
|
+
};
|
|
54660
|
+
|
|
54661
|
+
loadImage.blobSlice = blobSlice;
|
|
54662
|
+
loadImage.bufferSlice = bufferSlice;
|
|
54663
|
+
loadImage.replaceHead = replaceHead;
|
|
54664
|
+
loadImage.parseMetaData = parseMetaData;
|
|
54665
|
+
loadImage.metaDataParsers = metaDataParsers;
|
|
54666
|
+
});
|
|
54667
|
+
}(loadImageMeta));
|
|
54668
|
+
|
|
54669
|
+
var loadImageFetch = {exports: {}};
|
|
54670
|
+
|
|
54671
|
+
/*
|
|
54672
|
+
* JavaScript Load Image Fetch
|
|
54673
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
54674
|
+
*
|
|
54675
|
+
* Copyright 2017, Sebastian Tschan
|
|
54676
|
+
* https://blueimp.net
|
|
54677
|
+
*
|
|
54678
|
+
* Licensed under the MIT license:
|
|
54679
|
+
* https://opensource.org/licenses/MIT
|
|
54680
|
+
*/
|
|
54681
|
+
|
|
54682
|
+
(function (module) {
|
|
54683
|
+
(function (factory) {
|
|
54684
|
+
if (module.exports) {
|
|
54685
|
+
factory(loadImage.exports);
|
|
54686
|
+
} else {
|
|
54687
|
+
// Browser globals:
|
|
54688
|
+
factory(window.loadImage);
|
|
54689
|
+
}
|
|
54690
|
+
})(function (loadImage) {
|
|
54691
|
+
|
|
54692
|
+
var global = loadImage.global;
|
|
54693
|
+
|
|
54694
|
+
if (
|
|
54695
|
+
global.fetch &&
|
|
54696
|
+
global.Request &&
|
|
54697
|
+
global.Response &&
|
|
54698
|
+
global.Response.prototype.blob
|
|
54699
|
+
) {
|
|
54700
|
+
loadImage.fetchBlob = function (url, callback, options) {
|
|
54701
|
+
/**
|
|
54702
|
+
* Fetch response handler.
|
|
54703
|
+
*
|
|
54704
|
+
* @param {Response} response Fetch response
|
|
54705
|
+
* @returns {Blob} Fetched Blob.
|
|
54706
|
+
*/
|
|
54707
|
+
function responseHandler(response) {
|
|
54708
|
+
return response.blob()
|
|
54709
|
+
}
|
|
54710
|
+
if (global.Promise && typeof callback !== 'function') {
|
|
54711
|
+
return fetch(new Request(url, callback)).then(responseHandler)
|
|
54712
|
+
}
|
|
54713
|
+
fetch(new Request(url, options))
|
|
54714
|
+
.then(responseHandler)
|
|
54715
|
+
.then(callback)
|
|
54716
|
+
[
|
|
54717
|
+
// Avoid parsing error in IE<9, where catch is a reserved word.
|
|
54718
|
+
// eslint-disable-next-line dot-notation
|
|
54719
|
+
'catch'
|
|
54720
|
+
](function (err) {
|
|
54721
|
+
callback(null, err);
|
|
54722
|
+
});
|
|
54723
|
+
};
|
|
54724
|
+
} else if (
|
|
54725
|
+
global.XMLHttpRequest &&
|
|
54726
|
+
// https://xhr.spec.whatwg.org/#the-responsetype-attribute
|
|
54727
|
+
new XMLHttpRequest().responseType === ''
|
|
54728
|
+
) {
|
|
54729
|
+
loadImage.fetchBlob = function (url, callback, options) {
|
|
54730
|
+
/**
|
|
54731
|
+
* Promise executor
|
|
54732
|
+
*
|
|
54733
|
+
* @param {Function} resolve Resolution function
|
|
54734
|
+
* @param {Function} reject Rejection function
|
|
54735
|
+
*/
|
|
54736
|
+
function executor(resolve, reject) {
|
|
54737
|
+
options = options || {}; // eslint-disable-line no-param-reassign
|
|
54738
|
+
var req = new XMLHttpRequest();
|
|
54739
|
+
req.open(options.method || 'GET', url);
|
|
54740
|
+
if (options.headers) {
|
|
54741
|
+
Object.keys(options.headers).forEach(function (key) {
|
|
54742
|
+
req.setRequestHeader(key, options.headers[key]);
|
|
54743
|
+
});
|
|
54744
|
+
}
|
|
54745
|
+
req.withCredentials = options.credentials === 'include';
|
|
54746
|
+
req.responseType = 'blob';
|
|
54747
|
+
req.onload = function () {
|
|
54748
|
+
resolve(req.response);
|
|
54749
|
+
};
|
|
54750
|
+
req.onerror =
|
|
54751
|
+
req.onabort =
|
|
54752
|
+
req.ontimeout =
|
|
54753
|
+
function (err) {
|
|
54754
|
+
if (resolve === reject) {
|
|
54755
|
+
// Not using Promises
|
|
54756
|
+
reject(null, err);
|
|
54757
|
+
} else {
|
|
54758
|
+
reject(err);
|
|
54759
|
+
}
|
|
54760
|
+
};
|
|
54761
|
+
req.send(options.body);
|
|
54762
|
+
}
|
|
54763
|
+
if (global.Promise && typeof callback !== 'function') {
|
|
54764
|
+
options = callback; // eslint-disable-line no-param-reassign
|
|
54765
|
+
return new Promise(executor)
|
|
54766
|
+
}
|
|
54767
|
+
return executor(callback, callback)
|
|
54768
|
+
};
|
|
54769
|
+
}
|
|
54770
|
+
});
|
|
54771
|
+
}(loadImageFetch));
|
|
54772
|
+
|
|
54773
|
+
var loadImageExif = {exports: {}};
|
|
54774
|
+
|
|
54775
|
+
/*
|
|
54776
|
+
* JavaScript Load Image Exif Parser
|
|
54777
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
54778
|
+
*
|
|
54779
|
+
* Copyright 2013, Sebastian Tschan
|
|
54780
|
+
* https://blueimp.net
|
|
54781
|
+
*
|
|
54782
|
+
* Licensed under the MIT license:
|
|
54783
|
+
* https://opensource.org/licenses/MIT
|
|
54784
|
+
*/
|
|
54785
|
+
|
|
54786
|
+
(function (module) {
|
|
54787
|
+
(function (factory) {
|
|
54788
|
+
if (module.exports) {
|
|
54789
|
+
factory(loadImage.exports, loadImageMeta.exports);
|
|
54790
|
+
} else {
|
|
54791
|
+
// Browser globals:
|
|
54792
|
+
factory(window.loadImage);
|
|
54793
|
+
}
|
|
54794
|
+
})(function (loadImage) {
|
|
54795
|
+
|
|
54796
|
+
/**
|
|
54797
|
+
* Exif tag map
|
|
54798
|
+
*
|
|
54799
|
+
* @name ExifMap
|
|
54800
|
+
* @class
|
|
54801
|
+
* @param {number|string} tagCode IFD tag code
|
|
54802
|
+
*/
|
|
54803
|
+
function ExifMap(tagCode) {
|
|
54804
|
+
if (tagCode) {
|
|
54805
|
+
Object.defineProperty(this, 'map', {
|
|
54806
|
+
value: this.ifds[tagCode].map
|
|
54807
|
+
});
|
|
54808
|
+
Object.defineProperty(this, 'tags', {
|
|
54809
|
+
value: (this.tags && this.tags[tagCode]) || {}
|
|
54810
|
+
});
|
|
54811
|
+
}
|
|
54812
|
+
}
|
|
54813
|
+
|
|
54814
|
+
ExifMap.prototype.map = {
|
|
54815
|
+
Orientation: 0x0112,
|
|
54816
|
+
Thumbnail: 'ifd1',
|
|
54817
|
+
Blob: 0x0201, // Alias for JPEGInterchangeFormat
|
|
54818
|
+
Exif: 0x8769,
|
|
54819
|
+
GPSInfo: 0x8825,
|
|
54820
|
+
Interoperability: 0xa005
|
|
54821
|
+
};
|
|
54822
|
+
|
|
54823
|
+
ExifMap.prototype.ifds = {
|
|
54824
|
+
ifd1: { name: 'Thumbnail', map: ExifMap.prototype.map },
|
|
54825
|
+
0x8769: { name: 'Exif', map: {} },
|
|
54826
|
+
0x8825: { name: 'GPSInfo', map: {} },
|
|
54827
|
+
0xa005: { name: 'Interoperability', map: {} }
|
|
54828
|
+
};
|
|
54829
|
+
|
|
54830
|
+
/**
|
|
54831
|
+
* Retrieves exif tag value
|
|
54832
|
+
*
|
|
54833
|
+
* @param {number|string} id Exif tag code or name
|
|
54834
|
+
* @returns {object} Exif tag value
|
|
54835
|
+
*/
|
|
54836
|
+
ExifMap.prototype.get = function (id) {
|
|
54837
|
+
return this[id] || this[this.map[id]]
|
|
54838
|
+
};
|
|
54839
|
+
|
|
54840
|
+
/**
|
|
54841
|
+
* Returns the Exif Thumbnail data as Blob.
|
|
54842
|
+
*
|
|
54843
|
+
* @param {DataView} dataView Data view interface
|
|
54844
|
+
* @param {number} offset Thumbnail data offset
|
|
54845
|
+
* @param {number} length Thumbnail data length
|
|
54846
|
+
* @returns {undefined|Blob} Returns the Thumbnail Blob or undefined
|
|
54847
|
+
*/
|
|
54848
|
+
function getExifThumbnail(dataView, offset, length) {
|
|
54849
|
+
if (!length) return
|
|
54850
|
+
if (offset + length > dataView.byteLength) {
|
|
54851
|
+
console.log('Invalid Exif data: Invalid thumbnail data.');
|
|
54852
|
+
return
|
|
54853
|
+
}
|
|
54854
|
+
return new Blob(
|
|
54855
|
+
[loadImage.bufferSlice.call(dataView.buffer, offset, offset + length)],
|
|
54856
|
+
{
|
|
54857
|
+
type: 'image/jpeg'
|
|
54858
|
+
}
|
|
54859
|
+
)
|
|
54860
|
+
}
|
|
54861
|
+
|
|
54862
|
+
var ExifTagTypes = {
|
|
54863
|
+
// byte, 8-bit unsigned int:
|
|
54864
|
+
1: {
|
|
54865
|
+
getValue: function (dataView, dataOffset) {
|
|
54866
|
+
return dataView.getUint8(dataOffset)
|
|
54867
|
+
},
|
|
54868
|
+
size: 1
|
|
54869
|
+
},
|
|
54870
|
+
// ascii, 8-bit byte:
|
|
54871
|
+
2: {
|
|
54872
|
+
getValue: function (dataView, dataOffset) {
|
|
54873
|
+
return String.fromCharCode(dataView.getUint8(dataOffset))
|
|
54874
|
+
},
|
|
54875
|
+
size: 1,
|
|
54876
|
+
ascii: true
|
|
54877
|
+
},
|
|
54878
|
+
// short, 16 bit int:
|
|
54879
|
+
3: {
|
|
54880
|
+
getValue: function (dataView, dataOffset, littleEndian) {
|
|
54881
|
+
return dataView.getUint16(dataOffset, littleEndian)
|
|
54882
|
+
},
|
|
54883
|
+
size: 2
|
|
54884
|
+
},
|
|
54885
|
+
// long, 32 bit int:
|
|
54886
|
+
4: {
|
|
54887
|
+
getValue: function (dataView, dataOffset, littleEndian) {
|
|
54888
|
+
return dataView.getUint32(dataOffset, littleEndian)
|
|
54889
|
+
},
|
|
54890
|
+
size: 4
|
|
54891
|
+
},
|
|
54892
|
+
// rational = two long values, first is numerator, second is denominator:
|
|
54893
|
+
5: {
|
|
54894
|
+
getValue: function (dataView, dataOffset, littleEndian) {
|
|
54895
|
+
return (
|
|
54896
|
+
dataView.getUint32(dataOffset, littleEndian) /
|
|
54897
|
+
dataView.getUint32(dataOffset + 4, littleEndian)
|
|
54898
|
+
)
|
|
54899
|
+
},
|
|
54900
|
+
size: 8
|
|
54901
|
+
},
|
|
54902
|
+
// slong, 32 bit signed int:
|
|
54903
|
+
9: {
|
|
54904
|
+
getValue: function (dataView, dataOffset, littleEndian) {
|
|
54905
|
+
return dataView.getInt32(dataOffset, littleEndian)
|
|
54906
|
+
},
|
|
54907
|
+
size: 4
|
|
54908
|
+
},
|
|
54909
|
+
// srational, two slongs, first is numerator, second is denominator:
|
|
54910
|
+
10: {
|
|
54911
|
+
getValue: function (dataView, dataOffset, littleEndian) {
|
|
54912
|
+
return (
|
|
54913
|
+
dataView.getInt32(dataOffset, littleEndian) /
|
|
54914
|
+
dataView.getInt32(dataOffset + 4, littleEndian)
|
|
54915
|
+
)
|
|
54916
|
+
},
|
|
54917
|
+
size: 8
|
|
54918
|
+
}
|
|
54919
|
+
};
|
|
54920
|
+
// undefined, 8-bit byte, value depending on field:
|
|
54921
|
+
ExifTagTypes[7] = ExifTagTypes[1];
|
|
54922
|
+
|
|
54923
|
+
/**
|
|
54924
|
+
* Returns Exif tag value.
|
|
54925
|
+
*
|
|
54926
|
+
* @param {DataView} dataView Data view interface
|
|
54927
|
+
* @param {number} tiffOffset TIFF offset
|
|
54928
|
+
* @param {number} offset Tag offset
|
|
54929
|
+
* @param {number} type Tag type
|
|
54930
|
+
* @param {number} length Tag length
|
|
54931
|
+
* @param {boolean} littleEndian Little endian encoding
|
|
54932
|
+
* @returns {object} Tag value
|
|
54933
|
+
*/
|
|
54934
|
+
function getExifValue(
|
|
54935
|
+
dataView,
|
|
54936
|
+
tiffOffset,
|
|
54937
|
+
offset,
|
|
54938
|
+
type,
|
|
54939
|
+
length,
|
|
54940
|
+
littleEndian
|
|
54941
|
+
) {
|
|
54942
|
+
var tagType = ExifTagTypes[type];
|
|
54943
|
+
var tagSize;
|
|
54944
|
+
var dataOffset;
|
|
54945
|
+
var values;
|
|
54946
|
+
var i;
|
|
54947
|
+
var str;
|
|
54948
|
+
var c;
|
|
54949
|
+
if (!tagType) {
|
|
54950
|
+
console.log('Invalid Exif data: Invalid tag type.');
|
|
54951
|
+
return
|
|
54952
|
+
}
|
|
54953
|
+
tagSize = tagType.size * length;
|
|
54954
|
+
// Determine if the value is contained in the dataOffset bytes,
|
|
54955
|
+
// or if the value at the dataOffset is a pointer to the actual data:
|
|
54956
|
+
dataOffset =
|
|
54957
|
+
tagSize > 4
|
|
54958
|
+
? tiffOffset + dataView.getUint32(offset + 8, littleEndian)
|
|
54959
|
+
: offset + 8;
|
|
54960
|
+
if (dataOffset + tagSize > dataView.byteLength) {
|
|
54961
|
+
console.log('Invalid Exif data: Invalid data offset.');
|
|
54962
|
+
return
|
|
54963
|
+
}
|
|
54964
|
+
if (length === 1) {
|
|
54965
|
+
return tagType.getValue(dataView, dataOffset, littleEndian)
|
|
54966
|
+
}
|
|
54967
|
+
values = [];
|
|
54968
|
+
for (i = 0; i < length; i += 1) {
|
|
54969
|
+
values[i] = tagType.getValue(
|
|
54970
|
+
dataView,
|
|
54971
|
+
dataOffset + i * tagType.size,
|
|
54972
|
+
littleEndian
|
|
54973
|
+
);
|
|
54974
|
+
}
|
|
54975
|
+
if (tagType.ascii) {
|
|
54976
|
+
str = '';
|
|
54977
|
+
// Concatenate the chars:
|
|
54978
|
+
for (i = 0; i < values.length; i += 1) {
|
|
54979
|
+
c = values[i];
|
|
54980
|
+
// Ignore the terminating NULL byte(s):
|
|
54981
|
+
if (c === '\u0000') {
|
|
54982
|
+
break
|
|
54983
|
+
}
|
|
54984
|
+
str += c;
|
|
54985
|
+
}
|
|
54986
|
+
return str
|
|
54987
|
+
}
|
|
54988
|
+
return values
|
|
54989
|
+
}
|
|
54990
|
+
|
|
54991
|
+
/**
|
|
54992
|
+
* Determines if the given tag should be included.
|
|
54993
|
+
*
|
|
54994
|
+
* @param {object} includeTags Map of tags to include
|
|
54995
|
+
* @param {object} excludeTags Map of tags to exclude
|
|
54996
|
+
* @param {number|string} tagCode Tag code to check
|
|
54997
|
+
* @returns {boolean} True if the tag should be included
|
|
54998
|
+
*/
|
|
54999
|
+
function shouldIncludeTag(includeTags, excludeTags, tagCode) {
|
|
55000
|
+
return (
|
|
55001
|
+
(!includeTags || includeTags[tagCode]) &&
|
|
55002
|
+
(!excludeTags || excludeTags[tagCode] !== true)
|
|
55003
|
+
)
|
|
55004
|
+
}
|
|
55005
|
+
|
|
55006
|
+
/**
|
|
55007
|
+
* Parses Exif tags.
|
|
55008
|
+
*
|
|
55009
|
+
* @param {DataView} dataView Data view interface
|
|
55010
|
+
* @param {number} tiffOffset TIFF offset
|
|
55011
|
+
* @param {number} dirOffset Directory offset
|
|
55012
|
+
* @param {boolean} littleEndian Little endian encoding
|
|
55013
|
+
* @param {ExifMap} tags Map to store parsed exif tags
|
|
55014
|
+
* @param {ExifMap} tagOffsets Map to store parsed exif tag offsets
|
|
55015
|
+
* @param {object} includeTags Map of tags to include
|
|
55016
|
+
* @param {object} excludeTags Map of tags to exclude
|
|
55017
|
+
* @returns {number} Next directory offset
|
|
55018
|
+
*/
|
|
55019
|
+
function parseExifTags(
|
|
55020
|
+
dataView,
|
|
55021
|
+
tiffOffset,
|
|
55022
|
+
dirOffset,
|
|
55023
|
+
littleEndian,
|
|
55024
|
+
tags,
|
|
55025
|
+
tagOffsets,
|
|
55026
|
+
includeTags,
|
|
55027
|
+
excludeTags
|
|
55028
|
+
) {
|
|
55029
|
+
var tagsNumber, dirEndOffset, i, tagOffset, tagNumber, tagValue;
|
|
55030
|
+
if (dirOffset + 6 > dataView.byteLength) {
|
|
55031
|
+
console.log('Invalid Exif data: Invalid directory offset.');
|
|
55032
|
+
return
|
|
55033
|
+
}
|
|
55034
|
+
tagsNumber = dataView.getUint16(dirOffset, littleEndian);
|
|
55035
|
+
dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
|
|
55036
|
+
if (dirEndOffset + 4 > dataView.byteLength) {
|
|
55037
|
+
console.log('Invalid Exif data: Invalid directory size.');
|
|
55038
|
+
return
|
|
55039
|
+
}
|
|
55040
|
+
for (i = 0; i < tagsNumber; i += 1) {
|
|
55041
|
+
tagOffset = dirOffset + 2 + 12 * i;
|
|
55042
|
+
tagNumber = dataView.getUint16(tagOffset, littleEndian);
|
|
55043
|
+
if (!shouldIncludeTag(includeTags, excludeTags, tagNumber)) continue
|
|
55044
|
+
tagValue = getExifValue(
|
|
55045
|
+
dataView,
|
|
55046
|
+
tiffOffset,
|
|
55047
|
+
tagOffset,
|
|
55048
|
+
dataView.getUint16(tagOffset + 2, littleEndian), // tag type
|
|
55049
|
+
dataView.getUint32(tagOffset + 4, littleEndian), // tag length
|
|
55050
|
+
littleEndian
|
|
55051
|
+
);
|
|
55052
|
+
tags[tagNumber] = tagValue;
|
|
55053
|
+
if (tagOffsets) {
|
|
55054
|
+
tagOffsets[tagNumber] = tagOffset;
|
|
55055
|
+
}
|
|
55056
|
+
}
|
|
55057
|
+
// Return the offset to the next directory:
|
|
55058
|
+
return dataView.getUint32(dirEndOffset, littleEndian)
|
|
55059
|
+
}
|
|
55060
|
+
|
|
55061
|
+
/**
|
|
55062
|
+
* Parses tags in a given IFD (Image File Directory).
|
|
55063
|
+
*
|
|
55064
|
+
* @param {object} data Data object to store exif tags and offsets
|
|
55065
|
+
* @param {number|string} tagCode IFD tag code
|
|
55066
|
+
* @param {DataView} dataView Data view interface
|
|
55067
|
+
* @param {number} tiffOffset TIFF offset
|
|
55068
|
+
* @param {boolean} littleEndian Little endian encoding
|
|
55069
|
+
* @param {object} includeTags Map of tags to include
|
|
55070
|
+
* @param {object} excludeTags Map of tags to exclude
|
|
55071
|
+
*/
|
|
55072
|
+
function parseExifIFD(
|
|
55073
|
+
data,
|
|
55074
|
+
tagCode,
|
|
55075
|
+
dataView,
|
|
55076
|
+
tiffOffset,
|
|
55077
|
+
littleEndian,
|
|
55078
|
+
includeTags,
|
|
55079
|
+
excludeTags
|
|
55080
|
+
) {
|
|
55081
|
+
var dirOffset = data.exif[tagCode];
|
|
55082
|
+
if (dirOffset) {
|
|
55083
|
+
data.exif[tagCode] = new ExifMap(tagCode);
|
|
55084
|
+
if (data.exifOffsets) {
|
|
55085
|
+
data.exifOffsets[tagCode] = new ExifMap(tagCode);
|
|
55086
|
+
}
|
|
55087
|
+
parseExifTags(
|
|
55088
|
+
dataView,
|
|
55089
|
+
tiffOffset,
|
|
55090
|
+
tiffOffset + dirOffset,
|
|
55091
|
+
littleEndian,
|
|
55092
|
+
data.exif[tagCode],
|
|
55093
|
+
data.exifOffsets && data.exifOffsets[tagCode],
|
|
55094
|
+
includeTags && includeTags[tagCode],
|
|
55095
|
+
excludeTags && excludeTags[tagCode]
|
|
55096
|
+
);
|
|
55097
|
+
}
|
|
55098
|
+
}
|
|
55099
|
+
|
|
55100
|
+
loadImage.parseExifData = function (dataView, offset, length, data, options) {
|
|
55101
|
+
if (options.disableExif) {
|
|
55102
|
+
return
|
|
55103
|
+
}
|
|
55104
|
+
var includeTags = options.includeExifTags;
|
|
55105
|
+
var excludeTags = options.excludeExifTags || {
|
|
55106
|
+
0x8769: {
|
|
55107
|
+
// ExifIFDPointer
|
|
55108
|
+
0x927c: true // MakerNote
|
|
55109
|
+
}
|
|
55110
|
+
};
|
|
55111
|
+
var tiffOffset = offset + 10;
|
|
55112
|
+
var littleEndian;
|
|
55113
|
+
var dirOffset;
|
|
55114
|
+
var thumbnailIFD;
|
|
55115
|
+
// Check for the ASCII code for "Exif" (0x45786966):
|
|
55116
|
+
if (dataView.getUint32(offset + 4) !== 0x45786966) {
|
|
55117
|
+
// No Exif data, might be XMP data instead
|
|
55118
|
+
return
|
|
55119
|
+
}
|
|
55120
|
+
if (tiffOffset + 8 > dataView.byteLength) {
|
|
55121
|
+
console.log('Invalid Exif data: Invalid segment size.');
|
|
55122
|
+
return
|
|
55123
|
+
}
|
|
55124
|
+
// Check for the two null bytes:
|
|
55125
|
+
if (dataView.getUint16(offset + 8) !== 0x0000) {
|
|
55126
|
+
console.log('Invalid Exif data: Missing byte alignment offset.');
|
|
55127
|
+
return
|
|
55128
|
+
}
|
|
55129
|
+
// Check the byte alignment:
|
|
55130
|
+
switch (dataView.getUint16(tiffOffset)) {
|
|
55131
|
+
case 0x4949:
|
|
55132
|
+
littleEndian = true;
|
|
55133
|
+
break
|
|
55134
|
+
case 0x4d4d:
|
|
55135
|
+
littleEndian = false;
|
|
55136
|
+
break
|
|
55137
|
+
default:
|
|
55138
|
+
console.log('Invalid Exif data: Invalid byte alignment marker.');
|
|
55139
|
+
return
|
|
55140
|
+
}
|
|
55141
|
+
// Check for the TIFF tag marker (0x002A):
|
|
55142
|
+
if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002a) {
|
|
55143
|
+
console.log('Invalid Exif data: Missing TIFF marker.');
|
|
55144
|
+
return
|
|
55145
|
+
}
|
|
55146
|
+
// Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
|
|
55147
|
+
dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
|
|
55148
|
+
// Create the exif object to store the tags:
|
|
55149
|
+
data.exif = new ExifMap();
|
|
55150
|
+
if (!options.disableExifOffsets) {
|
|
55151
|
+
data.exifOffsets = new ExifMap();
|
|
55152
|
+
data.exifTiffOffset = tiffOffset;
|
|
55153
|
+
data.exifLittleEndian = littleEndian;
|
|
55154
|
+
}
|
|
55155
|
+
// Parse the tags of the main image directory (IFD0) and retrieve the
|
|
55156
|
+
// offset to the next directory (IFD1), usually the thumbnail directory:
|
|
55157
|
+
dirOffset = parseExifTags(
|
|
55158
|
+
dataView,
|
|
55159
|
+
tiffOffset,
|
|
55160
|
+
tiffOffset + dirOffset,
|
|
55161
|
+
littleEndian,
|
|
55162
|
+
data.exif,
|
|
55163
|
+
data.exifOffsets,
|
|
55164
|
+
includeTags,
|
|
55165
|
+
excludeTags
|
|
55166
|
+
);
|
|
55167
|
+
if (dirOffset && shouldIncludeTag(includeTags, excludeTags, 'ifd1')) {
|
|
55168
|
+
data.exif.ifd1 = dirOffset;
|
|
55169
|
+
if (data.exifOffsets) {
|
|
55170
|
+
data.exifOffsets.ifd1 = tiffOffset + dirOffset;
|
|
55171
|
+
}
|
|
55172
|
+
}
|
|
55173
|
+
Object.keys(data.exif.ifds).forEach(function (tagCode) {
|
|
55174
|
+
parseExifIFD(
|
|
55175
|
+
data,
|
|
55176
|
+
tagCode,
|
|
55177
|
+
dataView,
|
|
55178
|
+
tiffOffset,
|
|
55179
|
+
littleEndian,
|
|
55180
|
+
includeTags,
|
|
55181
|
+
excludeTags
|
|
55182
|
+
);
|
|
55183
|
+
});
|
|
55184
|
+
thumbnailIFD = data.exif.ifd1;
|
|
55185
|
+
// Check for JPEG Thumbnail offset and data length:
|
|
55186
|
+
if (thumbnailIFD && thumbnailIFD[0x0201]) {
|
|
55187
|
+
thumbnailIFD[0x0201] = getExifThumbnail(
|
|
55188
|
+
dataView,
|
|
55189
|
+
tiffOffset + thumbnailIFD[0x0201],
|
|
55190
|
+
thumbnailIFD[0x0202] // Thumbnail data length
|
|
55191
|
+
);
|
|
55192
|
+
}
|
|
55193
|
+
};
|
|
55194
|
+
|
|
55195
|
+
// Registers the Exif parser for the APP1 JPEG metadata segment:
|
|
55196
|
+
loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData);
|
|
55197
|
+
|
|
55198
|
+
loadImage.exifWriters = {
|
|
55199
|
+
// Orientation writer:
|
|
55200
|
+
0x0112: function (buffer, data, value) {
|
|
55201
|
+
var orientationOffset = data.exifOffsets[0x0112];
|
|
55202
|
+
if (!orientationOffset) return buffer
|
|
55203
|
+
var view = new DataView(buffer, orientationOffset + 8, 2);
|
|
55204
|
+
view.setUint16(0, value, data.exifLittleEndian);
|
|
55205
|
+
return buffer
|
|
55206
|
+
}
|
|
55207
|
+
};
|
|
55208
|
+
|
|
55209
|
+
loadImage.writeExifData = function (buffer, data, id, value) {
|
|
55210
|
+
return loadImage.exifWriters[data.exif.map[id]](buffer, data, value)
|
|
55211
|
+
};
|
|
55212
|
+
|
|
55213
|
+
loadImage.ExifMap = ExifMap;
|
|
55214
|
+
|
|
55215
|
+
// Adds the following properties to the parseMetaData callback data:
|
|
55216
|
+
// - exif: The parsed Exif tags
|
|
55217
|
+
// - exifOffsets: The parsed Exif tag offsets
|
|
55218
|
+
// - exifTiffOffset: TIFF header offset (used for offset pointers)
|
|
55219
|
+
// - exifLittleEndian: little endian order if true, big endian if false
|
|
55220
|
+
|
|
55221
|
+
// Adds the following options to the parseMetaData method:
|
|
55222
|
+
// - disableExif: Disables Exif parsing when true.
|
|
55223
|
+
// - disableExifOffsets: Disables storing Exif tag offsets when true.
|
|
55224
|
+
// - includeExifTags: A map of Exif tags to include for parsing.
|
|
55225
|
+
// - excludeExifTags: A map of Exif tags to exclude from parsing.
|
|
55226
|
+
});
|
|
55227
|
+
}(loadImageExif));
|
|
55228
|
+
|
|
55229
|
+
var loadImageExifMap = {exports: {}};
|
|
55230
|
+
|
|
55231
|
+
/*
|
|
55232
|
+
* JavaScript Load Image Exif Map
|
|
55233
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
55234
|
+
*
|
|
55235
|
+
* Copyright 2013, Sebastian Tschan
|
|
55236
|
+
* https://blueimp.net
|
|
55237
|
+
*
|
|
55238
|
+
* Exif tags mapping based on
|
|
55239
|
+
* https://github.com/jseidelin/exif-js
|
|
55240
|
+
*
|
|
55241
|
+
* Licensed under the MIT license:
|
|
55242
|
+
* https://opensource.org/licenses/MIT
|
|
55243
|
+
*/
|
|
55244
|
+
|
|
55245
|
+
(function (module) {
|
|
55246
|
+
(function (factory) {
|
|
55247
|
+
if (module.exports) {
|
|
55248
|
+
factory(loadImage.exports, loadImageExif.exports);
|
|
55249
|
+
} else {
|
|
55250
|
+
// Browser globals:
|
|
55251
|
+
factory(window.loadImage);
|
|
55252
|
+
}
|
|
55253
|
+
})(function (loadImage) {
|
|
55254
|
+
|
|
55255
|
+
var ExifMapProto = loadImage.ExifMap.prototype;
|
|
55256
|
+
|
|
55257
|
+
ExifMapProto.tags = {
|
|
55258
|
+
// =================
|
|
55259
|
+
// TIFF tags (IFD0):
|
|
55260
|
+
// =================
|
|
55261
|
+
0x0100: 'ImageWidth',
|
|
55262
|
+
0x0101: 'ImageHeight',
|
|
55263
|
+
0x0102: 'BitsPerSample',
|
|
55264
|
+
0x0103: 'Compression',
|
|
55265
|
+
0x0106: 'PhotometricInterpretation',
|
|
55266
|
+
0x0112: 'Orientation',
|
|
55267
|
+
0x0115: 'SamplesPerPixel',
|
|
55268
|
+
0x011c: 'PlanarConfiguration',
|
|
55269
|
+
0x0212: 'YCbCrSubSampling',
|
|
55270
|
+
0x0213: 'YCbCrPositioning',
|
|
55271
|
+
0x011a: 'XResolution',
|
|
55272
|
+
0x011b: 'YResolution',
|
|
55273
|
+
0x0128: 'ResolutionUnit',
|
|
55274
|
+
0x0111: 'StripOffsets',
|
|
55275
|
+
0x0116: 'RowsPerStrip',
|
|
55276
|
+
0x0117: 'StripByteCounts',
|
|
55277
|
+
0x0201: 'JPEGInterchangeFormat',
|
|
55278
|
+
0x0202: 'JPEGInterchangeFormatLength',
|
|
55279
|
+
0x012d: 'TransferFunction',
|
|
55280
|
+
0x013e: 'WhitePoint',
|
|
55281
|
+
0x013f: 'PrimaryChromaticities',
|
|
55282
|
+
0x0211: 'YCbCrCoefficients',
|
|
55283
|
+
0x0214: 'ReferenceBlackWhite',
|
|
55284
|
+
0x0132: 'DateTime',
|
|
55285
|
+
0x010e: 'ImageDescription',
|
|
55286
|
+
0x010f: 'Make',
|
|
55287
|
+
0x0110: 'Model',
|
|
55288
|
+
0x0131: 'Software',
|
|
55289
|
+
0x013b: 'Artist',
|
|
55290
|
+
0x8298: 'Copyright',
|
|
55291
|
+
0x8769: {
|
|
55292
|
+
// ExifIFDPointer
|
|
55293
|
+
0x9000: 'ExifVersion', // EXIF version
|
|
55294
|
+
0xa000: 'FlashpixVersion', // Flashpix format version
|
|
55295
|
+
0xa001: 'ColorSpace', // Color space information tag
|
|
55296
|
+
0xa002: 'PixelXDimension', // Valid width of meaningful image
|
|
55297
|
+
0xa003: 'PixelYDimension', // Valid height of meaningful image
|
|
55298
|
+
0xa500: 'Gamma',
|
|
55299
|
+
0x9101: 'ComponentsConfiguration', // Information about channels
|
|
55300
|
+
0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel
|
|
55301
|
+
0x927c: 'MakerNote', // Any desired information written by the manufacturer
|
|
55302
|
+
0x9286: 'UserComment', // Comments by user
|
|
55303
|
+
0xa004: 'RelatedSoundFile', // Name of related sound file
|
|
55304
|
+
0x9003: 'DateTimeOriginal', // Date and time when the original image was generated
|
|
55305
|
+
0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally
|
|
55306
|
+
0x9010: 'OffsetTime', // Time zone when the image file was last changed
|
|
55307
|
+
0x9011: 'OffsetTimeOriginal', // Time zone when the image was stored digitally
|
|
55308
|
+
0x9012: 'OffsetTimeDigitized', // Time zone when the image was stored digitally
|
|
55309
|
+
0x9290: 'SubSecTime', // Fractions of seconds for DateTime
|
|
55310
|
+
0x9291: 'SubSecTimeOriginal', // Fractions of seconds for DateTimeOriginal
|
|
55311
|
+
0x9292: 'SubSecTimeDigitized', // Fractions of seconds for DateTimeDigitized
|
|
55312
|
+
0x829a: 'ExposureTime', // Exposure time (in seconds)
|
|
55313
|
+
0x829d: 'FNumber',
|
|
55314
|
+
0x8822: 'ExposureProgram', // Exposure program
|
|
55315
|
+
0x8824: 'SpectralSensitivity', // Spectral sensitivity
|
|
55316
|
+
0x8827: 'PhotographicSensitivity', // EXIF 2.3, ISOSpeedRatings in EXIF 2.2
|
|
55317
|
+
0x8828: 'OECF', // Optoelectric conversion factor
|
|
55318
|
+
0x8830: 'SensitivityType',
|
|
55319
|
+
0x8831: 'StandardOutputSensitivity',
|
|
55320
|
+
0x8832: 'RecommendedExposureIndex',
|
|
55321
|
+
0x8833: 'ISOSpeed',
|
|
55322
|
+
0x8834: 'ISOSpeedLatitudeyyy',
|
|
55323
|
+
0x8835: 'ISOSpeedLatitudezzz',
|
|
55324
|
+
0x9201: 'ShutterSpeedValue', // Shutter speed
|
|
55325
|
+
0x9202: 'ApertureValue', // Lens aperture
|
|
55326
|
+
0x9203: 'BrightnessValue', // Value of brightness
|
|
55327
|
+
0x9204: 'ExposureBias', // Exposure bias
|
|
55328
|
+
0x9205: 'MaxApertureValue', // Smallest F number of lens
|
|
55329
|
+
0x9206: 'SubjectDistance', // Distance to subject in meters
|
|
55330
|
+
0x9207: 'MeteringMode', // Metering mode
|
|
55331
|
+
0x9208: 'LightSource', // Kind of light source
|
|
55332
|
+
0x9209: 'Flash', // Flash status
|
|
55333
|
+
0x9214: 'SubjectArea', // Location and area of main subject
|
|
55334
|
+
0x920a: 'FocalLength', // Focal length of the lens in mm
|
|
55335
|
+
0xa20b: 'FlashEnergy', // Strobe energy in BCPS
|
|
55336
|
+
0xa20c: 'SpatialFrequencyResponse',
|
|
55337
|
+
0xa20e: 'FocalPlaneXResolution', // Number of pixels in width direction per FPRUnit
|
|
55338
|
+
0xa20f: 'FocalPlaneYResolution', // Number of pixels in height direction per FPRUnit
|
|
55339
|
+
0xa210: 'FocalPlaneResolutionUnit', // Unit for measuring the focal plane resolution
|
|
55340
|
+
0xa214: 'SubjectLocation', // Location of subject in image
|
|
55341
|
+
0xa215: 'ExposureIndex', // Exposure index selected on camera
|
|
55342
|
+
0xa217: 'SensingMethod', // Image sensor type
|
|
55343
|
+
0xa300: 'FileSource', // Image source (3 == DSC)
|
|
55344
|
+
0xa301: 'SceneType', // Scene type (1 == directly photographed)
|
|
55345
|
+
0xa302: 'CFAPattern', // Color filter array geometric pattern
|
|
55346
|
+
0xa401: 'CustomRendered', // Special processing
|
|
55347
|
+
0xa402: 'ExposureMode', // Exposure mode
|
|
55348
|
+
0xa403: 'WhiteBalance', // 1 = auto white balance, 2 = manual
|
|
55349
|
+
0xa404: 'DigitalZoomRatio', // Digital zoom ratio
|
|
55350
|
+
0xa405: 'FocalLengthIn35mmFilm',
|
|
55351
|
+
0xa406: 'SceneCaptureType', // Type of scene
|
|
55352
|
+
0xa407: 'GainControl', // Degree of overall image gain adjustment
|
|
55353
|
+
0xa408: 'Contrast', // Direction of contrast processing applied by camera
|
|
55354
|
+
0xa409: 'Saturation', // Direction of saturation processing applied by camera
|
|
55355
|
+
0xa40a: 'Sharpness', // Direction of sharpness processing applied by camera
|
|
55356
|
+
0xa40b: 'DeviceSettingDescription',
|
|
55357
|
+
0xa40c: 'SubjectDistanceRange', // Distance to subject
|
|
55358
|
+
0xa420: 'ImageUniqueID', // Identifier assigned uniquely to each image
|
|
55359
|
+
0xa430: 'CameraOwnerName',
|
|
55360
|
+
0xa431: 'BodySerialNumber',
|
|
55361
|
+
0xa432: 'LensSpecification',
|
|
55362
|
+
0xa433: 'LensMake',
|
|
55363
|
+
0xa434: 'LensModel',
|
|
55364
|
+
0xa435: 'LensSerialNumber'
|
|
55365
|
+
},
|
|
55366
|
+
0x8825: {
|
|
55367
|
+
// GPSInfoIFDPointer
|
|
55368
|
+
0x0000: 'GPSVersionID',
|
|
55369
|
+
0x0001: 'GPSLatitudeRef',
|
|
55370
|
+
0x0002: 'GPSLatitude',
|
|
55371
|
+
0x0003: 'GPSLongitudeRef',
|
|
55372
|
+
0x0004: 'GPSLongitude',
|
|
55373
|
+
0x0005: 'GPSAltitudeRef',
|
|
55374
|
+
0x0006: 'GPSAltitude',
|
|
55375
|
+
0x0007: 'GPSTimeStamp',
|
|
55376
|
+
0x0008: 'GPSSatellites',
|
|
55377
|
+
0x0009: 'GPSStatus',
|
|
55378
|
+
0x000a: 'GPSMeasureMode',
|
|
55379
|
+
0x000b: 'GPSDOP',
|
|
55380
|
+
0x000c: 'GPSSpeedRef',
|
|
55381
|
+
0x000d: 'GPSSpeed',
|
|
55382
|
+
0x000e: 'GPSTrackRef',
|
|
55383
|
+
0x000f: 'GPSTrack',
|
|
55384
|
+
0x0010: 'GPSImgDirectionRef',
|
|
55385
|
+
0x0011: 'GPSImgDirection',
|
|
55386
|
+
0x0012: 'GPSMapDatum',
|
|
55387
|
+
0x0013: 'GPSDestLatitudeRef',
|
|
55388
|
+
0x0014: 'GPSDestLatitude',
|
|
55389
|
+
0x0015: 'GPSDestLongitudeRef',
|
|
55390
|
+
0x0016: 'GPSDestLongitude',
|
|
55391
|
+
0x0017: 'GPSDestBearingRef',
|
|
55392
|
+
0x0018: 'GPSDestBearing',
|
|
55393
|
+
0x0019: 'GPSDestDistanceRef',
|
|
55394
|
+
0x001a: 'GPSDestDistance',
|
|
55395
|
+
0x001b: 'GPSProcessingMethod',
|
|
55396
|
+
0x001c: 'GPSAreaInformation',
|
|
55397
|
+
0x001d: 'GPSDateStamp',
|
|
55398
|
+
0x001e: 'GPSDifferential',
|
|
55399
|
+
0x001f: 'GPSHPositioningError'
|
|
55400
|
+
},
|
|
55401
|
+
0xa005: {
|
|
55402
|
+
// InteroperabilityIFDPointer
|
|
55403
|
+
0x0001: 'InteroperabilityIndex'
|
|
55404
|
+
}
|
|
55405
|
+
};
|
|
55406
|
+
|
|
55407
|
+
// IFD1 directory can contain any IFD0 tags:
|
|
55408
|
+
ExifMapProto.tags.ifd1 = ExifMapProto.tags;
|
|
55409
|
+
|
|
55410
|
+
ExifMapProto.stringValues = {
|
|
55411
|
+
ExposureProgram: {
|
|
55412
|
+
0: 'Undefined',
|
|
55413
|
+
1: 'Manual',
|
|
55414
|
+
2: 'Normal program',
|
|
55415
|
+
3: 'Aperture priority',
|
|
55416
|
+
4: 'Shutter priority',
|
|
55417
|
+
5: 'Creative program',
|
|
55418
|
+
6: 'Action program',
|
|
55419
|
+
7: 'Portrait mode',
|
|
55420
|
+
8: 'Landscape mode'
|
|
55421
|
+
},
|
|
55422
|
+
MeteringMode: {
|
|
55423
|
+
0: 'Unknown',
|
|
55424
|
+
1: 'Average',
|
|
55425
|
+
2: 'CenterWeightedAverage',
|
|
55426
|
+
3: 'Spot',
|
|
55427
|
+
4: 'MultiSpot',
|
|
55428
|
+
5: 'Pattern',
|
|
55429
|
+
6: 'Partial',
|
|
55430
|
+
255: 'Other'
|
|
55431
|
+
},
|
|
55432
|
+
LightSource: {
|
|
55433
|
+
0: 'Unknown',
|
|
55434
|
+
1: 'Daylight',
|
|
55435
|
+
2: 'Fluorescent',
|
|
55436
|
+
3: 'Tungsten (incandescent light)',
|
|
55437
|
+
4: 'Flash',
|
|
55438
|
+
9: 'Fine weather',
|
|
55439
|
+
10: 'Cloudy weather',
|
|
55440
|
+
11: 'Shade',
|
|
55441
|
+
12: 'Daylight fluorescent (D 5700 - 7100K)',
|
|
55442
|
+
13: 'Day white fluorescent (N 4600 - 5400K)',
|
|
55443
|
+
14: 'Cool white fluorescent (W 3900 - 4500K)',
|
|
55444
|
+
15: 'White fluorescent (WW 3200 - 3700K)',
|
|
55445
|
+
17: 'Standard light A',
|
|
55446
|
+
18: 'Standard light B',
|
|
55447
|
+
19: 'Standard light C',
|
|
55448
|
+
20: 'D55',
|
|
55449
|
+
21: 'D65',
|
|
55450
|
+
22: 'D75',
|
|
55451
|
+
23: 'D50',
|
|
55452
|
+
24: 'ISO studio tungsten',
|
|
55453
|
+
255: 'Other'
|
|
55454
|
+
},
|
|
55455
|
+
Flash: {
|
|
55456
|
+
0x0000: 'Flash did not fire',
|
|
55457
|
+
0x0001: 'Flash fired',
|
|
55458
|
+
0x0005: 'Strobe return light not detected',
|
|
55459
|
+
0x0007: 'Strobe return light detected',
|
|
55460
|
+
0x0009: 'Flash fired, compulsory flash mode',
|
|
55461
|
+
0x000d: 'Flash fired, compulsory flash mode, return light not detected',
|
|
55462
|
+
0x000f: 'Flash fired, compulsory flash mode, return light detected',
|
|
55463
|
+
0x0010: 'Flash did not fire, compulsory flash mode',
|
|
55464
|
+
0x0018: 'Flash did not fire, auto mode',
|
|
55465
|
+
0x0019: 'Flash fired, auto mode',
|
|
55466
|
+
0x001d: 'Flash fired, auto mode, return light not detected',
|
|
55467
|
+
0x001f: 'Flash fired, auto mode, return light detected',
|
|
55468
|
+
0x0020: 'No flash function',
|
|
55469
|
+
0x0041: 'Flash fired, red-eye reduction mode',
|
|
55470
|
+
0x0045: 'Flash fired, red-eye reduction mode, return light not detected',
|
|
55471
|
+
0x0047: 'Flash fired, red-eye reduction mode, return light detected',
|
|
55472
|
+
0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',
|
|
55473
|
+
0x004d:
|
|
55474
|
+
'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',
|
|
55475
|
+
0x004f:
|
|
55476
|
+
'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',
|
|
55477
|
+
0x0059: 'Flash fired, auto mode, red-eye reduction mode',
|
|
55478
|
+
0x005d:
|
|
55479
|
+
'Flash fired, auto mode, return light not detected, red-eye reduction mode',
|
|
55480
|
+
0x005f:
|
|
55481
|
+
'Flash fired, auto mode, return light detected, red-eye reduction mode'
|
|
55482
|
+
},
|
|
55483
|
+
SensingMethod: {
|
|
55484
|
+
1: 'Undefined',
|
|
55485
|
+
2: 'One-chip color area sensor',
|
|
55486
|
+
3: 'Two-chip color area sensor',
|
|
55487
|
+
4: 'Three-chip color area sensor',
|
|
55488
|
+
5: 'Color sequential area sensor',
|
|
55489
|
+
7: 'Trilinear sensor',
|
|
55490
|
+
8: 'Color sequential linear sensor'
|
|
55491
|
+
},
|
|
55492
|
+
SceneCaptureType: {
|
|
55493
|
+
0: 'Standard',
|
|
55494
|
+
1: 'Landscape',
|
|
55495
|
+
2: 'Portrait',
|
|
55496
|
+
3: 'Night scene'
|
|
55497
|
+
},
|
|
55498
|
+
SceneType: {
|
|
55499
|
+
1: 'Directly photographed'
|
|
55500
|
+
},
|
|
55501
|
+
CustomRendered: {
|
|
55502
|
+
0: 'Normal process',
|
|
55503
|
+
1: 'Custom process'
|
|
55504
|
+
},
|
|
55505
|
+
WhiteBalance: {
|
|
55506
|
+
0: 'Auto white balance',
|
|
55507
|
+
1: 'Manual white balance'
|
|
55508
|
+
},
|
|
55509
|
+
GainControl: {
|
|
55510
|
+
0: 'None',
|
|
55511
|
+
1: 'Low gain up',
|
|
55512
|
+
2: 'High gain up',
|
|
55513
|
+
3: 'Low gain down',
|
|
55514
|
+
4: 'High gain down'
|
|
55515
|
+
},
|
|
55516
|
+
Contrast: {
|
|
55517
|
+
0: 'Normal',
|
|
55518
|
+
1: 'Soft',
|
|
55519
|
+
2: 'Hard'
|
|
55520
|
+
},
|
|
55521
|
+
Saturation: {
|
|
55522
|
+
0: 'Normal',
|
|
55523
|
+
1: 'Low saturation',
|
|
55524
|
+
2: 'High saturation'
|
|
55525
|
+
},
|
|
55526
|
+
Sharpness: {
|
|
55527
|
+
0: 'Normal',
|
|
55528
|
+
1: 'Soft',
|
|
55529
|
+
2: 'Hard'
|
|
55530
|
+
},
|
|
55531
|
+
SubjectDistanceRange: {
|
|
55532
|
+
0: 'Unknown',
|
|
55533
|
+
1: 'Macro',
|
|
55534
|
+
2: 'Close view',
|
|
55535
|
+
3: 'Distant view'
|
|
55536
|
+
},
|
|
55537
|
+
FileSource: {
|
|
55538
|
+
3: 'DSC'
|
|
55539
|
+
},
|
|
55540
|
+
ComponentsConfiguration: {
|
|
55541
|
+
0: '',
|
|
55542
|
+
1: 'Y',
|
|
55543
|
+
2: 'Cb',
|
|
55544
|
+
3: 'Cr',
|
|
55545
|
+
4: 'R',
|
|
55546
|
+
5: 'G',
|
|
55547
|
+
6: 'B'
|
|
55548
|
+
},
|
|
55549
|
+
Orientation: {
|
|
55550
|
+
1: 'Original',
|
|
55551
|
+
2: 'Horizontal flip',
|
|
55552
|
+
3: 'Rotate 180° CCW',
|
|
55553
|
+
4: 'Vertical flip',
|
|
55554
|
+
5: 'Vertical flip + Rotate 90° CW',
|
|
55555
|
+
6: 'Rotate 90° CW',
|
|
55556
|
+
7: 'Horizontal flip + Rotate 90° CW',
|
|
55557
|
+
8: 'Rotate 90° CCW'
|
|
55558
|
+
}
|
|
55559
|
+
};
|
|
55560
|
+
|
|
55561
|
+
ExifMapProto.getText = function (name) {
|
|
55562
|
+
var value = this.get(name);
|
|
55563
|
+
switch (name) {
|
|
55564
|
+
case 'LightSource':
|
|
55565
|
+
case 'Flash':
|
|
55566
|
+
case 'MeteringMode':
|
|
55567
|
+
case 'ExposureProgram':
|
|
55568
|
+
case 'SensingMethod':
|
|
55569
|
+
case 'SceneCaptureType':
|
|
55570
|
+
case 'SceneType':
|
|
55571
|
+
case 'CustomRendered':
|
|
55572
|
+
case 'WhiteBalance':
|
|
55573
|
+
case 'GainControl':
|
|
55574
|
+
case 'Contrast':
|
|
55575
|
+
case 'Saturation':
|
|
55576
|
+
case 'Sharpness':
|
|
55577
|
+
case 'SubjectDistanceRange':
|
|
55578
|
+
case 'FileSource':
|
|
55579
|
+
case 'Orientation':
|
|
55580
|
+
return this.stringValues[name][value]
|
|
55581
|
+
case 'ExifVersion':
|
|
55582
|
+
case 'FlashpixVersion':
|
|
55583
|
+
if (!value) return
|
|
55584
|
+
return String.fromCharCode(value[0], value[1], value[2], value[3])
|
|
55585
|
+
case 'ComponentsConfiguration':
|
|
55586
|
+
if (!value) return
|
|
55587
|
+
return (
|
|
55588
|
+
this.stringValues[name][value[0]] +
|
|
55589
|
+
this.stringValues[name][value[1]] +
|
|
55590
|
+
this.stringValues[name][value[2]] +
|
|
55591
|
+
this.stringValues[name][value[3]]
|
|
55592
|
+
)
|
|
55593
|
+
case 'GPSVersionID':
|
|
55594
|
+
if (!value) return
|
|
55595
|
+
return value[0] + '.' + value[1] + '.' + value[2] + '.' + value[3]
|
|
55596
|
+
}
|
|
55597
|
+
return String(value)
|
|
55598
|
+
};
|
|
55599
|
+
|
|
55600
|
+
ExifMapProto.getAll = function () {
|
|
55601
|
+
var map = {};
|
|
55602
|
+
var prop;
|
|
55603
|
+
var obj;
|
|
55604
|
+
var name;
|
|
55605
|
+
for (prop in this) {
|
|
55606
|
+
if (Object.prototype.hasOwnProperty.call(this, prop)) {
|
|
55607
|
+
obj = this[prop];
|
|
55608
|
+
if (obj && obj.getAll) {
|
|
55609
|
+
map[this.ifds[prop].name] = obj.getAll();
|
|
55610
|
+
} else {
|
|
55611
|
+
name = this.tags[prop];
|
|
55612
|
+
if (name) map[name] = this.getText(name);
|
|
55613
|
+
}
|
|
55614
|
+
}
|
|
55615
|
+
}
|
|
55616
|
+
return map
|
|
55617
|
+
};
|
|
55618
|
+
|
|
55619
|
+
ExifMapProto.getName = function (tagCode) {
|
|
55620
|
+
var name = this.tags[tagCode];
|
|
55621
|
+
if (typeof name === 'object') return this.ifds[tagCode].name
|
|
55622
|
+
return name
|
|
55623
|
+
}
|
|
55624
|
+
|
|
55625
|
+
// Extend the map of tag names to tag codes:
|
|
55626
|
+
;(function () {
|
|
55627
|
+
var tags = ExifMapProto.tags;
|
|
55628
|
+
var prop;
|
|
55629
|
+
var ifd;
|
|
55630
|
+
var subTags;
|
|
55631
|
+
// Map the tag names to tags:
|
|
55632
|
+
for (prop in tags) {
|
|
55633
|
+
if (Object.prototype.hasOwnProperty.call(tags, prop)) {
|
|
55634
|
+
ifd = ExifMapProto.ifds[prop];
|
|
55635
|
+
if (ifd) {
|
|
55636
|
+
subTags = tags[prop];
|
|
55637
|
+
for (prop in subTags) {
|
|
55638
|
+
if (Object.prototype.hasOwnProperty.call(subTags, prop)) {
|
|
55639
|
+
ifd.map[subTags[prop]] = Number(prop);
|
|
55640
|
+
}
|
|
55641
|
+
}
|
|
55642
|
+
} else {
|
|
55643
|
+
ExifMapProto.map[tags[prop]] = Number(prop);
|
|
55644
|
+
}
|
|
55645
|
+
}
|
|
55646
|
+
}
|
|
55647
|
+
})();
|
|
55648
|
+
});
|
|
55649
|
+
}(loadImageExifMap));
|
|
55650
|
+
|
|
55651
|
+
var loadImageIptc = {exports: {}};
|
|
55652
|
+
|
|
55653
|
+
/*
|
|
55654
|
+
* JavaScript Load Image IPTC Parser
|
|
55655
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
55656
|
+
*
|
|
55657
|
+
* Copyright 2013, Sebastian Tschan
|
|
55658
|
+
* Copyright 2018, Dave Bevan
|
|
55659
|
+
* https://blueimp.net
|
|
55660
|
+
*
|
|
55661
|
+
* Licensed under the MIT license:
|
|
55662
|
+
* https://opensource.org/licenses/MIT
|
|
55663
|
+
*/
|
|
55664
|
+
|
|
55665
|
+
(function (module) {
|
|
55666
|
+
(function (factory) {
|
|
55667
|
+
if (module.exports) {
|
|
55668
|
+
factory(loadImage.exports, loadImageMeta.exports);
|
|
55669
|
+
} else {
|
|
55670
|
+
// Browser globals:
|
|
55671
|
+
factory(window.loadImage);
|
|
55672
|
+
}
|
|
55673
|
+
})(function (loadImage) {
|
|
55674
|
+
|
|
55675
|
+
/**
|
|
55676
|
+
* IPTC tag map
|
|
55677
|
+
*
|
|
55678
|
+
* @name IptcMap
|
|
55679
|
+
* @class
|
|
55680
|
+
*/
|
|
55681
|
+
function IptcMap() {}
|
|
55682
|
+
|
|
55683
|
+
IptcMap.prototype.map = {
|
|
55684
|
+
ObjectName: 5
|
|
55685
|
+
};
|
|
55686
|
+
|
|
55687
|
+
IptcMap.prototype.types = {
|
|
55688
|
+
0: 'Uint16', // ApplicationRecordVersion
|
|
55689
|
+
200: 'Uint16', // ObjectPreviewFileFormat
|
|
55690
|
+
201: 'Uint16', // ObjectPreviewFileVersion
|
|
55691
|
+
202: 'binary' // ObjectPreviewData
|
|
55692
|
+
};
|
|
55693
|
+
|
|
55694
|
+
/**
|
|
55695
|
+
* Retrieves IPTC tag value
|
|
55696
|
+
*
|
|
55697
|
+
* @param {number|string} id IPTC tag code or name
|
|
55698
|
+
* @returns {object} IPTC tag value
|
|
55699
|
+
*/
|
|
55700
|
+
IptcMap.prototype.get = function (id) {
|
|
55701
|
+
return this[id] || this[this.map[id]]
|
|
55702
|
+
};
|
|
55703
|
+
|
|
55704
|
+
/**
|
|
55705
|
+
* Retrieves string for the given DataView and range
|
|
55706
|
+
*
|
|
55707
|
+
* @param {DataView} dataView Data view interface
|
|
55708
|
+
* @param {number} offset Offset start
|
|
55709
|
+
* @param {number} length Offset length
|
|
55710
|
+
* @returns {string} String value
|
|
55711
|
+
*/
|
|
55712
|
+
function getStringValue(dataView, offset, length) {
|
|
55713
|
+
var outstr = '';
|
|
55714
|
+
var end = offset + length;
|
|
55715
|
+
for (var n = offset; n < end; n += 1) {
|
|
55716
|
+
outstr += String.fromCharCode(dataView.getUint8(n));
|
|
55717
|
+
}
|
|
55718
|
+
return outstr
|
|
55719
|
+
}
|
|
55720
|
+
|
|
55721
|
+
/**
|
|
55722
|
+
* Retrieves tag value for the given DataView and range
|
|
55723
|
+
*
|
|
55724
|
+
* @param {number} tagCode tag code
|
|
55725
|
+
* @param {IptcMap} map IPTC tag map
|
|
55726
|
+
* @param {DataView} dataView Data view interface
|
|
55727
|
+
* @param {number} offset Range start
|
|
55728
|
+
* @param {number} length Range length
|
|
55729
|
+
* @returns {object} Tag value
|
|
55730
|
+
*/
|
|
55731
|
+
function getTagValue(tagCode, map, dataView, offset, length) {
|
|
55732
|
+
if (map.types[tagCode] === 'binary') {
|
|
55733
|
+
return new Blob([dataView.buffer.slice(offset, offset + length)])
|
|
55734
|
+
}
|
|
55735
|
+
if (map.types[tagCode] === 'Uint16') {
|
|
55736
|
+
return dataView.getUint16(offset)
|
|
55737
|
+
}
|
|
55738
|
+
return getStringValue(dataView, offset, length)
|
|
55739
|
+
}
|
|
55740
|
+
|
|
55741
|
+
/**
|
|
55742
|
+
* Combines IPTC value with existing ones.
|
|
55743
|
+
*
|
|
55744
|
+
* @param {object} value Existing IPTC field value
|
|
55745
|
+
* @param {object} newValue New IPTC field value
|
|
55746
|
+
* @returns {object} Resulting IPTC field value
|
|
55747
|
+
*/
|
|
55748
|
+
function combineTagValues(value, newValue) {
|
|
55749
|
+
if (value === undefined) return newValue
|
|
55750
|
+
if (value instanceof Array) {
|
|
55751
|
+
value.push(newValue);
|
|
55752
|
+
return value
|
|
55753
|
+
}
|
|
55754
|
+
return [value, newValue]
|
|
55755
|
+
}
|
|
55756
|
+
|
|
55757
|
+
/**
|
|
55758
|
+
* Parses IPTC tags.
|
|
55759
|
+
*
|
|
55760
|
+
* @param {DataView} dataView Data view interface
|
|
55761
|
+
* @param {number} segmentOffset Segment offset
|
|
55762
|
+
* @param {number} segmentLength Segment length
|
|
55763
|
+
* @param {object} data Data export object
|
|
55764
|
+
* @param {object} includeTags Map of tags to include
|
|
55765
|
+
* @param {object} excludeTags Map of tags to exclude
|
|
55766
|
+
*/
|
|
55767
|
+
function parseIptcTags(
|
|
55768
|
+
dataView,
|
|
55769
|
+
segmentOffset,
|
|
55770
|
+
segmentLength,
|
|
55771
|
+
data,
|
|
55772
|
+
includeTags,
|
|
55773
|
+
excludeTags
|
|
55774
|
+
) {
|
|
55775
|
+
var value, tagSize, tagCode;
|
|
55776
|
+
var segmentEnd = segmentOffset + segmentLength;
|
|
55777
|
+
var offset = segmentOffset;
|
|
55778
|
+
while (offset < segmentEnd) {
|
|
55779
|
+
if (
|
|
55780
|
+
dataView.getUint8(offset) === 0x1c && // tag marker
|
|
55781
|
+
dataView.getUint8(offset + 1) === 0x02 // record number, only handles v2
|
|
55782
|
+
) {
|
|
55783
|
+
tagCode = dataView.getUint8(offset + 2);
|
|
55784
|
+
if (
|
|
55785
|
+
(!includeTags || includeTags[tagCode]) &&
|
|
55786
|
+
(!excludeTags || !excludeTags[tagCode])
|
|
55787
|
+
) {
|
|
55788
|
+
tagSize = dataView.getInt16(offset + 3);
|
|
55789
|
+
value = getTagValue(tagCode, data.iptc, dataView, offset + 5, tagSize);
|
|
55790
|
+
data.iptc[tagCode] = combineTagValues(data.iptc[tagCode], value);
|
|
55791
|
+
if (data.iptcOffsets) {
|
|
55792
|
+
data.iptcOffsets[tagCode] = offset;
|
|
55793
|
+
}
|
|
55794
|
+
}
|
|
55795
|
+
}
|
|
55796
|
+
offset += 1;
|
|
55797
|
+
}
|
|
55798
|
+
}
|
|
55799
|
+
|
|
55800
|
+
/**
|
|
55801
|
+
* Tests if field segment starts at offset.
|
|
55802
|
+
*
|
|
55803
|
+
* @param {DataView} dataView Data view interface
|
|
55804
|
+
* @param {number} offset Segment offset
|
|
55805
|
+
* @returns {boolean} True if '8BIM<EOT><EOT>' exists at offset
|
|
55806
|
+
*/
|
|
55807
|
+
function isSegmentStart(dataView, offset) {
|
|
55808
|
+
return (
|
|
55809
|
+
dataView.getUint32(offset) === 0x3842494d && // Photoshop segment start
|
|
55810
|
+
dataView.getUint16(offset + 4) === 0x0404 // IPTC segment start
|
|
55811
|
+
)
|
|
55812
|
+
}
|
|
55813
|
+
|
|
55814
|
+
/**
|
|
55815
|
+
* Returns header length.
|
|
55816
|
+
*
|
|
55817
|
+
* @param {DataView} dataView Data view interface
|
|
55818
|
+
* @param {number} offset Segment offset
|
|
55819
|
+
* @returns {number} Header length
|
|
55820
|
+
*/
|
|
55821
|
+
function getHeaderLength(dataView, offset) {
|
|
55822
|
+
var length = dataView.getUint8(offset + 7);
|
|
55823
|
+
if (length % 2 !== 0) length += 1;
|
|
55824
|
+
// Check for pre photoshop 6 format
|
|
55825
|
+
if (length === 0) {
|
|
55826
|
+
// Always 4
|
|
55827
|
+
length = 4;
|
|
55828
|
+
}
|
|
55829
|
+
return length
|
|
55830
|
+
}
|
|
55831
|
+
|
|
55832
|
+
loadImage.parseIptcData = function (dataView, offset, length, data, options) {
|
|
55833
|
+
if (options.disableIptc) {
|
|
55834
|
+
return
|
|
55835
|
+
}
|
|
55836
|
+
var markerLength = offset + length;
|
|
55837
|
+
while (offset + 8 < markerLength) {
|
|
55838
|
+
if (isSegmentStart(dataView, offset)) {
|
|
55839
|
+
var headerLength = getHeaderLength(dataView, offset);
|
|
55840
|
+
var segmentOffset = offset + 8 + headerLength;
|
|
55841
|
+
if (segmentOffset > markerLength) {
|
|
55842
|
+
// eslint-disable-next-line no-console
|
|
55843
|
+
console.log('Invalid IPTC data: Invalid segment offset.');
|
|
55844
|
+
break
|
|
55845
|
+
}
|
|
55846
|
+
var segmentLength = dataView.getUint16(offset + 6 + headerLength);
|
|
55847
|
+
if (offset + segmentLength > markerLength) {
|
|
55848
|
+
// eslint-disable-next-line no-console
|
|
55849
|
+
console.log('Invalid IPTC data: Invalid segment size.');
|
|
55850
|
+
break
|
|
55851
|
+
}
|
|
55852
|
+
// Create the iptc object to store the tags:
|
|
55853
|
+
data.iptc = new IptcMap();
|
|
55854
|
+
if (!options.disableIptcOffsets) {
|
|
55855
|
+
data.iptcOffsets = new IptcMap();
|
|
55856
|
+
}
|
|
55857
|
+
parseIptcTags(
|
|
55858
|
+
dataView,
|
|
55859
|
+
segmentOffset,
|
|
55860
|
+
segmentLength,
|
|
55861
|
+
data,
|
|
55862
|
+
options.includeIptcTags,
|
|
55863
|
+
options.excludeIptcTags || { 202: true } // ObjectPreviewData
|
|
55864
|
+
);
|
|
55865
|
+
return
|
|
55866
|
+
}
|
|
55867
|
+
// eslint-disable-next-line no-param-reassign
|
|
55868
|
+
offset += 1;
|
|
55869
|
+
}
|
|
55870
|
+
};
|
|
55871
|
+
|
|
55872
|
+
// Registers this IPTC parser for the APP13 JPEG metadata segment:
|
|
55873
|
+
loadImage.metaDataParsers.jpeg[0xffed].push(loadImage.parseIptcData);
|
|
55874
|
+
|
|
55875
|
+
loadImage.IptcMap = IptcMap;
|
|
55876
|
+
|
|
55877
|
+
// Adds the following properties to the parseMetaData callback data:
|
|
55878
|
+
// - iptc: The iptc tags, parsed by the parseIptcData method
|
|
55879
|
+
|
|
55880
|
+
// Adds the following options to the parseMetaData method:
|
|
55881
|
+
// - disableIptc: Disables IPTC parsing when true.
|
|
55882
|
+
// - disableIptcOffsets: Disables storing IPTC tag offsets when true.
|
|
55883
|
+
// - includeIptcTags: A map of IPTC tags to include for parsing.
|
|
55884
|
+
// - excludeIptcTags: A map of IPTC tags to exclude from parsing.
|
|
55885
|
+
});
|
|
55886
|
+
}(loadImageIptc));
|
|
55887
|
+
|
|
55888
|
+
var loadImageIptcMap = {exports: {}};
|
|
55889
|
+
|
|
55890
|
+
/*
|
|
55891
|
+
* JavaScript Load Image IPTC Map
|
|
55892
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
55893
|
+
*
|
|
55894
|
+
* Copyright 2013, Sebastian Tschan
|
|
55895
|
+
* Copyright 2018, Dave Bevan
|
|
55896
|
+
*
|
|
55897
|
+
* IPTC tags mapping based on
|
|
55898
|
+
* https://iptc.org/standards/photo-metadata
|
|
55899
|
+
* https://exiftool.org/TagNames/IPTC.html
|
|
55900
|
+
*
|
|
55901
|
+
* Licensed under the MIT license:
|
|
55902
|
+
* https://opensource.org/licenses/MIT
|
|
55903
|
+
*/
|
|
55904
|
+
|
|
55905
|
+
(function (module) {
|
|
55906
|
+
(function (factory) {
|
|
55907
|
+
if (module.exports) {
|
|
55908
|
+
factory(loadImage.exports, loadImageIptc.exports);
|
|
55909
|
+
} else {
|
|
55910
|
+
// Browser globals:
|
|
55911
|
+
factory(window.loadImage);
|
|
55912
|
+
}
|
|
55913
|
+
})(function (loadImage) {
|
|
55914
|
+
|
|
55915
|
+
var IptcMapProto = loadImage.IptcMap.prototype;
|
|
55916
|
+
|
|
55917
|
+
IptcMapProto.tags = {
|
|
55918
|
+
0: 'ApplicationRecordVersion',
|
|
55919
|
+
3: 'ObjectTypeReference',
|
|
55920
|
+
4: 'ObjectAttributeReference',
|
|
55921
|
+
5: 'ObjectName',
|
|
55922
|
+
7: 'EditStatus',
|
|
55923
|
+
8: 'EditorialUpdate',
|
|
55924
|
+
10: 'Urgency',
|
|
55925
|
+
12: 'SubjectReference',
|
|
55926
|
+
15: 'Category',
|
|
55927
|
+
20: 'SupplementalCategories',
|
|
55928
|
+
22: 'FixtureIdentifier',
|
|
55929
|
+
25: 'Keywords',
|
|
55930
|
+
26: 'ContentLocationCode',
|
|
55931
|
+
27: 'ContentLocationName',
|
|
55932
|
+
30: 'ReleaseDate',
|
|
55933
|
+
35: 'ReleaseTime',
|
|
55934
|
+
37: 'ExpirationDate',
|
|
55935
|
+
38: 'ExpirationTime',
|
|
55936
|
+
40: 'SpecialInstructions',
|
|
55937
|
+
42: 'ActionAdvised',
|
|
55938
|
+
45: 'ReferenceService',
|
|
55939
|
+
47: 'ReferenceDate',
|
|
55940
|
+
50: 'ReferenceNumber',
|
|
55941
|
+
55: 'DateCreated',
|
|
55942
|
+
60: 'TimeCreated',
|
|
55943
|
+
62: 'DigitalCreationDate',
|
|
55944
|
+
63: 'DigitalCreationTime',
|
|
55945
|
+
65: 'OriginatingProgram',
|
|
55946
|
+
70: 'ProgramVersion',
|
|
55947
|
+
75: 'ObjectCycle',
|
|
55948
|
+
80: 'Byline',
|
|
55949
|
+
85: 'BylineTitle',
|
|
55950
|
+
90: 'City',
|
|
55951
|
+
92: 'Sublocation',
|
|
55952
|
+
95: 'State',
|
|
55953
|
+
100: 'CountryCode',
|
|
55954
|
+
101: 'Country',
|
|
55955
|
+
103: 'OriginalTransmissionReference',
|
|
55956
|
+
105: 'Headline',
|
|
55957
|
+
110: 'Credit',
|
|
55958
|
+
115: 'Source',
|
|
55959
|
+
116: 'CopyrightNotice',
|
|
55960
|
+
118: 'Contact',
|
|
55961
|
+
120: 'Caption',
|
|
55962
|
+
121: 'LocalCaption',
|
|
55963
|
+
122: 'Writer',
|
|
55964
|
+
125: 'RasterizedCaption',
|
|
55965
|
+
130: 'ImageType',
|
|
55966
|
+
131: 'ImageOrientation',
|
|
55967
|
+
135: 'LanguageIdentifier',
|
|
55968
|
+
150: 'AudioType',
|
|
55969
|
+
151: 'AudioSamplingRate',
|
|
55970
|
+
152: 'AudioSamplingResolution',
|
|
55971
|
+
153: 'AudioDuration',
|
|
55972
|
+
154: 'AudioOutcue',
|
|
55973
|
+
184: 'JobID',
|
|
55974
|
+
185: 'MasterDocumentID',
|
|
55975
|
+
186: 'ShortDocumentID',
|
|
55976
|
+
187: 'UniqueDocumentID',
|
|
55977
|
+
188: 'OwnerID',
|
|
55978
|
+
200: 'ObjectPreviewFileFormat',
|
|
55979
|
+
201: 'ObjectPreviewFileVersion',
|
|
55980
|
+
202: 'ObjectPreviewData',
|
|
55981
|
+
221: 'Prefs',
|
|
55982
|
+
225: 'ClassifyState',
|
|
55983
|
+
228: 'SimilarityIndex',
|
|
55984
|
+
230: 'DocumentNotes',
|
|
55985
|
+
231: 'DocumentHistory',
|
|
55986
|
+
232: 'ExifCameraInfo',
|
|
55987
|
+
255: 'CatalogSets'
|
|
55988
|
+
};
|
|
55989
|
+
|
|
55990
|
+
IptcMapProto.stringValues = {
|
|
55991
|
+
10: {
|
|
55992
|
+
0: '0 (reserved)',
|
|
55993
|
+
1: '1 (most urgent)',
|
|
55994
|
+
2: '2',
|
|
55995
|
+
3: '3',
|
|
55996
|
+
4: '4',
|
|
55997
|
+
5: '5 (normal urgency)',
|
|
55998
|
+
6: '6',
|
|
55999
|
+
7: '7',
|
|
56000
|
+
8: '8 (least urgent)',
|
|
56001
|
+
9: '9 (user-defined priority)'
|
|
56002
|
+
},
|
|
56003
|
+
75: {
|
|
56004
|
+
a: 'Morning',
|
|
56005
|
+
b: 'Both Morning and Evening',
|
|
56006
|
+
p: 'Evening'
|
|
56007
|
+
},
|
|
56008
|
+
131: {
|
|
56009
|
+
L: 'Landscape',
|
|
56010
|
+
P: 'Portrait',
|
|
56011
|
+
S: 'Square'
|
|
56012
|
+
}
|
|
56013
|
+
};
|
|
56014
|
+
|
|
56015
|
+
IptcMapProto.getText = function (id) {
|
|
56016
|
+
var value = this.get(id);
|
|
56017
|
+
var tagCode = this.map[id];
|
|
56018
|
+
var stringValue = this.stringValues[tagCode];
|
|
56019
|
+
if (stringValue) return stringValue[value]
|
|
56020
|
+
return String(value)
|
|
56021
|
+
};
|
|
56022
|
+
|
|
56023
|
+
IptcMapProto.getAll = function () {
|
|
56024
|
+
var map = {};
|
|
56025
|
+
var prop;
|
|
56026
|
+
var name;
|
|
56027
|
+
for (prop in this) {
|
|
56028
|
+
if (Object.prototype.hasOwnProperty.call(this, prop)) {
|
|
56029
|
+
name = this.tags[prop];
|
|
56030
|
+
if (name) map[name] = this.getText(name);
|
|
56031
|
+
}
|
|
56032
|
+
}
|
|
56033
|
+
return map
|
|
56034
|
+
};
|
|
56035
|
+
|
|
56036
|
+
IptcMapProto.getName = function (tagCode) {
|
|
56037
|
+
return this.tags[tagCode]
|
|
56038
|
+
}
|
|
56039
|
+
|
|
56040
|
+
// Extend the map of tag names to tag codes:
|
|
56041
|
+
;(function () {
|
|
56042
|
+
var tags = IptcMapProto.tags;
|
|
56043
|
+
var map = IptcMapProto.map || {};
|
|
56044
|
+
var prop;
|
|
56045
|
+
// Map the tag names to tags:
|
|
56046
|
+
for (prop in tags) {
|
|
56047
|
+
if (Object.prototype.hasOwnProperty.call(tags, prop)) {
|
|
56048
|
+
map[tags[prop]] = Number(prop);
|
|
56049
|
+
}
|
|
56050
|
+
}
|
|
56051
|
+
})();
|
|
56052
|
+
});
|
|
56053
|
+
}(loadImageIptcMap));
|
|
56054
|
+
|
|
56055
|
+
var loadImageOrientation = {exports: {}};
|
|
56056
|
+
|
|
56057
|
+
/*
|
|
56058
|
+
* JavaScript Load Image Orientation
|
|
56059
|
+
* https://github.com/blueimp/JavaScript-Load-Image
|
|
56060
|
+
*
|
|
56061
|
+
* Copyright 2013, Sebastian Tschan
|
|
56062
|
+
* https://blueimp.net
|
|
56063
|
+
*
|
|
56064
|
+
* Licensed under the MIT license:
|
|
56065
|
+
* https://opensource.org/licenses/MIT
|
|
56066
|
+
*/
|
|
56067
|
+
|
|
56068
|
+
(function (module) {
|
|
56069
|
+
(function (factory) {
|
|
56070
|
+
if (module.exports) {
|
|
56071
|
+
factory(
|
|
56072
|
+
loadImage.exports,
|
|
56073
|
+
loadImageScale.exports,
|
|
56074
|
+
loadImageMeta.exports
|
|
56075
|
+
);
|
|
56076
|
+
} else {
|
|
56077
|
+
// Browser globals:
|
|
56078
|
+
factory(window.loadImage);
|
|
56079
|
+
}
|
|
56080
|
+
})(function (loadImage) {
|
|
56081
|
+
|
|
56082
|
+
var originalTransform = loadImage.transform;
|
|
56083
|
+
var originalRequiresCanvas = loadImage.requiresCanvas;
|
|
56084
|
+
var originalRequiresMetaData = loadImage.requiresMetaData;
|
|
56085
|
+
var originalTransformCoordinates = loadImage.transformCoordinates;
|
|
56086
|
+
var originalGetTransformedOptions = loadImage.getTransformedOptions
|
|
56087
|
+
|
|
56088
|
+
;(function ($) {
|
|
56089
|
+
// Guard for non-browser environments (e.g. server-side rendering):
|
|
56090
|
+
if (!$.global.document) return
|
|
56091
|
+
// black+white 3x2 JPEG, with the following meta information set:
|
|
56092
|
+
// - EXIF Orientation: 6 (Rotated 90° CCW)
|
|
56093
|
+
// Image data layout (B=black, F=white):
|
|
56094
|
+
// BFF
|
|
56095
|
+
// BBB
|
|
56096
|
+
var testImageURL =
|
|
56097
|
+
'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +
|
|
56098
|
+
'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +
|
|
56099
|
+
'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +
|
|
56100
|
+
'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAIAAwMBEQACEQEDEQH/x' +
|
|
56101
|
+
'ABRAAEAAAAAAAAAAAAAAAAAAAAKEAEBAQADAQEAAAAAAAAAAAAGBQQDCAkCBwEBAAAAAAA' +
|
|
56102
|
+
'AAAAAAAAAAAAAABEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AG8T9NfSMEVMhQ' +
|
|
56103
|
+
'voP3fFiRZ+MTHDifa/95OFSZU5OzRzxkyejv8ciEfhSceSXGjS8eSdLnZc2HDm4M3BxcXw' +
|
|
56104
|
+
'H/9k=';
|
|
56105
|
+
var img = document.createElement('img');
|
|
56106
|
+
img.onload = function () {
|
|
56107
|
+
// Check if the browser supports automatic image orientation:
|
|
56108
|
+
$.orientation = img.width === 2 && img.height === 3;
|
|
56109
|
+
if ($.orientation) {
|
|
56110
|
+
var canvas = $.createCanvas(1, 1, true);
|
|
56111
|
+
var ctx = canvas.getContext('2d');
|
|
56112
|
+
ctx.drawImage(img, 1, 1, 1, 1, 0, 0, 1, 1);
|
|
56113
|
+
// Check if the source image coordinates (sX, sY, sWidth, sHeight) are
|
|
56114
|
+
// correctly applied to the auto-orientated image, which should result
|
|
56115
|
+
// in a white opaque pixel (e.g. in Safari).
|
|
56116
|
+
// Browsers that show a transparent pixel (e.g. Chromium) fail to crop
|
|
56117
|
+
// auto-oriented images correctly and require a workaround, e.g.
|
|
56118
|
+
// drawing the complete source image to an intermediate canvas first.
|
|
56119
|
+
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1074354
|
|
56120
|
+
$.orientationCropBug =
|
|
56121
|
+
ctx.getImageData(0, 0, 1, 1).data.toString() !== '255,255,255,255';
|
|
56122
|
+
}
|
|
56123
|
+
};
|
|
56124
|
+
img.src = testImageURL;
|
|
56125
|
+
})(loadImage);
|
|
56126
|
+
|
|
56127
|
+
/**
|
|
56128
|
+
* Determines if the orientation requires a canvas element.
|
|
56129
|
+
*
|
|
56130
|
+
* @param {object} [options] Options object
|
|
56131
|
+
* @param {boolean} [withMetaData] Is metadata required for orientation
|
|
56132
|
+
* @returns {boolean} Returns true if orientation requires canvas/meta
|
|
56133
|
+
*/
|
|
56134
|
+
function requiresCanvasOrientation(options, withMetaData) {
|
|
56135
|
+
var orientation = options && options.orientation;
|
|
56136
|
+
return (
|
|
56137
|
+
// Exif orientation for browsers without automatic image orientation:
|
|
56138
|
+
(orientation === true && !loadImage.orientation) ||
|
|
56139
|
+
// Orientation reset for browsers with automatic image orientation:
|
|
56140
|
+
(orientation === 1 && loadImage.orientation) ||
|
|
56141
|
+
// Orientation to defined value, requires meta for orientation reset only:
|
|
56142
|
+
((!withMetaData || loadImage.orientation) &&
|
|
56143
|
+
orientation > 1 &&
|
|
56144
|
+
orientation < 9)
|
|
56145
|
+
)
|
|
56146
|
+
}
|
|
56147
|
+
|
|
56148
|
+
/**
|
|
56149
|
+
* Determines if the image requires an orientation change.
|
|
56150
|
+
*
|
|
56151
|
+
* @param {number} [orientation] Defined orientation value
|
|
56152
|
+
* @param {number} [autoOrientation] Auto-orientation based on Exif data
|
|
56153
|
+
* @returns {boolean} Returns true if an orientation change is required
|
|
56154
|
+
*/
|
|
56155
|
+
function requiresOrientationChange(orientation, autoOrientation) {
|
|
56156
|
+
return (
|
|
56157
|
+
orientation !== autoOrientation &&
|
|
56158
|
+
((orientation === 1 && autoOrientation > 1 && autoOrientation < 9) ||
|
|
56159
|
+
(orientation > 1 && orientation < 9))
|
|
56160
|
+
)
|
|
56161
|
+
}
|
|
56162
|
+
|
|
56163
|
+
/**
|
|
56164
|
+
* Determines orientation combinations that require a rotation by 180°.
|
|
56165
|
+
*
|
|
56166
|
+
* The following is a list of combinations that return true:
|
|
56167
|
+
*
|
|
56168
|
+
* 2 (flip) => 5 (rot90,flip), 7 (rot90,flip), 6 (rot90), 8 (rot90)
|
|
56169
|
+
* 4 (flip) => 5 (rot90,flip), 7 (rot90,flip), 6 (rot90), 8 (rot90)
|
|
56170
|
+
*
|
|
56171
|
+
* 5 (rot90,flip) => 2 (flip), 4 (flip), 6 (rot90), 8 (rot90)
|
|
56172
|
+
* 7 (rot90,flip) => 2 (flip), 4 (flip), 6 (rot90), 8 (rot90)
|
|
56173
|
+
*
|
|
56174
|
+
* 6 (rot90) => 2 (flip), 4 (flip), 5 (rot90,flip), 7 (rot90,flip)
|
|
56175
|
+
* 8 (rot90) => 2 (flip), 4 (flip), 5 (rot90,flip), 7 (rot90,flip)
|
|
56176
|
+
*
|
|
56177
|
+
* @param {number} [orientation] Defined orientation value
|
|
56178
|
+
* @param {number} [autoOrientation] Auto-orientation based on Exif data
|
|
56179
|
+
* @returns {boolean} Returns true if rotation by 180° is required
|
|
56180
|
+
*/
|
|
56181
|
+
function requiresRot180(orientation, autoOrientation) {
|
|
56182
|
+
if (autoOrientation > 1 && autoOrientation < 9) {
|
|
56183
|
+
switch (orientation) {
|
|
56184
|
+
case 2:
|
|
56185
|
+
case 4:
|
|
56186
|
+
return autoOrientation > 4
|
|
56187
|
+
case 5:
|
|
56188
|
+
case 7:
|
|
56189
|
+
return autoOrientation % 2 === 0
|
|
56190
|
+
case 6:
|
|
56191
|
+
case 8:
|
|
56192
|
+
return (
|
|
56193
|
+
autoOrientation === 2 ||
|
|
56194
|
+
autoOrientation === 4 ||
|
|
56195
|
+
autoOrientation === 5 ||
|
|
56196
|
+
autoOrientation === 7
|
|
56197
|
+
)
|
|
56198
|
+
}
|
|
56199
|
+
}
|
|
56200
|
+
return false
|
|
56201
|
+
}
|
|
56202
|
+
|
|
56203
|
+
// Determines if the target image should be a canvas element:
|
|
56204
|
+
loadImage.requiresCanvas = function (options) {
|
|
56205
|
+
return (
|
|
56206
|
+
requiresCanvasOrientation(options) ||
|
|
56207
|
+
originalRequiresCanvas.call(loadImage, options)
|
|
56208
|
+
)
|
|
56209
|
+
};
|
|
56210
|
+
|
|
56211
|
+
// Determines if metadata should be loaded automatically:
|
|
56212
|
+
loadImage.requiresMetaData = function (options) {
|
|
56213
|
+
return (
|
|
56214
|
+
requiresCanvasOrientation(options, true) ||
|
|
56215
|
+
originalRequiresMetaData.call(loadImage, options)
|
|
56216
|
+
)
|
|
56217
|
+
};
|
|
56218
|
+
|
|
56219
|
+
loadImage.transform = function (img, options, callback, file, data) {
|
|
56220
|
+
originalTransform.call(
|
|
56221
|
+
loadImage,
|
|
56222
|
+
img,
|
|
56223
|
+
options,
|
|
56224
|
+
function (img, data) {
|
|
56225
|
+
if (data) {
|
|
56226
|
+
var autoOrientation =
|
|
56227
|
+
loadImage.orientation && data.exif && data.exif.get('Orientation');
|
|
56228
|
+
if (autoOrientation > 4 && autoOrientation < 9) {
|
|
56229
|
+
// Automatic image orientation switched image dimensions
|
|
56230
|
+
var originalWidth = data.originalWidth;
|
|
56231
|
+
var originalHeight = data.originalHeight;
|
|
56232
|
+
data.originalWidth = originalHeight;
|
|
56233
|
+
data.originalHeight = originalWidth;
|
|
56234
|
+
}
|
|
56235
|
+
}
|
|
56236
|
+
callback(img, data);
|
|
56237
|
+
},
|
|
56238
|
+
file,
|
|
56239
|
+
data
|
|
56240
|
+
);
|
|
56241
|
+
};
|
|
56242
|
+
|
|
56243
|
+
// Transforms coordinate and dimension options
|
|
56244
|
+
// based on the given orientation option:
|
|
56245
|
+
loadImage.getTransformedOptions = function (img, opts, data) {
|
|
56246
|
+
var options = originalGetTransformedOptions.call(loadImage, img, opts);
|
|
56247
|
+
var exifOrientation = data.exif && data.exif.get('Orientation');
|
|
56248
|
+
var orientation = options.orientation;
|
|
56249
|
+
var autoOrientation = loadImage.orientation && exifOrientation;
|
|
56250
|
+
if (orientation === true) orientation = exifOrientation;
|
|
56251
|
+
if (!requiresOrientationChange(orientation, autoOrientation)) {
|
|
56252
|
+
return options
|
|
56253
|
+
}
|
|
56254
|
+
var top = options.top;
|
|
56255
|
+
var right = options.right;
|
|
56256
|
+
var bottom = options.bottom;
|
|
56257
|
+
var left = options.left;
|
|
56258
|
+
var newOptions = {};
|
|
56259
|
+
for (var i in options) {
|
|
56260
|
+
if (Object.prototype.hasOwnProperty.call(options, i)) {
|
|
56261
|
+
newOptions[i] = options[i];
|
|
56262
|
+
}
|
|
56263
|
+
}
|
|
56264
|
+
newOptions.orientation = orientation;
|
|
56265
|
+
if (
|
|
56266
|
+
(orientation > 4 && !(autoOrientation > 4)) ||
|
|
56267
|
+
(orientation < 5 && autoOrientation > 4)
|
|
56268
|
+
) {
|
|
56269
|
+
// Image dimensions and target dimensions are switched
|
|
56270
|
+
newOptions.maxWidth = options.maxHeight;
|
|
56271
|
+
newOptions.maxHeight = options.maxWidth;
|
|
56272
|
+
newOptions.minWidth = options.minHeight;
|
|
56273
|
+
newOptions.minHeight = options.minWidth;
|
|
56274
|
+
newOptions.sourceWidth = options.sourceHeight;
|
|
56275
|
+
newOptions.sourceHeight = options.sourceWidth;
|
|
56276
|
+
}
|
|
56277
|
+
if (autoOrientation > 1) {
|
|
56278
|
+
// Browsers which correctly apply source image coordinates to
|
|
56279
|
+
// auto-oriented images
|
|
56280
|
+
switch (autoOrientation) {
|
|
56281
|
+
case 2:
|
|
56282
|
+
// Horizontal flip
|
|
56283
|
+
right = options.left;
|
|
56284
|
+
left = options.right;
|
|
56285
|
+
break
|
|
56286
|
+
case 3:
|
|
56287
|
+
// 180° Rotate CCW
|
|
56288
|
+
top = options.bottom;
|
|
56289
|
+
right = options.left;
|
|
56290
|
+
bottom = options.top;
|
|
56291
|
+
left = options.right;
|
|
56292
|
+
break
|
|
56293
|
+
case 4:
|
|
56294
|
+
// Vertical flip
|
|
56295
|
+
top = options.bottom;
|
|
56296
|
+
bottom = options.top;
|
|
56297
|
+
break
|
|
56298
|
+
case 5:
|
|
56299
|
+
// Horizontal flip + 90° Rotate CCW
|
|
56300
|
+
top = options.left;
|
|
56301
|
+
right = options.bottom;
|
|
56302
|
+
bottom = options.right;
|
|
56303
|
+
left = options.top;
|
|
56304
|
+
break
|
|
56305
|
+
case 6:
|
|
56306
|
+
// 90° Rotate CCW
|
|
56307
|
+
top = options.left;
|
|
56308
|
+
right = options.top;
|
|
56309
|
+
bottom = options.right;
|
|
56310
|
+
left = options.bottom;
|
|
56311
|
+
break
|
|
56312
|
+
case 7:
|
|
56313
|
+
// Vertical flip + 90° Rotate CCW
|
|
56314
|
+
top = options.right;
|
|
56315
|
+
right = options.top;
|
|
56316
|
+
bottom = options.left;
|
|
56317
|
+
left = options.bottom;
|
|
56318
|
+
break
|
|
56319
|
+
case 8:
|
|
56320
|
+
// 90° Rotate CW
|
|
56321
|
+
top = options.right;
|
|
56322
|
+
right = options.bottom;
|
|
56323
|
+
bottom = options.left;
|
|
56324
|
+
left = options.top;
|
|
56325
|
+
break
|
|
56326
|
+
}
|
|
56327
|
+
// Some orientation combinations require additional rotation by 180°:
|
|
56328
|
+
if (requiresRot180(orientation, autoOrientation)) {
|
|
56329
|
+
var tmpTop = top;
|
|
56330
|
+
var tmpRight = right;
|
|
56331
|
+
top = bottom;
|
|
56332
|
+
right = left;
|
|
56333
|
+
bottom = tmpTop;
|
|
56334
|
+
left = tmpRight;
|
|
56335
|
+
}
|
|
56336
|
+
}
|
|
56337
|
+
newOptions.top = top;
|
|
56338
|
+
newOptions.right = right;
|
|
56339
|
+
newOptions.bottom = bottom;
|
|
56340
|
+
newOptions.left = left;
|
|
56341
|
+
// Account for defined browser orientation:
|
|
56342
|
+
switch (orientation) {
|
|
56343
|
+
case 2:
|
|
56344
|
+
// Horizontal flip
|
|
56345
|
+
newOptions.right = left;
|
|
56346
|
+
newOptions.left = right;
|
|
56347
|
+
break
|
|
56348
|
+
case 3:
|
|
56349
|
+
// 180° Rotate CCW
|
|
56350
|
+
newOptions.top = bottom;
|
|
56351
|
+
newOptions.right = left;
|
|
56352
|
+
newOptions.bottom = top;
|
|
56353
|
+
newOptions.left = right;
|
|
56354
|
+
break
|
|
56355
|
+
case 4:
|
|
56356
|
+
// Vertical flip
|
|
56357
|
+
newOptions.top = bottom;
|
|
56358
|
+
newOptions.bottom = top;
|
|
56359
|
+
break
|
|
56360
|
+
case 5:
|
|
56361
|
+
// Vertical flip + 90° Rotate CW
|
|
56362
|
+
newOptions.top = left;
|
|
56363
|
+
newOptions.right = bottom;
|
|
56364
|
+
newOptions.bottom = right;
|
|
56365
|
+
newOptions.left = top;
|
|
56366
|
+
break
|
|
56367
|
+
case 6:
|
|
56368
|
+
// 90° Rotate CW
|
|
56369
|
+
newOptions.top = right;
|
|
56370
|
+
newOptions.right = bottom;
|
|
56371
|
+
newOptions.bottom = left;
|
|
56372
|
+
newOptions.left = top;
|
|
56373
|
+
break
|
|
56374
|
+
case 7:
|
|
56375
|
+
// Horizontal flip + 90° Rotate CW
|
|
56376
|
+
newOptions.top = right;
|
|
56377
|
+
newOptions.right = top;
|
|
56378
|
+
newOptions.bottom = left;
|
|
56379
|
+
newOptions.left = bottom;
|
|
56380
|
+
break
|
|
56381
|
+
case 8:
|
|
56382
|
+
// 90° Rotate CCW
|
|
56383
|
+
newOptions.top = left;
|
|
56384
|
+
newOptions.right = top;
|
|
56385
|
+
newOptions.bottom = right;
|
|
56386
|
+
newOptions.left = bottom;
|
|
56387
|
+
break
|
|
56388
|
+
}
|
|
56389
|
+
return newOptions
|
|
56390
|
+
};
|
|
56391
|
+
|
|
56392
|
+
// Transform image orientation based on the given EXIF orientation option:
|
|
56393
|
+
loadImage.transformCoordinates = function (canvas, options, data) {
|
|
56394
|
+
originalTransformCoordinates.call(loadImage, canvas, options, data);
|
|
56395
|
+
var orientation = options.orientation;
|
|
56396
|
+
var autoOrientation =
|
|
56397
|
+
loadImage.orientation && data.exif && data.exif.get('Orientation');
|
|
56398
|
+
if (!requiresOrientationChange(orientation, autoOrientation)) {
|
|
56399
|
+
return
|
|
56400
|
+
}
|
|
56401
|
+
var ctx = canvas.getContext('2d');
|
|
56402
|
+
var width = canvas.width;
|
|
56403
|
+
var height = canvas.height;
|
|
56404
|
+
var sourceWidth = width;
|
|
56405
|
+
var sourceHeight = height;
|
|
56406
|
+
if (
|
|
56407
|
+
(orientation > 4 && !(autoOrientation > 4)) ||
|
|
56408
|
+
(orientation < 5 && autoOrientation > 4)
|
|
56409
|
+
) {
|
|
56410
|
+
// Image dimensions and target dimensions are switched
|
|
56411
|
+
canvas.width = height;
|
|
56412
|
+
canvas.height = width;
|
|
56413
|
+
}
|
|
56414
|
+
if (orientation > 4) {
|
|
56415
|
+
// Destination and source dimensions are switched
|
|
56416
|
+
sourceWidth = height;
|
|
56417
|
+
sourceHeight = width;
|
|
56418
|
+
}
|
|
56419
|
+
// Reset automatic browser orientation:
|
|
56420
|
+
switch (autoOrientation) {
|
|
56421
|
+
case 2:
|
|
56422
|
+
// Horizontal flip
|
|
56423
|
+
ctx.translate(sourceWidth, 0);
|
|
56424
|
+
ctx.scale(-1, 1);
|
|
56425
|
+
break
|
|
56426
|
+
case 3:
|
|
56427
|
+
// 180° Rotate CCW
|
|
56428
|
+
ctx.translate(sourceWidth, sourceHeight);
|
|
56429
|
+
ctx.rotate(Math.PI);
|
|
56430
|
+
break
|
|
56431
|
+
case 4:
|
|
56432
|
+
// Vertical flip
|
|
56433
|
+
ctx.translate(0, sourceHeight);
|
|
56434
|
+
ctx.scale(1, -1);
|
|
56435
|
+
break
|
|
56436
|
+
case 5:
|
|
56437
|
+
// Horizontal flip + 90° Rotate CCW
|
|
56438
|
+
ctx.rotate(-0.5 * Math.PI);
|
|
56439
|
+
ctx.scale(-1, 1);
|
|
56440
|
+
break
|
|
56441
|
+
case 6:
|
|
56442
|
+
// 90° Rotate CCW
|
|
56443
|
+
ctx.rotate(-0.5 * Math.PI);
|
|
56444
|
+
ctx.translate(-sourceWidth, 0);
|
|
56445
|
+
break
|
|
56446
|
+
case 7:
|
|
56447
|
+
// Vertical flip + 90° Rotate CCW
|
|
56448
|
+
ctx.rotate(-0.5 * Math.PI);
|
|
56449
|
+
ctx.translate(-sourceWidth, sourceHeight);
|
|
56450
|
+
ctx.scale(1, -1);
|
|
56451
|
+
break
|
|
56452
|
+
case 8:
|
|
56453
|
+
// 90° Rotate CW
|
|
56454
|
+
ctx.rotate(0.5 * Math.PI);
|
|
56455
|
+
ctx.translate(0, -sourceHeight);
|
|
56456
|
+
break
|
|
56457
|
+
}
|
|
56458
|
+
// Some orientation combinations require additional rotation by 180°:
|
|
56459
|
+
if (requiresRot180(orientation, autoOrientation)) {
|
|
56460
|
+
ctx.translate(sourceWidth, sourceHeight);
|
|
56461
|
+
ctx.rotate(Math.PI);
|
|
56462
|
+
}
|
|
56463
|
+
switch (orientation) {
|
|
56464
|
+
case 2:
|
|
56465
|
+
// Horizontal flip
|
|
56466
|
+
ctx.translate(width, 0);
|
|
56467
|
+
ctx.scale(-1, 1);
|
|
56468
|
+
break
|
|
56469
|
+
case 3:
|
|
56470
|
+
// 180° Rotate CCW
|
|
56471
|
+
ctx.translate(width, height);
|
|
56472
|
+
ctx.rotate(Math.PI);
|
|
56473
|
+
break
|
|
56474
|
+
case 4:
|
|
56475
|
+
// Vertical flip
|
|
56476
|
+
ctx.translate(0, height);
|
|
56477
|
+
ctx.scale(1, -1);
|
|
56478
|
+
break
|
|
56479
|
+
case 5:
|
|
56480
|
+
// Vertical flip + 90° Rotate CW
|
|
56481
|
+
ctx.rotate(0.5 * Math.PI);
|
|
56482
|
+
ctx.scale(1, -1);
|
|
56483
|
+
break
|
|
56484
|
+
case 6:
|
|
56485
|
+
// 90° Rotate CW
|
|
56486
|
+
ctx.rotate(0.5 * Math.PI);
|
|
56487
|
+
ctx.translate(0, -height);
|
|
56488
|
+
break
|
|
56489
|
+
case 7:
|
|
56490
|
+
// Horizontal flip + 90° Rotate CW
|
|
56491
|
+
ctx.rotate(0.5 * Math.PI);
|
|
56492
|
+
ctx.translate(width, -height);
|
|
56493
|
+
ctx.scale(-1, 1);
|
|
56494
|
+
break
|
|
56495
|
+
case 8:
|
|
56496
|
+
// 90° Rotate CCW
|
|
56497
|
+
ctx.rotate(-0.5 * Math.PI);
|
|
56498
|
+
ctx.translate(-width, 0);
|
|
56499
|
+
break
|
|
56500
|
+
}
|
|
56501
|
+
};
|
|
56502
|
+
});
|
|
56503
|
+
}(loadImageOrientation));
|
|
56504
|
+
|
|
56505
|
+
/* global module, require */
|
|
56506
|
+
|
|
56507
|
+
var js = loadImage.exports;
|
|
56508
|
+
|
|
53832
56509
|
const dom$A = new Dom();
|
|
53833
56510
|
class Image {
|
|
53834
56511
|
constructor(builder) {
|
|
@@ -54894,1149 +57571,51 @@ class Image {
|
|
|
54894
57571
|
new_canvas.id = 'myTmpCanvasNoCrop';
|
|
54895
57572
|
new_canvas.style.display = 'none';
|
|
54896
57573
|
document.querySelector('body').appendChild(new_canvas);
|
|
54897
|
-
}
|
|
54898
|
-
|
|
54899
|
-
if (this.builder.opts.autoResizeImageEmbed) {
|
|
54900
|
-
// var imgName;
|
|
54901
|
-
var extension;
|
|
54902
|
-
|
|
54903
|
-
if (!file.name) {
|
|
54904
|
-
//file is an URL
|
|
54905
|
-
// imgName = file.substr((file.lastIndexOf('/') + 1));
|
|
54906
|
-
extension = file.substr(file.lastIndexOf('.') + 1).toLowerCase();
|
|
54907
|
-
} else {
|
|
54908
|
-
//file is an image file
|
|
54909
|
-
// imgName = file.name;
|
|
54910
|
-
extension = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase();
|
|
54911
|
-
}
|
|
54912
|
-
|
|
54913
|
-
var type, quality;
|
|
54914
|
-
|
|
54915
|
-
if (extension === 'jpg' || extension === 'jpeg') {
|
|
54916
|
-
type = 'image/jpeg';
|
|
54917
|
-
quality = this.builder.opts.imageQuality;
|
|
54918
|
-
} else {
|
|
54919
|
-
type = 'image/png';
|
|
54920
|
-
quality = 1;
|
|
54921
|
-
}
|
|
54922
|
-
|
|
54923
|
-
loadImage(file, (img, data) => {
|
|
54924
|
-
var orientation;
|
|
54925
|
-
|
|
54926
|
-
if (data.exif) {
|
|
54927
|
-
orientation = data.exif.get('Orientation');
|
|
54928
|
-
} //Check orientation
|
|
54929
|
-
//http://stackoverflow.com/questions/20600800/js-client-side-exif-orientation-rotate-and-mirror-jpeg-images
|
|
54930
|
-
|
|
54931
|
-
|
|
54932
|
-
var initialWidth;
|
|
54933
|
-
var initialHeight;
|
|
54934
|
-
|
|
54935
|
-
if (4 < orientation && orientation < 9) {
|
|
54936
|
-
//potrait
|
|
54937
|
-
initialWidth = img.height;
|
|
54938
|
-
initialHeight = img.width;
|
|
54939
|
-
} else {
|
|
54940
|
-
//landscape
|
|
54941
|
-
initialWidth = img.width;
|
|
54942
|
-
initialHeight = img.height;
|
|
54943
|
-
} // Use normal process for small images
|
|
54944
|
-
// if(initialWidth <200 && initialHeight<200) {
|
|
54945
|
-
|
|
54946
|
-
|
|
54947
|
-
if (initialWidth <= 1600 && initialHeight <= 1600 && this.builder.opts.maxEmbedImageWidth >= 1600) {
|
|
54948
|
-
let reader = new FileReader();
|
|
54949
|
-
reader.addEventListener('load', e => {
|
|
54950
|
-
if (!document.getElementById('__preview')) {
|
|
54951
|
-
var previewImage = document.createElement('img');
|
|
54952
|
-
previewImage.id = '__preview';
|
|
54953
|
-
previewImage.style.display = 'none';
|
|
54954
|
-
let builderStuff = this.util.builderStuff();
|
|
54955
|
-
dom$A.appendChild(builderStuff, previewImage);
|
|
54956
|
-
}
|
|
54957
|
-
|
|
54958
|
-
var src_image = document.querySelector('#__preview');
|
|
54959
|
-
|
|
54960
|
-
src_image.onload = () => {
|
|
54961
|
-
var tmpCanvasNoCrop = document.getElementById('myTmpCanvasNoCrop');
|
|
54962
|
-
var context = tmpCanvasNoCrop.getContext('2d');
|
|
54963
|
-
tmpCanvasNoCrop.height = src_image.height;
|
|
54964
|
-
tmpCanvasNoCrop.width = src_image.width;
|
|
54965
|
-
context.drawImage(src_image, 0, 0);
|
|
54966
|
-
var imageData = tmpCanvasNoCrop.toDataURL(type, quality);
|
|
54967
|
-
targetImg.src = imageData;
|
|
54968
|
-
src_image.onload = null;
|
|
54969
|
-
tmpCanvasNoCrop.parentNode.removeChild(tmpCanvasNoCrop);
|
|
54970
|
-
processImageDone();
|
|
54971
|
-
};
|
|
54972
|
-
|
|
54973
|
-
src_image.src = e.target.result;
|
|
54974
|
-
});
|
|
54975
|
-
reader.readAsDataURL(file);
|
|
54976
|
-
return;
|
|
54977
|
-
} //Specify target dimension: 2 times bigger than placement, but not more than 1200px
|
|
54978
|
-
// var targetWidth = targetImg.clientWidth * 2;
|
|
54979
|
-
// if (targetWidth > 1200) targetWidth = 1200;
|
|
54980
|
-
// targetWidth = 1200; //force target width to 1200px
|
|
54981
|
-
|
|
54982
|
-
|
|
54983
|
-
var targetWidth = initialWidth; // default is original image width (no change)
|
|
54984
|
-
|
|
54985
|
-
if (this.builder.opts.maxEmbedImageWidth !== -1) {
|
|
54986
|
-
targetWidth = this.builder.opts.maxEmbedImageWidth;
|
|
54987
|
-
}
|
|
54988
|
-
|
|
54989
|
-
var targetHeight = targetWidth * initialHeight / initialWidth; //Adjust target dimension (in case image is smaller than targeted dimension)
|
|
54990
|
-
|
|
54991
|
-
var resize = false; // var targetWidth; var targetHeight;
|
|
54992
|
-
|
|
54993
|
-
if (initialHeight <= targetHeight && initialWidth > targetWidth) {
|
|
54994
|
-
//Original height is smaller than placeholder height. Original width is bigger than placeholder width.
|
|
54995
|
-
//targetWidth = targetWidth;
|
|
54996
|
-
targetHeight = initialHeight * targetWidth / initialWidth;
|
|
54997
|
-
|
|
54998
|
-
if (initialHeight <= targetHeight) {
|
|
54999
|
-
targetHeight = initialHeight;
|
|
55000
|
-
targetWidth = initialHeight * targetWidth / targetHeight;
|
|
55001
|
-
}
|
|
55002
|
-
|
|
55003
|
-
resize = true;
|
|
55004
|
-
} else if (initialWidth <= targetWidth && initialHeight > targetHeight) {
|
|
55005
|
-
//Original width is smaller than placeholder width. Original height is bigger than placeholder height.
|
|
55006
|
-
//targetHeight = targetHeight;
|
|
55007
|
-
targetWidth = initialWidth * targetHeight / initialHeight;
|
|
55008
|
-
|
|
55009
|
-
if (initialWidth <= targetWidth) {
|
|
55010
|
-
targetWidth = initialWidth;
|
|
55011
|
-
targetHeight = initialWidth * targetHeight / targetWidth;
|
|
55012
|
-
}
|
|
55013
|
-
|
|
55014
|
-
resize = true;
|
|
55015
|
-
} else if (initialWidth <= targetWidth && initialHeight <= targetHeight) {
|
|
55016
|
-
//no resize (original image is smaller than placeholder)
|
|
55017
|
-
targetWidth = initialWidth;
|
|
55018
|
-
targetHeight = initialHeight;
|
|
55019
|
-
} else {
|
|
55020
|
-
//targetWidth = targetWidth;
|
|
55021
|
-
targetHeight = initialHeight * targetWidth / initialWidth;
|
|
55022
|
-
resize = true;
|
|
55023
|
-
}
|
|
55024
|
-
|
|
55025
|
-
if (type === 'image/png') {
|
|
55026
|
-
resize = false;
|
|
55027
|
-
}
|
|
55028
|
-
|
|
55029
|
-
if (this.builder.opts.maxEmbedImageWidth === -1) {
|
|
55030
|
-
resize = false;
|
|
55031
|
-
}
|
|
55032
|
-
|
|
55033
|
-
if (!resize) {
|
|
55034
|
-
// NEW: this is to prevent using MegaPixImage (problem with some PNG. PNG doesn't need to resize, so no need to use MegaPixImage)
|
|
55035
|
-
let tmpCanvasNoCrop = document.getElementById('myTmpCanvasNoCrop');
|
|
55036
|
-
let context = tmpCanvasNoCrop.getContext('2d');
|
|
55037
|
-
tmpCanvasNoCrop.height = initialHeight;
|
|
55038
|
-
tmpCanvasNoCrop.width = initialWidth;
|
|
55039
|
-
context.drawImage(img, 0, 0);
|
|
55040
|
-
|
|
55041
|
-
targetImg.onload = () => {
|
|
55042
|
-
targetImg.onload = null;
|
|
55043
|
-
targetImg.src = tmpCanvasNoCrop.toDataURL(type, quality); //finished
|
|
55044
|
-
|
|
55045
|
-
tmpCanvasNoCrop.parentNode.removeChild(tmpCanvasNoCrop);
|
|
55046
|
-
processImageDone();
|
|
55047
|
-
};
|
|
55048
|
-
|
|
55049
|
-
targetImg.src = tmpCanvasNoCrop.toDataURL(type, quality);
|
|
55050
|
-
return;
|
|
55051
|
-
} //RENDER (tmpCanvasNoCrop)
|
|
55052
|
-
|
|
55053
|
-
|
|
55054
|
-
var mpImg = new MegaPixImage(img);
|
|
55055
|
-
var tmpCanvasNoCrop = document.getElementById('myTmpCanvasNoCrop');
|
|
55056
|
-
mpImg.render(tmpCanvasNoCrop, {
|
|
55057
|
-
width: initialWidth,
|
|
55058
|
-
height: initialHeight,
|
|
55059
|
-
orientation: orientation
|
|
55060
|
-
}, () => {
|
|
55061
|
-
if (resize) {
|
|
55062
|
-
//RESIZE (tmpCanvasNoCrop) with good quality.
|
|
55063
|
-
//var tmpImg = new Image();
|
|
55064
|
-
var iW = initialWidth;
|
|
55065
|
-
var iH = initialHeight;
|
|
55066
|
-
|
|
55067
|
-
targetImg.onload = () => {
|
|
55068
|
-
this.count++; // count increment
|
|
55069
|
-
|
|
55070
|
-
iW /= 2;
|
|
55071
|
-
iH /= 2;
|
|
55072
|
-
|
|
55073
|
-
if (iW < targetWidth || iH < targetHeight) {
|
|
55074
|
-
iW = targetWidth;
|
|
55075
|
-
iH = targetHeight;
|
|
55076
|
-
}
|
|
55077
|
-
|
|
55078
|
-
var mpImg = new MegaPixImage(targetImg); //console.log(iW + ' ' + iH)
|
|
55079
|
-
|
|
55080
|
-
mpImg.render(tmpCanvasNoCrop, {
|
|
55081
|
-
width: iW,
|
|
55082
|
-
height: iH
|
|
55083
|
-
}, () => {
|
|
55084
|
-
// must specify both width & height correctly (proportionally)
|
|
55085
|
-
if (iW <= targetWidth || iH <= targetHeight) {
|
|
55086
|
-
targetImg.src = tmpCanvasNoCrop.toDataURL(type, quality); //finished
|
|
55087
|
-
//console.log(this.count); // count check
|
|
55088
|
-
|
|
55089
|
-
if (this.count === 3) {
|
|
55090
|
-
targetImg.onload = null;
|
|
55091
|
-
|
|
55092
|
-
try {
|
|
55093
|
-
tmpCanvasNoCrop.parentNode.removeChild(tmpCanvasNoCrop);
|
|
55094
|
-
} catch (e) {// Do Nothing
|
|
55095
|
-
}
|
|
55096
|
-
|
|
55097
|
-
processImageDone();
|
|
55098
|
-
}
|
|
55099
|
-
|
|
55100
|
-
try {
|
|
55101
|
-
tmpCanvasNoCrop.parentNode.removeChild(tmpCanvasNoCrop);
|
|
55102
|
-
} catch (e) {// Do Nothing
|
|
55103
|
-
}
|
|
55104
|
-
|
|
55105
|
-
processImageDone();
|
|
55106
|
-
return false;
|
|
55107
|
-
}
|
|
55108
|
-
|
|
55109
|
-
targetImg.src = tmpCanvasNoCrop.toDataURL(type, quality); //console.log(this.count); // count check
|
|
55110
|
-
|
|
55111
|
-
if (this.count === 3) {
|
|
55112
|
-
targetImg.onload = null;
|
|
55113
|
-
|
|
55114
|
-
try {
|
|
55115
|
-
tmpCanvasNoCrop.parentNode.removeChild(tmpCanvasNoCrop);
|
|
55116
|
-
} catch (e) {// Do Nothing
|
|
55117
|
-
}
|
|
57574
|
+
} // var imgName;
|
|
55118
57575
|
|
|
55119
|
-
processImageDone();
|
|
55120
|
-
}
|
|
55121
|
-
});
|
|
55122
|
-
};
|
|
55123
57576
|
|
|
55124
|
-
|
|
55125
|
-
this.count = 0; //console.log(this.count); // count start
|
|
55126
|
-
} else {
|
|
55127
|
-
targetImg.src = tmpCanvasNoCrop.toDataURL(type, quality); //finished
|
|
57577
|
+
var extension;
|
|
55128
57578
|
|
|
55129
|
-
|
|
55130
|
-
|
|
55131
|
-
|
|
55132
|
-
|
|
55133
|
-
}, {
|
|
55134
|
-
canvas: false,
|
|
55135
|
-
meta: true
|
|
55136
|
-
});
|
|
57579
|
+
if (!file.name) {
|
|
57580
|
+
//file is an URL
|
|
57581
|
+
// imgName = file.substr((file.lastIndexOf('/') + 1));
|
|
57582
|
+
extension = file.substr(file.lastIndexOf('.') + 1).toLowerCase();
|
|
55137
57583
|
} else {
|
|
55138
|
-
|
|
55139
|
-
|
|
55140
|
-
|
|
55141
|
-
// targetImg.onload = ()=> {
|
|
55142
|
-
// let tmpCanvasNoCrop = document.getElementById('myTmpCanvasNoCrop');
|
|
55143
|
-
// let context = tmpCanvasNoCrop.getContext('2d');
|
|
55144
|
-
// tmpCanvasNoCrop.height = targetImg.height;
|
|
55145
|
-
// tmpCanvasNoCrop.width = targetImg.width;
|
|
55146
|
-
// context.drawImage(targetImg, 0, 0);
|
|
55147
|
-
// let imageData = tmpCanvasNoCrop.toDataURL("image/png");
|
|
55148
|
-
// targetImg.src = imageData;
|
|
55149
|
-
// targetImg.onload = null;
|
|
55150
|
-
// //tmpCanvasNoCrop.parentNode.removeChild(tmpCanvasNoCrop);
|
|
55151
|
-
// processImageDone();
|
|
55152
|
-
// }
|
|
55153
|
-
// targetImg.src = e.target.result;
|
|
55154
|
-
//Fix:
|
|
55155
|
-
if (!document.getElementById('__preview')) {
|
|
55156
|
-
var previewImage = document.createElement('img');
|
|
55157
|
-
previewImage.id = '__preview';
|
|
55158
|
-
previewImage.style.display = 'none';
|
|
55159
|
-
let builderStuff = this.util.builderStuff();
|
|
55160
|
-
dom$A.appendChild(builderStuff, previewImage);
|
|
55161
|
-
}
|
|
55162
|
-
|
|
55163
|
-
var src_image = document.querySelector('#__preview');
|
|
55164
|
-
|
|
55165
|
-
src_image.onload = () => {
|
|
55166
|
-
var tmpCanvasNoCrop = document.getElementById('myTmpCanvasNoCrop');
|
|
55167
|
-
var context = tmpCanvasNoCrop.getContext('2d');
|
|
55168
|
-
tmpCanvasNoCrop.height = src_image.height;
|
|
55169
|
-
tmpCanvasNoCrop.width = src_image.width;
|
|
55170
|
-
context.drawImage(src_image, 0, 0);
|
|
55171
|
-
var imageData = tmpCanvasNoCrop.toDataURL(type, quality);
|
|
55172
|
-
targetImg.src = imageData;
|
|
55173
|
-
src_image.onload = null;
|
|
55174
|
-
tmpCanvasNoCrop.parentNode.removeChild(tmpCanvasNoCrop);
|
|
55175
|
-
processImageDone();
|
|
55176
|
-
};
|
|
55177
|
-
|
|
55178
|
-
src_image.src = e.target.result;
|
|
55179
|
-
});
|
|
55180
|
-
reader.readAsDataURL(file);
|
|
55181
|
-
return;
|
|
57584
|
+
//file is an image file
|
|
57585
|
+
// imgName = file.name;
|
|
57586
|
+
extension = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase();
|
|
55182
57587
|
}
|
|
55183
|
-
}
|
|
55184
|
-
|
|
55185
|
-
}
|
|
55186
|
-
/*!
|
|
55187
|
-
Mega pixel image rendering library for iOS6 Safari
|
|
55188
|
-
Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
55189
|
-
MIT license
|
|
55190
|
-
https://github.com/stomita/ios-imagefile-megapixel
|
|
55191
|
-
*/
|
|
55192
|
-
|
|
55193
|
-
/**
|
|
55194
|
-
* Mega pixel image rendering library for iOS6 Safari
|
|
55195
|
-
*
|
|
55196
|
-
* Fixes iOS6 Safari's image file rendering issue for large size image (over mega-pixel),
|
|
55197
|
-
* which causes unexpected subsampling when drawing it in canvas.
|
|
55198
|
-
* By using this library, you can safely render the image with proper stretching.
|
|
55199
|
-
*
|
|
55200
|
-
* Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
55201
|
-
* Released under the MIT license
|
|
55202
|
-
*/
|
|
55203
|
-
|
|
55204
|
-
/**
|
|
55205
|
-
* Detect subsampling in loaded image.
|
|
55206
|
-
* In iOS, larger images than 2M pixels may be subsampled in rendering.
|
|
55207
|
-
*/
|
|
55208
|
-
|
|
55209
|
-
function detectSubsampling(img) {
|
|
55210
|
-
var iw = img.naturalWidth,
|
|
55211
|
-
ih = img.naturalHeight;
|
|
55212
|
-
|
|
55213
|
-
if (iw * ih > 1024 * 1024) {
|
|
55214
|
-
// subsampling may happen over megapixel image
|
|
55215
|
-
var canvas = document.createElement('canvas');
|
|
55216
|
-
canvas.width = canvas.height = 1;
|
|
55217
|
-
var ctx = canvas.getContext('2d');
|
|
55218
|
-
ctx.drawImage(img, -iw + 1, 0); // subsampled image becomes half smaller in rendering size.
|
|
55219
|
-
// check alpha channel value to confirm image is covering edge pixel or not.
|
|
55220
|
-
// if alpha value is 0 image is not covering, hence subsampled.
|
|
55221
|
-
|
|
55222
|
-
return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
|
|
55223
|
-
} else {
|
|
55224
|
-
return false;
|
|
55225
|
-
}
|
|
55226
|
-
}
|
|
55227
|
-
/**
|
|
55228
|
-
* Detecting vertical squash in loaded image.
|
|
55229
|
-
* Fixes a bug which squash image vertically while drawing into canvas for some images.
|
|
55230
|
-
*/
|
|
55231
|
-
|
|
55232
|
-
|
|
55233
|
-
function detectVerticalSquash(img, iw, ih) {
|
|
55234
|
-
var canvas = document.createElement('canvas');
|
|
55235
|
-
canvas.width = 1;
|
|
55236
|
-
canvas.height = ih;
|
|
55237
|
-
var ctx = canvas.getContext('2d');
|
|
55238
|
-
ctx.drawImage(img, 0, 0);
|
|
55239
|
-
var data = ctx.getImageData(0, 0, 1, ih).data; // search image edge pixel position in case it is squashed vertically.
|
|
55240
57588
|
|
|
55241
|
-
|
|
55242
|
-
var ey = ih;
|
|
55243
|
-
var py = ih;
|
|
57589
|
+
var type, quality;
|
|
55244
57590
|
|
|
55245
|
-
|
|
55246
|
-
|
|
55247
|
-
|
|
55248
|
-
if (alpha === 0) {
|
|
55249
|
-
ey = py;
|
|
57591
|
+
if (extension === 'jpg' || extension === 'jpeg') {
|
|
57592
|
+
type = 'image/jpeg';
|
|
57593
|
+
quality = this.builder.opts.imageQuality;
|
|
55250
57594
|
} else {
|
|
55251
|
-
|
|
55252
|
-
|
|
55253
|
-
|
|
55254
|
-
py = ey + sy >> 1;
|
|
55255
|
-
}
|
|
55256
|
-
|
|
55257
|
-
var ratio = py / ih;
|
|
55258
|
-
return ratio === 0 ? 1 : ratio;
|
|
55259
|
-
}
|
|
55260
|
-
/**
|
|
55261
|
-
* Rendering image element (with resizing) and get its data URL
|
|
55262
|
-
*/
|
|
55263
|
-
|
|
55264
|
-
|
|
55265
|
-
function renderImageToDataURL(img, options, doSquash) {
|
|
55266
|
-
var canvas = document.createElement('canvas');
|
|
55267
|
-
renderImageToCanvas(img, canvas, options, doSquash);
|
|
55268
|
-
return canvas.toDataURL('image/jpeg', options.quality || 0.8);
|
|
55269
|
-
}
|
|
55270
|
-
/**
|
|
55271
|
-
* Rendering image element (with resizing) into the canvas element
|
|
55272
|
-
*/
|
|
55273
|
-
|
|
55274
|
-
|
|
55275
|
-
function renderImageToCanvas(img, canvas, options, doSquash) {
|
|
55276
|
-
var iw = img.naturalWidth,
|
|
55277
|
-
ih = img.naturalHeight;
|
|
55278
|
-
if (!(iw + ih)) return;
|
|
55279
|
-
var width = options.width,
|
|
55280
|
-
height = options.height;
|
|
55281
|
-
var ctx = canvas.getContext('2d');
|
|
55282
|
-
ctx.save();
|
|
55283
|
-
transformCoordinate(canvas, ctx, width, height, options.orientation);
|
|
55284
|
-
var subsampled = detectSubsampling(img);
|
|
55285
|
-
|
|
55286
|
-
if (subsampled) {
|
|
55287
|
-
iw /= 2;
|
|
55288
|
-
ih /= 2;
|
|
55289
|
-
}
|
|
55290
|
-
|
|
55291
|
-
var d = 1024; // size of tiling canvas
|
|
55292
|
-
|
|
55293
|
-
var tmpCanvas = document.createElement('canvas');
|
|
55294
|
-
tmpCanvas.width = tmpCanvas.height = d;
|
|
55295
|
-
var tmpCtx = tmpCanvas.getContext('2d');
|
|
55296
|
-
var vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1;
|
|
55297
|
-
var dw = Math.ceil(d * width / iw);
|
|
55298
|
-
var dh = Math.ceil(d * height / ih / vertSquashRatio);
|
|
55299
|
-
var sy = 0;
|
|
55300
|
-
var dy = 0;
|
|
55301
|
-
|
|
55302
|
-
while (sy < ih) {
|
|
55303
|
-
var sx = 0;
|
|
55304
|
-
var dx = 0;
|
|
55305
|
-
|
|
55306
|
-
while (sx < iw) {
|
|
55307
|
-
tmpCtx.clearRect(0, 0, d, d);
|
|
55308
|
-
tmpCtx.drawImage(img, -sx, -sy);
|
|
55309
|
-
ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);
|
|
55310
|
-
sx += d;
|
|
55311
|
-
dx += dw;
|
|
55312
|
-
}
|
|
55313
|
-
|
|
55314
|
-
sy += d;
|
|
55315
|
-
dy += dh;
|
|
55316
|
-
}
|
|
55317
|
-
|
|
55318
|
-
ctx.restore();
|
|
55319
|
-
tmpCanvas = tmpCtx = null;
|
|
55320
|
-
}
|
|
55321
|
-
/**
|
|
55322
|
-
* Transform canvas coordination according to specified frame size and orientation
|
|
55323
|
-
* Orientation value is from EXIF tag
|
|
55324
|
-
*/
|
|
55325
|
-
|
|
55326
|
-
|
|
55327
|
-
function transformCoordinate(canvas, ctx, width, height, orientation) {
|
|
55328
|
-
switch (orientation) {
|
|
55329
|
-
case 5:
|
|
55330
|
-
case 6:
|
|
55331
|
-
case 7:
|
|
55332
|
-
case 8:
|
|
55333
|
-
canvas.width = height;
|
|
55334
|
-
canvas.height = width;
|
|
55335
|
-
break;
|
|
55336
|
-
|
|
55337
|
-
default:
|
|
55338
|
-
canvas.width = width;
|
|
55339
|
-
canvas.height = height;
|
|
55340
|
-
}
|
|
55341
|
-
|
|
55342
|
-
switch (orientation) {
|
|
55343
|
-
case 2:
|
|
55344
|
-
// horizontal flip
|
|
55345
|
-
ctx.translate(width, 0);
|
|
55346
|
-
ctx.scale(-1, 1);
|
|
55347
|
-
break;
|
|
55348
|
-
|
|
55349
|
-
case 3:
|
|
55350
|
-
// 180 rotate left
|
|
55351
|
-
ctx.translate(width, height);
|
|
55352
|
-
ctx.rotate(Math.PI);
|
|
55353
|
-
break;
|
|
55354
|
-
|
|
55355
|
-
case 4:
|
|
55356
|
-
// vertical flip
|
|
55357
|
-
ctx.translate(0, height);
|
|
55358
|
-
ctx.scale(1, -1);
|
|
55359
|
-
break;
|
|
55360
|
-
|
|
55361
|
-
case 5:
|
|
55362
|
-
// vertical flip + 90 rotate right
|
|
55363
|
-
ctx.rotate(0.5 * Math.PI);
|
|
55364
|
-
ctx.scale(1, -1);
|
|
55365
|
-
break;
|
|
55366
|
-
|
|
55367
|
-
case 6:
|
|
55368
|
-
// 90 rotate right
|
|
55369
|
-
ctx.rotate(0.5 * Math.PI);
|
|
55370
|
-
ctx.translate(0, -height);
|
|
55371
|
-
break;
|
|
55372
|
-
|
|
55373
|
-
case 7:
|
|
55374
|
-
// horizontal flip + 90 rotate right
|
|
55375
|
-
ctx.rotate(0.5 * Math.PI);
|
|
55376
|
-
ctx.translate(width, -height);
|
|
55377
|
-
ctx.scale(-1, 1);
|
|
55378
|
-
break;
|
|
55379
|
-
|
|
55380
|
-
case 8:
|
|
55381
|
-
// 90 rotate left
|
|
55382
|
-
ctx.rotate(-0.5 * Math.PI);
|
|
55383
|
-
ctx.translate(-width, 0);
|
|
55384
|
-
break;
|
|
55385
|
-
}
|
|
55386
|
-
}
|
|
55387
|
-
|
|
55388
|
-
var URL;
|
|
55389
|
-
|
|
55390
|
-
if (typeof window !== 'undefined') {
|
|
55391
|
-
//new
|
|
55392
|
-
URL = window.URL && window.URL.createObjectURL ? window.URL : window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null;
|
|
55393
|
-
}
|
|
55394
|
-
/**
|
|
55395
|
-
* MegaPixImage class
|
|
55396
|
-
*/
|
|
55397
|
-
|
|
55398
|
-
|
|
55399
|
-
function MegaPixImage(srcImage) {
|
|
55400
|
-
if (window.Blob && srcImage instanceof Blob) {
|
|
55401
|
-
if (!URL) {
|
|
55402
|
-
throw Error('No createObjectURL function found to create blob url');
|
|
55403
|
-
}
|
|
55404
|
-
|
|
55405
|
-
var img = new Image();
|
|
55406
|
-
img.src = URL.createObjectURL(srcImage);
|
|
55407
|
-
this.blob = srcImage;
|
|
55408
|
-
srcImage = img;
|
|
55409
|
-
}
|
|
55410
|
-
|
|
55411
|
-
if (!srcImage.naturalWidth && !srcImage.naturalHeight) {
|
|
55412
|
-
var _this = this;
|
|
55413
|
-
|
|
55414
|
-
srcImage.onload = srcImage.onerror = function () {
|
|
55415
|
-
var listeners = _this.imageLoadListeners;
|
|
55416
|
-
|
|
55417
|
-
if (listeners) {
|
|
55418
|
-
_this.imageLoadListeners = null;
|
|
55419
|
-
|
|
55420
|
-
for (var i = 0, len = listeners.length; i < len; i++) {
|
|
55421
|
-
listeners[i]();
|
|
55422
|
-
}
|
|
55423
|
-
}
|
|
55424
|
-
};
|
|
55425
|
-
|
|
55426
|
-
this.imageLoadListeners = [];
|
|
55427
|
-
}
|
|
55428
|
-
|
|
55429
|
-
this.srcImage = srcImage;
|
|
55430
|
-
}
|
|
55431
|
-
/**
|
|
55432
|
-
* Rendering megapix image into specified target element
|
|
55433
|
-
*/
|
|
55434
|
-
|
|
55435
|
-
|
|
55436
|
-
MegaPixImage.prototype.render = function (target, options, callback) {
|
|
55437
|
-
if (this.imageLoadListeners) {
|
|
55438
|
-
var _this = this;
|
|
55439
|
-
|
|
55440
|
-
this.imageLoadListeners.push(function () {
|
|
55441
|
-
_this.render(target, options, callback);
|
|
55442
|
-
});
|
|
55443
|
-
return;
|
|
55444
|
-
}
|
|
55445
|
-
|
|
55446
|
-
options = options || {};
|
|
55447
|
-
var imgWidth = this.srcImage.naturalWidth,
|
|
55448
|
-
imgHeight = this.srcImage.naturalHeight,
|
|
55449
|
-
width = options.width,
|
|
55450
|
-
height = options.height,
|
|
55451
|
-
maxWidth = options.maxWidth,
|
|
55452
|
-
maxHeight = options.maxHeight,
|
|
55453
|
-
doSquash = !this.blob || this.blob.type === 'image/jpeg';
|
|
55454
|
-
|
|
55455
|
-
if (width && !height) {
|
|
55456
|
-
height = imgHeight * width / imgWidth << 0;
|
|
55457
|
-
} else if (height && !width) {
|
|
55458
|
-
width = imgWidth * height / imgHeight << 0;
|
|
55459
|
-
} else {
|
|
55460
|
-
width = imgWidth;
|
|
55461
|
-
height = imgHeight;
|
|
55462
|
-
}
|
|
55463
|
-
|
|
55464
|
-
if (maxWidth && width > maxWidth) {
|
|
55465
|
-
width = maxWidth;
|
|
55466
|
-
height = imgHeight * width / imgWidth << 0;
|
|
55467
|
-
}
|
|
55468
|
-
|
|
55469
|
-
if (maxHeight && height > maxHeight) {
|
|
55470
|
-
height = maxHeight;
|
|
55471
|
-
width = imgWidth * height / imgHeight << 0;
|
|
55472
|
-
}
|
|
55473
|
-
|
|
55474
|
-
var opt = {
|
|
55475
|
-
width: width,
|
|
55476
|
-
height: height
|
|
55477
|
-
};
|
|
55478
|
-
|
|
55479
|
-
for (var k in options) opt[k] = options[k];
|
|
55480
|
-
|
|
55481
|
-
var tagName = target.tagName.toLowerCase();
|
|
55482
|
-
|
|
55483
|
-
if (tagName === 'img') {
|
|
55484
|
-
target.src = renderImageToDataURL(this.srcImage, opt, doSquash);
|
|
55485
|
-
} else if (tagName === 'canvas') {
|
|
55486
|
-
renderImageToCanvas(this.srcImage, target, opt, doSquash);
|
|
55487
|
-
}
|
|
55488
|
-
|
|
55489
|
-
if (typeof this.onrender === 'function') {
|
|
55490
|
-
this.onrender(target);
|
|
55491
|
-
}
|
|
55492
|
-
|
|
55493
|
-
if (callback) {
|
|
55494
|
-
callback();
|
|
55495
|
-
}
|
|
55496
|
-
|
|
55497
|
-
if (this.blob) {
|
|
55498
|
-
this.blob = null;
|
|
55499
|
-
if (URL) URL.revokeObjectURL(this.srcImage.src); //new
|
|
55500
|
-
}
|
|
55501
|
-
};
|
|
55502
|
-
/*
|
|
55503
|
-
* JavaScript Load Image
|
|
55504
|
-
* https://github.com/blueimp/JavaScript-Load-Image
|
|
55505
|
-
*
|
|
55506
|
-
* Copyright 2011, Sebastian Tschan
|
|
55507
|
-
* https://blueimp.net
|
|
55508
|
-
*
|
|
55509
|
-
* Licensed under the MIT license:
|
|
55510
|
-
* https://opensource.org/licenses/MIT
|
|
55511
|
-
*/
|
|
55512
|
-
|
|
55513
|
-
/**
|
|
55514
|
-
* Loads an image for a given File object.
|
|
55515
|
-
* Invokes the callback with an img or optional canvas element
|
|
55516
|
-
* (if supported by the browser) as parameter:.
|
|
55517
|
-
*
|
|
55518
|
-
* @param {File|Blob|string} file File or Blob object or image URL
|
|
55519
|
-
* @param {Function} [callback] Image load event callback
|
|
55520
|
-
* @param {object} [options] Options object
|
|
55521
|
-
* @returns {HTMLImageElement|HTMLCanvasElement|FileReader} image object
|
|
55522
|
-
*/
|
|
55523
|
-
|
|
55524
|
-
|
|
55525
|
-
function loadImage(file, callback, options) {
|
|
55526
|
-
var img = document.createElement('img');
|
|
55527
|
-
var url;
|
|
55528
|
-
|
|
55529
|
-
img.onerror = function (event) {
|
|
55530
|
-
return loadImage.onerror(img, event, file, callback, options);
|
|
55531
|
-
};
|
|
55532
|
-
|
|
55533
|
-
img.onload = function (event) {
|
|
55534
|
-
return loadImage.onload(img, event, file, callback, options);
|
|
55535
|
-
};
|
|
55536
|
-
|
|
55537
|
-
if (typeof file === 'string') {
|
|
55538
|
-
loadImage.fetchBlob(file, function (blob) {
|
|
55539
|
-
if (blob) {
|
|
55540
|
-
// eslint-disable-next-line no-param-reassign
|
|
55541
|
-
file = blob;
|
|
55542
|
-
url = loadImage.createObjectURL(file);
|
|
55543
|
-
} else {
|
|
55544
|
-
url = file;
|
|
55545
|
-
|
|
55546
|
-
if (options && options.crossOrigin) {
|
|
55547
|
-
img.crossOrigin = options.crossOrigin;
|
|
55548
|
-
}
|
|
55549
|
-
}
|
|
55550
|
-
|
|
55551
|
-
img.src = url;
|
|
55552
|
-
}, options);
|
|
55553
|
-
return img;
|
|
55554
|
-
} else if (loadImage.isInstanceOf('Blob', file) || // Files are also Blob instances, but some browsers
|
|
55555
|
-
// (Firefox 3.6) support the File API but not Blobs:
|
|
55556
|
-
loadImage.isInstanceOf('File', file)) {
|
|
55557
|
-
url = img._objectURL = loadImage.createObjectURL(file);
|
|
55558
|
-
|
|
55559
|
-
if (url) {
|
|
55560
|
-
img.src = url;
|
|
55561
|
-
return img;
|
|
55562
|
-
}
|
|
55563
|
-
|
|
55564
|
-
return loadImage.readFile(file, function (e) {
|
|
55565
|
-
var target = e.target;
|
|
55566
|
-
|
|
55567
|
-
if (target && target.result) {
|
|
55568
|
-
img.src = target.result;
|
|
55569
|
-
} else if (callback) {
|
|
55570
|
-
callback(e);
|
|
55571
|
-
}
|
|
55572
|
-
});
|
|
55573
|
-
}
|
|
55574
|
-
} // The check for URL.revokeObjectURL fixes an issue with Opera 12,
|
|
55575
|
-
// which provides URL.createObjectURL but doesn't properly implement it:
|
|
55576
|
-
// var urlAPI = (URL.revokeObjectURL && URL) || webkitURL;
|
|
55577
|
-
|
|
55578
|
-
|
|
55579
|
-
var urlAPI;
|
|
55580
|
-
if (URL) urlAPI = URL.revokeObjectURL && URL; // Oct 29, 2019 //new
|
|
55581
|
-
|
|
55582
|
-
/**
|
|
55583
|
-
* Helper function to revoke an object URL
|
|
55584
|
-
*
|
|
55585
|
-
* @param {HTMLImageElement} img Image element
|
|
55586
|
-
* @param {object} [options] Options object
|
|
55587
|
-
*/
|
|
55588
|
-
|
|
55589
|
-
function revokeHelper(img, options) {
|
|
55590
|
-
if (img._objectURL && !(options && options.noRevoke)) {
|
|
55591
|
-
loadImage.revokeObjectURL(img._objectURL);
|
|
55592
|
-
delete img._objectURL;
|
|
55593
|
-
}
|
|
55594
|
-
} // If the callback given to this function returns a blob, it is used as image
|
|
55595
|
-
// source instead of the original url and overrides the file argument used in
|
|
55596
|
-
// the onload and onerror event callbacks:
|
|
55597
|
-
|
|
55598
|
-
|
|
55599
|
-
loadImage.fetchBlob = function (url, callback) {
|
|
55600
|
-
callback();
|
|
55601
|
-
};
|
|
55602
|
-
|
|
55603
|
-
loadImage.isInstanceOf = function (type, obj) {
|
|
55604
|
-
// Cross-frame instanceof check
|
|
55605
|
-
return Object.prototype.toString.call(obj) === '[object ' + type + ']';
|
|
55606
|
-
};
|
|
55607
|
-
|
|
55608
|
-
loadImage.transform = function (img, options, callback, file, data) {
|
|
55609
|
-
callback(img, data);
|
|
55610
|
-
};
|
|
55611
|
-
|
|
55612
|
-
loadImage.onerror = function (img, event, file, callback, options) {
|
|
55613
|
-
revokeHelper(img, options);
|
|
55614
|
-
|
|
55615
|
-
if (callback) {
|
|
55616
|
-
callback.call(img, event);
|
|
55617
|
-
}
|
|
55618
|
-
};
|
|
55619
|
-
|
|
55620
|
-
loadImage.onload = function (img, event, file, callback, options) {
|
|
55621
|
-
revokeHelper(img, options);
|
|
55622
|
-
|
|
55623
|
-
if (callback) {
|
|
55624
|
-
loadImage.transform(img, options, callback, file, {
|
|
55625
|
-
originalWidth: img.naturalWidth || img.width,
|
|
55626
|
-
originalHeight: img.naturalHeight || img.height
|
|
55627
|
-
});
|
|
55628
|
-
}
|
|
55629
|
-
};
|
|
55630
|
-
|
|
55631
|
-
loadImage.createObjectURL = function (file) {
|
|
55632
|
-
return urlAPI ? urlAPI.createObjectURL(file) : false;
|
|
55633
|
-
};
|
|
55634
|
-
|
|
55635
|
-
loadImage.revokeObjectURL = function (url) {
|
|
55636
|
-
return urlAPI ? urlAPI.revokeObjectURL(url) : false;
|
|
55637
|
-
}; // Loads a given File object via FileReader interface,
|
|
55638
|
-
// invokes the callback with the event object (load or error).
|
|
55639
|
-
// The result can be read via event.target.result:
|
|
55640
|
-
|
|
55641
|
-
|
|
55642
|
-
loadImage.readFile = function (file, callback, method) {
|
|
55643
|
-
if (FileReader) {
|
|
55644
|
-
var fileReader = new FileReader();
|
|
55645
|
-
fileReader.onload = fileReader.onerror = callback; // eslint-disable-next-line no-param-reassign
|
|
55646
|
-
|
|
55647
|
-
method = method || 'readAsDataURL';
|
|
55648
|
-
|
|
55649
|
-
if (fileReader[method]) {
|
|
55650
|
-
fileReader[method](file);
|
|
55651
|
-
return fileReader;
|
|
57595
|
+
type = 'image/png';
|
|
57596
|
+
quality = 1;
|
|
55652
57597
|
}
|
|
55653
|
-
}
|
|
55654
|
-
|
|
55655
|
-
return false;
|
|
55656
|
-
};
|
|
55657
|
-
/*
|
|
55658
|
-
load-image-meta.js
|
|
55659
|
-
*/
|
|
55660
|
-
|
|
55661
|
-
|
|
55662
|
-
var hasblobSlice = typeof Blob !== 'undefined' && (Blob.prototype.slice || Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
|
|
55663
|
-
|
|
55664
|
-
loadImage.blobSlice = hasblobSlice && function () {
|
|
55665
|
-
var slice = this.slice || this.webkitSlice || this.mozSlice;
|
|
55666
|
-
return slice.apply(this, arguments);
|
|
55667
|
-
};
|
|
55668
57598
|
|
|
55669
|
-
|
|
55670
|
-
|
|
55671
|
-
|
|
55672
|
-
|
|
55673
|
-
|
|
55674
|
-
|
|
55675
|
-
|
|
55676
|
-
}; // Parses image meta data and calls the callback with an object argument
|
|
55677
|
-
// with the following properties:
|
|
55678
|
-
// * imageHead: The complete image head as ArrayBuffer (Uint8Array for IE10)
|
|
55679
|
-
// The options argument accepts an object and supports the following
|
|
55680
|
-
// properties:
|
|
55681
|
-
// * maxMetaDataSize: Defines the maximum number of bytes to parse.
|
|
55682
|
-
// * disableImageHead: Disables creating the imageHead property.
|
|
55683
|
-
|
|
55684
|
-
loadImage.parseMetaData = function (file, callback, options, data) {
|
|
55685
|
-
// eslint-disable-next-line no-param-reassign
|
|
55686
|
-
options = options || {}; // eslint-disable-next-line no-param-reassign
|
|
55687
|
-
|
|
55688
|
-
data = data || {};
|
|
55689
|
-
var that = this; // 256 KiB should contain all EXIF/ICC/IPTC segments:
|
|
55690
|
-
|
|
55691
|
-
var maxMetaDataSize = options.maxMetaDataSize || 262144;
|
|
55692
|
-
var noMetaData = !(typeof DataView !== 'undefined' && file && file.size >= 12 && file.type === 'image/jpeg' && loadImage.blobSlice); //callback(data);return;
|
|
55693
|
-
//noMetaData=true;
|
|
55694
|
-
|
|
55695
|
-
if (noMetaData || !loadImage.readFile(loadImage.blobSlice.call(file, 0, maxMetaDataSize), function (e) {
|
|
55696
|
-
if (e.target.error) {
|
|
55697
|
-
// FileReader error
|
|
55698
|
-
// eslint-disable-next-line no-console
|
|
55699
|
-
console.log(e.target.error);
|
|
55700
|
-
callback(data);
|
|
55701
|
-
return;
|
|
55702
|
-
} // Note on endianness:
|
|
55703
|
-
// Since the marker and length bytes in JPEG files are always
|
|
55704
|
-
// stored in big endian order, we can leave the endian parameter
|
|
55705
|
-
// of the DataView methods undefined, defaulting to big endian.
|
|
55706
|
-
|
|
55707
|
-
|
|
55708
|
-
var buffer = e.target.result;
|
|
55709
|
-
var dataView = new DataView(buffer);
|
|
55710
|
-
var offset = 2;
|
|
55711
|
-
var maxOffset = dataView.byteLength - 4;
|
|
55712
|
-
var headLength = offset;
|
|
55713
|
-
var markerBytes;
|
|
55714
|
-
var markerLength;
|
|
55715
|
-
var parsers;
|
|
55716
|
-
var i; // Check for the JPEG marker (0xffd8):
|
|
55717
|
-
|
|
55718
|
-
if (dataView.getUint16(0) === 0xffd8) {
|
|
55719
|
-
while (offset < maxOffset) {
|
|
55720
|
-
markerBytes = dataView.getUint16(offset); // Search for APPn (0xffeN) and COM (0xfffe) markers,
|
|
55721
|
-
// which contain application-specific meta-data like
|
|
55722
|
-
// Exif, ICC and IPTC data and text comments:
|
|
55723
|
-
|
|
55724
|
-
if (markerBytes >= 0xffe0 && markerBytes <= 0xffef || markerBytes === 0xfffe) {
|
|
55725
|
-
// The marker bytes (2) are always followed by
|
|
55726
|
-
// the length bytes (2), indicating the length of the
|
|
55727
|
-
// marker segment, which includes the length bytes,
|
|
55728
|
-
// but not the marker bytes, so we add 2:
|
|
55729
|
-
markerLength = dataView.getUint16(offset + 2) + 2;
|
|
55730
|
-
|
|
55731
|
-
if (offset + markerLength > dataView.byteLength) {
|
|
55732
|
-
// eslint-disable-next-line no-console
|
|
55733
|
-
console.log('Invalid meta data: Invalid segment size.');
|
|
55734
|
-
break;
|
|
55735
|
-
}
|
|
55736
|
-
|
|
55737
|
-
parsers = loadImage.metaDataParsers.jpeg[markerBytes];
|
|
55738
|
-
|
|
55739
|
-
if (parsers) {
|
|
55740
|
-
for (i = 0; i < parsers.length; i += 1) {
|
|
55741
|
-
parsers[i].call(that, dataView, offset, markerLength, data, options);
|
|
55742
|
-
}
|
|
55743
|
-
}
|
|
55744
|
-
|
|
55745
|
-
offset += markerLength;
|
|
55746
|
-
headLength = offset;
|
|
55747
|
-
} else {
|
|
55748
|
-
// Not an APPn or COM marker, probably safe to
|
|
55749
|
-
// assume that this is the end of the meta data
|
|
55750
|
-
break;
|
|
55751
|
-
}
|
|
55752
|
-
} // Meta length must be longer than JPEG marker (2)
|
|
55753
|
-
// plus APPn marker (2), followed by length bytes (2):
|
|
55754
|
-
|
|
55755
|
-
|
|
55756
|
-
if (!options.disableImageHead && headLength > 6) {
|
|
55757
|
-
if (buffer.slice) {
|
|
55758
|
-
data.imageHead = buffer.slice(0, headLength);
|
|
55759
|
-
} else {
|
|
55760
|
-
// Workaround for IE10, which does not yet
|
|
55761
|
-
// support ArrayBuffer.slice:
|
|
55762
|
-
data.imageHead = new Uint8Array(buffer).subarray(0, headLength);
|
|
55763
|
-
}
|
|
55764
|
-
}
|
|
57599
|
+
if (this.builder.opts.maxEmbedImageWidth === -1) {
|
|
57600
|
+
js(file, img => {
|
|
57601
|
+
targetImg.src = img.toDataURL(type, quality);
|
|
57602
|
+
processImageDone();
|
|
57603
|
+
}, {
|
|
57604
|
+
canvas: true
|
|
57605
|
+
});
|
|
55765
57606
|
} else {
|
|
55766
|
-
|
|
55767
|
-
|
|
55768
|
-
|
|
55769
|
-
|
|
55770
|
-
|
|
55771
|
-
|
|
55772
|
-
|
|
55773
|
-
|
|
55774
|
-
}; // Determines if meta data should be loaded automatically:
|
|
55775
|
-
|
|
55776
|
-
|
|
55777
|
-
loadImage.hasMetaOption = function (options) {
|
|
55778
|
-
return options && options.meta;
|
|
55779
|
-
};
|
|
55780
|
-
|
|
55781
|
-
var originalTransform = loadImage.transform;
|
|
55782
|
-
|
|
55783
|
-
loadImage.transform = function (img, options, callback, file, data) {
|
|
55784
|
-
if (loadImage.hasMetaOption(options)) {
|
|
55785
|
-
loadImage.parseMetaData(file, function (data) {
|
|
55786
|
-
originalTransform.call(loadImage, img, options, callback, file, data);
|
|
55787
|
-
}, options, data);
|
|
55788
|
-
} else {
|
|
55789
|
-
originalTransform.apply(loadImage, arguments);
|
|
55790
|
-
}
|
|
55791
|
-
};
|
|
55792
|
-
/*
|
|
55793
|
-
load-image-exif.js
|
|
55794
|
-
*/
|
|
55795
|
-
|
|
55796
|
-
|
|
55797
|
-
loadImage.ExifMap = function () {
|
|
55798
|
-
return this;
|
|
55799
|
-
};
|
|
55800
|
-
|
|
55801
|
-
loadImage.ExifMap.prototype.map = {
|
|
55802
|
-
Orientation: 0x0112
|
|
55803
|
-
};
|
|
55804
|
-
|
|
55805
|
-
loadImage.ExifMap.prototype.get = function (id) {
|
|
55806
|
-
return this[id] || this[this.map[id]];
|
|
55807
|
-
};
|
|
55808
|
-
|
|
55809
|
-
loadImage.getExifThumbnail = function (dataView, offset, length) {
|
|
55810
|
-
if (!length || offset + length > dataView.byteLength) {
|
|
55811
|
-
console.log('Invalid Exif data: Invalid thumbnail data.');
|
|
55812
|
-
return;
|
|
55813
|
-
}
|
|
55814
|
-
|
|
55815
|
-
return loadImage.createObjectURL(new Blob([dataView.buffer.slice(offset, offset + length)]));
|
|
55816
|
-
};
|
|
55817
|
-
|
|
55818
|
-
loadImage.exifTagTypes = {
|
|
55819
|
-
// byte, 8-bit unsigned int:
|
|
55820
|
-
1: {
|
|
55821
|
-
getValue: function (dataView, dataOffset) {
|
|
55822
|
-
return dataView.getUint8(dataOffset);
|
|
55823
|
-
},
|
|
55824
|
-
size: 1
|
|
55825
|
-
},
|
|
55826
|
-
// ascii, 8-bit byte:
|
|
55827
|
-
2: {
|
|
55828
|
-
getValue: function (dataView, dataOffset) {
|
|
55829
|
-
return String.fromCharCode(dataView.getUint8(dataOffset));
|
|
55830
|
-
},
|
|
55831
|
-
size: 1,
|
|
55832
|
-
ascii: true
|
|
55833
|
-
},
|
|
55834
|
-
// short, 16 bit int:
|
|
55835
|
-
3: {
|
|
55836
|
-
getValue: function (dataView, dataOffset, littleEndian) {
|
|
55837
|
-
return dataView.getUint16(dataOffset, littleEndian);
|
|
55838
|
-
},
|
|
55839
|
-
size: 2
|
|
55840
|
-
},
|
|
55841
|
-
// long, 32 bit int:
|
|
55842
|
-
4: {
|
|
55843
|
-
getValue: function (dataView, dataOffset, littleEndian) {
|
|
55844
|
-
return dataView.getUint32(dataOffset, littleEndian);
|
|
55845
|
-
},
|
|
55846
|
-
size: 4
|
|
55847
|
-
},
|
|
55848
|
-
// rational = two long values, first is numerator, second is denominator:
|
|
55849
|
-
5: {
|
|
55850
|
-
getValue: function (dataView, dataOffset, littleEndian) {
|
|
55851
|
-
return dataView.getUint32(dataOffset, littleEndian) / dataView.getUint32(dataOffset + 4, littleEndian);
|
|
55852
|
-
},
|
|
55853
|
-
size: 8
|
|
55854
|
-
},
|
|
55855
|
-
// slong, 32 bit signed int:
|
|
55856
|
-
9: {
|
|
55857
|
-
getValue: function (dataView, dataOffset, littleEndian) {
|
|
55858
|
-
return dataView.getInt32(dataOffset, littleEndian);
|
|
55859
|
-
},
|
|
55860
|
-
size: 4
|
|
55861
|
-
},
|
|
55862
|
-
// srational, two slongs, first is numerator, second is denominator:
|
|
55863
|
-
10: {
|
|
55864
|
-
getValue: function (dataView, dataOffset, littleEndian) {
|
|
55865
|
-
return dataView.getInt32(dataOffset, littleEndian) / dataView.getInt32(dataOffset + 4, littleEndian);
|
|
55866
|
-
},
|
|
55867
|
-
size: 8
|
|
55868
|
-
}
|
|
55869
|
-
}; // undefined, 8-bit byte, value depending on field:
|
|
55870
|
-
|
|
55871
|
-
loadImage.exifTagTypes[7] = loadImage.exifTagTypes[1];
|
|
55872
|
-
|
|
55873
|
-
loadImage.getExifValue = function (dataView, tiffOffset, offset, type, length, littleEndian) {
|
|
55874
|
-
var tagType = loadImage.exifTagTypes[type];
|
|
55875
|
-
var tagSize;
|
|
55876
|
-
var dataOffset;
|
|
55877
|
-
var values;
|
|
55878
|
-
var i;
|
|
55879
|
-
var str;
|
|
55880
|
-
var c;
|
|
55881
|
-
|
|
55882
|
-
if (!tagType) {
|
|
55883
|
-
console.log('Invalid Exif data: Invalid tag type.');
|
|
55884
|
-
return;
|
|
55885
|
-
}
|
|
55886
|
-
|
|
55887
|
-
tagSize = tagType.size * length; // Determine if the value is contained in the dataOffset bytes,
|
|
55888
|
-
// or if the value at the dataOffset is a pointer to the actual data:
|
|
55889
|
-
|
|
55890
|
-
dataOffset = tagSize > 4 ? tiffOffset + dataView.getUint32(offset + 8, littleEndian) : offset + 8;
|
|
55891
|
-
|
|
55892
|
-
if (dataOffset + tagSize > dataView.byteLength) {
|
|
55893
|
-
console.log('Invalid Exif data: Invalid data offset.');
|
|
55894
|
-
return;
|
|
55895
|
-
}
|
|
55896
|
-
|
|
55897
|
-
if (length === 1) {
|
|
55898
|
-
return tagType.getValue(dataView, dataOffset, littleEndian);
|
|
55899
|
-
}
|
|
55900
|
-
|
|
55901
|
-
values = [];
|
|
55902
|
-
|
|
55903
|
-
for (i = 0; i < length; i += 1) {
|
|
55904
|
-
values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);
|
|
55905
|
-
}
|
|
55906
|
-
|
|
55907
|
-
if (tagType.ascii) {
|
|
55908
|
-
str = ''; // Concatenate the chars:
|
|
55909
|
-
|
|
55910
|
-
for (i = 0; i < values.length; i += 1) {
|
|
55911
|
-
c = values[i]; // Ignore the terminating NULL byte(s):
|
|
55912
|
-
|
|
55913
|
-
if (c === '\u0000') {
|
|
55914
|
-
break;
|
|
55915
|
-
}
|
|
55916
|
-
|
|
55917
|
-
str += c;
|
|
55918
|
-
}
|
|
55919
|
-
|
|
55920
|
-
return str;
|
|
55921
|
-
}
|
|
55922
|
-
|
|
55923
|
-
return values;
|
|
55924
|
-
};
|
|
55925
|
-
|
|
55926
|
-
loadImage.parseExifTag = function (dataView, tiffOffset, offset, littleEndian, data) {
|
|
55927
|
-
var tag = dataView.getUint16(offset, littleEndian);
|
|
55928
|
-
data.exif[tag] = loadImage.getExifValue(dataView, tiffOffset, offset, dataView.getUint16(offset + 2, littleEndian), dataView.getUint32(offset + 4, littleEndian), littleEndian);
|
|
55929
|
-
};
|
|
55930
|
-
|
|
55931
|
-
loadImage.parseExifTags = function (dataView, tiffOffset, dirOffset, littleEndian, data) {
|
|
55932
|
-
var tagsNumber, dirEndOffset, i;
|
|
55933
|
-
|
|
55934
|
-
if (dirOffset + 6 > dataView.byteLength) {
|
|
55935
|
-
console.log('Invalid Exif data: Invalid directory offset.');
|
|
55936
|
-
return;
|
|
55937
|
-
}
|
|
55938
|
-
|
|
55939
|
-
tagsNumber = dataView.getUint16(dirOffset, littleEndian);
|
|
55940
|
-
dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
|
|
55941
|
-
|
|
55942
|
-
if (dirEndOffset + 4 > dataView.byteLength) {
|
|
55943
|
-
console.log('Invalid Exif data: Invalid directory size.');
|
|
55944
|
-
return;
|
|
55945
|
-
}
|
|
55946
|
-
|
|
55947
|
-
for (i = 0; i < tagsNumber; i += 1) {
|
|
55948
|
-
this.parseExifTag(dataView, tiffOffset, dirOffset + 2 + 12 * i, littleEndian, data);
|
|
55949
|
-
} // Return the offset to the next directory:
|
|
55950
|
-
|
|
55951
|
-
|
|
55952
|
-
return dataView.getUint32(dirEndOffset, littleEndian);
|
|
55953
|
-
};
|
|
55954
|
-
|
|
55955
|
-
loadImage.parseExifData = function (dataView, offset, length, data, options) {
|
|
55956
|
-
if (options.disableExif) {
|
|
55957
|
-
return;
|
|
55958
|
-
}
|
|
55959
|
-
|
|
55960
|
-
var tiffOffset = offset + 10;
|
|
55961
|
-
var littleEndian;
|
|
55962
|
-
var dirOffset;
|
|
55963
|
-
var thumbnailData; // Check for the ASCII code for "Exif" (0x45786966):
|
|
55964
|
-
|
|
55965
|
-
if (dataView.getUint32(offset + 4) !== 0x45786966) {
|
|
55966
|
-
// No Exif data, might be XMP data instead
|
|
55967
|
-
return;
|
|
55968
|
-
}
|
|
55969
|
-
|
|
55970
|
-
if (tiffOffset + 8 > dataView.byteLength) {
|
|
55971
|
-
console.log('Invalid Exif data: Invalid segment size.');
|
|
55972
|
-
return;
|
|
55973
|
-
} // Check for the two null bytes:
|
|
55974
|
-
|
|
55975
|
-
|
|
55976
|
-
if (dataView.getUint16(offset + 8) !== 0x0000) {
|
|
55977
|
-
console.log('Invalid Exif data: Missing byte alignment offset.');
|
|
55978
|
-
return;
|
|
55979
|
-
} // Check the byte alignment:
|
|
55980
|
-
|
|
55981
|
-
|
|
55982
|
-
switch (dataView.getUint16(tiffOffset)) {
|
|
55983
|
-
case 0x4949:
|
|
55984
|
-
littleEndian = true;
|
|
55985
|
-
break;
|
|
55986
|
-
|
|
55987
|
-
case 0x4d4d:
|
|
55988
|
-
littleEndian = false;
|
|
55989
|
-
break;
|
|
55990
|
-
|
|
55991
|
-
default:
|
|
55992
|
-
console.log('Invalid Exif data: Invalid byte alignment marker.');
|
|
55993
|
-
return;
|
|
55994
|
-
} // Check for the TIFF tag marker (0x002A):
|
|
55995
|
-
|
|
55996
|
-
|
|
55997
|
-
if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002a) {
|
|
55998
|
-
console.log('Invalid Exif data: Missing TIFF marker.');
|
|
55999
|
-
return;
|
|
56000
|
-
} // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
|
|
56001
|
-
|
|
56002
|
-
|
|
56003
|
-
dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian); // Create the exif object to store the tags:
|
|
56004
|
-
|
|
56005
|
-
data.exif = new loadImage.ExifMap(); // Parse the tags of the main image directory and retrieve the
|
|
56006
|
-
// offset to the next directory, usually the thumbnail directory:
|
|
56007
|
-
|
|
56008
|
-
dirOffset = loadImage.parseExifTags(dataView, tiffOffset, tiffOffset + dirOffset, littleEndian, data);
|
|
56009
|
-
|
|
56010
|
-
if (dirOffset && !options.disableExifThumbnail) {
|
|
56011
|
-
thumbnailData = {
|
|
56012
|
-
exif: {}
|
|
56013
|
-
};
|
|
56014
|
-
dirOffset = loadImage.parseExifTags(dataView, tiffOffset, tiffOffset + dirOffset, littleEndian, thumbnailData); // Check for JPEG Thumbnail offset:
|
|
56015
|
-
|
|
56016
|
-
if (thumbnailData.exif[0x0201]) {
|
|
56017
|
-
data.exif.Thumbnail = loadImage.getExifThumbnail(dataView, tiffOffset + thumbnailData.exif[0x0201], thumbnailData.exif[0x0202]);
|
|
57607
|
+
js(file, img => {
|
|
57608
|
+
targetImg.src = img.toDataURL(type, quality);
|
|
57609
|
+
processImageDone();
|
|
57610
|
+
}, {
|
|
57611
|
+
maxWidth: this.builder.opts.maxEmbedImageWidth,
|
|
57612
|
+
maxHeight: this.builder.opts.maxEmbedImageWidth,
|
|
57613
|
+
canvas: true
|
|
57614
|
+
});
|
|
56018
57615
|
}
|
|
56019
|
-
} // Check for Exif Sub IFD Pointer:
|
|
56020
|
-
|
|
56021
|
-
|
|
56022
|
-
if (data.exif[0x8769] && !options.disableExifSub) {
|
|
56023
|
-
loadImage.parseExifTags(dataView, tiffOffset, tiffOffset + data.exif[0x8769], littleEndian, data);
|
|
56024
|
-
} // Check for GPS Info IFD Pointer:
|
|
56025
|
-
|
|
56026
|
-
|
|
56027
|
-
if (data.exif[0x8825] && !options.disableExifGps) {
|
|
56028
|
-
loadImage.parseExifTags(dataView, tiffOffset, tiffOffset + data.exif[0x8825], littleEndian, data);
|
|
56029
57616
|
}
|
|
56030
|
-
}; // Registers the Exif parser for the APP1 JPEG meta data segment:
|
|
56031
|
-
|
|
56032
57617
|
|
|
56033
|
-
|
|
56034
|
-
// * exif: The exif tags, parsed by the parseExifData method
|
|
56035
|
-
// Adds the following options to the parseMetaData method:
|
|
56036
|
-
// * disableExif: Disables Exif parsing.
|
|
56037
|
-
// * disableExifThumbnail: Disables parsing of the Exif Thumbnail.
|
|
56038
|
-
// * disableExifSub: Disables parsing of the Exif Sub IFD.
|
|
56039
|
-
// * disableExifGps: Disables parsing of the Exif GPS Info IFD.
|
|
57618
|
+
}
|
|
56040
57619
|
|
|
56041
57620
|
const dom$z = new Dom();
|
|
56042
57621
|
|
|
@@ -74903,7 +76482,6 @@ class ContentBuilder {
|
|
|
74903
76482
|
animatedSorting
|
|
74904
76483
|
dragWithoutHandle
|
|
74905
76484
|
*/
|
|
74906
|
-
autoResizeImageEmbed: true,
|
|
74907
76485
|
maxEmbedImageWidth: 1600,
|
|
74908
76486
|
//set -1 for no max (use original image width)
|
|
74909
76487
|
zoom: 1,
|
|
@@ -79111,7 +80689,7 @@ var pace = {exports: {}};
|
|
|
79111
80689
|
{
|
|
79112
80690
|
module.exports = Pace;
|
|
79113
80691
|
}
|
|
79114
|
-
}).call(commonjsGlobal);
|
|
80692
|
+
}).call(commonjsGlobal$1);
|
|
79115
80693
|
})(pace);
|
|
79116
80694
|
|
|
79117
80695
|
var Pace = pace.exports;
|
|
@@ -79191,10 +80769,6 @@ class ContentBox {
|
|
|
79191
80769
|
name: 'symbols',
|
|
79192
80770
|
showInMainToolbar: true,
|
|
79193
80771
|
showInElementToolbar: false
|
|
79194
|
-
}, {
|
|
79195
|
-
name: 'buttoneditor',
|
|
79196
|
-
showInMainToolbar: false,
|
|
79197
|
-
showInElementToolbar: false
|
|
79198
80772
|
}],
|
|
79199
80773
|
disableConfig: false,
|
|
79200
80774
|
useLightbox: true,
|