@innovastudio/contentbox 1.6.109 → 1.6.110

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@innovastudio/contentbox",
3
3
  "type": "module",
4
- "version": "1.6.109",
4
+ "version": "1.6.110",
5
5
  "description": "",
6
6
  "main": "public/contentbox/contentbox.esm.js",
7
7
  "types": "index.d.ts",
@@ -59,7 +59,7 @@
59
59
  "ws": "^8.13.0"
60
60
  },
61
61
  "dependencies": {
62
- "@innovastudio/contentbuilder": "^1.5.106",
62
+ "@innovastudio/contentbuilder": "^1.5.108",
63
63
  "js-beautify": "^1.14.0",
64
64
  "sortablejs": "^1.15.2"
65
65
  }
@@ -27302,6 +27302,14 @@ class Snippets {
27302
27302
  // }
27303
27303
 
27304
27304
  }
27305
+
27306
+
27307
+ if(!(parent._cb.win.FormViewer)){
27308
+ const result = snippets.filter((item)=>{
27309
+ return !(item.type === 'form');
27310
+ });
27311
+ snippets = [...result];
27312
+ }
27305
27313
 
27306
27314
 
27307
27315
  for (let i = 0; i <snippets.length; i++) {
@@ -44467,6 +44475,15 @@ const renderSnippetPanel = (builder, snippetOpen) => {
44467
44475
 
44468
44476
  builder.opts.snippetJSON.snippets = [...snippets];
44469
44477
  }
44478
+
44479
+ // Exclude form snippet if FormViewer not found.
44480
+ if (!builder.win.FormViewer) {
44481
+ const result = snippets.filter(item => {
44482
+ return !(item.type === 'form');
44483
+ });
44484
+ snippets = [...result];
44485
+ }
44486
+ builder.opts.snippetJSON.snippets = [...snippets];
44470
44487
  let index = 1;
44471
44488
  if (builder.opts.emailMode) {
44472
44489
  builder.opts.snippetJSON.snippets.forEach(item => {
@@ -71925,6 +71942,106 @@ var loadImageOrientation = {exports: {}};
71925
71942
 
71926
71943
  var js$2 = loadImage.exports;
71927
71944
 
71945
+ class DragDropImageUploader {
71946
+ constructor(element, builder) {
71947
+ this.element = element;
71948
+ this.builder = builder;
71949
+ this.targetImage = null;
71950
+ this.isAttached = false;
71951
+ this._onDragOver = this._onDragOver.bind(this);
71952
+ this._onDragLeave = this._onDragLeave.bind(this);
71953
+ this._onDrop = this._onDrop.bind(this);
71954
+ }
71955
+ attach() {
71956
+ if (this.isAttached) return; // Prevent duplicate attachment
71957
+
71958
+ this.element.addEventListener('dragover', this._onDragOver);
71959
+ this.element.addEventListener('dragleave', this._onDragLeave);
71960
+ this.element.addEventListener('drop', this._onDrop);
71961
+ this.isAttached = true;
71962
+ }
71963
+ detach() {
71964
+ if (!this.isAttached) return;
71965
+ this.element.removeEventListener('dragover', this._onDragOver);
71966
+ this.element.removeEventListener('dragleave', this._onDragLeave);
71967
+ this.element.removeEventListener('drop', this._onDrop);
71968
+ this.isAttached = false;
71969
+ }
71970
+ _getImageUnderCursor(e) {
71971
+ const doc = this.element.ownerDocument || document;
71972
+ const range = doc.caretRangeFromPoint ? doc.caretRangeFromPoint(e.clientX, e.clientY) : doc.caretPositionFromPoint(e.clientX, e.clientY);
71973
+ if (!range) return null;
71974
+ const node = range.startContainer.nodeType === 1 ? range.startContainer : range.startContainer.parentElement;
71975
+ if (this.element.getAttribute('id') === 'divImageResizer') {
71976
+ return this.builder.activeImage;
71977
+ }
71978
+ return node.tagName === 'IMG' ? node : node.querySelector && node.querySelector('img');
71979
+ }
71980
+ async _onDrop(e) {
71981
+ e.preventDefault();
71982
+ if (this.targetImage) {
71983
+ this.targetImage.classList.remove('drag-over-image');
71984
+ }
71985
+ const files = e.dataTransfer.files;
71986
+ if (files && files.length > 0 && files[0].type.startsWith('image/')) {
71987
+ const file = files[0];
71988
+ const result = await this._onUpload(file);
71989
+ if (result && this.targetImage) {
71990
+ this.targetImage.setAttribute('src', result.url);
71991
+
71992
+ // finished steps:
71993
+
71994
+ // let imageProgress = document.querySelector('#divImageProgress');
71995
+ // if(imageProgress) imageProgress.style.display = 'none';
71996
+
71997
+ //Check if image is part of module snippet. If so, refresh the (active) module (hide imageTool). If not, refresh imageTool position
71998
+ this.builder.element.image.refreshIfIsModule(this.targetImage);
71999
+ this.builder.element.image.startImageMonitor(this.targetImage);
72000
+
72001
+ //Trigger Change event
72002
+ this.builder.opts.onChange();
72003
+ this.builder.elmTool.refresh();
72004
+ if (this.builder.onImageChange) this.builder.onImageChange();
72005
+ }
72006
+ }
72007
+ this.targetImage = null;
72008
+ }
72009
+ _onDragOver(e) {
72010
+ e.preventDefault();
72011
+ const img = this._getImageUnderCursor(e);
72012
+ if (img) {
72013
+ if (this.targetImage && this.targetImage !== img) {
72014
+ this.targetImage.classList.remove('drag-over-image');
72015
+ }
72016
+ this.targetImage = img;
72017
+ this.targetImage.classList.add('drag-over-image');
72018
+ }
72019
+ }
72020
+ _onDragLeave() {
72021
+ if (this.targetImage) {
72022
+ this.targetImage.classList.remove('drag-over-image');
72023
+ this.targetImage = null;
72024
+ }
72025
+ }
72026
+ _onUpload(file) {
72027
+ return new Promise(resolve => {
72028
+ this.builder.opts.onAssetUpload = url => {
72029
+ resolve({
72030
+ url: url,
72031
+ name: file.name,
72032
+ size: file.size
72033
+ });
72034
+ };
72035
+ const fakeEvent = {
72036
+ target: {
72037
+ files: [file]
72038
+ }
72039
+ };
72040
+ this.builder.opts.onImageUpload(fakeEvent);
72041
+ });
72042
+ }
72043
+ }
72044
+
71928
72045
  class Image$1 {
71929
72046
  constructor(builder) {
71930
72047
  this.builder = builder;
@@ -71966,6 +72083,15 @@ class Image$1 {
71966
72083
  this.imageTool = imageTool;
71967
72084
  imageResizer = document.querySelector('#divImageResizer');
71968
72085
  this.imageResizer = imageResizer;
72086
+
72087
+ // upload
72088
+ if (this.builder.opts.onImageUpload) {
72089
+ if (!imageResizer._dragDropUploaderAttached) {
72090
+ imageResizer._dragDropUploaderAttached = true;
72091
+ const uploader = new DragDropImageUploader(imageResizer, this.builder);
72092
+ uploader.attach();
72093
+ }
72094
+ }
71969
72095
  imageResizer.addEventListener('wheel', () => {
71970
72096
  this.hideImageResizer();
71971
72097
  }, {
@@ -72109,20 +72235,70 @@ class Image$1 {
72109
72235
 
72110
72236
  // Browse local image
72111
72237
  let elm = imageTool.querySelector('#fileEmbedImage');
72112
- dom.addEventListener(elm, 'change', e => {
72238
+ dom.addEventListener(elm, 'change', async e => {
72113
72239
  this.builder.uo.saveForUndo();
72114
72240
  var input = e.target;
72115
72241
  let img = this.builder.activeImage;
72242
+
72243
+ // content scaling
72244
+ let scale = 1;
72245
+ const contentView = document.querySelector('.is-content-view');
72246
+ if (contentView) {
72247
+ const style = window.getComputedStyle(contentView);
72248
+ const transform = style.transform;
72249
+ if (transform.startsWith('matrix(')) {
72250
+ const matrix = new DOMMatrix(transform);
72251
+ if (matrix.b === 0 && matrix.c === 0 && matrix.a === matrix.d) {
72252
+ scale = matrix.a; // only if pure scale()
72253
+ }
72254
+ }
72255
+ }
72256
+
72116
72257
  let imageProgress = builderStuff.querySelector('#divImageProgress');
72117
72258
  imageProgress.style.display = 'table';
72118
- imageProgress.style.width = img.offsetWidth * this.builder.opts.zoom + 'px';
72119
- imageProgress.style.height = img.offsetHeight * this.builder.opts.zoom + 'px';
72259
+ imageProgress.style.width = img.offsetWidth * this.builder.opts.zoom * scale + 'px';
72260
+ imageProgress.style.height = img.offsetHeight * this.builder.opts.zoom * scale + 'px';
72120
72261
  const newPos = this.builder.util.getElementPosition(img);
72121
72262
  let top = newPos.top + window.pageYOffset;
72122
72263
  let left = newPos.left + window.pageXOffset;
72123
72264
  imageProgress.style.top = top + 'px';
72124
72265
  imageProgress.style.left = left + 'px';
72125
72266
 
72267
+ // upload
72268
+ const onUpload = async e => {
72269
+ let file = e.target.files[0];
72270
+ return new Promise(resolve => {
72271
+ this.builder.opts.onAssetUpload = url => {
72272
+ resolve({
72273
+ url: url,
72274
+ name: file.name,
72275
+ size: file.size
72276
+ });
72277
+ };
72278
+ this.builder.opts.onImageUpload(e);
72279
+ });
72280
+ };
72281
+ if (this.builder.opts.onImageUpload) {
72282
+ const result = await onUpload(e);
72283
+ img.setAttribute('src', result.url);
72284
+
72285
+ // finished steps:
72286
+
72287
+ imageProgress.style.display = 'none';
72288
+ elm = imageTool.querySelector('#fileEmbedImage');
72289
+ elm.value = ''; //clear input
72290
+
72291
+ //Check if image is part of module snippet. If so, refresh the (active) module (hide imageTool). If not, refresh imageTool position
72292
+ this.refreshIfIsModule(img);
72293
+ this.startImageMonitor(img);
72294
+
72295
+ //Trigger Change event
72296
+ this.builder.opts.onChange();
72297
+ this.builder.elmTool.refresh();
72298
+ if (this.builder.onImageChange) this.builder.onImageChange();
72299
+ return;
72300
+ }
72301
+
72126
72302
  //The #fileEmbedImage triggered 2 times in IE (because of clearInputs below). This makes input.files[0].name returns error on 2nd trigger. Just add try{}!
72127
72303
  try {
72128
72304
  img.setAttribute('data-filename', input.files[0].name); //needed for saveimage.js |
@@ -72644,9 +72820,113 @@ class Image$1 {
72644
72820
 
72645
72821
  // Apply (crop) image
72646
72822
  elm = modalImageEdit.querySelector('.input-ok');
72647
- dom.addEventListener(elm, 'click', () => {
72823
+ dom.addEventListener(elm, 'click', async () => {
72648
72824
  this.builder.uo.saveForUndo();
72649
72825
  let img = this.builder.activeImage;
72826
+ if (this.builder.opts.onImageUpload) {
72827
+ let basename, extension, newname, newfilename;
72828
+ let src = img.getAttribute('src');
72829
+ if (src.indexOf('base64') === -1) {
72830
+ let filename = src.substring(src.lastIndexOf('/') + 1);
72831
+ basename = dom.baseName(filename);
72832
+ extension = filename.substr(filename.lastIndexOf('.') + 1).toLowerCase();
72833
+ } else if (img.getAttribute('data-filename')) {
72834
+ let attr = img.getAttribute('data-filename');
72835
+ basename = dom.baseName(attr);
72836
+ extension = attr.substr(attr.lastIndexOf('.') + 1).toLowerCase();
72837
+ } else {
72838
+ basename = util.makeId();
72839
+ extension = 'png';
72840
+ const match = src.match(/^data:image\/(.*?);base64,/);
72841
+ if (match) {
72842
+ extension = match[1]; // e.g., "png", "jpeg", "gif"
72843
+ }
72844
+ }
72845
+
72846
+ if (basename.indexOf('-edit') !== -1) {
72847
+ basename = basename.substr(0, basename.indexOf('-edit'));
72848
+ }
72849
+ newname = basename + '-edit' + util.makeId();
72850
+ newname = newname.replaceAll('%20', '-'); // fix 404 error after file upload
72851
+
72852
+ newfilename = newname + '.' + extension;
72853
+ let base64;
72854
+ if (extension === 'jpg' || extension === 'jpeg' || extension === 'webm' || extension === 'webp') {
72855
+ base64 = this.cropper.getCroppedCanvas({
72856
+ fillColor: '#fff',
72857
+ imageSmoothingEnabled: true,
72858
+ imageSmoothingQuality: 'high'
72859
+ }).toDataURL('image/jpeg');
72860
+ } else {
72861
+ base64 = this.cropper.getCroppedCanvas({}).toDataURL();
72862
+ }
72863
+
72864
+ // await this.builder.opts.onBase64Upload(img, base64, newfilename);
72865
+ const getMimeTypeFromFilename = filename => {
72866
+ const ext = filename.split('.').pop().toLowerCase();
72867
+ const mimeTypes = {
72868
+ jpg: 'image/jpeg',
72869
+ jpeg: 'image/jpeg',
72870
+ png: 'image/png',
72871
+ gif: 'image/gif',
72872
+ webp: 'image/webp',
72873
+ svg: 'image/svg+xml',
72874
+ pdf: 'application/pdf',
72875
+ txt: 'text/plain',
72876
+ mp3: 'audio/mpeg',
72877
+ mp4: 'video/mp4',
72878
+ mov: 'video/quicktime',
72879
+ wav: 'audio/wav',
72880
+ json: 'application/json'
72881
+ // add more as needed
72882
+ };
72883
+
72884
+ return mimeTypes[ext] || 'application/octet-stream';
72885
+ };
72886
+ const base64ToFile = (base64, filename) => {
72887
+ const mimeType = getMimeTypeFromFilename(filename);
72888
+ const byteString = atob(base64.split(',')[1]);
72889
+ const byteArray = new Uint8Array(byteString.length);
72890
+ for (let i = 0; i < byteString.length; i++) {
72891
+ byteArray[i] = byteString.charCodeAt(i);
72892
+ }
72893
+ return new File([byteArray], filename, {
72894
+ type: mimeType
72895
+ });
72896
+ };
72897
+ const onUpload = file => {
72898
+ return new Promise(resolve => {
72899
+ this.builder.opts.onAssetUpload = url => {
72900
+ resolve({
72901
+ url: url,
72902
+ name: file.name,
72903
+ size: file.size
72904
+ });
72905
+ };
72906
+ const fakeEvent = {
72907
+ target: {
72908
+ files: [file]
72909
+ }
72910
+ };
72911
+ this.builder.opts.onImageUpload(fakeEvent);
72912
+ });
72913
+ };
72914
+ const file = base64ToFile(base64, newfilename);
72915
+ const result = await onUpload(file);
72916
+ img.setAttribute('src', result.url);
72917
+
72918
+ // finished steps:
72919
+
72920
+ //Check if image is part of module snippet. If so, refresh the (active) module (hide imageTool). If not, refresh imageTool position
72921
+ this.refreshIfIsModule(img);
72922
+
72923
+ //Trigger Change event
72924
+ this.builder.opts.onChange();
72925
+ util.hideModal(modalImageEdit);
72926
+ this.builder.elmTool.refresh();
72927
+ if (this.builder.onImageChange) this.builder.onImageChange();
72928
+ return;
72929
+ }
72650
72930
  let attr = img.getAttribute('data-filename');
72651
72931
  let extension = 'jpg';
72652
72932
  if (attr) {
@@ -76394,6 +76674,9 @@ class Module {
76394
76674
  let result = await fetch(this.builder.opts.modulePath + modulename + '.html');
76395
76675
  result = await result.text();
76396
76676
  result = result.replace(/<script>/g, `${this.builder.nonce ? `<script nonce="${this.builder.nonce}">` : '<script>'}`);
76677
+
76678
+ // Replace assets path
76679
+ result = result.replace(/="assets\//g, '="' + this.builder.settings.assetPath);
76397
76680
  iframe.srcdoc = result;
76398
76681
  setTimeout(() => {
76399
76682
  iframe.style.opacity = '';
@@ -94417,7 +94700,7 @@ class Rte {
94417
94700
  });
94418
94701
 
94419
94702
  const btnInsertImageOk = modalInsertImage.querySelector('.input-ok');
94420
- dom.addEventListener(btnInsertImageOk, 'click', () => {
94703
+ dom.addEventListener(btnInsertImageOk, 'click', async () => {
94421
94704
  if (!this.builder.activeCol) {
94422
94705
  util.hideModal(modalInsertImage);
94423
94706
  return;
@@ -94433,7 +94716,76 @@ class Rte {
94433
94716
  }
94434
94717
  if (val === '') return;
94435
94718
  let fileToInsert = modalInsertImage.querySelector('#imgInsertImagePreview').getAttribute('data-filename');
94436
- util.pasteHtmlAtCaret('<img data-filename="' + fileToInsert + '" src="' + val + '" alt="" />', false);
94719
+ if (this.builder.opts.onImageUpload && val.indexOf('base64') !== -1) {
94720
+ let basename, extension, newname, newfilename;
94721
+ basename = dom.baseName(fileToInsert);
94722
+ extension = fileToInsert.substr(fileToInsert.lastIndexOf('.') + 1).toLowerCase();
94723
+ if (basename.indexOf('-edit') !== -1) {
94724
+ basename = basename.substr(0, basename.indexOf('-edit'));
94725
+ }
94726
+ newname = basename + '-edit' + util.makeId();
94727
+ newname = newname.replaceAll('%20', '-'); // fix 404 error after file upload
94728
+
94729
+ newfilename = newname + '.' + extension;
94730
+ let base64 = val;
94731
+
94732
+ // await this.builder.opts.onBase64Upload(img, base64, newfilename);
94733
+ const getMimeTypeFromFilename = filename => {
94734
+ const ext = filename.split('.').pop().toLowerCase();
94735
+ const mimeTypes = {
94736
+ jpg: 'image/jpeg',
94737
+ jpeg: 'image/jpeg',
94738
+ png: 'image/png',
94739
+ gif: 'image/gif',
94740
+ webp: 'image/webp',
94741
+ svg: 'image/svg+xml',
94742
+ pdf: 'application/pdf',
94743
+ txt: 'text/plain',
94744
+ mp3: 'audio/mpeg',
94745
+ mp4: 'video/mp4',
94746
+ mov: 'video/quicktime',
94747
+ wav: 'audio/wav',
94748
+ json: 'application/json'
94749
+ // add more as needed
94750
+ };
94751
+
94752
+ return mimeTypes[ext] || 'application/octet-stream';
94753
+ };
94754
+ const base64ToFile = (base64, filename) => {
94755
+ const mimeType = getMimeTypeFromFilename(filename);
94756
+ const byteString = atob(base64.split(',')[1]);
94757
+ const byteArray = new Uint8Array(byteString.length);
94758
+ for (let i = 0; i < byteString.length; i++) {
94759
+ byteArray[i] = byteString.charCodeAt(i);
94760
+ }
94761
+ return new File([byteArray], filename, {
94762
+ type: mimeType
94763
+ });
94764
+ };
94765
+ const onUpload = file => {
94766
+ return new Promise(resolve => {
94767
+ this.builder.opts.onAssetUpload = url => {
94768
+ resolve({
94769
+ url: url,
94770
+ name: file.name,
94771
+ size: file.size
94772
+ });
94773
+ };
94774
+ const fakeEvent = {
94775
+ target: {
94776
+ files: [file]
94777
+ }
94778
+ };
94779
+ this.builder.opts.onImageUpload(fakeEvent);
94780
+ });
94781
+ };
94782
+ const file = base64ToFile(base64, newfilename);
94783
+ const result = await onUpload(file);
94784
+ val = result.url;
94785
+ }
94786
+
94787
+ // util.pasteHtmlAtCaret('<img data-filename="' + fileToInsert + '" src="' + val + '" alt="" />', false);
94788
+ util.pasteHtmlAtCaret('<img src="' + val + '" alt="" />', false);
94437
94789
  util.hideModal(modalInsertImage);
94438
94790
  let builderActive = this.builder.doc.querySelector('.builder-active');
94439
94791
  if (builderActive) this.builder.applyBehaviorOn(builderActive);
@@ -109505,6 +109857,9 @@ class Dictation {
109505
109857
  this.modalConfig = modalConfig;
109506
109858
  const btnConfig = builderStuff.querySelector('.cmd-command-config');
109507
109859
  const btnDictation = builderStuff.querySelector('.cmd-enable-dictation');
109860
+ if (!this.builder.settings.enableDictation) {
109861
+ btnDictation.style.display = 'none';
109862
+ }
109508
109863
  const btnClear = builderStuff.querySelector('.cmd-clear-command');
109509
109864
  const chkAutoSend = builderStuff.querySelector('#chkAutoSendCommand');
109510
109865
  const btnCommandList = builderStuff.querySelector('.cmd-command-list');
@@ -118514,7 +118869,7 @@ class ContentBuilder {
118514
118869
  // Option for self-hosted fonts:
118515
118870
  // fontPath: 'assets/cssfonts/', // If set, will be used
118516
118871
 
118517
- snippetModal: false,
118872
+ snippetModal: true,
118518
118873
  snippetModalLeft: false,
118519
118874
  snippetData: 'assets/minimalist-blocks/snippetlist.html',
118520
118875
  // Deprecated
@@ -118794,7 +119149,7 @@ class ContentBuilder {
118794
119149
  maxEmbedImageWidth: 1600,
118795
119150
  //set -1 for no max (use original image width)
118796
119151
  zoom: 1,
118797
- useLightbox: false,
119152
+ useLightbox: true,
118798
119153
  lightboxArrow: true,
118799
119154
  imageRenameOnEdit: true,
118800
119155
  disableAutoEmbedVideo: false,
@@ -119183,6 +119538,7 @@ class ContentBuilder {
119183
119538
  sendCommandUrl: '',
119184
119539
  // http://localhost:8081/answer
119185
119540
  // speechTranscribeUrl: 'http://192.168.1.7:8081',
119541
+ enableDictation: false,
119186
119542
  onlineDemo: false,
119187
119543
  autoSendDelay: 4000,
119188
119544
  autoEditBlock: false,
@@ -119588,6 +119944,10 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
119588
119944
  }
119589
119945
  this.settings = this.opts; // Backward compatible
119590
119946
 
119947
+ if (this.isContentBox) {
119948
+ this.settings.snippetModal = false;
119949
+ }
119950
+
119591
119951
  // freeform
119592
119952
  if (this.canvas && !this.isContentBox) {
119593
119953
  /*
@@ -121320,6 +121680,15 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
121320
121680
  applyBehaviorOn(builder) {
121321
121681
  const util = this.util;
121322
121682
 
121683
+ // upload
121684
+ if (this.opts.onImageUpload) {
121685
+ if (!builder._dragDropUploaderAttached) {
121686
+ builder._dragDropUploaderAttached = true;
121687
+ const uploader = new DragDropImageUploader(builder, this);
121688
+ uploader.attach();
121689
+ }
121690
+ }
121691
+
121323
121692
  //Make absolute
121324
121693
  if (this.opts.absolutePath) {
121325
121694
  let links = builder.querySelectorAll('a');
@@ -156192,8 +156561,26 @@ class ContentBox {
156192
156561
  designPathReplace: ['assets/', 'https://.../assets/'], // Only if needed
156193
156562
  */
156194
156563
  // New Template System: => this will replace the previous approach (designUrl1, designUrl2, designPath, designPathReplace & defaultDesignCategory)
156195
- templates: [],
156196
- // ver.5.3
156564
+ // templates: [], // ver.5.3
156565
+ templates: [{
156566
+ url: 'assets/templates-simple/templates.js',
156567
+ path: 'assets/templates-simple/',
156568
+ pathReplace: [],
156569
+ numbering: true,
156570
+ showNumberOnHover: true
156571
+ }, {
156572
+ url: 'assets/templates-quick/templates.js',
156573
+ path: 'assets/templates-quick/',
156574
+ pathReplace: [],
156575
+ numbering: true,
156576
+ showNumberOnHover: true
156577
+ }, {
156578
+ url: 'assets/templates-animated/templates.js',
156579
+ path: 'assets/templates-animated/',
156580
+ pathReplace: [],
156581
+ numbering: true,
156582
+ showNumberOnHover: true
156583
+ }],
156197
156584
 
156198
156585
  /*
156199
156586
  Example:
@@ -156387,7 +156774,7 @@ class ContentBox {
156387
156774
  blockCodeEditorHeight: '45vh',
156388
156775
  blockCodeEditorMaxWidth: '960px',
156389
156776
  assetRefresh: false,
156390
- slider: '',
156777
+ slider: 'glide',
156391
156778
  navbar: false,
156392
156779
  screenMode: 'fullview',
156393
156780
  onRender: function () {},
@@ -160271,6 +160658,10 @@ Add an image for each feature.`, 'Create a new block showcasing a photo gallery
160271
160658
  z-index: 2;
160272
160659
  }
160273
160660
 
160661
+ .is-wrapper .drag-over-image {
160662
+ outline: #a2f0ce 3px solid;
160663
+ }
160664
+
160274
160665
  /*
160275
160666
  .is-wrapper.is-edit {
160276
160667
  min-height: 100vh;