(function() {
  var AddItemMixin, ExpandableFilterNodeMixin, FilterMixin, InfiniteScrollMixin, InspectedItemMixin, OptionFilterLabelRenderMixin, OptionFilterMixin, classSet, models, ui,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  if (typeof scrivito === "undefined" || scrivito === null) {
    console.error("'scrivito' is undefined, the content browser will not be available");
    $(function() {
      if (typeof scrivito === "undefined" || scrivito === null) {
        return console.log("possible reason: '//= require scrivito_sdk' is missing");
      } else {
        return console.log("possible reason: 'scrivito_sdk'/'scrivito_body_tags' is included after 'scrivito_content_browser'");
      }
    });
    return;
  }

  scrivito.content_browser = (function() {
    return {
      filters: {},
      base_preset: {},
      components: {},
      models: {},
      base_query: null,
      _center: function() {
        var domElement, domElements, _i, _len, _results;
        domElements = $(".scrivito-content-browser");
        _results = [];
        for (_i = 0, _len = domElements.length; _i < _len; _i++) {
          domElement = domElements[_i];
          domElement = $(domElement);
          _results.push(domElement.css({
            marginLeft: -domElement.innerWidth() / 2,
            marginTop: -domElement.innerHeight() / 2,
            left: '50%'
          }));
        }
        return _results;
      },
      _showConfirm: function(props) {
        props.mode = 'confirm';
        return this._showAlert(props);
      },
      _showAlert: function(props) {
        var alertContainer;
        alertContainer = document.createElement('DIV');
        document.body.appendChild(alertContainer);
        props.promise = $.Deferred();
        props.container = alertContainer;
        React.render(React.createElement(models.DialogApp, React.__spread({}, props)), alertContainer);
        return props.promise;
      },
      _loadModal: function() {
        $('<div></div>').addClass('scrivito_overlay scrivito_show').appendTo($('body'));
        $('<div></div>').addClass('scrivito-content-browser show').appendTo($('body'));
        return this._center();
      },
      _buildFilter: function(filter_definition) {
        return new models.Filter(filter_definition);
      },
      _startReact: function(options, promise) {
        var baseQuery, filter, filterConfig;
        filterConfig = options.filters || this.filters;
        baseQuery = options.base_query || this.base_query;
        filter = this._buildFilter(filterConfig);
        return this._reactApp = React.render(React.createElement(ui.App, {
          "initialFilter": filter,
          "baseQuery": baseQuery,
          "promise": promise,
          "options": options
        }), this._getLastContentBrowserElement());
      },
      _getLastElementByClassName: function(className) {
        var elements;
        elements = document.getElementsByClassName(className);
        return _.last(elements);
      },
      _getLastOverlayElement: function() {
        return this._getLastElementByClassName('scrivito_overlay scrivito_show');
      },
      _getLastContentBrowserElement: function() {
        return this._getLastElementByClassName('scrivito-content-browser show');
      },
      close: function() {
        this._getLastOverlayElement().remove();
        return this._getLastContentBrowserElement().remove();
      },
      open: function(options) {
        var promise;
        if (options == null) {
          options = {};
        }
        if (!options.hasOwnProperty('base_preset')) {
          options.base_preset = this.base_preset;
        }
        promise = $.Deferred();
        this._loadModal();
        this._startReact(options, promise);
        $(window).resize((function(_this) {
          return function() {
            return _this._center();
          };
        })(this));
        promise.always((function(_this) {
          return function() {
            return _this.close();
          };
        })(this));
        return promise;
      }
    };
  })();

  ui = scrivito.content_browser.components;

  models = scrivito.content_browser.models;

  classSet = React.addons.classSet;

  scrivito.register_public_api("content_browser", scrivito.content_browser);

  AddItemMixin = {
    itemClassName: function() {
      var className;
      className = "scrivito-content-browser-add";
      if (!this.props.objCreation.isActive()) {
        className += " disabled";
      }
      return className;
    },
    iconClassName: function() {
      var iconClass;
      iconClass = this.props.objCreation.isActive() ? "scrivito_icon_plus" : "scrivito_icon_disabled";
      return "scrivito_icon " + iconClass;
    },
    creationNotPossibleBody: function(error) {
      return React.createElement("ul", null, _.map(error.nodeTitles, function(title) {
        return React.createElement("li", null, title);
      }));
    },
    presetConflictBody: function(error) {
      return React.createElement("div", null, "The selected filter options cannot be applied to the file(s)\nyou wanted to upload. Please select only one of the following options,\nthen try again:\n", _.map(error.fields, function(values, field) {
        return React.createElement("div", null, React.createElement("h4", null, field), React.createElement("ul", null, _.map(values, function(value) {
          return React.createElement("li", null, value);
        })));
      }));
    },
    showErrorAlert: function(error) {
      var alertProps;
      alertProps = (function() {
        switch (error.type) {
          case 'creation_not_possible':
            return {
              subtitle: 'Creation of items matching the selected filters has been disabled.',
              body: this.creationNotPossibleBody(error)
            };
          case 'obj_class_not_provided':
            return {
              subtitle: "Configuration error: No '_obj_class' provided."
            };
          case 'preset_conflict':
            return {
              body: this.presetConflictBody(error)
            };
        }
      }).call(this);
      alertProps.title = "Creation not possible";
      return scrivito.content_browser._showAlert(alertProps);
    },
    buildErrorMessage: function(error) {
      var message, nodesString;
      switch (error.type) {
        case 'creation_not_possible':
          nodesString = error.nodeTitles.join(', ');
          return "The selected filter options " + nodesString + " prevent the creation";
        case 'obj_class_not_provided':
          return "Configuration error: No '_obj_class' provided";
        case 'preset_conflict':
          message = 'The selected filter options cannot be applied to the file(s) you wanted to upload. Please select only one of the following options, then try again:\n';
          _.each(error.fields, function(value, field) {
            return message += "" + field + ": " + (value.join(', ')) + "\n";
          });
          return message;
      }
    },
    iconTitle: function() {
      if (!this.props.objCreation.isActive()) {
        return this.buildErrorMessage(this.props.objCreation.error());
      }
    },
    textMessage: function() {
      if (this.props.objCreation.isActive()) {
        return "Create Item";
      } else {
        return "Item creation not possible";
      }
    },
    createClick: function() {
      if (this.props.objCreation.isActive()) {
        return this.props.addedObjsCollection.createObj(this.props.objCreation.preset());
      } else {
        return this.showErrorAlert(this.props.objCreation.error());
      }
    }
  };

  ExpandableFilterNodeMixin = {
    defaultExpansionState: function() {
      return {
        open: this.props.filter.isExpanded()
      };
    },
    arrowHandleClick: function() {
      return this.setState({
        open: !this.state.open
      });
    },
    renderArrowTag: function() {
      return React.createElement("div", {
        "className": "scrivito-content-browser-hierarchy-arrow",
        "onClick": this.arrowHandleClick
      });
    },
    openClassSetOptions: function() {
      return {
        'open': this.state.open,
        'closed': !this.state.open
      };
    }
  };

  FilterMixin = {
    renderSubFiltersList: function(subFilters, additionalClasses) {
      var ulClassName;
      ulClassName = "scrivito-content-browser-hierarchy-filter";
      if (additionalClasses && additionalClasses.length > 0) {
        ulClassName = ulClassName + " " + additionalClasses;
      }
      return React.createElement("ul", {
        "className": ulClassName
      }, subFilters);
    }
  };

  InfiniteScrollMixin = {
    loadingAdditionalItems: function() {
      return this.props.objCollection.loadNextPage();
    },
    hasMoreItems: function() {
      return this.props.objCollection.hasMoreItems();
    },
    isViewportNotFullFilled: function() {
      return this.props.objCollection.objs().length > 0;
    },
    screenBottomTolerance: function() {
      return 20;
    },
    componentDidMount: function() {
      return this.attachScrollListener();
    },
    componentDidUpdate: function() {
      this.attachScrollListener();
      if (this.isViewportNotFullFilled()) {
        return this.fillViewPort();
      }
    },
    scrollListener: function() {
      var isViewportAtBottom, node;
      node = this.getElementDOMNode();
      isViewportAtBottom = node.scrollTop + node.offsetHeight >= node.scrollHeight - this.screenBottomTolerance();
      if (isViewportAtBottom) {
        this.detachScrollListener();
        this.loadingAdditionalItems();
      }
    },
    attachScrollListener: function() {
      var node;
      if (!this.hasMoreItems()) {
        return;
      }
      node = this.getElementDOMNode();
      node.addEventListener("scroll", this.scrollListener);
      return this.scrollListener();
    },
    fillViewPort: function() {
      if (!this._isFullViewPort()) {
        return this.loadingAdditionalItems();
      }
    },
    _isFullViewPort: function() {
      return this.getElementDOMNode().scrollHeight > this.getElementDOMNode().offsetHeight;
    },
    detachScrollListener: function() {
      var node;
      node = this.getElementDOMNode();
      return node.removeEventListener("scroll", this.scrollListener);
    },
    componentWillUnmount: function() {
      return this.detachScrollListener();
    }
  };

  InspectedItemMixin = {
    changeInspectObj: function() {
      return this.props.inspector.setInspectedObj(this.props.obj);
    },
    getItemClasses: function() {
      var className;
      className = 'content-browser-item ';
      if (this.props.obj.equals(this.props.inspector.getInspectedObj())) {
        className += 'active';
      }
      return className;
    },
    selectClass: function() {
      var className;
      className = this.baseSelectClass();
      if (this.props.objCollection.isSelected(this.props.obj.id())) {
        className += ' active';
      }
      return className;
    },
    handleSelectClick: function() {
      return this.props.objCollection.toggleSelected(this.props.obj.id());
    }
  };

  OptionFilterLabelRenderMixin = {
    renderHierarchyLabelTitle: function(title) {
      return React.createElement("div", {
        "className": "scrivito-content-browser-hierarchy-label"
      }, React.createElement("span", null, title));
    }
  };

  OptionFilterMixin = {
    mixins: [OptionFilterLabelRenderMixin],
    optionLabelToggleClick: function() {
      return this.props.filter.toggleActive();
    },
    activeClassName: function() {
      if (this.props.filter.isActive()) {
        return "active";
      } else {
        return "";
      }
    },
    renderOptionFilterTitle: function() {
      return this.renderHierarchyLabelTitle(this.props.filter.title);
    }
  };

  models.FilterNode = (function() {
    function FilterNode(filter, name, filterDefinition) {
      this.filter = filter;
      this.name = name;
      this.title = filterDefinition.title;
      this.title || (this.title = this._fallbackTitle());
    }

    FilterNode.prototype._fallbackTitle = function() {
      return this._capitalize(this.name.replace(/_/g, ' ').trim());
    };

    FilterNode.prototype._capitalize = function(string) {
      return string.charAt(0).toUpperCase() + string.slice(1);
    };

    return FilterNode;

  })();

  models.FilterCollectionNode = (function(_super) {
    __extends(FilterCollectionNode, _super);

    function FilterCollectionNode(filter, name, filterDefinition) {
      FilterCollectionNode.__super__.constructor.call(this, filter, name, filterDefinition);
      this.field = filterDefinition.field, this.operator = filterDefinition.operator;
      this.expanded = filterDefinition.expanded !== false;
      this.children = [];
    }

    FilterCollectionNode.prototype.deselect = function() {
      return _.each(this.children, function(child) {
        return child.active = false;
      });
    };

    FilterCollectionNode.prototype.isExpanded = function() {
      return !!this.expanded;
    };

    FilterCollectionNode.prototype.hasActiveChildren = function() {
      return _.some(this.children, function(child) {
        return child.isActive();
      });
    };

    return FilterCollectionNode;

  })(models.FilterNode);

  models.Listenable = (function() {
    function Listenable() {
      this._callbacks = {};
    }

    Listenable.prototype.on = function(eventName, callback) {
      var _base;
      (_base = this._callbacks)[eventName] || (_base[eventName] = []);
      return this._callbacks[eventName].push(callback);
    };

    Listenable.prototype.trigger = function() {
      var callbacks, eventName, params;
      eventName = arguments[0];
      params = _.toArray(arguments).slice(1);
      callbacks = this._callbacks[eventName];
      if (callbacks) {
        return _.each(callbacks, function(callback) {
          return callback.apply(this, params);
        });
      }
    };

    Listenable.prototype.onChange = function(callback) {
      return this.on('change', callback);
    };

    Listenable.prototype.changed = function() {
      return this.trigger('change', this);
    };

    return Listenable;

  })();

  models.ActiveNodeConfig = (function() {
    function ActiveNodeConfig(parents, nodes) {
      this._parents = parents;
      this._activeNodes = nodes;
    }

    ActiveNodeConfig.prototype.activeNodes = function() {
      return this._activeNodes;
    };

    ActiveNodeConfig.prototype.values = function() {
      return _.flatten(_.map(this._activeNodes, this._valueForNode));
    };

    ActiveNodeConfig.prototype.query = function() {
      return this._filter().type !== 'checkbox' && this._activeNodes[0].query;
    };

    ActiveNodeConfig.prototype.hasQuery = function() {
      return !!this.query();
    };

    ActiveNodeConfig.prototype.field = function() {
      return this._findConfig('field');
    };

    ActiveNodeConfig.prototype.hasField = function() {
      return !!this.field();
    };

    ActiveNodeConfig.prototype.preventsCreation = function() {
      return this.nodesPreventingCreation().length > 0;
    };

    ActiveNodeConfig.prototype.nodesPreventingCreation = function() {
      return _.select(this.activeNodes(), function(node) {
        return node.enable_create === false;
      });
    };

    ActiveNodeConfig.prototype.enablesCreation = function() {
      return _.some(this.activeNodes(), function(node) {
        return node.enable_create === true;
      });
    };

    ActiveNodeConfig.prototype.operator = function() {
      return this._findConfig('operator') || 'equals';
    };

    ActiveNodeConfig.prototype._valueForNode = function(node) {
      return node.value || node.name;
    };

    ActiveNodeConfig.prototype._findConfig = function(attrName) {
      var activeNode, parentWithAttribute;
      activeNode = this._activeNodes[0];
      if (this._filter().type !== 'checkbox' && activeNode[attrName]) {
        return activeNode[attrName];
      } else {
        parentWithAttribute = _.find(this._parents, function(node) {
          return node[attrName];
        });
        return parentWithAttribute && parentWithAttribute[attrName];
      }
    };

    ActiveNodeConfig.prototype._filter = function() {
      return _.last(this._parents);
    };

    return ActiveNodeConfig;

  })();

  models.ActiveNodeConfigCollector = (function() {
    function ActiveNodeConfigCollector(filter) {
      this._filter = filter;
    }

    ActiveNodeConfigCollector.prototype.findActiveFilterItems = function() {
      var filterItems, treeFilterItem;
      filterItems = this._findActiveAdditionalFilters();
      treeFilterItem = this._findActiveTreeFilterItem();
      if (treeFilterItem) {
        filterItems.unshift(treeFilterItem);
      }
      return filterItems;
    };

    ActiveNodeConfigCollector.prototype._findActiveTreeFilterItem = function() {
      var activeConfig, subFilter, treeFilter, _i, _j, _len, _len1, _ref, _ref1;
      _ref = this._filter.getTreeFilters();
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        treeFilter = _ref[_i];
        _ref1 = treeFilter.subFilters;
        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
          subFilter = _ref1[_j];
          activeConfig = this._findActiveSubFilterItem(subFilter);
          if (activeConfig) {
            activeConfig.parents.push(treeFilter.config);
            return new models.ActiveNodeConfig(activeConfig.parents, [activeConfig.node]);
          }
        }
      }
    };

    ActiveNodeConfigCollector.prototype._findActiveAdditionalFilters = function() {
      var activeChildren, activeFilters, additionalFilter, _i, _len, _ref;
      activeFilters = [];
      _ref = this._filter.additionalFilters;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        additionalFilter = _ref[_i];
        activeChildren = _.filter(additionalFilter.children, function(child) {
          return child.isActive();
        });
        if (activeChildren.length > 0) {
          activeFilters.push(new models.ActiveNodeConfig([additionalFilter], activeChildren));
        }
      }
      return activeFilters;
    };

    ActiveNodeConfigCollector.prototype._findActiveSubFilterItem = function(filterNode) {
      var activeConfig, childNode, _i, _len, _ref;
      if (filterNode.isActive()) {
        return {
          node: filterNode,
          parents: []
        };
      } else {
        _ref = filterNode.children;
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          childNode = _ref[_i];
          activeConfig = this._findActiveSubFilterItem(childNode);
          if (activeConfig) {
            activeConfig.parents.push(filterNode);
            return activeConfig;
          }
        }
      }
    };

    return ActiveNodeConfigCollector;

  })();

  models.AddedObj = (function() {
    AddedObj.prototype.MAX_RETRY = 2;

    function AddedObj(addedObjsCollection, file, presetAttributes) {
      var objAttributes;
      this.addedObjsCollection = addedObjsCollection;
      if (presetAttributes == null) {
        presetAttributes = {};
      }
      this._status = 'active';
      this._updateProgressByStatus(this._status);
      this._fileName = file != null ? file.name : void 0;
      objAttributes = this._buildObjAttributes(file, presetAttributes);
      scrivito.create_obj(objAttributes).done((function(_this) {
        return function(objData) {
          _this._progress = 50;
          _this.addedObjsCollection.changed();
          return _this._fetchObj(objData.id);
        };
      })(this)).fail((function(_this) {
        return function(failure) {
          _this._failureMessage = failure.message;
          return _this._setStatus('failed');
        };
      })(this));
    }

    AddedObj.prototype.status = function() {
      return this._status;
    };

    AddedObj.prototype.createdObj = function() {
      return this._obj;
    };

    AddedObj.prototype.failureMessage = function() {
      return this._failureMessage;
    };

    AddedObj.prototype.fileName = function() {
      return this._fileName;
    };

    AddedObj.prototype.progress = function() {
      return this._progress;
    };

    AddedObj.prototype._fetchObj = function(id, retryCount) {
      if (retryCount == null) {
        retryCount = 0;
      }
      return models.QueryBuilder.byId(id).load_batch().then(((function(_this) {
        return function(searchResult) {
          if (searchResult.hits.length > 0) {
            _this._obj = new models.Obj(searchResult.hits[0]);
            return _this._setStatus('completed');
          } else {
            return _this._objNotYetIndexed(id, retryCount);
          }
        };
      })(this)), (function(_this) {
        return function() {
          return _this._setStatus('failed');
        };
      })(this));
    };

    AddedObj.prototype._objNotYetIndexed = function(id, retryCount) {
      var fetchObjFunction;
      if (retryCount < this.MAX_RETRY) {
        fetchObjFunction = (function(_this) {
          return function() {
            return _this._fetchObj(id, retryCount + 1);
          };
        })(this);
        return window.setTimeout(fetchObjFunction, 500);
      } else {
        this._setStatus('failed');
        return $.Deferred().reject();
      }
    };

    AddedObj.prototype._setStatus = function(status) {
      this._status = status;
      this._updateProgressByStatus(status);
      return this.addedObjsCollection.changed();
    };

    AddedObj.prototype._updateProgressByStatus = function(status) {
      return this._progress = (function() {
        switch (this.status()) {
          case 'active':
            return 10;
          case 'completed':
            return 100;
          case 'failed':
            return 0;
        }
      }).call(this);
    };

    AddedObj.prototype._buildObjAttributes = function(file, presetAttributes) {
      var objAttributes;
      objAttributes = {
        _path: this._path()
      };
      if (file) {
        _.extend(objAttributes, this._fileAttributes(file));
      }
      return _.extend(objAttributes, presetAttributes);
    };

    AddedObj.prototype._fileAttributes = function(file) {
      var objClass;
      objClass = scrivito.default_obj_class_for_content_type(file.type);
      return {
        blob: file,
        _obj_class: objClass
      };
    };

    AddedObj.prototype._path = function() {
      return "_resources/" + (this._randomResourceId()) + "/" + (this._lastPathComponent());
    };

    AddedObj.prototype._randomResourceId = function() {
      var hex;
      hex = Math.floor(Math.random() * Math.pow(16, 8)).toString(16);
      while (hex.length < 8) {
        hex = '0' + hex;
      }
      return hex;
    };

    AddedObj.prototype._lastPathComponent = function() {
      if (this.fileName()) {
        return this.fileName().replace(/[^a-z0-9_.$\-]/ig, '-');
      } else {
        return this._randomResourceId();
      }
    };

    return AddedObj;

  })();

  models.AddedObjsCollection = (function(_super) {
    __extends(AddedObjsCollection, _super);

    function AddedObjsCollection(basePreset) {
      if (basePreset == null) {
        basePreset = {};
      }
      AddedObjsCollection.__super__.constructor.call(this);
      this._basePreset = basePreset;
      this._objs = [];
    }

    AddedObjsCollection.prototype.objs = function() {
      return this._objs;
    };

    AddedObjsCollection.prototype.addFiles = function(files, presets) {
      if (presets == null) {
        presets = {};
      }
      presets = this._buildPresets(presets);
      _.each(files, (function(_this) {
        return function(file) {
          return _this._objs.unshift(new models.AddedObj(_this, file, presets));
        };
      })(this));
      return this.changed();
    };

    AddedObjsCollection.prototype.createObj = function(presets) {
      presets = this._buildPresets(presets);
      this._objs.unshift(new models.AddedObj(this, null, presets));
      return this.changed();
    };

    AddedObjsCollection.prototype.hasActiveCreations = function() {
      return _.some(this._objs, function(upload) {
        return upload.status() === 'active';
      });
    };

    AddedObjsCollection.prototype._buildPresets = function(presets) {
      return _.extend({}, this._basePreset, presets);
    };

    return AddedObjsCollection;

  })(models.Listenable);

  models.CheckboxFilter = (function(_super) {
    __extends(CheckboxFilter, _super);

    function CheckboxFilter(filter, name, filterDefinition) {
      CheckboxFilter.__super__.constructor.call(this, filter, name, filterDefinition);
      this.type = 'checkbox';
      this.children = _.map(filterDefinition.options, (function(_this) {
        return function(definition, name) {
          return new models.CheckboxOption(_this.filter, name, definition);
        };
      })(this));
    }

    return CheckboxFilter;

  })(models.FilterCollectionNode);

  models.CheckboxOption = (function(_super) {
    __extends(CheckboxOption, _super);

    function CheckboxOption(filter, name, filterDefinition) {
      CheckboxOption.__super__.constructor.call(this, filter, name, filterDefinition);
      this.value = filterDefinition.value, this.preset = filterDefinition.preset, this.enable_create = filterDefinition.enable_create;
      this.active = filterDefinition.selected;
    }

    CheckboxOption.prototype.toggleActive = function() {
      this.active = !this.active;
      return this.filter.changed();
    };

    CheckboxOption.prototype.isActive = function() {
      return !!this.active;
    };

    return CheckboxOption;

  })(models.FilterNode);

  models.Filter = (function(_super) {
    __extends(Filter, _super);

    function Filter(filter_definition) {
      Filter.__super__.constructor.call(this);
      this._initFilters(filter_definition);
    }

    Filter.prototype.deselectHierarchicalFilters = function() {
      return _.each(this.getHierarchicalFilters(), function(filter) {
        return filter.deselect();
      });
    };

    Filter.prototype.setSearchTerm = function(newTerm) {
      this.searchTerm = newTerm;
      return this.changed();
    };

    Filter.prototype.setSortCriteria = function(sortCriteria) {
      if (!this.sortCriteria.equals(sortCriteria)) {
        this.sortCriteria = sortCriteria;
        return this.changed();
      }
    };

    Filter.prototype._deselectAdditionalFilters = function() {
      if (this.hasAdditionalFilters()) {
        return _.each(this.additionalFilters, function(filter) {
          return filter.deselect();
        });
      }
    };

    Filter.prototype.getAllFilters = function() {
      return _.union(this.getHierarchicalFilters(), this.additionalFilters);
    };

    Filter.prototype.hasActiveChildren = function() {
      return _.some(this.getAllFilters(), function(subFilter) {
        return subFilter.hasActiveChildren();
      });
    };

    Filter.prototype.getHierarchicalFilters = function() {
      return _.flatten(_.map(this.getTreeFilters(), function(filter) {
        return filter.subFilters;
      }));
    };

    Filter.prototype.getTreeFilters = function() {
      return this.treeFilters;
    };

    Filter.prototype.hasHierarchicalFilters = function() {
      return this.treeFilters.length > 0;
    };

    Filter.prototype.hasAdditionalFilters = function() {
      return this.additionalFilters.length > 0;
    };

    Filter.prototype._initFilters = function(filter_definition) {
      this.treeFilters = [];
      this.additionalFilters = [];
      this.sortCriteria = new models.SortCriteria();
      return _.each(filter_definition, (function(_this) {
        return function(definition, name) {
          var subFilters;
          if ((definition.type == null) || definition.type === 'tree') {
            subFilters = [];
            _.each(definition.options, function(definition, name) {
              return subFilters.push(new models.TreeFilter(_this, name, definition));
            });
            _this.treeFilters.push({
              config: definition,
              subFilters: subFilters
            });
          }
          if (definition.type === 'radio_button') {
            _this.additionalFilters.push(new models.RadioFilter(_this, name, definition));
          }
          if (definition.type === 'check_box') {
            return _this.additionalFilters.push(new models.CheckboxFilter(_this, name, definition));
          }
        };
      })(this));
    };

    return Filter;

  })(models.Listenable);

  models.Inspector = (function(_super) {
    __extends(Inspector, _super);

    function Inspector() {
      return Inspector.__super__.constructor.apply(this, arguments);
    }

    Inspector.prototype.fileDetail = function() {
      if (this._inpsectedObj != null) {
        return this._inpsectedObj.title();
      }
    };

    Inspector.prototype.inspectorUrl = function() {
      if (this._inpsectedObj != null) {
        return scrivito.details_url_for_obj_id(this._inpsectedObj.id());
      }
    };

    Inspector.prototype.setInspectedObj = function(obj) {
      this._inpsectedObj = obj;
      return this.changed();
    };

    Inspector.prototype.getInspectedObj = function() {
      return this._inpsectedObj;
    };

    return Inspector;

  })(models.Listenable);

  models.MimeTypeIcon = (function() {
    function MimeTypeIcon() {}

    MimeTypeIcon.getMimeTypeIconClassName = function(mimeType) {
      var icon, matchedType;
      if (mimeType != null) {
        matchedType = this._getMatchedIconType(mimeType);
        icon = this._mimeTypesHash[matchedType];
      }
      if (icon == null) {
        icon = "scrivito_icon_generic";
      }
      return icon;
    };

    MimeTypeIcon._mimeTypesHash = {
      "video": "scrivito_icon_movie",
      "audio": "scrivito_icon_music",
      "msword": "scrivito_icon_doc",
      "zip": "scrivito_icon_zip",
      "pdf": "scrivito_icon_pdf",
      "ms-excel": "scrivito_icon_xls",
      "ms-powerpoint": "scrivito_icon_ppt",
      "openxmlformats-officedocument.spreadsheetml": "scrivito_icon_xls",
      "wordprocessingml": "scrivito_icon_doc",
      "presentationml": "scrivito_icon_ppt"
    };

    MimeTypeIcon._getMatchedIconType = function(mimeType) {
      return _.find(Object.keys(this._mimeTypesHash), function(keyName) {
        return mimeType.match(RegExp("\\b" + keyName + "\\b"));
      });
    };

    return MimeTypeIcon;

  })();

  models.Obj = (function() {
    function Obj(attributes) {
      this._attr = attributes;
    }

    Obj.prototype.title = function() {
      var rawTitle;
      rawTitle = this._attr['title'] || '(No description)';
      return rawTitle.trim();
    };

    Obj.prototype.subtitle = function() {
      return this._attr['subtitle'];
    };

    Obj.prototype.id = function() {
      return this._attr['id'];
    };

    Obj.prototype.equals = function(other) {
      return this.id() === (other != null ? other.id() : void 0);
    };

    Obj.prototype.hasPreview = function() {
      return !!this._attr['preview'];
    };

    Obj.prototype.previewUrl = function() {
      return this._attr['preview'];
    };

    Obj.prototype.lastChanged = function() {
      return this._attr['last_changed'];
    };

    Obj.prototype.mimeType = function() {
      return this._attr['mime_type'];
    };

    Obj.prototype.fileSize = function() {
      return this._attr['file_size'];
    };

    Obj.prototype.fileType = function() {
      return this._attr['file_type'];
    };

    Obj.prototype.hasDetailsView = function() {
      return this._attr['has_details_view'];
    };

    return Obj;

  })();

  models.ObjCollection = (function(_super) {
    __extends(ObjCollection, _super);

    function ObjCollection(selectedObjs, _selectionMode, objs, sortCriteria) {
      this._selectionMode = _selectionMode;
      ObjCollection.__super__.constructor.call(this);
      this._selectionMode || (this._selectionMode = 'multi');
      sortCriteria || (sortCriteria = new models.SortCriteria());
      this._sortCriteria = sortCriteria;
      this._selectedObjs = selectedObjs || [];
      this._objs = objs || [];
      this._isAlreadyReversed = false;
      this._curQueryNumber = 0;
    }

    ObjCollection.prototype.objs = function() {
      return this._objs;
    };

    ObjCollection.prototype.hasMoreItems = function() {
      return this._nextQuery != null;
    };

    ObjCollection.prototype.selectedObjs = function() {
      return this._selectedObjs;
    };

    ObjCollection.prototype.reload = function() {
      if (this._query) {
        return this.loadFromBackend(this._query);
      }
    };

    ObjCollection.prototype.loadFromBackend = function(query) {
      var promise;
      this._query = query;
      this._curQueryNumber += 1;
      this._resetLoadingState();
      promise = $.Deferred();
      if (query) {
        this._initialLoadObjs(query, promise, this._curQueryNumber);
      } else {
        promise.resolve();
        this._objs = [];
      }
      this.trigger('loading-obj', promise);
      return promise;
    };

    ObjCollection.prototype.toggleSelected = function(objId) {
      if (this.isSelected(objId)) {
        this._removeObjFromSelectedCollection(objId);
      } else {
        if (this.isSingleSelectionMode()) {
          this._selectedObjs = [objId];
        } else {
          this._selectedObjs.push(objId);
        }
      }
      return this.changed();
    };

    ObjCollection.prototype.isSelected = function(objId) {
      return _.contains(this._selectedObjs, objId);
    };

    ObjCollection.prototype.destroyObj = function(obj) {
      var promise;
      promise = this._destroyById(obj.id()).done((function(_this) {
        return function() {
          return _this.reload();
        };
      })(this));
      return this.trigger('loading-obj', promise);
    };

    ObjCollection.prototype.loadNextPage = function() {
      var isLoadingPagePromise, queryNumber;
      if (this.hasMoreItems()) {
        this._isLoadingPagePromise = this._getLoadingPagePromise();
        this.trigger('start-page-load');
        queryNumber = this._curQueryNumber;
        isLoadingPagePromise = this._isLoadingPagePromise;
        return this._nextQuery.load_batch().then((function(_this) {
          return function(results, next) {
            return _this._setAndLoadObjs(results, next, queryNumber);
          };
        })(this)).always((function(_this) {
          return function() {
            return isLoadingPagePromise.resolve();
          };
        })(this));
      }
    };

    ObjCollection.prototype.destroySelectedObjs = function() {
      var deferreds, promise;
      if (this._selectedObjs.length > 0) {
        deferreds = _.map(this._selectedObjs, (function(_this) {
          return function(objId) {
            return _this._destroyById(objId);
          };
        })(this));
        promise = $.when.apply($, deferreds).done((function(_this) {
          return function() {
            return _this.reload();
          };
        })(this));
        return this.trigger('loading-obj', promise);
      }
    };

    ObjCollection.prototype.isSingleSelectionMode = function() {
      return this._selectionMode === 'single';
    };

    ObjCollection.prototype._destroyById = function(objId) {
      return scrivito.delete_obj(objId).done((function(_this) {
        return function() {
          return _this._removeObjFromSelectedCollection(objId);
        };
      })(this));
    };

    ObjCollection.prototype._removeObjFromSelectedCollection = function(objId) {
      return this._selectedObjs = _.without(this._selectedObjs, objId);
    };

    ObjCollection.prototype._getLoadingPagePromise = function() {
      return $.Deferred().always((function(_this) {
        return function() {
          return _this.trigger('end-page-load');
        };
      })(this));
    };

    ObjCollection.prototype._resetLoadingState = function() {
      var _ref;
      this._nextQuery = null;
      return (_ref = this._isLoadingPagePromise) != null ? _ref.resolve() : void 0;
    };

    ObjCollection.prototype._initialLoadObjs = function(query, promise, queryNumber) {
      return query.load_batch().then((function(_this) {
        return function(results, next) {
          promise.resolve();
          if (queryNumber === _this._curQueryNumber) {
            _this._objs = [];
            return _this._setAndLoadObjs(results, next, queryNumber);
          }
        };
      })(this));
    };

    ObjCollection.prototype._setAndLoadObjs = function(results, next, queryNumber) {
      var curObjs;
      if (queryNumber === this._curQueryNumber) {
        curObjs = _.map(results.hits, function(attr) {
          return new models.Obj(attr);
        });
        this._objs = this._objs.concat(curObjs);
        this._nextQuery = next;
        return this.changed();
      }
    };

    ObjCollection.prototype.isSingleSelectionMode = function() {
      return this._selectionMode === 'single';
    };

    return ObjCollection;

  })(models.Listenable);

  models.ObjCreation = (function() {
    function ObjCreation(filter) {
      var collector, presetBuilder;
      collector = new models.ActiveNodeConfigCollector(filter);
      this.activeConfigs = collector.findActiveFilterItems();
      presetBuilder = new models.PresetBuilder(filter);
      this._preset = presetBuilder.generatePreset();
    }

    ObjCreation.prototype.preset = function() {
      return this._preset.values();
    };

    ObjCreation.prototype.showCreationItem = function() {
      return _.some(this.activeConfigs, function(nodeConfig) {
        return nodeConfig.enablesCreation();
      });
    };

    ObjCreation.prototype.isActive = function() {
      return !!(!this._preventCreation() && this._presetIsValid());
    };

    ObjCreation.prototype.error = function() {
      if (this._preventCreation()) {
        return {
          type: 'creation_not_possible',
          nodeTitles: this._nodeTitlesPreventingCreation()
        };
      } else if (this._preset.isValid()) {
        return {
          type: 'obj_class_not_provided'
        };
      } else {
        return {
          type: 'preset_conflict',
          fields: this._buildPresetConflictError()
        };
      }
    };

    ObjCreation.prototype._preventCreation = function() {
      return _.some(this.activeConfigs, function(nodeConfig) {
        return nodeConfig.preventsCreation();
      });
    };

    ObjCreation.prototype._presetIsValid = function() {
      return this._preset.isValid() && this.preset()['_obj_class'];
    };

    ObjCreation.prototype._nodeTitlesPreventingCreation = function() {
      var nodes;
      nodes = _.flatten(_.map(this.activeConfigs, function(node) {
        return node.nodesPreventingCreation();
      }));
      return _.map(nodes, function(node) {
        return node.title;
      });
    };

    ObjCreation.prototype._buildPresetConflictError = function() {
      var presetConflicts;
      presetConflicts = {};
      _.each(this._preset.errors(), function(values, field) {
        return presetConflicts[field] = values;
      });
      return presetConflicts;
    };

    return ObjCreation;

  })();

  models.PresetBuilder = (function() {
    var Preset;

    Preset = (function() {
      function Preset() {
        this._errors = {};
        this._values = {};
        this._titles = {};
      }

      Preset.prototype.isValid = function() {
        return _.keys(this.errors()).length === 0;
      };

      Preset.prototype.values = function() {
        if (this.isValid()) {
          return this._values;
        } else {
          throw new Error('#values can not be called on an invalid Preset');
        }
      };

      Preset.prototype.errors = function() {
        return this._errors;
      };

      Preset.prototype._addValue = function(key, value, title) {
        if (this._values.hasOwnProperty(key)) {
          return this._addError(key, this._titles[key], title);
        } else {
          this._values[key] = value;
          return this._titles[key] = title;
        }
      };

      Preset.prototype._addError = function(key, previouslySetValue, newValue) {
        if (this._errors[key]) {
          return this._errors[key].push(newValue);
        } else {
          return this._errors[key] = [previouslySetValue, newValue];
        }
      };

      return Preset;

    })();

    function PresetBuilder(filter) {
      this._collector = new models.ActiveNodeConfigCollector(filter);
    }

    PresetBuilder.prototype.generatePreset = function() {
      var activeNodeConfigs, presetCollection;
      presetCollection = new Preset();
      activeNodeConfigs = this._collector.findActiveFilterItems();
      _.each(activeNodeConfigs, (function(_this) {
        return function(activeNodeConfig) {
          var nodesWithPreset;
          nodesWithPreset = _this._nodesWithPreset(activeNodeConfig);
          return _.each(nodesWithPreset, function(filterNode) {
            return _this._addPresetsForFilterNode(filterNode, presetCollection);
          });
        };
      })(this));
      return presetCollection;
    };

    PresetBuilder.prototype._nodesWithPreset = function(config) {
      return _.select(config.activeNodes(), function(node) {
        return node.preset;
      });
    };

    PresetBuilder.prototype._addPresetsForFilterNode = function(node, presetCollection) {
      return _.each(node.preset, function(value, key) {
        if (value !== void 0) {
          return presetCollection._addValue(key, value, node.title);
        }
      });
    };

    return PresetBuilder;

  })();

  models.QueryBuilder = (function() {
    function QueryBuilder(filter, baseQuery) {
      this.filter = filter;
      this._collector = new models.ActiveNodeConfigCollector(this.filter);
      if (baseQuery) {
        this._baseQuery = models.QueryBuilder.prepareQuery(baseQuery);
      }
    }

    QueryBuilder.prototype.searchRequest = function() {
      var query;
      query = this._baseQuery;
      query = this._addFilterQueries(query);
      query = this._addSearchTermQuery(query);
      return query = this._sortQuery(query);
    };

    QueryBuilder.prototype._addFilterQueries = function(baseQuery) {
      var activeConfig, combinedQuery, searchQuery, _i, _len, _ref;
      combinedQuery = baseQuery;
      _ref = this._collector.findActiveFilterItems();
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        activeConfig = _ref[_i];
        searchQuery = this._buildActiveChildrenSearchQuery(activeConfig);
        if (searchQuery) {
          combinedQuery = this._addOrCreateQuery(combinedQuery, searchQuery);
        }
      }
      return combinedQuery;
    };

    QueryBuilder.prototype._sortQuery = function(query) {
      if (query != null) {
        query = query.order(this.filter.sortCriteria.type());
        if (this.filter.sortCriteria.isReverse()) {
          if (!query.orderReversed) {
            query.reverse_order();
          }
        }
      }
      return query;
    };

    QueryBuilder.prototype._addSearchTermQuery = function(query) {
      var searchQuery;
      if (this.filter.searchTerm && this.filter.searchTerm.length > 0) {
        searchQuery = scrivito.obj_where('*', 'contains_prefix', this.filter.searchTerm);
        return this._addOrCreateQuery(query, searchQuery);
      } else {
        return query;
      }
    };

    QueryBuilder.prototype._buildActiveChildrenSearchQuery = function(activeConfig) {
      if (activeConfig.hasQuery()) {
        activeConfig.query().query().order = void 0;
        activeConfig.query().query().reverse_order = void 0;
        return activeConfig.query();
      } else {
        return this._buildFOVQuery(activeConfig);
      }
    };

    QueryBuilder.prototype._buildFOVQuery = function(activeConfig) {
      if (activeConfig.hasField()) {
        return scrivito.obj_where(activeConfig.field(), activeConfig.operator(), activeConfig.values());
      }
    };

    QueryBuilder.prototype._addOrCreateQuery = function(oldQuery, newQuery) {
      if (oldQuery) {
        return oldQuery.and(newQuery);
      } else {
        return models.QueryBuilder.prepareQuery(newQuery);
      }
    };

    return QueryBuilder;

  })();

  models.QueryBuilder.prepareQuery = function(query) {
    return query.clone().format('content_browser').batch_size(24);
  };

  models.QueryBuilder.byId = function(ids) {
    return models.QueryBuilder.prepareQuery(scrivito.obj_where('id', 'equals', ids));
  };

  models.RadioFilter = (function(_super) {
    __extends(RadioFilter, _super);

    function RadioFilter(filter, name, filterDefinition) {
      RadioFilter.__super__.constructor.call(this, filter, name, filterDefinition);
      this.type = 'radio';
      this.children = _.map(filterDefinition.options, (function(_this) {
        return function(definition, name) {
          return new models.RadioOption(_this, name, definition);
        };
      })(this));
    }

    RadioFilter.prototype.activate = function(radioOption) {
      _.each(this.children, function(child) {
        return child.active = child === radioOption;
      });
      return this.filter.changed();
    };

    RadioFilter.prototype.deactivateAll = function() {
      this.deselect();
      return this.filter.changed();
    };

    return RadioFilter;

  })(models.FilterCollectionNode);

  models.RadioOption = (function(_super) {
    __extends(RadioOption, _super);

    function RadioOption(group, name, filterDefinition) {
      this.group = group;
      RadioOption.__super__.constructor.call(this, this.group.filter, name, filterDefinition);
      this.value = filterDefinition.value, this.query = filterDefinition.query, this.preset = filterDefinition.preset, this.enable_create = filterDefinition.enable_create;
      this.active = filterDefinition.selected;
    }

    RadioOption.prototype.setActive = function() {
      return this.group.activate(this);
    };

    RadioOption.prototype.isActive = function() {
      return !!this.active;
    };

    return RadioOption;

  })(models.FilterNode);

  models.SortCriteria = (function() {
    function SortCriteria(type, reverse, activeElement, activeSortItemGroupTitle) {
      if (reverse == null) {
        reverse = true;
      }
      if (type == null) {
        type = "_last_changed";
      }
      if (activeElement == null) {
        activeElement = "Last change: latest first";
      }
      if (activeSortItemGroupTitle == null) {
        activeSortItemGroupTitle = "Sort by date";
      }
      this._activeSortItemGroupTitle = activeSortItemGroupTitle;
      this._activeElement = activeElement;
      this._isReverse = reverse;
      this._type = type;
    }

    SortCriteria.prototype.isReverse = function() {
      return this._isReverse;
    };

    SortCriteria.prototype.type = function() {
      return this._type;
    };

    SortCriteria.prototype.activeElement = function() {
      return this._activeElement;
    };

    SortCriteria.prototype.activeSortItemGroupTitle = function() {
      return this._activeSortItemGroupTitle;
    };

    SortCriteria.prototype.equals = function(sortCriteria) {
      return sortCriteria.type() === this._type && sortCriteria.isReverse() === this._isReverse;
    };

    return SortCriteria;

  })();

  models.SortMenuItem = (function(_super) {
    __extends(SortMenuItem, _super);

    function SortMenuItem(group) {
      this.group = group;
    }

    SortMenuItem.prototype.setActive = function() {
      return this.group.activate(this);
    };

    SortMenuItem.prototype.isActive = function() {
      return !!this.active;
    };

    return SortMenuItem;

  })(models.Listenable);

  models.TreeFilter = (function(_super) {
    __extends(TreeFilter, _super);

    function TreeFilter(filter, name, filterDefinition) {
      var childrenDefinition;
      TreeFilter.__super__.constructor.call(this, filter, name, filterDefinition);
      this.type = 'tree';
      this.icon = filterDefinition.icon, this.query = filterDefinition.query, this.expanded = filterDefinition.expanded, this.value = filterDefinition.value, this.field = filterDefinition.field, this.operator = filterDefinition.operator, this.preset = filterDefinition.preset, this.enable_create = filterDefinition.enable_create;
      this.active = filterDefinition.selected;
      childrenDefinition = filterDefinition.options || [];
      this.children = _.map(childrenDefinition, function(definition, name) {
        return new models.TreeFilter(filter, name, definition);
      });
    }

    TreeFilter.prototype.isLeaf = function() {
      return this.children.length === 0;
    };

    TreeFilter.prototype.isExpanded = function() {
      return !!this.expanded;
    };

    TreeFilter.prototype.isActive = function() {
      return !!this.active;
    };

    TreeFilter.prototype.toggleActive = function() {
      if (this.isActive()) {
        this.active = false;
      } else {
        this.filter.deselectHierarchicalFilters();
        this.active = true;
      }
      return this.filter.changed();
    };

    TreeFilter.prototype.hasActiveChildren = function() {
      return this.isActive() || _.some(this.children, function(child) {
        return child.isActive();
      });
    };

    TreeFilter.prototype.deselect = function() {
      this.active = false;
      return _.each(this.children, function(filter) {
        return filter.deselect();
      });
    };

    return TreeFilter;

  })(models.FilterNode);

  models.ViewMode = (function(_super) {
    __extends(ViewMode, _super);

    function ViewMode(mode) {
      ViewMode.__super__.constructor.call(this);
      if (mode == null) {
        mode = "thumbnails";
      }
      this._mode = mode;
    }

    ViewMode.prototype.setMode = function(newMode) {
      this._mode = newMode;
      return this.changed();
    };

    ViewMode.prototype.getMode = function() {
      return this._mode;
    };

    ViewMode.prototype.isList = function() {
      return this._mode === "list";
    };

    return ViewMode;

  })(models.Listenable);

  ui.App = React.createClass({
    displayName: 'App',
    updateFilter: function(filter) {
      return this.setState({
        filter: filter
      });
    },
    updateViewMode: function(viewMode) {
      return this.setState({
        viewMode: viewMode
      });
    },
    updateObjCollection: function(objCollection) {
      return this.setState({
        objCollection: objCollection
      });
    },
    setLoadingState: function(promise) {
      this.refs.itemView.setState({
        loading: true
      });
      return promise.always((function(_this) {
        return function() {
          return _this.refs.itemView.setState({
            loading: false
          });
        };
      })(this));
    },
    updateAddedObjsCollection: function(addedObjsCollection) {
      var lastCreatedObj;
      this.setState({
        addedObjsCollection: addedObjsCollection
      });
      if (!addedObjsCollection.hasActiveCreations()) {
        lastCreatedObj = _.first(addedObjsCollection.objs()).createdObj();
        this.state.inspector.setInspectedObj(lastCreatedObj);
        return this.state.objCollection.reload();
      }
    },
    updateInspector: function(inspector) {
      return this.setState({
        inspector: inspector
      });
    },
    activateInitialFilter: function() {
      if (this.refs.filterView.activateInitialFilter) {
        return this.refs.filterView.activateInitialFilter();
      }
    },
    componentDidMount: function() {
      this.state.filter.onChange(this.updateFilter);
      this.state.viewMode.onChange(this.updateViewMode);
      this.state.addedObjsCollection.onChange(this.updateAddedObjsCollection);
      this.state.objCollection.onChange(this.updateObjCollection);
      this.state.objCollection.on('loading-obj', this.setLoadingState);
      this.state.inspector.onChange(this.updateInspector);
      return this.activateInitialFilter();
    },
    getInitialState: function() {
      var basePreset, initialSelection, selectionMode;
      initialSelection = this.props.options.selection || [];
      selectionMode = this.props.options.selection_mode;
      basePreset = this.props.options.base_preset;
      return {
        filter: this.props.initialFilter,
        objs: [],
        viewMode: new models.ViewMode(),
        sortCriteria: this.props.initialFilter.sortCriteria,
        addedObjsCollection: new models.AddedObjsCollection(basePreset),
        objCollection: new models.ObjCollection(initialSelection, selectionMode),
        inspector: new models.Inspector()
      };
    },
    render: function() {
      return React.createElement("div", {
        "className": "scrivito-app-root"
      }, React.createElement("div", {
        "className": "scrivito-content-browser-body"
      }, React.createElement("div", {
        "className": "scrivito-content-browser-wrapper"
      }, React.createElement(ui.TopBar, {
        "filter": this.state.filter,
        "sortCriteria": this.state.sortCriteria,
        "viewMode": this.state.viewMode
      }), React.createElement(ui.Filter, {
        "ref": "filterView",
        "filter": this.state.filter,
        "baseQuery": this.props.baseQuery,
        "objCollection": this.state.objCollection
      }), React.createElement(ui.Items, {
        "ref": "itemView",
        "objCollection": this.state.objCollection,
        "viewMode": this.state.viewMode,
        "addedObjsCollection": this.state.addedObjsCollection,
        "inspector": this.state.inspector,
        "filter": this.state.filter
      }), React.createElement(ui.MoreItemsSpinner, {
        "objCollection": this.state.objCollection
      })), React.createElement(ui.Inspector, {
        "inspector": this.state.inspector,
        "objCollection": this.state.objCollection
      })), React.createElement(ui.Footer, {
        "promise": this.props.promise,
        "objCollection": this.state.objCollection
      }));
    }
  });

  models.DialogBody = React.createClass({
    displayName: 'DialogBody',
    render: function() {
      return React.createElement("div", {
        "className": "scrivito_modal_body"
      }, this.props.body);
    }
  });

  models.DialogHeader = React.createClass({
    displayName: 'DialogHeader',
    render: function() {
      return React.createElement("div", {
        "className": "scrivito_modal_header"
      }, React.createElement("i", {
        "className": "scrivito_icon scrivito_icon_error"
      }), React.createElement("h3", {
        "className": "scrivito_title"
      }, this.props.title), (this.props.subtitle ? React.createElement("p", {
        "className": "scrivito_description"
      }, this.props.subtitle) : void 0));
    }
  });

  models.DialogApp = React.createClass({
    displayName: 'DialogApp',
    dialogClassName: function() {
      return "scrivito_prompt_dialog scrivito_center_dialog scrivito_modal_prompt scrivito_show scrivito_red";
    },
    showConfirmButton: function() {
      return this.props.mode === "confirm";
    },
    closeButtonText: function() {
      if (this.showConfirmButton()) {
        return "Cancel";
      } else {
        return "Close";
      }
    },
    resolveAndClose: function(event) {
      this.props.promise.resolve();
      return this.closeDialog(event);
    },
    rejectAndClose: function(event) {
      this.props.promise.reject();
      return this.closeDialog(event);
    },
    closeDialog: function(event) {
      event.preventDefault();
      React.unmountComponentAtNode(this.props.container);
      return this.props.container.remove();
    },
    render: function() {
      return React.createElement("div", null, React.createElement("div", {
        "className": "scrivito_overlay two scrivito_show",
        "style": {
          zIndex: 4444444
        }
      }), React.createElement("div", {
        "className": this.dialogClassName(),
        "style": {
          zIndex: 4444444
        }
      }, React.createElement(models.DialogHeader, {
        "title": this.props.title,
        "subtitle": this.props.subtitle
      }), React.createElement(models.DialogBody, {
        "body": this.props.body
      }), React.createElement("div", {
        "className": "scrivito_modal_footer"
      }, React.createElement("a", {
        "className": "scrivito_button scrivito_cancel",
        "onClick": this.rejectAndClose
      }, this.closeButtonText()), (this.showConfirmButton() ? React.createElement("a", {
        "className": "scrivito_button scrivito_red scrivito_confirm",
        "onClick": this.resolveAndClose
      }, "Confirm") : void 0))));
    }
  });

  ui.Filter = React.createClass({
    displayName: 'Filter',
    mixins: [FilterMixin],
    renderAdditionalFilters: function() {
      var subFilters;
      subFilters = _.map(this.props.filter.additionalFilters, function(additionalFilter) {
        return React.createElement(ui.Filter.AdditionalOptionFilter, {
          "filter": additionalFilter
        });
      });
      return this.renderSubFiltersList(subFilters, "compact");
    },
    loadObjsByFilterQuery: function(filter) {
      var query, queryBuilder;
      this.setState({
        selectedFilter: false
      });
      queryBuilder = new models.QueryBuilder(filter, this.props.baseQuery);
      query = queryBuilder.searchRequest();
      return this.props.objCollection.loadFromBackend(query);
    },
    componentDidMount: function() {
      return this.props.filter.onChange(this.loadObjsByFilterQuery);
    },
    activateInitialFilter: function() {
      if (this.props.filter.hasActiveChildren()) {
        return this.loadObjsByFilterQuery(this.props.filter);
      } else {
        return this.activateSelectedFilter();
      }
    },
    activateSelectedFilter: function() {
      var query;
      this.props.filter.deselectHierarchicalFilters();
      this.setState({
        selectedFilter: true
      });
      query = models.QueryBuilder.byId(this.props.objCollection.selectedObjs());
      return this.props.objCollection.loadFromBackend(query);
    },
    getInitialState: function() {
      return {
        selectedFilter: false
      };
    },
    renderFilterSeparator: function() {
      if (this.props.filter.hasAdditionalFilters() && this.props.filter.hasHierarchicalFilters()) {
        return React.createElement("div", {
          "className": "scrivito_separator"
        }, "more filters");
      }
    },
    render: function() {
      var selectedObjsCount, treeSubFilters;
      treeSubFilters = _.map(this.props.filter.getHierarchicalFilters(), function(treeFilter) {
        return React.createElement(ui.Filter.TreeFilter, {
          "filter": treeFilter
        });
      });
      selectedObjsCount = this.props.objCollection.selectedObjs().length;
      return React.createElement("div", {
        "className": "scrivito-content-browser-filter"
      }, React.createElement(ui.Filter.SelectedFilter, {
        "selectedCount": selectedObjsCount,
        "active": this.state.selectedFilter,
        "activateSelectedFilter": this.activateSelectedFilter
      }), React.createElement("div", {
        "className": "scrivito-content-browser-filter-scroll"
      }, this.renderSubFiltersList(treeSubFilters), this.renderFilterSeparator(), this.renderAdditionalFilters()));
    }
  });

  ui.Filter.AdditionalOptionFilter = React.createClass({
    displayName: 'AdditionalOptionFilter',
    mixins: [ExpandableFilterNodeMixin],
    getInitialState: function() {
      return this.defaultExpansionState();
    },
    getAdditionalLableClasses: function() {
      return classSet(this.openClassSetOptions());
    },
    createDeselctAllRadioOption: function() {
      return React.createElement(ui.Filter.DeselectAllRadioOptionFilter, {
        "filter": this.props.filter
      });
    },
    renderSubRadioOptionFilters: function() {
      var childKey, element, i, _i, _len, _ref, _results;
      _ref = this.props.filter.children;
      _results = [];
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
        element = _ref[i];
        childKey = "" + element.title + "-" + i;
        if (this.props.filter.type === "radio") {
          _results.push(React.createElement(ui.Filter.RadioOptionFilter, {
            "key": childKey,
            "filter": element
          }));
        } else if (this.props.filter.type === "checkbox") {
          _results.push(React.createElement(ui.Filter.CheckBoxOptionFilter, {
            "key": childKey,
            "filter": element
          }));
        } else {
          _results.push(void 0);
        }
      }
      return _results;
    },
    render: function() {
      var labelClasses;
      labelClasses = this.getAdditionalLableClasses();
      return React.createElement("li", {
        "className": labelClasses
      }, this.renderArrowTag(), React.createElement("div", {
        "className": "scrivito-content-browser-hierarchy-label",
        "onClick": this.arrowHandleClick
      }, React.createElement("span", null, this.props.filter.title)), React.createElement("ul", null, (this.props.filter.type === "radio" ? this.createDeselctAllRadioOption() : void 0), this.renderSubRadioOptionFilters()));
    }
  });

  ui.Filter.CheckBoxOptionFilter = React.createClass({
    displayName: 'CheckBoxOptionFilter',
    mixins: [OptionFilterMixin],
    render: function() {
      return React.createElement("li", {
        "className": this.activeClassName(),
        "onClick": this.optionLabelToggleClick
      }, React.createElement("div", {
        "className": "scrivito-content-browser-hierarchy-checkbox"
      }), this.renderOptionFilterTitle());
    }
  });

  ui.Filter.DeselectAllRadioOptionFilter = React.createClass({
    displayName: 'DeselectAllRadioOptionFilter',
    mixins: [OptionFilterLabelRenderMixin],
    getActiveClass: function() {
      if (this.props.filter.hasActiveChildren()) {
        return '';
      } else {
        return "active";
      }
    },
    deselectAllRadioOption: function() {
      return this.props.filter.deactivateAll();
    },
    render: function() {
      return React.createElement("li", {
        "className": this.getActiveClass(),
        "onClick": this.deselectAllRadioOption
      }, React.createElement("div", {
        "className": "scrivito-content-browser-hierarchy-radio"
      }), this.renderHierarchyLabelTitle('All'));
    }
  });

  ui.Filter.RadioOptionFilter = React.createClass({
    displayName: 'RadioOptionFilter',
    mixins: [OptionFilterMixin],
    labelToggleClick: function() {
      if (!this.props.filter.isActive()) {
        return this.props.filter.setActive();
      }
    },
    render: function() {
      return React.createElement("li", {
        "className": this.activeClassName(),
        "onClick": this.labelToggleClick
      }, React.createElement("div", {
        "className": "scrivito-content-browser-hierarchy-radio"
      }), this.renderOptionFilterTitle());
    }
  });

  ui.Filter.SelectedFilter = React.createClass({
    displayName: 'SelectedFilter',
    filterClass: function() {
      return classSet({
        'scrivito-content-browser-filter-item': true,
        'selected-filter': true,
        'active': this.props.active
      });
    },
    render: function() {
      return React.createElement("div", {
        "className": "scrivito-content-browser-filter-fixed"
      }, React.createElement("div", {
        "className": this.filterClass(),
        "onClick": this.props.activateSelectedFilter
      }, React.createElement("span", {
        "className": "scrivito-content-browser-filter-label"
      }, "Selected", React.createElement("span", {
        "className": "scrivito-content-browser-counter selected-total"
      }, this.props.selectedCount))));
    }
  });

  ui.Filter.TreeFilter = React.createClass({
    displayName: 'TreeFilter',
    mixins: [ExpandableFilterNodeMixin],
    getInitialState: function() {
      return this.defaultExpansionState();
    },
    renderIconTag: function() {
      var baseIconClass, iconClass;
      if (this.props.filter.icon != null) {
        baseIconClass = "scrivito_icon";
        iconClass = baseIconClass + ("_" + this.props.filter.icon);
        return React.createElement("i", {
          "className": "" + baseIconClass + " " + iconClass
        });
      }
    },
    getLabelClasses: function() {
      var activeClass, classes;
      activeClass = {
        'active': this.props.filter.isActive()
      };
      classes = _.extend(this.openClassSetOptions(), activeClass);
      return classSet(classes);
    },
    renderSubTrees: function() {
      var childKey, element, i, _i, _len, _ref, _results;
      _ref = this.props.filter.children;
      _results = [];
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
        element = _ref[i];
        childKey = "" + element.title + "-" + i;
        _results.push(React.createElement(ui.Filter.TreeFilter, {
          "key": childKey,
          "filter": element
        }));
      }
      return _results;
    },
    labelToggleClick: function() {
      return this.props.filter.toggleActive();
    },
    render: function() {
      var labelClasses;
      labelClasses = this.getLabelClasses();
      return React.createElement("li", {
        "className": labelClasses
      }, (!this.props.filter.isLeaf() ? this.renderArrowTag() : void 0), React.createElement("div", {
        "className": "scrivito-content-browser-hierarchy-label",
        "onClick": this.labelToggleClick
      }, this.renderIconTag(), React.createElement("span", null, this.props.filter.title)), (!this.props.filter.isLeaf() ? React.createElement("ul", null, this.renderSubTrees()) : void 0));
    }
  });

  ui.Footer = React.createClass({
    displayName: 'Footer',
    currentSelectedCount: function() {
      return this.props.objCollection.selectedObjs().length;
    },
    deleteButtonClass: function() {
      var className;
      className = ' scrivito_button scrivito_lightgrey content-browser-delete scrivito_left';
      if (this.currentSelectedCount() === 0) {
        className += ' scrivito_disabled';
      }
      return className;
    },
    cancelClick: function() {
      return this.props.promise.reject();
    },
    doneClick: function() {
      return this.props.promise.resolve(this.props.objCollection.selectedObjs());
    },
    deleteClick: function() {
      var objectsToBeDeleted;
      if (this.currentSelectedCount() > 0) {
        objectsToBeDeleted = this.currentSelectedCount() === 1 ? "one CMS object" : "" + (this.currentSelectedCount()) + " CMS objects";
        return scrivito.content_browser._showConfirm({
          title: 'Really delete the selected items?',
          subtitle: "This will delete " + objectsToBeDeleted + ". Objects that were created in this working copy cannot be restored."
        }).then((function(_this) {
          return function() {
            return _this.props.objCollection.destroySelectedObjs();
          };
        })(this));
      }
    },
    render: function() {
      return React.createElement("div", {
        "className": "scrivito-content-browser-footer"
      }, React.createElement("a", {
        "className": this.deleteButtonClass(),
        "onClick": this.deleteClick
      }, "Delete", React.createElement("span", {
        "className": "scrivito-content-browser-counter selected-total"
      }, this.currentSelectedCount())), React.createElement("a", {
        "className": "scrivito_button scrivito_green content-browser-save",
        "onClick": this.doneClick
      }, "Select", React.createElement("span", {
        "className": "scrivito-content-browser-counter selected-total"
      }, this.currentSelectedCount())), React.createElement("a", {
        "className": "scrivito_button content-browser-close",
        "onClick": this.cancelClick
      }, "Cancel"));
    }
  });

  ui.Inspector = React.createClass({
    displayName: 'Inspector',
    getDetailsClassName: function() {
      return "scrivito_icon scrivito_icon_eye";
    },
    getEmptyPlaceholder: function() {
      return React.createElement("div", {
        "className": "details-view"
      }, React.createElement("p", {
        "className": "no-editing-available"
      }, React.createElement("span", {
        "className": "scrivito_icon scrivito_icon_generic"
      }), "No edit view available."));
    },
    _deleteInspectedObj: function() {
      return scrivito.content_browser._showConfirm({
        title: React.createElement("span", null, "Really delete ", React.createElement("q", null, this.props.inspector.fileDetail()), "?"),
        subtitle: 'Objects that were created in this working copy cannot be restored.'
      }).then((function(_this) {
        return function() {
          _this.props.objCollection.destroyObj(_this.props.inspector.getInspectedObj());
          return _this.props.inspector.setInspectedObj(void 0);
        };
      })(this));
    },
    render: function() {
      return React.createElement("div", {
        "className": "scrivito-content-browser-inspector"
      }, (this.props.inspector.inspectorUrl() != null ? React.createElement("div", null, React.createElement("h3", {
        "title": this.props.inspector.fileDetail()
      }, React.createElement("span", {
        "title": "Details",
        "className": this.getDetailsClassName()
      }), React.createElement("span", {
        "className": "title"
      }, this.props.inspector.fileDetail()), React.createElement("span", {
        "className": "scrivito_icon scrivito_icon_trash scrivito_delete",
        "onClick": this._deleteInspectedObj
      })), React.createElement("div", {
        "className": "inspector-content"
      }, (this.props.inspector.getInspectedObj().hasDetailsView() ? React.createElement("iframe", {
        "src": this.props.inspector.inspectorUrl(),
        "name": "scrivito_inspector"
      }) : this.getEmptyPlaceholder()))) : void 0));
    }
  });

  ui.Items = React.createClass({
    displayName: 'Items',
    getInitialState: function() {
      return {
        dragInProgres: false
      };
    },
    dropZoneClass: function() {
      return classSet({
        "scrivito-content-browser-items": true,
        "uploader-drag-over": this.state.dragInProgres
      });
    },
    _showConflictingPresetsAlert: function(errors) {
      var message;
      message = React.createElement("div", null, "Please select only one of the following options,\nthen try again:", _.map(errors, function(values, field) {
        return React.createElement("div", null, React.createElement("h4", null, field), React.createElement("ul", null, _.map(values, function(value) {
          return React.createElement("li", null, value);
        })));
      }));
      return scrivito.content_browser._showAlert({
        title: 'The selected filter options cannot be applied to the file(s) you wanted to upload',
        body: React.createElement("div", null, message)
      });
    },
    uploadFiles: function(event) {
      var dataTransfer, files, preset;
      this.changeDragState(false)(event);
      dataTransfer = event.dataTransfer;
      if (dataTransfer == null) {
        return;
      }
      files = dataTransfer.files;
      if (files.length > 0) {
        preset = this.buildPreset();
        if (preset.isValid()) {
          return this.props.addedObjsCollection.addFiles(files, preset.values());
        } else {
          return this._showConflictingPresetsAlert(preset.errors());
        }
      }
    },
    buildPreset: function() {
      var presetBuilder;
      presetBuilder = new models.PresetBuilder(this.props.filter);
      return presetBuilder.generatePreset();
    },
    changeDragState: function(toValue) {
      return (function(_this) {
        return function(event) {
          event.preventDefault();
          event.stopPropagation();
          return _this.setState({
            dragInProgres: toValue
          });
        };
      })(this);
    },
    render: function() {
      return React.createElement("div", {
        "className": this.dropZoneClass(),
        "onDragOver": this.changeDragState(true),
        "onDrop": this.uploadFiles,
        "onDragLeave": this.changeDragState(false)
      }, (this.state.loading ? React.createElement("div", {
        "className": "scrivito-content-browser-loading"
      }, React.createElement("i", {
        "className": "scrivito_icon scrivito_icon_refresh"
      })) : this.props.addedObjsCollection.hasActiveCreations() ? React.createElement(ui.UploadItems, {
        "addedObjsCollection": this.props.addedObjsCollection
      }) : this.props.viewMode.isList() ? React.createElement(ui.TableView, {
        "objCollection": this.props.objCollection,
        "toggleSelected": this.props.toggleSelected,
        "filter": this.props.filter,
        "inspector": this.props.inspector,
        "addedObjsCollection": this.props.addedObjsCollection
      }) : React.createElement(ui.ThumbnailItems, {
        "objCollection": this.props.objCollection,
        "viewMode": this.props.viewMode.getMode(),
        "onBuildAllItems": this.fillViewPort,
        "inspector": this.props.inspector,
        "filter": this.props.filter,
        "addedObjsCollection": this.props.addedObjsCollection
      })));
    }
  });

  ui.MoreItemsSpinner = React.createClass({
    displayName: 'MoreItemsSpinner',
    getInitialState: function() {
      return {
        isSpinning: false
      };
    },
    componentDidMount: function() {
      this.props.objCollection.on('start-page-load', this.setEndlessLoadingState);
      return this.props.objCollection.on('end-page-load', this.removeEndlessLoadingState);
    },
    setEndlessLoadingState: function() {
      return this.setState({
        isSpinning: true
      });
    },
    removeEndlessLoadingState: function() {
      if (this.state.isSpinning) {
        return this.setState({
          isSpinning: false
        });
      }
    },
    render: function() {
      return React.createElement("div", null, (this.state.isSpinning ? React.createElement("div", {
        "className": "scrivito-content-browser-endless-loader"
      }, React.createElement("i", {
        "className": "scrivito_icon scrivito_icon_refresh"
      })) : void 0));
    }
  });

  ui.SortMenu = React.createClass({
    displayName: 'SortMenu',
    sortItemsData: {
      "date": {
        itemTitle: "Sort by date",
        descCriteriaTitle: "Last change: latest first",
        ascCriteriaTitle: "Last change: oldest first",
        sortItemType: "_last_changed"
      }
    },
    toggleSortMenu: function() {
      return $('.scrivito_menu_box').fadeToggle();
    },
    getSortIconClassName: function() {
      var sortIcon;
      sortIcon = "scrivito_icon ";
      if (this.props.filter.sortCriteria.isReverse()) {
        sortIcon += "scrivito_icon_sort_up";
      } else {
        sortIcon += "scrivito_icon_sort_down";
      }
      return sortIcon;
    },
    render: function() {
      var sortItem;
      return React.createElement("span", {
        "className": "scrivito_button scrivito_lightgrey scrivito_right",
        "onClick": this.toggleSortMenu
      }, React.createElement("i", {
        "className": this.getSortIconClassName()
      }), this.props.filter.sortCriteria.activeElement(), React.createElement("i", {
        "className": "scrivito_icon scrivito-content-browser-menu-icon scrivito_icon_chevron_down"
      }), React.createElement("ul", {
        "className": "scrivito_menu_box scrivito_right"
      }, (function() {
        var _i, _len, _ref, _results;
        _ref = Object.keys(this.sortItemsData);
        _results = [];
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          sortItem = _ref[_i];
          _results.push(React.createElement(ui.SortMenuItem, {
            "filter": this.props.filter,
            "sortItem": this.sortItemsData[sortItem]
          }));
        }
        return _results;
      }).call(this)));
    }
  });

  ui.SortMenuItem = React.createClass({
    displayName: 'SortMenuItem',
    basicIcon: "scrivito_icon  ",
    _ascIconSortClass: function() {
      return this.basicIcon + "scrivito_icon_sort_down";
    },
    _descIconSortClass: function() {
      return this.basicIcon + "scrivito_icon_sort_up";
    },
    getSortLiClassName: function(activeElement) {
      var itemIcon;
      itemIcon = "scrivito_menu_item";
      if (this.props.filter.sortCriteria.activeElement() === activeElement) {
        itemIcon += " active";
      }
      return itemIcon;
    },
    _getAscSortLiClassName: function() {
      return this.getSortLiClassName(this.currentSortItem().ascCriteriaTitle);
    },
    _getDescSortLiClassName: function() {
      return this.getSortLiClassName(this.currentSortItem().descCriteriaTitle);
    },
    currentSortItem: function() {
      return this.props.sortItem;
    },
    _changeSortCriteria: function(reverse, activeItemElement) {
      var sortCriteria;
      sortCriteria = new models.SortCriteria(this.currentSortItem().sortItemType, reverse, activeItemElement, this.currentSortItem().itemTitle);
      return this.props.filter.setSortCriteria(sortCriteria);
    },
    _sortInAscOrder: function() {
      return this._changeSortCriteria(false, this.currentSortItem().ascCriteriaTitle);
    },
    _sortInDescOrder: function() {
      return this._changeSortCriteria(true, this.currentSortItem().descCriteriaTitle);
    },
    render: function() {
      return React.createElement("div", null, React.createElement("li", {
        "className": "scrivito_menu_separator"
      }, React.createElement("span", null, (this.currentSortItem().itemTitle))), React.createElement("li", {
        "className": this._getDescSortLiClassName(),
        "onClick": this._sortInDescOrder
      }, React.createElement("span", null, React.createElement("i", {
        "className": this._descIconSortClass()
      }, " "), (this.currentSortItem().descCriteriaTitle))), React.createElement("li", {
        "className": this._getAscSortLiClassName(),
        "onClick": this._sortInAscOrder
      }, React.createElement("span", null, React.createElement("i", {
        "className": this._ascIconSortClass()
      }, " "), (this.currentSortItem().ascCriteriaTitle))));
    }
  });

  ui.TableView = React.createClass({
    render: function() {
      return React.createElement("div", {
        "className": "scrivito-content-browser-list"
      }, React.createElement("div", {
        "className": "scrivito-content-browser-list-head"
      }, React.createElement("table", null, React.createElement("tbody", null, React.createElement("tr", null, React.createElement("th", null), React.createElement("th", null, "Title"), React.createElement("th", null, "Type"), React.createElement("th", null, "File type"), React.createElement("th", null, "File size"), React.createElement("th", null, "Last change"))))), React.createElement(ui.TableViewContent, React.__spread({}, this.props)));
    }
  });

  ui.TableViewAddItem = React.createClass({
    mixins: [AddItemMixin],
    render: function() {
      return React.createElement("tr", {
        "onClick": this.createClick
      }, React.createElement("td", {
        "colSpan": "6"
      }, React.createElement("div", {
        "className": this.itemClassName()
      }, React.createElement("div", {
        "className": "scrivito-content-browser-text"
      }, React.createElement("span", {
        "className": this.iconClassName(),
        "title": this.iconTitle()
      }), React.createElement("span", null, this.textMessage())))));
    }
  });

  ui.TableViewContent = React.createClass({
    mixins: [InfiniteScrollMixin],
    getTableViewItems: function() {
      var items;
      return items = _.map(this.props.objCollection.objs(), (function(_this) {
        return function(obj) {
          return React.createElement(ui.TableViewItem, {
            "key": obj.id(),
            "obj": obj,
            "objCollection": _this.props.objCollection,
            "inspector": _this.props.inspector
          });
        };
      })(this));
    },
    getElementDOMNode: function() {
      return this.getDOMNode();
    },
    objCreation: function() {
      return new models.ObjCreation(this.props.filter);
    },
    render: function() {
      return React.createElement("div", {
        "className": "scrivito-content-browser-list-content"
      }, React.createElement("table", null, React.createElement("tbody", null, (this.objCreation().showCreationItem() ? React.createElement(ui.TableViewAddItem, {
        "objCreation": this.objCreation(),
        "addedObjsCollection": this.props.addedObjsCollection
      }) : void 0), this.getTableViewItems())));
    }
  });

  ui.TableViewItem = React.createClass({
    displayName: 'TableViewItem',
    mixins: [InspectedItemMixin],
    baseSelectClass: function() {
      return 'scrivito-content-browser-list-select';
    },
    getLastChangedFormatedDate: function() {
      var result;
      if (this.props.obj.lastChanged() !== void 0) {
        result = moment(this.props.obj.lastChanged()).utcOffset(this.props.obj.lastChanged());
        return result.format("dddd, MMMM Do YYYY, h:mm A");
      }
    },
    _getFileTypeTitleTag: function() {
      var mimeType;
      mimeType = this.props.obj.mimeType();
      if (mimeType != null) {
        return mimeType.match(/\w+$/)[0];
      }
    },
    render: function() {
      return React.createElement("tr", {
        "onClick": this.changeInspectObj,
        "className": this.getItemClasses()
      }, React.createElement("td", null, React.createElement("div", {
        "onClick": this.handleSelectClick,
        "className": this.selectClass()
      })), React.createElement("td", {
        "title": this.props.obj.title()
      }, this.props.obj.title()), React.createElement("td", null, this.props.obj.fileType()), React.createElement("td", {
        "title": this.props.obj.mimeType()
      }, this._getFileTypeTitleTag()), React.createElement("td", null, this.props.obj.fileSize()), React.createElement("td", null, React.createElement("span", null, React.createElement("time", {
        "dateTime": this.props.obj.lastChanged(),
        "title": this.getLastChangedFormatedDate()
      }, moment.utc(this.props.obj.lastChanged()).fromNow()))));
    }
  });

  ui.ThumbnailAddItem = React.createClass({
    displayName: 'ThumbnailAddItem',
    mixins: [AddItemMixin],
    render: function() {
      return React.createElement("li", {
        "className": "content-browser-item",
        "onClick": this.createClick
      }, React.createElement("div", {
        "className": this.itemClassName()
      }, React.createElement("div", {
        "className": "scrivito-content-browser-text"
      }, React.createElement("span", {
        "className": this.iconClassName(),
        "title": this.iconTitle()
      }), React.createElement("span", null, this.textMessage()))));
    }
  });

  ui.ThumbnailItem = React.createClass({
    displayName: 'ThumbnailItem',
    mixins: [InspectedItemMixin],
    itemToolTip: function() {
      var itemToolTip;
      itemToolTip = this.props.obj.title();
      if (this.props.obj.subtitle() != null) {
        itemToolTip += "\n" + (this.props.obj.subtitle());
      }
      return itemToolTip;
    },
    baseSelectClass: function() {
      return 'scrivito-content-browser-meta ';
    },
    mimeTypeIconClassName: function() {
      var className;
      className = 'scrivito_icon ';
      className += models.MimeTypeIcon.getMimeTypeIconClassName(this.props.obj.mimeType());
      return className;
    },
    previewImage: function() {
      if (this.props.obj.hasPreview()) {
        return React.createElement("img", {
          "src": this.props.obj.previewUrl()
        });
      } else {
        return React.createElement("span", {
          "className": this.mimeTypeIconClassName()
        });
      }
    },
    render: function() {
      return React.createElement("li", {
        "className": this.getItemClasses()
      }, React.createElement("div", {
        "className": "scrivito-content-browser-item-wrapper"
      }, React.createElement("div", {
        "className": "scrivito-content-browser-preview",
        "onClick": this.changeInspectObj
      }, this.previewImage(), React.createElement("span", {
        "className": "scrivito-content-browser-inspect"
      })), React.createElement("div", {
        "className": this.selectClass(),
        "onClick": this.handleSelectClick,
        "title": this.itemToolTip()
      }, React.createElement("span", {
        "className": "scrivito-content-browser-thumbnails-name"
      }, this.props.obj.title()), React.createElement("span", {
        "className": "scrivito-content-browser-thumbnails-size"
      }, this.props.obj.subtitle()), (!this.props.objCollection.isSingleSelectionMode() ? React.createElement("span", {
        "className": 'scrivito-content-browser-thumbnails-select select-item'
      }) : void 0))));
    }
  });

  ui.ThumbnailItems = React.createClass({
    displayName: 'ThumbnailItems',
    mixins: [InfiniteScrollMixin],
    getElementDOMNode: function() {
      return this.getDOMNode().parentElement;
    },
    getSizeClassName: function() {
      return "items scrivito-content-browser-thumbnails small";
    },
    activeFilterNodes: function() {
      var collector;
      collector = new models.ActiveNodeConfigCollector(this.props.filter);
      return collector.findActiveFilterItems();
    },
    objCreation: function() {
      return new models.ObjCreation(this.props.filter);
    },
    buildItems: function() {
      return _.map(this.props.objCollection.objs(), (function(_this) {
        return function(obj) {
          return React.createElement(ui.ThumbnailItem, {
            "key": obj.id(),
            "obj": obj,
            "objCollection": _this.props.objCollection,
            "inspector": _this.props.inspector
          });
        };
      })(this));
    },
    render: function() {
      return React.createElement("ul", {
        "className": this.getSizeClassName()
      }, (this.objCreation().showCreationItem() ? React.createElement(ui.ThumbnailAddItem, {
        "objCreation": this.objCreation(),
        "addedObjsCollection": this.props.addedObjsCollection
      }) : void 0), this.buildItems());
    }
  });

  ui.TopBar = React.createClass({
    displayName: 'TopBar',
    setSearchTerm: function() {
      return this.props.filter.setSearchTerm(this.state.searchTerm);
    },
    getInitialState: function() {
      return {
        searchTerm: this.props.filter.searchTerm
      };
    },
    triggerSearchWithEnter: function(event) {
      if (event.keyCode === 13) {
        return this.setSearchTerm();
      }
    },
    _getSearchPlaceholder: function() {
      var activeCriteriaTitle, activeFilters, actvieFilterNodeConfigs, collector, searchPlaceHolder;
      collector = new models.ActiveNodeConfigCollector(this.props.filter);
      searchPlaceHolder = "Search everywhere";
      actvieFilterNodeConfigs = collector.findActiveFilterItems();
      activeFilters = _.flatten(_.map(actvieFilterNodeConfigs, function(config) {
        return config.activeNodes();
      }));
      if (activeFilters.length > 1) {
        searchPlaceHolder = "Search filtered content";
      } else if (activeFilters.length === 1) {
        activeCriteriaTitle = activeFilters[0].title;
        searchPlaceHolder = "Search \"" + activeCriteriaTitle + "\" ";
      }
      return searchPlaceHolder;
    },
    updateSearchTerm: function(event) {
      return this.setState({
        searchTerm: event.target.value
      });
    },
    render: function() {
      return React.createElement("div", {
        "className": "scrivito-content-browser-topbar"
      }, React.createElement("div", {
        "className": "scrivito-content-browser-search"
      }, React.createElement("input", {
        "type": "text",
        "placeholder": this._getSearchPlaceholder(),
        "className": "search-field",
        "value": this.state.searchTerm,
        "onChange": this.updateSearchTerm,
        "onKeyUp": this.triggerSearchWithEnter
      }), React.createElement("button", {
        "className": "search-field-button",
        "onClick": this.setSearchTerm
      }, "Search")), React.createElement(ui.ViewModeBar, {
        "viewMode": this.props.viewMode
      }), React.createElement(ui.SortMenu, {
        "filter": this.props.filter
      }));
    }
  });

  ui.UploadItem = React.createClass({
    displayName: 'UploadItem',
    progressWidth: function() {
      return {
        width: "" + (this.props.objUpload.progress()) + "%"
      };
    },
    failureMessage: function() {
      return this.props.objUpload.failureMessage() || "Upload failed. Please check your network connection.";
    },
    failureContent: function() {
      if (this.props.objUpload.status() === 'failed') {
        return React.createElement("p", {
          "className": "scrivito-content-browser-error"
        }, this.failureMessage());
      }
    },
    render: function() {
      return React.createElement("div", {
        "className": "scrivito-content-browser-progress-file"
      }, React.createElement("p", null, this.props.objUpload.fileName()), this.failureContent(), React.createElement("div", {
        "className": "scrivito-content-browser-progress"
      }, React.createElement("div", {
        "className": "scrivito-content-browser-progress-bar",
        "style": this.progressWidth()
      })));
    }
  });

  ui.UploadItems = React.createClass({
    displayName: 'UploadItems',
    render: function() {
      var items;
      items = _.map(this.props.addedObjsCollection.objs(), function(objUpload) {
        return React.createElement(ui.UploadItem, {
          "objUpload": objUpload
        });
      });
      return React.createElement("div", {
        "className": "scrivito-content-browser-progress-wrapper"
      }, items);
    }
  });

  ui.ViewModeBar = React.createClass({
    displayName: 'ViewModeBar',
    viewModeButtonsData: ["list", "thumbnails"],
    render: function() {
      var mode;
      return React.createElement("div", null, (function() {
        var _i, _len, _ref, _results;
        _ref = this.viewModeButtonsData;
        _results = [];
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          mode = _ref[_i];
          _results.push(React.createElement(ui.ViewModeBarItem, {
            "viewMode": this.props.viewMode,
            "mode": mode
          }));
        }
        return _results;
      }).call(this));
    }
  });

  ui.ViewModeBarItem = React.createClass({
    displayName: 'ViewModeBarItem',
    viewModeButtonsData: {
      "thumbnails": {
        iconTitle: "Thumbnails",
        iconClassName: "scrivito_icon_th_small"
      },
      "list": {
        iconTitle: "List",
        iconClassName: "scrivito_icon_list_medium"
      }
    },
    getIconClassName: function(mode) {
      return "scrivito_icon " + this.viewModeButtonsData[mode].iconClassName;
    },
    getIconTitle: function(mode) {
      return this.viewModeButtonsData[mode].iconTitle;
    },
    getLabelClasses: function() {
      return classSet({
        'active': this.props.viewMode.getMode() === this.props.mode,
        "editing-button-view": true
      });
    },
    changeViewMode: function() {
      return this.props.viewMode.setMode(this.props.mode);
    },
    render: function() {
      return React.createElement("span", {
        "data-size": this.props.mode,
        "className": this.getLabelClasses(),
        "onClick": this.changeViewMode
      }, React.createElement("i", {
        "title": this.getIconTitle(this.props.mode),
        "className": this.getIconClassName(this.props.mode)
      }));
    }
  });

  scrivito.content_browser.stub_filters = {
    categories: {
      type: 'tree',
      options: {
        all_generics: {
          title: 'Generics',
          query: scrivito.obj_where('_obj_class', 'equals', 'Generic'),
          icon: 'pdf',
          options: {
            reports: {
              title: 'Reports',
              query: 'empty'
            },
            datasheets: {
              title: 'Datasheets',
              query: 'empty'
            }
          }
        }
      }
    }
  };

}).call(this);