@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.
@@ -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$1 = {exports: {}};
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$1));
8049
+ }(js$2));
8050
8050
 
8051
- var JsBeautify$1 = js$1.exports;
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') + ': &nbsp;<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;">&#8598;</button>' + '<button title="' + out('Top Center') + '" class="cmd-box-content-pos" data-value="topcenter" style="width:40px;border-left:none;">&#8593;</button>' + '<button title="' + out('Top Right') + '" class="cmd-box-content-pos" data-value="topright" style="width:40px;border-left:none;">&#8599;</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;">&#8592;</button>' + '<button title="' + out('Middle Center') + '" class="cmd-box-content-pos" data-value="middlecenter" style="width:40px;border-left:none;border-top:none;">&#9737;</button>' + '<button title="' + out('Middle Right') + '" class="cmd-box-content-pos" data-value="middleright" style="width:40px;border-left:none;border-top:none;">&#8594;</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;">&#8601;</button>' + '<button title="' + out('Bottom Center') + '" class="cmd-box-content-pos" data-value="bottomcenter" style="width:40px;border-left:none;border-top:none;">&#8595;</button>' + '<button title="' + out('Bottom Right') + '" class="cmd-box-content-pos" data-value="bottomright" style="width:40px;border-left:none;border-top:none;">&#8600;</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;">&#8598;</button>' + '<button title="' + out('Top Center') + '" class="cmd-box-content-pos" data-value="topcenter" style="width:40px;border-left:none;">&#8593;</button>' + '<button title="' + out('Top Right') + '" class="cmd-box-content-pos" data-value="topright" style="width:40px;border-left:none;">&#8599;</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;">&#8592;</button>' + '<button title="' + out('Middle Center') + '" class="cmd-box-content-pos" data-value="middlecenter" style="width:40px;border-left:none;border-top:none;">&#9737;</button>' + '<button title="' + out('Middle Right') + '" class="cmd-box-content-pos" data-value="middleright" style="width:40px;border-left:none;border-top:none;">&#8594;</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;">&#8601;</button>' + '<button title="' + out('Bottom Center') + '" class="cmd-box-content-pos" data-value="bottomcenter" style="width:40px;border-left:none;border-top:none;">&#8595;</button>' + '<button title="' + out('Bottom Right') + '" class="cmd-box-content-pos" data-value="bottomright" style="width:40px;border-left:none;border-top:none;">&#8600;</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 = s;
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.style.display = '';
8381
- container.style.flexDirection = '';
8382
- container.style.justifyContent = '';
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.style.height = '100%';
8388
- container.style.display = 'flex';
8389
- container.style.flexDirection = 'column';
8390
- container.style.justifyContent = 'space-between';
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
- if (container.style.height === '100%') {
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
- const html = `<div>
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
- const html = `<div>
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> &nbsp;
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
- targetImg.src = tmpCanvasNoCrop.toDataURL(type, quality);
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
- tmpCanvasNoCrop.parentNode.removeChild(tmpCanvasNoCrop);
55130
- processImageDone();
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
- let reader = new FileReader();
55139
- reader.addEventListener('load', e => {
55140
- //Problem: image not fully rendered
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
- var sy = 0;
55242
- var ey = ih;
55243
- var py = ih;
57589
+ var type, quality;
55244
57590
 
55245
- while (py > sy) {
55246
- var alpha = data[(py - 1) * 4 + 3];
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
- sy = py;
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
- loadImage.metaDataParsers = {
55670
- jpeg: {
55671
- 0xffe1: [],
55672
- // APP1 marker
55673
- 0xffed: [] // APP13 marker
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
- // eslint-disable-next-line no-console
55767
- console.log('Invalid JPEG file: Missing JPEG marker.');
55768
- }
55769
-
55770
- callback(data);
55771
- }, 'readAsArrayBuffer')) {
55772
- callback(data);
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
- loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData); // Adds the following properties to the parseMetaData callback data:
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,