HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/sdo/sdoschoonmaak.nl/wwwroot/js/kms/core.js
'use strict'; //inject directives and services.

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

var app = angular.module('fileUpload', ['ngFileUpload']);
app.controller('fileUploadController', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
  console.log('fileuploadcontroller loading'); //The files list
  //Todo, extend with the files form the database

  $scope.files = []; //These are the fileIds, used for saving

  $scope.dynamic = false;
  $scope.uploadSizes = '';
  $scope.maxImages;
  $scope.errorMsg = {};
  $scope.subFolder = false;
  $scope.attributeKey = '';
  $scope.forModel;
  $scope.forModelId;
  $scope.canUploadNewImage;
  /**
   * This function uploads the new files
   * @param files
   * @param errFiles
   * @param maximages
   * @param blockId
   * @param tabId optional
   */

  $scope.uploadFiles = function (files, errFiles, maximages, blockId, tabId) {
    console.log("upload for block with blockId: " + blockId + " and tabKey: " + tabId);
    console.log("uploadedFiles files:");
    console.log(files); //Get the model and the id where we are uploading images for. Should flow via a service but due to bad design and an upcoming newer angular version does not. todo: improve me

    var htmlElement = document.querySelector("[ng-controller=KmsAttributeDynamicController]");
    $scope.forModel = htmlElement.dataset.forModel;
    $scope.forModelId = htmlElement.dataset.forModelId;
    console.log("fileUploadController uploading files For model: " + $scope.forModel + " with id: " + $scope.forModelId + " and blockId: " + blockId);
    if (typeof $scope.files == 'undefined') $scope.files = [];

    if ($scope.files.length >= maximages) {
      console.log("File upload not allowed. " + $scope.files.length + "/" + maximages + " uploaded");
      return false;
    } //Set the files


    $scope.errFiles = errFiles; //Foreach each file

    angular.forEach(files, function (file) {
      //Push to true adds image at the back, false at the front
      var push = true; //Add the placeholder

      var loadingImage = {
        loading: true,
        thumb_image_url: '/images/kms/loading.gif'
      };

      if (push == true) {
        $scope.files.push(loadingImage);
        var imageKey = $scope.files.length - 1;
      } else {
        //Add at the front
        $scope.files.unshift(loadingImage);
        var imageKey = 0;
      } //Upload to the server


      file.upload = Upload.upload({
        url: '/kms/upload',
        data: {
          //Sent the data and the options
          file: file,
          uploadSizes: $scope.uploadSizes,
          dynamic: $scope.dynamic,
          subFolder: $scope.subFolder,
          attribute_key: $scope.attributeKey,
          forModelName: $scope.forModel,
          forModelId: $scope.forModelId,
          forBlockId: blockId,
          forTabId: tabId
        }
      }); //After uploading

      file.upload.then(function (response) {
        $timeout(function () {
          // delete $scope.files.loading
          console.log(response); //Set the response data
          // file.result = response.data;
          // file.result = response.data.uploaded[0];
          // console.log("Thumb: "+response.data.uploaded.[0].thumb);

          console.log("Image Id: " + response.data.uploaded[0].id); //Add the file to the current files

          $scope.files[imageKey] = response.data.uploaded[0];
          console.log("$scope.files[" + imageKey + "] =");
          console.log($scope.files[imageKey]); //Reverse push
          //Add the file to the current files
          // $scope.files.unshift(file.result);
          // $scope.setFileIds()
          //Update fileids

          var forBlockId = response.data.uploaded[0].forBlockId;
          var blocksDataObject = $scope.getBlocksData(); //Defined in the KmsAttributeDynamicController

          for (var key in blocksDataObject) {
            console.log("Looping over blocks to find a block with id: " + forBlockId + ". Current block id: " + blocksDataObject[key].blockId); // console.log(blocksDataObject[key]);

            if (blocksDataObject.hasOwnProperty(key) === false || blocksDataObject[key].hasOwnProperty("blockId") === false) {
              console.warn("Detected block data without a block id. Because of this, it is not possible to upload a file for that block. This does not mean that the uploaded image can be linked to the block your uploading currently for");
              continue;
            }

            if (blocksDataObject[key].blockId == forBlockId) {
              console.log("found block with id: " + forBlockId);
              var data = [];

              if (response.data.uploaded[0].forTabId) {
                console.log("Uploaded an image for tab: " + response.data.uploaded[0].forTabId);
                data = response.data.uploaded[0].id + "#" + response.data.uploaded[0].forTabId; //imageid#multipleimagesslot
              } else {
                console.log("Uploaded an image without tab: " + response.data.uploaded[0].id);
                data = response.data.uploaded[0].id;
              }

              var fileIds = [];

              if (blocksDataObject[key].hasOwnProperty('fileIds')) {
                var length = blocksDataObject[key]['fileIds'].length; //Determine if it is a single image or multiple images.

                blocksDataObject[key]['fileIds'][length] = data;
                console.log("Updating fileIds with image id: " + data);
              } else {
                console.log("Setting fileIds to a new array with image id: " + data);
                blocksDataObject[key].fileIds = [data];
              }

              console.log("files.length = " + blocksDataObject[key].fileIds.length + " maxImages = " + $scope.maxImages);
              $scope.canUploadNewImage = blocksDataObject[key].fileIds.length < $scope.maxImages;
            }

            $scope.setBlocksData(blocksDataObject);
          }
        });
      }, function (response) {
        if (response.status > 0) $scope.errorMsg = response.status + ': ' + response.data;
        console.error("Error: " + $scope.errorMsg);
      }, function (evt) {
        file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
      });
    });
  };

  $scope.deleteImage = function (index, blockId, tab_key) {
    var idToDelete = $scope.files[index].id;
    console.log("idToDelete: " + idToDelete + " from blockId: " + blockId); //Delete the image

    $scope.files.splice(index, 1);
    console.log("Current image amount: " + $scope.files.length); //Delete the image id
    // $scope.setFileIds()

    var blocksDataObject = $scope.getBlocksData(); //Defined in the KmsAttributeDynamicController

    for (var blockIndex in blocksDataObject) {
      if (blocksDataObject.hasOwnProperty(blockIndex) === false || blocksDataObject[blockIndex].hasOwnProperty("blockId") === false) {
        console.warn("Detected block data without a block id. Because of this, it is not possible to upload a file for that block. This does not mean that the uploaded image can be linked to the block your uploading currently for");
        continue;
      }

      if (blocksDataObject[blockIndex].blockId == blockId) {
        console.log("found block with id: " + blockId);
        if (blocksDataObject[blockIndex].hasOwnProperty('fileIdsToDelete') === false) blocksDataObject[blockIndex].fileIdsToDelete = [];
        console.log("Current files to delete: " + blocksDataObject[blockIndex].fileIdsToDelete);
        idToDelete = typeof tab_key !== 'undefined' ? idToDelete + "#" + tab_key : idToDelete;

        for (var index in blocksDataObject[blockIndex].fileIds) {
          var currentId = blocksDataObject[blockIndex].fileIds[index];

          if (typeof tab_key !== 'undefined') {
            console.log("Looping over the file ids to find an image with id: " + idToDelete + " for tab: " + tab_key + " (" + currentId + ")");
          } else {
            console.log("Looping over the file ids to find an image with id: " + idToDelete);
          }

          if (currentId == idToDelete) {
            console.log("Image marked to delete on save: " + idToDelete);
            blocksDataObject[blockIndex].fileIdsToDelete[blocksDataObject[blockIndex].fileIdsToDelete.length] = idToDelete;
            blocksDataObject[blockIndex].fileIds.splice(index, 1);

            if (typeof tab_key === 'undefined') {
              $scope.canUploadNewImage = blocksDataObject[blockIndex].fileIds.length < $scope.maxImages;
            } else {
              var count = 0;

              for (var index in blocksDataObject[blockIndex].fileIds) {
                if (blocksDataObject[blockIndex].fileIds[index].split("#")[1] == tab_key) {
                  count++;
                }
              }

              $scope.canUploadNewImage = count < $scope.maxImages;
            }

            break;
          }
        }
      }
    }

    $scope.setBlocksData(blocksDataObject);
    delete $scope.errorMsg.toMany;
  }; // $scope.moveImage = function (index, direction) {
  //     var currentFile = $scope.files[index]
  //     var currentFileId = $scope.fileIds[index]
  //
  //     if (direction == 'left') {
  //         $scope.files[index] = $scope.files[index - 1];
  //         $scope.files[index - 1] = currentFile;
  //     } else {
  //         $scope.files[index] = $scope.files[index + 1];
  //         $scope.files[index + 1] = currentFile;
  //     }
  //     $scope.setFileIds()
  // };


  $scope.initFiles = function (files, maxImages, tab_key) {
    console.log("fileupload:initFiles: " + files + " maxImages: " + maxImages);

    if (files) {
      // //Strip out the image ids that do not belong to the tab we are processing for
      var filesToUse = [];

      if (typeof tab_key !== 'undefined') {
        for (var index in files) {
          var split = files[index].split("#");
          if (split.length !== 2) continue; //The imageId did not contain a #

          if (split[1] != tab_key) {
            console.log("fileupload:initFiles: Ignoring image with id: " + split[0] + " because it belongs to tab " + split[1] + " and we are processing images for tab " + tab_key);
          } else {
            filesToUse[filesToUse.length] = files[index];
          }
        }
      } else {
        filesToUse = files;
      }

      if (filesToUse.length > 0) {
        $.ajax({
          type: "POST",
          url: "/kms/getimagedata",
          data: {
            fileIds: filesToUse
          },
          success: function success(response) {
            console.log("Retrieved files: ");
            console.log(response); // files must look like this files[index].id files[index].sizes

            $scope.files = response; // $scope.setFileIds();

            if (typeof maxImages != 'undefined') {
              $scope.maxImages = maxImages;
            }

            console.log("files.length < $scope.maxImages: " + filesToUse.length < $scope.maxImages);
            $scope.canUploadNewImage = filesToUse.length < $scope.maxImages;
            $scope.$apply();
          },
          error: function error() {
            console.log("An error occured while retrieving image(s)");
          },
          headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          },
          dataType: 'json'
        });
      } else {
        $scope.maxImages = maxImages;
        $scope.canUploadNewImage = true;
        $scope.files = [];
      }
    } else {
      $scope.maxImages = maxImages;
      $scope.canUploadNewImage = true;
      $scope.files = [];
    }
  };

  $scope.updateFiles = function (files) {
    console.log("Updated files");
    $scope.files = files;
  }; // $scope.setFileIds = function () {
  //     var local_fileIds = [];
  //
  //     angular.forEach($scope.files, function (file) {
  //         local_fileIds.push(file.id);
  //     });
  //
  //     console.log("set file ids ($scope.fileIds):");
  //     console.log(local_fileIds);
  //     $scope.fileIds = local_fileIds
  // };
  // $scope.getFileCount = function () {
  //     return $scope.fileIds.length;
  // };


  $scope.sortableOptions = {
    update: function update(e, ui) {
      ui.item.sortable.cancel();
      var originalIndex = ui.item.sortable.index;
      var newIndex = ui.item.sortable.dropindex;
      var oldImage = $scope.files[originalIndex];
      $scope.files[originalIndex] = $scope.files[newIndex];
      $scope.files[newIndex] = oldImage;
      $scope.setFileIds();
    }
  };
  console.log('fileuploadcontroller initialized');
}]);
'use strict';

angular.element(document).ready(function () {// angular.element(document.querySelector('[ng-controller]')).scope().debug();
  // //console.log('page loading completed');
});
angular.module('kms.dynamic-attribute', []).controller('KmsAttributeDynamicController', function ($scope, $element, $compile, $timeout) {
  //console.log('KmsAttributeDynamicController initializing');
  // var htmlElement = document.querySelector("[ng-controller=KmsAttributeDynamicController]");
  //console.log("Controller element");
  //console.log($($element)[0]);
  var htmlElement = $($element)[0]; //For which model and id of the model the dynamic attribute works

  $scope.forModel = htmlElement.dataset.forModel;
  $scope.forModelId = htmlElement.dataset.forModelId; //console.log("KmsAttributeDynamicController further initializing For model: "+$scope.forModel+" with id: "+$scope.forModelId);

  $scope.key = htmlElement.dataset.key; //console.log("Controller key: "+$scope.key);

  var removeBlocks = function removeBlocks() {
    // Remove the block list for re-render
    angular.element('#' + $scope.key + '_blocks .inner').remove();
  }; // Check if any blocks exists to prevent JSON.parse error
  // Default is an empty array


  $scope.blocks = [];
  var html = $('#' + $scope.key + '_data', $element).html(); //console.log("JSON to parse (in element: #"+$scope.key+"_data): "+html);

  if (html != '' && html != '""' && html != undefined) {
    $scope.blocks = JSON.parse(html);
  } else {} //console.log("Element called: " + "#" + $scope.key + "_data does not have json data set");
  //console.log('scope blocks');
  //console.log($scope.blocks);


  $scope.blockSettings = {};
  var blockSettingsElement = document.getElementById('blockSettings');

  if (blockSettingsElement) {
    var block_settings = blockSettingsElement.value;

    if (block_settings != '' && block_settings != '""') {
      $scope.blockSettings = JSON.parse(block_settings);
    }
  } else {} //console.log("No blocksettings element");
  //console.log("blocksettings");
  //console.log($scope.blockSettings);


  $scope.blockTypes = getBlockTypes($scope.blockSettings);

  $scope.addBlock = function (blockType) {
    if (!angular.isUndefined(blockType)) {
      $scope.blocks.push(angular.copy(blockType));
    }
  };

  $scope.removeBlock = function (block) {
    startToMove();
    var index = $scope.blocks.indexOf(block);
    $scope.blocks.splice(index, 1);
    stopToMove();
  };

  $scope.upBlock = function (block) {
    //load index from the block
    var index = $scope.blocks.indexOf(block); //if the index is 0 return

    if (index < 1) return; //Remove the editor

    startToMove(); //Set the block index-1 to current index

    $scope.blocks[index] = $scope.blocks[index - 1]; //set the triggerd block to index-1

    $scope.blocks[index - 1] = block; //enable the editor

    stopToMove();
  };

  $scope.downBlock = function (block) {
    //load the index from the block
    var index = $scope.blocks.indexOf(block); //If the block is the last return false

    if (index >= $scope.blocks.length - 1) return; //Remove the editor

    startToMove(); //set the block +1 to the current index

    $scope.blocks[index] = $scope.blocks[index + 1]; //set the triggerd block to index +1

    $scope.blocks[index + 1] = block; //enable the editor

    stopToMove();
  };

  $scope.deleteImage = function (direction, block_key, image_key, tab_key) {
    if (tab_key == null) {
      $scope.blocks[block_key].images.splice(image_key, 1);
    } else {
      $scope.blocks[block_key].tab[tab_key].images.splice(image_key, 1);
    }
  };

  $scope.deleteFile = function (block_key) {
    delete $scope.blocks[block_key].file;
  };

  $scope.changeOrder = function (direction, block_key, image_key, tab_key) {
    //load the index from the block
    var index = image_key;

    if (tab_key == null) {
      var temp_image = $scope.blocks[block_key].images[image_key];

      switch (direction) {
        case 'left':
          if (index == 0) return;
          $scope.blocks[block_key].images[image_key] = $scope.blocks[block_key].images[image_key - 1];
          $scope.blocks[block_key].images[image_key - 1] = temp_image;
          break;

        case 'right':
          if (index + 1 == $scope.blocks[block_key].images.length) return;
          $scope.blocks[block_key].images[image_key] = $scope.blocks[block_key].images[image_key + 1];
          $scope.blocks[block_key].images[image_key + 1] = temp_image;
          break;
      }
    } else {
      var temp_image = $scope.blocks[block_key].tab[tab_key].images[image_key];

      switch (direction) {
        case 'left':
          if (index == 0) return;
          $scope.blocks[block_key].tab[tab_key].images[image_key] = $scope.blocks[block_key].tab[tab_key].images[image_key - 1];
          $scope.blocks[block_key].tab[tab_key].images[image_key - 1] = temp_image;
          break;

        case 'right':
          if (index + 1 == $scope.blocks[block_key].tab[tab_key].images.length) return;
          $scope.blocks[block_key].tab[tab_key].images[image_key] = $scope.blocks[block_key].tab[tab_key].images[image_key + 1];
          $scope.blocks[block_key].tab[tab_key].images[image_key + 1] = temp_image;
          break;
      }
    }
  };
  /**
   * Add new image tab
   * @param block_index
   */


  $scope.addImageTab = function (block_index) {
    $scope.blocks[block_index].tab.push({
      title: ''
    });
    var new_index = $scope.blocks[block_index].tab.length; //set the new tab as active (-1) arrays start at 0

    $scope.setActiveTab(block_index, new_index - 1);
  };
  /**
   * Remove image tab
   * @param block_index
   */


  $scope.removeImageTab = function (block_index, tab_index) {
    $scope.blocks[block_index].tab.splice(tab_index, 1); //set the active tab to 0

    $scope.setActiveTab(block_index, 0);
  };

  $scope.setActiveTab = function (index, tab) {
    $scope.blocks[index].active_tab = tab;
  };

  $scope.moveTab = function (direction, index, tab_index) {
    var temptab = $scope.blocks[index].tab[tab_index];

    switch (direction) {
      case 'left':
        if (tab_index == 0) return;
        $scope.blocks[index].tab[tab_index] = $scope.blocks[index].tab[tab_index - 1];
        $scope.blocks[index].tab[tab_index - 1] = temptab;
        break;

      case 'right':
        if (tab_index + 1 == $scope.blocks[index].tab.length) return;
        $scope.blocks[index].tab[tab_index] = $scope.blocks[index].tab[tab_index + 1];
        $scope.blocks[index].tab[tab_index + 1] = temptab;
        break;
    }
  };

  $scope.setUniqueId = function (block_index) {
    if (typeof $scope.blocks[block_index].blockId == 'undefined') {
      var stamp = new Date().valueOf();
      $scope.blocks[block_index].blockId = Math.round(stamp + Math.random() * 1000);
    }
  };

  $scope.debug = function () {//console.log('key: ' + $scope.key);
  }; //console.log('KmsAttributeDynamicController initialized');

}).directive('block', function ($compile) {
  return {
    restrict: 'E',
    template: '<div class="header">' + '<div class="start">' + '<div class="block-title">{{block.typeName}}</div>' + '<div class="buttons">' + '<div class="position-button up" ng-click="upBlock(block)"></div>' + '<div class="position-button down" ng-click="downBlock(block)"></div>' + '</div></div>' + '<div class="end">' + '<div class="btn btn-danger btn-trash" ng-click="removeBlock(block)">&nbsp</div>' + '</div></div>',
    link: function link(scope, element, attr) {
      switch (scope.block.typeSlug) {
        case 'content-block':
          // //console.log('rendering a content block with this data: '+scope.block);
          scope.imageBoxId = scope.key + '-image-box-' + scope.$index;
          scope.textBoxId = scope.key + '-text-box-' + scope.$index; //console.log("Rendering content-block (afbeelding en tekst)");
          //console.log(scope.block);

          element.append($compile("<content-block></content-block>")(scope));
          break;

        case 'view-block':
          element.append($compile("<view-block></view-block>")(scope));
          break;

        case 'page-link-block':
          element.append($compile("<page-link-block></page-link-block>")(scope));
          break;

        case 'image-slider-block':
          element.append($compile("<image-slider-block></image-slider-block>")(scope));
          break;

        case 'video-block':
          element.append($compile("<video-block></video-block>")(scope));
          break;

        case 'file-block':
          element.append($compile("<file-block></file-block>")(scope));
          break;

        case 'two-column-block':
          scope.textBoxIds = [];
          scope.textBoxIds.left = scope.key + '-text-box-' + scope.$index + '-left';
          scope.textBoxIds.right = scope.key + '-text-box-' + scope.$index + '-right';
          element.append($compile("<two-column-block></two-column-block>")(scope));
          break;

        case 'full-text-block':
          scope.textBoxId = scope.key + '-text-box-' + scope.$index;
          element.append($compile("<full-text-block></full-text-block>")(scope));
          break;

        case 'full-image-block':
          element.append($compile("<full-image-block></full-image-block>")(scope));
          break;

        case 'multiple-images-block':
          element.append($compile("<multiple-images-block></multiple-images-block>")(scope));
          break;
      } // //console.log("block data element: "+attr.dataElement);


      scope.dataElement = document.querySelector(attr.dataElement);

      scope.getBlocksData = function () {
        return JSON.parse(scope.dataElement.getAttribute("value"));
      };

      scope.setBlocksData = function (data) {
        scope.dataElement.setAttribute("value", JSON.stringify(data));
        scope.$parent.blocks = data;
      };
    }
  };
}).directive('contentBlock', function ($timeout) {
  var count = 0;
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-page-content-block',
    link: function link(scope, element, attrs) {
      scope.image = 'imageHolder';
      scope.loopCount = count;
      count++;
      scope.loopCount = scope.key; // //console.log("getting content block data");
      // //console.log(scope.getBlocksData();
      //initiate the tinyMce editor

      initiateTinyMceWithDelay(scope, $timeout, 100);

      scope.openBox = function (imageBoxId) {
        $.colorbox({
          href: '/kms/elfinder/standalonepopup/' + imageBoxId,
          fastIframe: true,
          iframe: true,
          width: '70%',
          height: '520px'
        });
      };
    }
  };
}).directive('viewBlock', function ($timeout) {
  var count = 0;
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-view',
    link: function link(scope) {}
  };
}).directive('twoColumnBlock', function ($timeout) {
  var count = 0;
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/two-column-block',
    link: function link(scope, element, attrs) {
      scope.image = 'imageHolder', scope.loopCount = count;
      count++;
      scope.loopCount = scope.key; //initiate the tinyMce editor

      initiateTinyMceWithDelay(scope, $timeout, 100);

      scope.openBox = function (imageBoxId) {
        $.colorbox({
          href: '/kms/elfinder/standalonepopup/' + imageBoxId,
          fastIframe: true,
          iframe: true,
          width: '70%',
          height: '520px'
        });
      };
    }
  };
}).directive('imageSliderBlock', function () {
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-image-slider-block',
    link: function link(node) {////console.log(node);
    }
  };
}).directive('fullImageBlock', function () {
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-full-image-block',
    link: function link(node) {////console.log(node);
    }
  };
}).directive('fullTextBlock', function ($timeout) {
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-full-text-block',
    link: function link(scope) {
      //initiate the tinyMce editor
      initiateTinyMceWithDelay(scope, $timeout, 100);
    }
  };
}).directive('multipleImagesBlock', function () {
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-multiple-images-block',
    link: function link(node) {////console.log(node);
    }
  };
}).directive('pageLinkBlock', function ($http) {
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-page-link-block',
    link: function link(scope, element, attr) {
      scope.pages = [];
      $http.get('/kms/api/pages').then(function (response) {
        // Adopt data
        var pages = [];

        var getChildren = function getChildren(node) {
          for (var child in node) {
            if (node[child].title) {
              pages.push({
                value: node[child].id,
                label: node[child].title
              });
            }

            getChildren(node[child].children);
          }
        };

        getChildren(response.data); // Set the data

        scope.pages = pages;
      });
    }
  };
}).directive('videoBlock', function () {
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-video-block',
    link: function link(node) {////console.log(node);
    }
  };
}).directive('fileBlock', function () {
  return {
    restrict: 'E',
    templateUrl: '/kms/api/template/dynamic-file-block',
    link: function link(node) {////console.log(node);
    }
  };
});
/**
 * Callback function for ElFinder (hard to implement in angular?)
 *
 * @param filePath
 * @param requestingElementId
 */

function processSelectedFile(filePath, requestingElementId) {
  // Get the scope of the the element that is passed into ElFinder
  var elementScope = $('#' + requestingElementId).parent().parent().scope();
  elementScope.block.image = filePath;
  elementScope.$apply();
}
/**
 * This function will initiate the tinyMce editor on an block
 * It the initiation will be delayed because of the angular
 *
 * @param $scope
 * @param $timeout
 */


function initiateTinyMceWithDelay($scope, $timeout, delay) {
  //if (tinymce) tinymce.remove();
  $timeout(function () {
    initiateTinyMce($scope, $scope.textBoxId);

    if (typeof $scope.textBoxIds !== 'undefined') {
      if ($scope.textBoxIds.left != null) initiateTinyMce($scope, $scope.textBoxIds.left, 'description', 'left');
      if ($scope.textBoxIds.right != null) initiateTinyMce($scope, $scope.textBoxIds.right, 'description', 'right');
    }
  }, delay);
}

function initiateTinyMce($scope, field, blockElement, blockSubElement) {
  if (typeof field === 'undefined') {
    field = $scope.textboxId;
  }

  if (typeof blockElement === 'undefined') {
    blockElement = 'description';
  } //textboxIds[] =


  tinymce.init({
    elements: field,
    mode: 'exact',
    skin: 'kms',
    menubar: false,
    statusbar: false,
    plugins: ['code', 'paste', 'link', 'table'],
    toolbar: 'styleselect | bold italic underline | bullist numlist  | indent | link | code',
    height: '200',
    default_link_target: "_blank",
    paste_as_text: true,
    style_formats: [{
      title: 'Titel 1',
      block: 'h1'
    }, {
      title: 'Titel 2',
      block: 'h2'
    }, {
      title: 'Titel 3',
      block: 'h3'
    }, {
      title: 'Titel 4',
      block: 'h4'
    }],
    convert_urls: false,
    // link_list: "/kms/file-list?key=komma_kms",
    setup: function setup(editor) {
      editor.on('change', function (e) {
        editor.save();

        if (typeof blockSubElement === 'undefined') {
          $scope.block[blockElement] = editor.getContent();
        } else {
          $scope.block[blockElement][blockSubElement] = editor.getContent();
        }

        if (!$scope.$$phase) {
          $scope.$apply();
        }
      }); // Update model on keypress

      editor.on('KeyUp', function (e) {
        editor.save();

        if (typeof blockSubElement === 'undefined') {
          $scope.block[blockElement] = editor.getContent();
        } else {
          $scope.block[blockElement][blockSubElement] = editor.getContent();
        }

        if (!$scope.$$phase) {
          $scope.$apply();
        }
      });
    }
  });
}

function startToMove() {
  $(document).find('textarea').each(function () {
    tinyMCE.execCommand('mceFocus', false, $(this).attr('id'));
    tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'));
  });
}

function stopToMove() {
  //todo: Reanbling ONLY works after a timeout.
  setTimeout(function () {
    $(document).find('textarea').each(function () {
      tinymce.execCommand('mceAddEditor', true, $(this).attr('id'));
    });
  }, 100);
}

function getBlockTypes(blockSettings) {
  var blocks = {
    two_column_block: {
      typeSlug: 'two-column-block',
      code_name: '',
      view: '',
      typeName: 'Twee tekstkolommen',
      status: true,
      description: {
        left: '',
        right: ''
      },
      textWidth: '50'
    },
    content_block: {
      typeSlug: 'content-block',
      code_name: '',
      view: '',
      typeName: 'Afbeelding en tekst',
      status: true,
      location: 'left',
      textWidth: '66',
      description: '',
      subFolder: 'dynamic',
      image: null,
      max_images: 4,
      link: '',
      link_text: 'Lees meer'
    },
    view_block: {
      typeSlug: 'view-block',
      code_name: '',
      view: '',
      typeName: 'View',
      status: true
    },
    full_image_block: {
      typeSlug: 'full-image-block',
      code_name: '',
      view: '',
      typeName: '100% Afbeelding',
      subFolder: 'dynamic',
      max_images: 2,
      status: true,
      image: null
    },
    full_text_block: {
      typeSlug: 'full-text-block',
      code_name: '',
      view: '',
      typeName: 'Een tekstkolom',
      description: '',
      status: true,
      link: '',
      link_text: 'Lees meer'
    },
    multiple_images_block: {
      typeSlug: 'multiple-images-block',
      code_name: '',
      view: '',
      typeName: 'Meerdere afbeeldingen',
      tab: [{
        title: 'Afbeelding 1',
        max_images: 1
      }, {
        title: 'Afbeelding 2a',
        max_images: 2
      }, {
        title: 'Afbeelding 2b (optioneel)',
        max_images: 1
      }],
      status: true,
      location: 'left',
      subFolder: 'dynamic',
      textWidth: '66'
    },
    page_link_block: {
      typeSlug: 'page-link-block',
      code_name: '',
      view: '',
      typeName: 'Page-link block',
      link_text: 'Lees meer',
      special: 0,
      status: true,
      pageId: null
    },
    image_slider_block: {
      typeSlug: 'image-slider-block',
      code_name: '',
      view: '',
      typeName: 'Image gallery',
      tab: [{
        title: ''
      }],
      subFolder: 'dynamic',
      status: true,
      pageId: null
    },
    video_block: {
      typeSlug: 'video-block',
      code_name: '',
      view: '',
      typeName: 'Video',
      youtube: '',
      status: true,
      pageId: null
    },
    file_block: {
      typeSlug: 'file-block',
      code_name: '',
      view: '',
      typeName: 'Bestand block',
      title: '',
      special: 0,
      download_text: 'Download',
      file: '',
      status: true,
      pageId: null
    }
  };
  var blockTypes = {};
  angular.forEach(blockSettings, function (block, blockName) {
    blockTypes[blockName] = angular.merge(blocks[blockName], block);
  });
  return blockTypes;
}

'use strict';

var attributes = {};
var app = angular.module('kms', ['ui.bootstrap', 'ngSanitize', 'kms.dynamic-attribute', 'fileUpload' // 'ui.select',
// 'ui.date',
// 'ui.tree',
// 'ui.sortable',
// 'ui.utils.masks',
]);
app.controller('KmsEntities', ['$scope', '$element', function ($scope, $element) {
  $scope.entities = [];
  $scope.paginatedEntities = [];
  $scope.isSorting = false;

  $scope.isSearching = function () {
    return $scope.searchEntitiesText.text.length > 1;
  };

  $scope.currentPage = 1;
  $scope.numPerPage = 5;
  $scope.maxSize = 5;
  var entityList = $('.entities-list-items .entities-list-item', $element);

  for (var i = 0; i < entityList.length; i++) {
    var dataElement = entityList[i];
    var dataObject = {
      thumbHtml: $('.entities-item-pre', dataElement).html(),
      text: $('.entities-item-text', dataElement).html(),
      status: $('.entities-item-status', dataElement).html(),
      link: $('a', dataElement).first().attr('href'),
      active: $(dataElement).hasClass('active')
    };
    $scope.entities.push(dataObject);
  }

  $scope.activateSorting = function () {
    $scope.isSorting = true;
  };

  $scope.deactivateSorting = function () {
    $scope.isSorting = false;
  };

  $scope.$watch("currentPage + numPerPage", function () {
    var begin = ($scope.currentPage - 1) * $scope.numPerPage,
        end = begin + $scope.numPerPage;
    $scope.paginatedEntities = $scope.entities.slice(begin, end);
  });
}]);
app.controller('KmsEntity', ['$scope', '$element', function ($scope, $element) {
  // console.log("attaching save to scope");
  $scope.save = function () {
    var button = document.querySelector('input[value="submit-cloaked"]'); // console.log(button);

    button.click();
  };
}]);
app.controller('SortableTree', ['$scope', '$http', '$attrs', function ($scope, $http, $attrs) {
  $http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
  $scope.data = [];
  $scope.treeOptions = {
    dropped: function dropped(event) {
      $http({
        method: 'POST',
        url: '/kms/api/' + $attrs.siteslug + '/' + $attrs.slug,
        data: {
          "tree": angular.toJson($scope.data)
        }
      }).then(function (response) {});
    }
  };

  $scope.openLink = function (id) {
    window.location = $scope.url + '/' + id;
  };

  $scope.toggle = function (scope) {
    scope.toggle();
  };

  var getRootNodesScope = function getRootNodesScope() {
    return angular.element(document.getElementById('tree-root').scope());
  };

  $scope.collapseAll = function () {
    var scope = getRootNodesScope();
    scope.collapseAll();
  };

  $scope.expandAll = function () {
    var scope = getRootNodesScope();
    scope.expandAll();
  }; // console.log('/kms/api/' + $attrs.siteslug + '/' + $attrs.slug);


  $http.get('/kms/api/' + $attrs.siteslug + '/' + $attrs.slug).then(function (response) {
    // console.log("Kms.js SortableTree controller got data from '"+'/kms/api/' + $attrs.siteslug + '/' + $attrs.slug+"':");
    // console.log(angular.toJson(response.data));
    $scope.data = response.data[0]['children'];
  });
}]);
app.controller('KmsAttributes', ['$scope', function ($scope) {
  $scope.attributes = attributes; // console.log("$scope.attributes (via KmsAttributes)");
  // console.log($scope.attributes);
  // $scope.createModelString = function (modelKey, $itemKey) {
  //
  //
  //     //Check if the modelKey is an array structure (field_name[x])
  //     var match = modelKey.match(/(.*)\[(.*)]/)
  //
  //     //There is no match, so a basic key
  //     if (match == null) {
  //         //SEt the modelKey as modelString
  //         $scope.modelString = modelKey
  //         //ItemKy is null
  //         $scope.itemKey = null;
  //         //return and exit
  //         return $scope.modelString
  //     }
  //
  //     //Set the match[2] as the itemKey
  //     var itemCounter = match[2];
  //
  //     //If the itemKey is not undefined and itemkey is the string itemKey
  //     if (typeof($itemKey) != "undefined" && match[2] == 'itemKey') {
  //         //Set the $itemKey to the scope itemKey
  //         itemCounter = $itemKey
  //     }
  //     //Glue the parts together
  //     var modelString = match[1] + '_' + itemCounter
  //
  //     //Set to the global modelString
  //     $scope.modelString = modelString;
  //     $scope.itemCounter = itemCounter;
  //
  //     //Return the string
  //     return modelString
  // }

  /**
   * Wrapper for Json.parse()
   * So i can parse Json in blade
   * @param value
   */

  $scope.parse = function (value) {
    //If there is no value return;
    if (!value) {
      console.log("Parse without a value");
      return;
    } //If it is already an object, return the value


    if (_typeof(value) == 'object') {
      console.log("Parse value: " + value);
      return value;
    } //Parse the string to a Json object


    console.log("Parse string to Json: " + JSON.parse(value));
    return JSON.parse(value);
  };

  $scope.convertToSlug = function (str) {
    str = str.replace(/^\s+|\s+$/g, ''); // trim

    str = str.toLowerCase(); // remove accents, swap ñ for n, etc

    var from = "ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;";
    var to = "aaaaaeeeeeiiiiooooouuuunc------";

    for (var i = 0, l = from.length; i < l; i++) {
      str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
    }

    str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
    .replace(/\s+/g, '-') // collapse whitespace and replace by -
    .replace(/-+/g, '-'); // collapse dashes

    return str;
  };
}]);
app.controller('KmsAttributeTextFieldController', ['$scope', '$element', function ($scope, $element) {
  $scope.attributes = attributes;
}]);
app.controller('KmsAttributePasswordController', ['$scope', '$element', function ($scope, $element) {
  $scope.attributes = attributes; //Set enabler true (show enable bottom)

  $scope.enabler = true; //Change the password field to a hidden field

  $('.passwordField', $element).attr('type', 'hidden'); //Method called when clikced on the enable button

  $scope.enablePasswordField = function () {
    //Change the type of the password field to password
    $('.passwordField', $element).attr('type', 'password'); //Disable the enable buttom

    $scope.enabler = false;
  };
}]);
app.controller('KmsAttributeDateController', ['$scope', '$element', function ($scope, $element) {
  $scope.attributes = attributes;
  $('input[ui-date]', $element).datepicker({
    changeYear: true,
    changeMonth: true,
    firstDay: 1,
    dateFormat: 'dd-mm-yy'
  });
}]);
app.controller('KmsAttributeCurrencyFieldController', ['$scope', '$element', '$locale', function ($scope, $element, $locale) {
  $scope.attributes = attributes;

  $scope.initCurrencyField = function (dec_value, currency) {
    if (typeof currency !== 'undefined') {
      //Set currencySymbol
      $locale.NUMBER_FORMATS.CURRENCY_SYM = currency;
    } //Set the value an de dec_value


    attributes[$scope.modelString] = {
      "value": dec_value / 100,
      "dec_value": dec_value
    };
    $scope.$watch('attributes.' + $scope.modelString + '.value', function (newValue, oldValue) {
      if (newValue === oldValue) return;
      attributes[$scope.modelString].dec_value = newValue * 100;
    });
  };
}]);
app.controller('KmsAttributePercentageFieldController', ['$scope', '$element', '$timeout', function ($scope, $element, $timeout) {
  $scope.attributes = attributes;
}]);
app.controller('KmsAttributeTextFieldCurrencyController', ['$scope', '$element', '$timeout', function ($scope, $element, $timeout) {
  $scope.attributes = attributes;
  var id = $('input', $element).attr('id'); // get the id of the hidden field

  var taxSelectFieldId = $('[data-kms-tax-field]', $element).attr('data-kms-tax-field');
  var taxFieldId = id + '_tax';
  var noTaxFieldId = id + '_no_tax';

  var parseCurrencyStringToCents = function parseCurrencyStringToCents(currencyString) {
    var val = currencyString.toString();
    val = val.replace(/[.]/g, '');
    val = val.replace(/[,]/g, '.');
    val = val.replace(/[^0-9\.]+/g, '');
    val = val * 100;
    return val;
  };

  var addTax = function addTax(value) {
    if (attributes[taxSelectFieldId].selected) {
      var factor = 1 + attributes[taxSelectFieldId].selected.fullValue.rate / 100;
      return value * factor;
    }
  };

  var subtractTax = function subtractTax(value) {
    if (attributes[taxSelectFieldId].selected) {
      var factor = 1 + attributes[taxSelectFieldId].selected.fullValue.rate / 100;
      return value / factor;
    }
  };

  $scope.$watch('attributes.' + taxFieldId, function (newValue, oldValue) {
    if (newValue !== oldValue) {
      $scope.attributes[id] = parseCurrencyStringToCents(newValue);
    }
  });
  $scope.$watch('attributes.' + noTaxFieldId, function (newValue, oldValue) {
    if (newValue !== oldValue) {
      $scope.attributes[id] = Math.round(addTax(parseCurrencyStringToCents(newValue)));
    }
  });

  var watcherMain = function watcherMain(newValue, oldVal) {
    if ($.isNumeric($scope.attributes[id])) {
      var $taxField = $('#' + taxFieldId);
      var $noTaxField = $('#' + noTaxFieldId);

      if (!$taxField.is(':focus')) {
        $taxField.val($scope.attributes[id] / 100);
      }

      if (!$noTaxField.is(':focus')) {
        $noTaxField.val(Math.round(subtractTax($scope.attributes[id])) / 100);
      }
    }
  }; // Clear fields on blur if no value


  $('#' + taxFieldId + ', #' + noTaxFieldId).blur(function (e) {
    if ($scope.attributes[id] == 0) {
      $('#' + taxFieldId + ', #' + noTaxFieldId).val(0);
    }
  });
  $scope.$watch('attributes.' + id, watcherMain);
  $scope.$watch('attributes.' + taxSelectFieldId + '.selected', watcherMain);
  $scope.attributes[id] = $('input', $element).attr('value'); // get the value of the hidden field

  $timeout(watcherMain, 500);
}]);
app.controller('KmsAttributeMultiSelectController', ['$scope', '$element', function ($scope, $element) {
  $scope.attributes = attributes;
  $scope.selectData = [];
  /**
   * Initialize the choices for ui-select
   *
   * @param choices | string
   * @returns {*}
   */

  $scope.initChoices = function (choices) {
    //If there are no choices;
    if (!choices) return; //If it is not already an object, make one from json

    if (_typeof(choices) != 'object') choices = JSON.parse(choices); //Set the choices to the selectData

    $scope.selectData = choices;
    return choices;
  };

  $scope.setValue = function (values) {
    if (!values) return; // compare "values" array and "$scope.selectData" array

    var result = [];

    for (var i = 0; i < $scope.selectData.length; i++) {
      var valueInElement = false;

      for (var j = 0; j < values.length; j++) {
        if ($scope.selectData[i].value == values[j]) {
          valueInElement = true;
          break;
        }
      }

      if (valueInElement) result.push($scope.selectData[i]);
    } // $scope.attributes[id] = angular.toJson(values);
    // $scope.attributes[id + '_select'] = result;


    return result;
  };
}]);
app.controller('KmsAttributeSlugController', ['$scope', '$element', function ($scope, $element) {
  $scope.attributes = attributes; //Get the slugField key

  var slugField = $('[data-kms-slug-field]', $element).attr('data-kms-slug-field'); //Change [[itemCounter]] with the $scope.itemCounter (fieldGroup)

  slugField = slugField.replace('[[itemCounter]]', $scope.itemCounter); //Watch the slugField

  $scope.$watch('attributes.' + slugField, function (newValue, oldValue) {
    //When nothing changes, do nothing
    if (newValue === oldValue) return; //Set the string converted to Slug to the field

    attributes[$scope.modelString] = $scope.convertToSlug(attributes[slugField]);
  });
}]);
app.controller('KmsAttributeFieldGroupController', ['$scope', '$element', function ($scope, $element) {
  $scope.number = 0;
  $scope.itemKey = 1;
  $scope.maxFieldGroups = null;

  $scope.getNumber = function () {
    return new Array($scope.number);
  };

  $scope.addRow = function () {
    if ($scope.itemKey >= $scope.maxFieldGroups) return; //Add one to the itemKey

    $scope.itemKey++; //Addd one to the numbers

    $scope.number++;
  };
  /**
   * Initialize the given values
   * @param itemKey | Amount (-1) of  items fieldGroups
   * @param maxFieldGroups | max fieldgroups
   */


  $scope.init = function (itemKey, maxFieldGroups) {
    //Items in the fieldGroup
    $scope.itemKey = itemKey; //Max items in fieldGroup

    $scope.maxFieldGroups = maxFieldGroups; //If it is a new, add a row

    if (itemKey == 0) $scope.addRow();
  };
}]);
app.controller('KmsAttributeRouteController', ['$scope', '$element', function ($scope, $element) {
  $scope.attributes = attributes;
  var id = $('input', $element).attr('id');
  attributes[id] = $('input', $element).attr('value'); //Get the name of the slugField

  var slugField = $('[data-kms-slug-field]', $element).attr('data-kms-slug-field'); //Change [[itemCounter]] with the $scope.itemCounter (fieldGroup)

  slugField = slugField.replace('[[itemCounter]]', $scope.itemCounter); //Get the name of the parentField

  var parentField = $('[data-kms-parent-field]', $element).attr('data-kms-parent-field'); //Set the languageId

  var languageId = $('[data-kms-language-id]', $element).attr('data-kms-language-id'); //Set the structure

  var structure = $('[data-kms-structure]', $element).attr('data-kms-structure');
  /**
   * This function generates the correct Route
   * when a watched field is changed
   *
   * @param newValue
   * @param oldValue
   */

  var parseStructure = function parseStructure(newValue, oldValue) {
    //If the value is the same, stop and return
    if (newValue === oldValue) return; //Create an empty parentSlug string

    var parentSlug = ''; // todo: make this work
    //Check if the parentField exist in then attributes

    if (attributes[parentField]) {
      //Check if the parentField has an selected.routes object
      if (!attributes[parentField].selected.routes) {
        //If not trow an error
        console.error('Routes are not set in the ' + parentField + 'field');
      } //Set the routes for the current language to parentSlug


      parentSlug = attributes[parentField].selected.routes[languageId];
    } //Create newRoute


    var newRoute = ''; //Replace {{parentSlugs}} with the parentSlug

    newRoute = structure.replace('{{parentSlugs}}', parentSlug); //Replace {{slug}} with the Slug

    newRoute = newRoute.replace('{{slug}}', $scope.convertToSlug(newValue)); //Set the new route to the attribute of the current $scope.modelString

    attributes[$scope.modelString] = newRoute;
  }; //Set a watch on the slugField, and execute the parseStructure method on a change


  $scope.$watch('attributes.' + slugField, parseStructure); //If there is an parentField

  if (attributes[parentField]) {
    //Set a watch on the parentField, and execute the parseStructure method on a change
    $scope.$watch('attributes.' + parentField + '.selected', parseStructure);
  }
}]);
app.controller('KmsAttributeSorterController', ['$scope', '$element', function ($scope, $element) {
  $scope.attributes = attributes;
}]);
app.filter("multiWordFilter", ['$filter', function ($filter) {
  console.log('hoi');
  return function (inputArray, searchText) {
    var wordArray = searchText ? searchText.toLowerCase().split(/\s+/) : [];
    var wordCount = wordArray.length;

    for (var i = 0; i < wordCount; i++) {
      // Hack for filtering on text parameter: {text:wordArray[i]}
      inputArray = $filter('filter')(inputArray, {
        text: wordArray[i]
      });
    }

    return inputArray;
  };
}]);
app.filter('valuesToArrayFilter', function () {
  return function (input) {
    if (!input) return;
    var output = input.map(function (a) {
      return a.value;
    });
    return output;
  };
});
/**
 * AngularJS default filter with the following expression:
 * "person in people | filter: {name: $select.search, age: $select.search}"
 * performs a AND between 'name: $select.search' and 'age: $select.search'.
 * We want to perform a OR.
 */

app.filter('propsFilter', function () {
  return function (items, props) {
    var out = [];

    if (angular.isArray(items)) {
      items.forEach(function (item) {
        var itemMatches = false;
        var keys = Object.keys(props);

        for (var i = 0; i < keys.length; i++) {
          var prop = keys[i];
          var text = props[prop].toLowerCase();

          if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
            itemMatches = true;
            break;
          }
        }

        if (itemMatches) {
          out.push(item);
        }
      });
    } else {
      // Let the output be the input untouched
      out = items;
    }

    return out;
  };
});

var IsJsonString = function IsJsonString(str) {
  try {
    JSON.parse(str);
  } catch (e) {
    return false;
  }

  return true;
};

$(function () {
  var activeListItem = $('#sidebar .navigation li.active');
  var activeListItemParents = activeListItem.parents();
  var activeListItemParentsLength = activeListItemParents.length;

  for (var i = 0; i <= activeListItemParentsLength; i++) {
    var node = activeListItemParents[i];

    if (node && node.tagName == 'LI' && node.classList.contains('has-sub-items')) {
      node.classList.add('active');
    }
  }

  var siteListItems = document.querySelectorAll('#sidebar .navigation .has-sub-items');
  var siteListItemsLength = siteListItems.length;

  for (var i = 0; i < siteListItemsLength; i++) {
    var siteListItem = siteListItems[i].querySelector('span');
    siteListItem.addEventListener('click', function () {
      this.parentNode.classList.toggle('active');
    });
  }
});

(function ($) {
  // TinyMCE
  tinymce.init({
    selector: 'textarea.tiny-mce',
    skin: 'kms',
    menubar: false,
    statusbar: false,
    plugins: ['code', 'paste', 'link'],
    toolbar: 'styleselect | bold italic underline | bullist numlist  | indent | link image | code',
    height: '200',
    paste_as_text: true,
    style_formats: [{
      title: 'Titel 1',
      block: 'h1'
    }, {
      title: 'Titel 2',
      block: 'h2'
    }, {
      title: 'Titel 3',
      block: 'h3'
    }, {
      title: 'Titel 4',
      block: 'h4'
    }],
    convert_urls: false // link_list: "/kms/file-list?key=komma_kms",

  }); // Hierarchical list

  $('.entities-list-item .dropdown-icon').click(function (e) {
    e.preventDefault();

    if ($(this).parent().parent().hasClass('open')) {
      //$('.animate-to-triangle', this)[0].beginElement();
      $(this).parent().parent().removeClass('open');
    } else {
      //$('.animate-to-minus', this)[0].beginElement();
      $(this).parent().parent().addClass('open');
    }
  });
  var toggled = true; // Scroll to active item in list

  $(window).load(function () {
    if ($('#entity-form .lock').hasClass('open')) {
      toggled = false;
      $('#entity-form').find('input, textarea').attr('disabled', toggled);
    }

    var $container = $('#entities .entities-list');
    var $activeListItem = $('.entities-list-item.active', $container).first();
    if ($activeListItem.length == 0) return;
    var top = $activeListItem.position().top;
    $container.scrollTop(top);
    $('.site-brand-name input').attr('placeholder', $('#global_name').val());
  });
  $('#global_name').change(function () {
    $('.site-brand-name input').attr('placeholder', $(this).val());
  }); //error accordian

  $('.error-accordion .collapsible-ul').hide();
  $('.error-accordion h3').click(function () {
    $(this).parent().find('.collapsible-ul').toggle();
  }); //$('.order-status.selectize').selectize();
  // Product category selector
  //$('#productCategorySelector').selectize();
  //$('#selectYearAndMonthForm select').selectize();

  $('#selectYearAndMonthForm select').change(function () {
    var location = '/kms/orders/voltooid?month=' + $('#selectYearAndMonthForm select#orderMonthSelector').val() + '&year=' + $('#selectYearAndMonthForm select#orderYearSelector').val();
    window.location = location;
  });
  $('#productCategorySelector').change(function () {
    window.location = '/kms/products?category=' + encodeURIComponent(this.value);
  }); // Flash messages

  var hideFlashMessage = function hideFlashMessage() {
    $('#flash-message').fadeOut();
  };

  $('#flash-message').click(function () {
    hideFlashMessage();
  });
  setTimeout(function () {
    hideFlashMessage();
  }, 5000); //var toggled = true;

  $('#entity-form .lock').click(function () {
    $(this).toggleClass('open');
    toggled = !toggled;
    $(this).parents('#entity-form').find('input, textarea').attr('disabled', toggled);
  });
  /* grab important elements */

  var sortInput = jQuery('#sort_order');
  var submit = jQuery('#autoSubmit');
  var messageBox = jQuery('#message-box');
  var list = jQuery('.fieldGroupItems');
  /* create requesting function to avoid duplicate code */

  /* worker function */

  var fnSubmit = function fnSubmit(save) {
    var sortOrder = [];
    list.children('li').each(function () {
      sortOrder.push(jQuery(this).data('id'));
    });
    sortInput.val(sortOrder.join(','));
    console.log(sortInput.val());

    if (save) {
      request();
    }
  };
  /* store values */


  list.children('li').each(function () {
    var li = jQuery(this);
    li.data('id', li.attr('title')).attr('title', '');
  });
  /* sortables */

  list.sortable({
    opacity: 0.7,
    update: function update() {}
  });
  /* ajax form submission */

  jQuery('#dd-form').bind('submit', function (e) {
    if (e) e.preventDefault();
    fnSubmit(true);
  });
})(jQuery);
/**
 * Fills an ul element with data retrieved from an api and makes the items searchable.
 /* The data to and from the api has this structure for example.
 *
 * [
 *  {
 *      id:1
 *      title:false
 *      thumbnail:false
 *      status: "active"
 *      routes: []
 *      children: [
 *          {
 *              id: 12
 *              title: "Thuis"
 *              thumbnail: false
 *              routes: [{
 *                  40: "en/Homenew",
 *                  104: "nl/Thuisnew"
 *              }]
 *          }
 *      ]
 *  }
 * ]
 */


var SearchController =
/*#__PURE__*/
function () {
  function SearchController(sectionId, selector, inputSelector, mainUlId, resultCounterId) {
    _classCallCheck(this, SearchController);

    this.apiUrl = '';
    this.data = '';
    this.dataToLoad = '';
    this.editEntitiesUrl = '';
    this.initialized = false;
    this.sectionId = sectionId;
    this.selector = selector;
    this.mainUlId = mainUlId;
    this.resultCounterId = resultCounterId;
    this.disabled = true;
    this.inputSelector = inputSelector;
    this.listItemClass = 'entities-list-item'; //The class that is added to li items that must be visible because they match (a part) of the search value).
    //This is also the class applied to the rootUl if any results are found.

    this.visibleClass = 'active';
    this.invisibleClass = 'hide';
    this.section = document.getElementById(this.sectionId);
    var rootUl = document.querySelector(this.selector);
    this.siteSlug = rootUl.dataset.siteSlug;
    this.slug = rootUl.dataset.slug;
    this.activeId = rootUl.dataset.activeId;
  }
  /**
   * Initializes the controller so that it knows where it can get its data from,
   * where it needs to direct users when they click on an item and from which ul it
   * should create a sortable ul
   *
   * @param dataSource A string|Object
   * @param editEntitiesUrl A string
   *
   * In case of the data source being an object it must look like this:
   * {
   *  data: [{
   *      id: null,
   *      routes: []
   *      status: "",
   *      title: "",
   *      children: [
   *          {
   *              id: "2",
   *              routes: []
   *              status: "",
   *              title: "My username"
   *              children: []
   *          }
   *      ]
   *  }]
   * }
   */


  _createClass(SearchController, [{
    key: "init",
    value: function init(dataSource, editEntitiesUrl) {
      if (typeof dataSource === "string") {
        this.apiUrl = dataSource;
      } else {
        this.dataToLoad = dataSource;
      }

      this.editEntitiesUrl = editEntitiesUrl;
      this.initialized = true;
    }
    /**
     * Returns a promise that resolves with the root ul that then will contain the items retrieved from the api
     */

  }, {
    key: "load",
    value: function load() {
      if (this.initialized === false) {
        console.error('Please initialize the controller with the init method first.');
        return;
      }

      var self = this;
      return new Promise(function (resolve, reject) {
        if (self.initialized === false) {
          reject('Please initialize the controller with the init method first.');
        }

        if (self.apiUrl !== '' && self.dataToLoad === '') {
          axios.get(self.apiUrl).then(function (response) {
            if (!response.data) {
              reject('The sortable did not get any data from the api');
              return;
            } // console.log(response);

            /** @var Array[] menuItemArrays*/


            response.data[0].children.forEach(function (itemObject) {
              /** @var array htmlElements **/
              var htmlElements = self.createHtmlElement(itemObject);
              htmlElements.forEach(function (element) {
                document.querySelector(self.selector).append(element);
              });
            }); // console.log(document.querySelector(self.selector));

            self.initializeSearch();
            resolve(document.querySelector(self.selector));
          }).catch(function (error) {
            reject(error);
          });
        } else if (self.apiUrl === '' && self.dataToLoad !== '') {
          // console.log('data children');
          // console.log(self.dataToLoad.data[0].children);
          self.dataToLoad.data[0].children.forEach(function (itemObject) {
            var htmlElements = self.createHtmlElement(itemObject);
            htmlElements.forEach(function (element) {
              document.querySelector(self.selector).append(element);
            });
          });
          self.initializeSearch();
          resolve(document.querySelector(self.selector));
        }
      });
    }
    /**
     * Initialize search functionality on the ul this searchable does its job for
     */

  }, {
    key: "initializeSearch",
    value: function initializeSearch() {
      var _this = this;

      var section = this.section;
      var input = document.querySelector(this.inputSelector);
      var searchUl = document.querySelector(this.selector);
      var resultCounter = document.getElementById(this.resultCounterId); //handles searching

      input.addEventListener('keyup', function (event) {
        var mainUl = document.getElementById(_this.mainUlId);
        var resultsCount = 0;
        var filterValue = input.value.toLowerCase();
        var noSearchValue = filterValue == '' ? true : false;
        var listItems = searchUl.querySelectorAll('li');
        var listItemsCount = listItems.length; // console.log(listItemsCount);

        for (var i = 0; i < listItemsCount; i++) {
          var itemValue = listItems[i].dataset.title.toLowerCase();

          if (itemValue.indexOf(filterValue) > -1 && noSearchValue === false) {
            //item found
            resultsCount++;
            listItems[i].classList.add(_this.visibleClass);
          } else {
            //item not found
            listItems[i].classList.remove(_this.visibleClass);
          }
        }

        if (resultsCount > 0) {// searchUl.parentNode.classList.add(this.visibleClass);
          // mainUl.classList.add(this.invisibleClass);
        } else {// searchUl.parentNode.classList.remove(this.visibleClass);
            // mainUl.classList.remove(this.invisibleClass);
          }

        resultCounter.innerHTML = resultsCount + "";

        if (!noSearchValue) {
          section.classList.add(_this.visibleClass);
          mainUl.classList.add(_this.invisibleClass);
        } else {
          section.classList.remove(_this.visibleClass);
          mainUl.classList.remove(_this.invisibleClass);
        }
      });
      searchUl.classList.remove(this.visibleClass);
    }
    /**
     * Creates a menu item (HTMLElement) and sub menu items if necessary
     *
     * @param data
     * @param items array Used internally. Humans must not touch this
     * @param currentTreeLevel string Used internally. Humans must not touch this
     * @returns {Array}
     */

  }, {
    key: "createHtmlElement",
    value: function createHtmlElement(data) {
      var items = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
      var currentTreeLevel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';

      if (this.initialized === false) {
        console.error('Please initialize the controller with the init method first.');
        return;
      }

      var self = this;
      var activeId = self.activeId;
      var id = data.id;
      var title = data.title;
      var children = data.children;
      var status = data.status;
      var thumbnail = data.thumbnail;
      var breadcrumb = currentTreeLevel;
      var treeBreadcrumb = currentTreeLevel !== "" ? currentTreeLevel + " | " + title : title; // console.log(breadcrumb);
      // console.log(data);
      //Render all child html items first

      var childItems = [];
      var _iteratorNormalCompletion = true;
      var _didIteratorError = false;
      var _iteratorError = undefined;

      try {
        for (var _iterator = children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
          var object = _step.value;
          childItems.push(this.createHtmlElement(object, items, treeBreadcrumb));
        } //Displays a red or green line in front of the item depending on if the status (class) is active or not

      } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion && _iterator.return != null) {
            _iterator.return();
          }
        } finally {
          if (_didIteratorError) {
            throw _iteratorError;
          }
        }
      }

      var colorStatusHtml = "\n            <span class=\"color-status\" data-status-type=\"".concat(status, "\">\n                &nbsp;\n            </span>\n        "); //Displays the items icon thumbnail OR the first character of its title

      var iconHtml = "\n            <div class=\"icon\" ".concat(thumbnail ? "style=\"background-image: url('".concat(thumbnail, "');\"") : '', " >\n                ").concat(thumbnail ? '' : "<span>".concat(title ? title.substring(0, 1) : "", "</span>"), "\n            </div>\n        "); //The main item html that has all other items

      var listIem = "\n            <li data-title=\"".concat(title, "\" class=\"").concat(this.listItemClass, " ").concat(id == activeId ? 'active' : '', "\"> \n                <a href=\"").concat(this.editEntitiesUrl, "/").concat(id, "\">\n                    ").concat(colorStatusHtml, "\n                    ").concat(iconHtml, "\n                    <p data-breadcrumb=\"").concat(breadcrumb, "\">").concat(title, "</p>\n                </a>\n            </li> \n        "); //Render it to a real html element

      var domParser = new DOMParser();
      var document = domParser.parseFromString(listIem, "text/html");
      items.push(document.body.firstChild); // console.log('rendered item: ');
      // console.log(items);
      //And then add the children inside

      if (childItems.length > 0) {
        // console.log('adding rendered childitems');
        childItems.forEach(function (element) {
          items.push(element[0]);
        });
      } // console.log('items result:');
      // console.log(items);
      //and return it


      return items;
    }
  }]);

  return SearchController;
}();
/**
 * Fills an ul element with data retrieved from an api and makes the items draggable so that you can sort them.
 * Also updates the api with the new positions of the items. The data to and from the api has this structure for example.
 *
 * [
 *  {
 *      id:1
 *      title:false
 *      thumbnail:false
 *      status: "active"
 *      routes: []
 *      children: [
 *          {
 *              id: 12
 *              title: "Thuis"
 *              thumbnail: false
 *              routes: [{
 *                  40: "en/Homenew",
 *                  104: "nl/Thuisnew"
 *              }]
 *          }
 *      ]
 *  }
 * ]
 */


var SortableController =
/*#__PURE__*/
function () {
  function SortableController(selector) {
    _classCallCheck(this, SortableController);

    this.apiUrl = '';
    this.editEntitiesUrl = '';
    this.initialized = false;
    this.selector = selector;
    this.disabled = true;
    this.listItemClass = 'entities-list-item';
    var rootUl = document.querySelector(this.selector);
    this.siteSlug = rootUl.dataset.siteSlug;
    this.slug = rootUl.dataset.slug;
    this.activeId = rootUl.dataset.activeId;
  }
  /**
   * Initializes the controller so that it knows where it can get its data from,
   * where it needs to direct users when they click on an item and from which ul it
   * should create a sortable ul
   *
   * @param apiUrl A string
   * @param editEntitiesUrl A string
   */


  _createClass(SortableController, [{
    key: "init",
    value: function init(apiUrl, editEntitiesUrl) {
      this.apiUrl = apiUrl;
      this.editEntitiesUrl = editEntitiesUrl;
      var itemsThatHaveSubUl = document.querySelectorAll(this.selector + " li ul");
      itemsThatHaveSubUl.forEach(function (node, index) {
        // console.log('clicked ul');
        node.style.display = node.style.display !== 'none' ? 'none' : '';
      });
      this.initialized = true;
    }
  }, {
    key: "updateSortableJavascript",
    value: function updateSortableJavascript() {
      // console.log("Updating all sortable elements with these selectors: '" + this.selector+" .sortable' AND '"+this.selector+"'");
      $('.sortable').sortable({
        connectWith: ".sortable",
        placeholder: "sortable-placeholder",
        disabled: this.disabled
      });
      var itemsThatHaveSubUl = document.querySelectorAll(this.selector + " li ul");
      itemsThatHaveSubUl.forEach(function (node, index) {// console.log('clicked ul');
        // node.style.display = node.style.display !== 'none' ? 'none' : '';
      });
    }
    /**
     * Makes the rootUl sortable
     */

  }, {
    key: "enableSortable",
    value: function enableSortable() {
      if (this.initialized === false) {
        console.error('Please initialize the controller with the init method first.');
        return;
      }

      this.disabled = false;
      $(this.selector).sortable({
        disabled: this.disabled
      }).addClass('sorting');
      this.updateSortableJavascript();
    }
    /**
     * Diables the rootUl so that it cannot be sorted
     */

  }, {
    key: "disableSortable",
    value: function disableSortable() {
      // if (this.initialized === false) { console.error('Please initialize the controller with the init method first.'); return; }
      this.disabled = true;
      $(this.selector).sortable({
        disabled: this.disabled
      }).removeClass('sorting');
      this.save();
    }
    /**
     * Saves the item data to the api
     */

  }, {
    key: "save",
    value: function save() {
      if (this.initialized === false) {
        console.error('Please initialize the controller with the init method first.');
        return;
      }

      var itemsJson = this.itemsToJson(document.querySelector(this.selector));
      itemsJson = JSON.stringify(itemsJson);
      var apiJson = {
        "tree": itemsJson
      };
      axios.post(this.apiUrl, apiJson).then(function (response) {// console.log('Successfully stored the sort order to the api: ');
        // console.log(response);
      }).catch(function (error) {
        // console.error('Could not save sortable sort order to api because an error occured: ');
        console.error(error);
      });
    }
    /**
     * Converts the rootUl back to json for saving it
     *
     * @param htmlElement HTMLElement Root ul
     * @return null|[] if something went wrong null, or an array containing json items if successfull.
     */

  }, {
    key: "itemsToJson",
    value: function itemsToJson(htmlElement) {
      if (this.initialized === false) {
        console.error('Please initialize the controller with the init method first.');
        return;
      }

      var jsonArray = [];
      var error = false; //find all child li items

      var listItems = htmlElement.querySelectorAll(':scope > li.' + this.listItemClass);
      var _iteratorNormalCompletion2 = true;
      var _didIteratorError2 = false;
      var _iteratorError2 = undefined;

      try {
        for (var _iterator2 = listItems[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
          var listItem = _step2.value;
          var elementJson = listItem.dataset.json;

          if (!elementJson) {
            console.error('One or more li HTMLElements with class "' + this.listItemClass + '" did not have data-json attribute set while it should.');
            error = true;
          }

          var currentItemJson = JSON.parse(listItem.dataset.json);
          var childUl = listItem.querySelector('ul');

          if (childUl) {
            currentItemJson.children = this.itemsToJson(childUl);
            if (!currentItemJson.children) error = true;
          } else {
            currentItemJson.children = [];
          }

          jsonArray.push(currentItemJson);
        }
      } catch (err) {
        _didIteratorError2 = true;
        _iteratorError2 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
            _iterator2.return();
          }
        } finally {
          if (_didIteratorError2) {
            throw _iteratorError2;
          }
        }
      }

      if (error) return null;
      return jsonArray;
    }
    /**
     * Returns a promise that resolves with the root ul that then will contain the items retrieved from the api
     */

  }, {
    key: "load",
    value: function load() {
      if (this.initialized === false) {
        console.error('Please initialize the controller with the init method first.');
        return;
      }

      self = this;
      return new Promise(function (resolve, reject) {
        if (self.initialized === false) {
          reject('Please initialize the controller with the init method first.');
        }

        axios.get(self.apiUrl).then(function (response) {
          if (!response.data) {
            reject('The sortable did not get any data from the api');
            return;
          }
          /** @var HTMLElement[] menuItems*/


          var menuItems = [];
          response.data[0].children.forEach(function (itemObject) {
            menuItems.push(self.createHtmlElement(itemObject));
          });
          menuItems.forEach(function (htmlElementItem) {
            document.querySelector(self.selector).appendChild(htmlElementItem);
          });
          self.updateSortableJavascript();
          resolve(document.querySelector(self.selector));
        }).catch(function (error) {
          reject(error);
        });
      });
    }
    /**
     * Removes all children from the ul
     */

  }, {
    key: "clearRootUl",
    value: function clearRootUl() {
      if (this.initialized === false) {
        console.error('Please initialize the controller with the init method first.');
        return;
      }

      var rootUl = document.querySelector(this.selector);

      while (rootUl.firstChild) {
        rootUl.removeChild(rootUl.firstChild);
      }
    }
    /**
     * Creates a menu item (HTMLElement) and sub menu items if necessary
     *
     * @param data
     * @returns {HTMLElement}
     */

  }, {
    key: "createHtmlElement",
    value: function createHtmlElement(data) {
      if (this.initialized === false) {
        console.error('Please initialize the controller with the init method first.');
        return;
      }

      self = this;
      var activeId = self.activeId;
      var id = data.id;
      var title = data.title;
      var thumbnail = data.thumbnail;
      var children = data.children;
      var status = data.status;
      var routes = data.routes; //Generate json data representing that element

      var routesForElement = {};

      for (var routeProperty in routes) {
        if (!routes.hasOwnProperty(routeProperty)) continue;
        routesForElement[routeProperty] = routes[routeProperty];
      }

      if (routesForElement == {}) routesForElement = [];
      var elementJson = {
        id: data.id,
        title: data.title,
        thumbnail: data.thumbnail,
        routes: routesForElement,
        status: data.status
      };
      elementJson = JSON.stringify(elementJson); //Render all child html items first

      var childItems = [];
      var _iteratorNormalCompletion3 = true;
      var _didIteratorError3 = false;
      var _iteratorError3 = undefined;

      try {
        for (var _iterator3 = children[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
          var object = _step3.value;
          childItems.push(this.createHtmlElement(object));
        } //Displays a red or green line in front of the item depending on if the status (class) is active or not

      } catch (err) {
        _didIteratorError3 = true;
        _iteratorError3 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
            _iterator3.return();
          }
        } finally {
          if (_didIteratorError3) {
            throw _iteratorError3;
          }
        }
      }

      var colorStatusHtml = "\n            <span class=\"color-status\" data-status-type=\"".concat(status, "\">\n                &nbsp;\n            </span>\n        "); //Displays the items icon thumbnail OR the first character of its title

      var iconHtml = "\n            <div class=\"icon\" ".concat(thumbnail ? "style=\"background-image: url('".concat(thumbnail, "');\"") : '', " >\n                ").concat(thumbnail ? '' : "<span>".concat(title ? title.substring(0, 1) : "", "</span>"), "\n            </div>\n        "); //The main item html that has all other items

      var listIem = "\n            <li data-json='".concat(elementJson, "' class=\"").concat(this.listItemClass, " ").concat(id == activeId ? 'active' : '', "\"> \n                <a href=\"").concat(this.editEntitiesUrl, "/").concat(id, "\">\n                    ").concat(colorStatusHtml, "\n                    ").concat(iconHtml, "\n                    <p>").concat(title, "</p>\n                </a>\n            </li> \n        "); //Render it to a real html element

      var domParser = new DOMParser();
      var document = domParser.parseFromString(listIem, "text/html");
      var node = document.body.firstChild; //And add the children inside

      if (childItems.length > 0) {
        var subList = document.createElement('ul');
        subList.className = 'sortable'; // console.log('rendered childItems');
        // console.log(childItems);

        childItems.forEach(function (element) {
          subList.appendChild(element);
        });
        node.appendChild(subList);
      } //and return it


      return node;
    }
  }]);

  return SortableController;
}();

var ConfirmationController =
/*#__PURE__*/
function () {
  /**
   * ConfirmationController constructor
   *
   * @param selector
   * @param headerText
   * @param message
   * @param confirmText
   * @param cancelText
   */
  function ConfirmationController(selector, headerText, message, confirmText, cancelText) {
    _classCallCheck(this, ConfirmationController);

    if (ConfirmationController.selectorValid(selector) === false) {
      console.error('The selector "' + selector + '" isn\'t valid. Did not enable the confirmation functionality for that selector');
      return;
    }

    ConfirmationController.headerText = headerText;
    ConfirmationController.message = message;
    ConfirmationController.confirmText = confirmText;
    ConfirmationController.cancelText = cancelText;
    ConfirmationController.button = document.querySelector(selector);
    ConfirmationController.promptElement = this.createPrompt();
    document.body.appendChild(ConfirmationController.promptElement);
    this.addListenersToButton(ConfirmationController.button);
    this.addListenersToModalButtons();
  }
  /**
   * Adds listeners to the button that the selector from the constructor references to.
   * So that the button works
   *
   * @param button
   */


  _createClass(ConfirmationController, [{
    key: "addListenersToButton",
    value: function addListenersToButton(button) {
      button.addEventListener('click', function (controller) {
        return function (clickEvent) {
          clickEvent.preventDefault();
          controller.showConfirmationPrompt(true);
        };
      }(this));
    }
    /**
     * Add listeners to the modals buttons.
     * Usually the yes no buttons.
     */

  }, {
    key: "addListenersToModalButtons",
    value: function addListenersToModalButtons() {
      if (!ConfirmationController.promptElement) console.error('First create the modal with the createPrompt method');
      var confirmButton = ConfirmationController.promptElement.querySelector('button.confirm');
      var cancelButton = ConfirmationController.promptElement.querySelector('button.cancel');
      var shader = ConfirmationController.promptElement.querySelector('div.shader'); // console.log(confirmButton);
      // console.log(cancelButton);

      confirmButton.addEventListener('click', this.confirmClicked.bind(this));
      cancelButton.addEventListener('click', this.cancelClicked.bind(this));
      shader.addEventListener('click', this.cancelClicked.bind(this));
    }
  }, {
    key: "confirmClicked",
    value: function confirmClicked(mouseEvent) {
      mouseEvent.preventDefault();
      console.log(ConfirmationController.button);
      var form = this.findForm(ConfirmationController.button);
      console.log(form);
      if (form) form.submit();
      this.showConfirmationPrompt(false);
    }
  }, {
    key: "cancelClicked",
    value: function cancelClicked(mouseEvent) {
      mouseEvent.preventDefault();
      this.showConfirmationPrompt(false);
    }
    /**
     * Retrieves an HTML element and starts traversing up into the dom to find the first form the element is in.
     * Returns the form or false if it cannot be found
     * @param element
     */

  }, {
    key: "findForm",
    value: function findForm(element) {
      if (!element.parentNode) return false;
      if (element.parentNode.tagName === 'FORM') return element.parentNode;
      return this.findForm(element.parentNode);
    }
    /**
     * Create a div that represents a prompt
     *
     * @returns {HTMLDivElement}
     */

  }, {
    key: "createPrompt",
    value: function createPrompt() {
      var html = '<div class="modal">' + '<div class="header"><h4>' + ConfirmationController.headerText + '</h4></div>' + '<div class="body">' + '<p class="message">' + ConfirmationController.message + '</p>' + '<div class="buttons">' + '<button class="confirm">' + ConfirmationController.confirmText + '</button>' + '<button class="cancel">' + ConfirmationController.cancelText + '</button>' + '</div>' + '</div>' + '</div>' + '</div>' + '<div class="shader"></div>';
      var promptElement = document.createElement("div");
      promptElement.setAttribute('id', 'confirmBox');
      promptElement.innerHTML = html;
      return promptElement;
    }
    /**
     * Show or hides the confirmation prompt by adding a hidden class to it.
     */

  }, {
    key: "showConfirmationPrompt",
    value: function showConfirmationPrompt(show) {
      ConfirmationController.promptElement.classList.add('show');
      if (!show) ConfirmationController.promptElement.classList.remove('show');
    }
    /**
     * Returns true when a selector references a button tag or an input tag with type button.
     * false if not
     *
     * @param selector
     * @returns {boolean}
     */

  }], [{
    key: "selectorValid",
    value: function selectorValid(selector) {
      var button = document.querySelector(selector);
      if (!button) return false;
      if (button.tagName !== 'BUTTON' && button.tagName !== 'INPUT') return false;
      if (button.tagName === "INPUT") if (button.getAttribute('type').toLowerCase() !== 'button' && button.getAttribute('type').toLowerCase() !== 'submit') return false;
      return true;
    }
  }]);

  return ConfirmationController;
}();

var TabsController =
/*#__PURE__*/
function () {
  /**
   * The tab controller can obviously control tabs.
   * You just have to have a couple of divs that hold the content. These divs must all have a class name that
   * corresponds to the value of constructor parameter tabContentIdAndClassAndPrefix. And they all must have an id
   * that also starts with the value of tabContentIdAndClassAndPrefix followed by the tab slug.
   *
   * You can specify if you have an hidden input field that needs to be updated with the curent tab slug. You do that
   * with the tabSlugInputSelector.
   *
   * Content tab divs and buttons will also receive an active state class to make them visible / stand out when present
   * or hidden / to background. You can specify this class name with the activeClass parameter.
   *
   * The tabButtonGroupSelector selects an element that holds the tab buttons to switch tabs. This element must have an
   * ul element that holds li elements containing a elements.
   *
   * The reactToUrlHashChange parameter controls if the controller should react if the hash part of the url did change.
   *
   * @param tabContentIdAndClassAndPrefix stringseelc
   * @param tabButtonGroupSelector string
   * @param activeClass string
   * @param reactToUrlHashChange
   * @param tabSlugInputSelector string
   */
  function TabsController() {
    var tabContentIdAndClassAndPrefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'tab';
    var tabButtonGroupSelector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '.tab-buttons';
    var activeClass = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'active';
    var reactToUrlHashChange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
    var tabSlugInputSelector = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;

    _classCallCheck(this, TabsController);

    this.tabContentDivsClassAndIdPrefix = tabContentIdAndClassAndPrefix;
    this.tabSlugInputId = tabSlugInputSelector;
    this.activeClass = activeClass;
    this.reactToUrlHashChange = reactToUrlHashChange;
    if (reactToUrlHashChange) this.addListenerForHashChange(reactToUrlHashChange);
  }
  /**
   * Opens the tab by using the tab slug
   *
   * @param tabSlug
   */


  _createClass(TabsController, [{
    key: "openTab",
    value: function openTab(tabSlug) {
      //Remove trailing / on the left hand side
      tabSlug = this.removeLeftHandSlashInSlug(tabSlug);

      if (!tabSlug) {
        console.error("TabsController: Could not open tab with an empty slug");
        return;
      }

      this.updateTabSlugInput(tabSlug);
      this.showTabContentForTabWithSlug(tabSlug);
      this.makeTabButtonActiveForSlug(tabSlug);
    }
    /**
     * Removes a / at the beginning of a tab slug
     *
     * @param tabSlug
     */

  }, {
    key: "removeLeftHandSlashInSlug",
    value: function removeLeftHandSlashInSlug(tabSlug) {
      return tabSlug.replace(/^\/(.*)/, '$1');
    }
    /**
     * Updates a usually hidden input field holding the tab slug with a new slug
     *
     * @param newSlug string
     */

  }, {
    key: "updateTabSlugInput",
    value: function updateTabSlugInput(newSlug) {
      if (this.tabSlugInputId === undefined) return;
      var element = document.querySelector(this.tabSlugInputId);
      if (element) element.value = newSlug;
    }
  }, {
    key: "makeTabButtonActiveForSlug",
    value: function makeTabButtonActiveForSlug(slug) {
      $('.entity-tabs >ul >li').removeClass('active');
      $('.entity-tabs >ul >li a[href="#' + slug + '"]').parent().addClass('active');
    }
    /**
     * Shows the tab content div with the specified slug and hides the other content div tabs.
     * It does this by adding and removing classes (the active class you specified in the constructor)
     *
     * @param slug string
     */

  }, {
    key: "showTabContentForTabWithSlug",
    value: function showTabContentForTabWithSlug(slug) {
      var _this2 = this;

      //Remove the active class from all tab content classes
      document.querySelectorAll('.' + this.tabContentDivsClassAndIdPrefix).forEach(function (element) {
        element.classList.remove(_this2.activeClass);
      }); //Add the active class to the tab that has the correct slug appended to the IdPrefix

      var activeTab = document.querySelector("#" + this.tabContentDivsClassAndIdPrefix + "-" + slug);

      if (!activeTab) {
        console.error("TabsController: Could not make content tab active. It should have an ID with: #" + this.tabContentDivsClassAndIdPrefix + "-" + slug);
        return;
      }

      activeTab.classList.add(this.activeClass);
    }
    /**
     * Adds or disables listening for hashchange events to update tabs
     *
     * @param boolean
     */

  }, {
    key: "addListenerForHashChange",
    value: function addListenerForHashChange(boolean) {
      if (boolean) {
        window.addEventListener('hashchange', this.hashChanged.bind(this));
        window.addEventListener('load', this.hashChanged.bind(this));
      } else {
        window.removeEventListener('hashchange', this.hashChanged);
        window.removeEventListener('load', this.hashChanged);
      }
    }
    /**
     * Called automatically by an internal listener (controlled by the addListenerForHashChange method)
     */

  }, {
    key: "hashChanged",
    value: function hashChanged(event) {
      var tabSlug = window.location.hash.substring(1);

      if (tabSlug) {
        this.openTab(tabSlug);
        return;
      }

      var tabSlugElement = document.querySelector(this.tabSlugInputId);
      if (!tabSlugElement) return;
      this.openTab(tabSlugElement.value);
    }
  }]);

  return TabsController;
}();