text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  
  var _isPlainObject = require('is-plain-object');
  
  var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
  
  var _immutable = require('immutable');
  
  var _modelTypes = require('../constants/model-types');
  
  var _modelTypes2 = _interopRequireDefault(_modelTypes);
  
  var _data = require('./data');
  
  var _data2 = _interopRequireDefault(_data);
  
  var _memoize = require('../utils/memoize');
  
  var _memoize2 = _interopRequireDefault(_memoize);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  
  /**
   * Default properties.
   *
   * @type {Object}
   */
  
  var DEFAULTS = {
    data: new _immutable.Map(),
    type: undefined
  };
  
  /**
   * Mark.
   *
   * @type {Mark}
   */
  
  var Mark = function (_Record) {
    _inherits(Mark, _Record);
  
    function Mark() {
      _classCallCheck(this, Mark);
  
      return _possibleConstructorReturn(this, (Mark.__proto__ || Object.getPrototypeOf(Mark)).apply(this, arguments));
    }
  
    _createClass(Mark, [{
      key: 'getComponent',
  
  
      /**
       * Get the component for the node from a `schema`.
       *
       * @param {Schema} schema
       * @return {Component|Void}
       */
  
      value: function getComponent(schema) {
        return schema.__getComponent(this);
      }
  
      /**
       * Return a JSON representation of the mark.
       *
       * @return {Object}
       */
  
    }, {
      key: 'toJSON',
      value: function toJSON() {
        var object = {
          kind: this.kind,
          type: this.type,
          data: this.data.toJSON()
        };
  
        return object;
      }
  
      /**
       * Alias `toJS`.
       */
  
    }, {
      key: 'toJS',
      value: function toJS() {
        return this.toJSON();
      }
    }, {
      key: 'kind',
  
  
      /**
       * Get the kind.
       */
  
      get: function get() {
        return 'mark';
      }
    }], [{
      key: 'create',
  
  
      /**
       * Create a new `Mark` with `attrs`.
       *
       * @param {Object|Mark} attrs
       * @return {Mark}
       */
  
      value: function create() {
        var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  
        if (Mark.isMark(attrs)) {
          return attrs;
        }
  
        if (typeof attrs == 'string') {
          attrs = { type: attrs };
        }
  
        if ((0, _isPlainObject2.default)(attrs)) {
          return Mark.fromJSON(attrs);
        }
  
        throw new Error('`Mark.create` only accepts objects, strings or marks, but you passed it: ' + attrs);
      }
  
      /**
       * Create a set of marks.
       *
       * @param {Array<Object|Mark>} elements
       * @return {Set<Mark>}
       */
  
    }, {
      key: 'createSet',
      value: function createSet(elements) {
        if (_immutable.Set.isSet(elements) || Array.isArray(elements)) {
          var marks = new _immutable.Set(elements.map(Mark.create));
          return marks;
        }
  
        if (elements == null) {
          return new _immutable.Set();
        }
  
        throw new Error('`Mark.createSet` only accepts sets, arrays or null, but you passed it: ' + elements);
      }
  
      /**
       * Create a dictionary of settable mark properties from `attrs`.
       *
       * @param {Object|String|Mark} attrs
       * @return {Object}
       */
  
    }, {
      key: 'createProperties',
      value: function createProperties() {
        var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  
        if (Mark.isMark(attrs)) {
          return {
            data: attrs.data,
            type: attrs.type
          };
        }
  
        if (typeof attrs == 'string') {
          return { type: attrs };
        }
  
        if ((0, _isPlainObject2.default)(attrs)) {
          var props = {};
          if ('type' in attrs) props.type = attrs.type;
          if ('data' in attrs) props.data = _data2.default.create(attrs.data);
          return props;
        }
  
        throw new Error('`Mark.createProperties` only accepts objects, strings or marks, but you passed it: ' + attrs);
      }
  
      /**
       * Create a `Mark` from a JSON `object`.
       *
       * @param {Object} object
       * @return {Mark}
       */
  
    }, {
      key: 'fromJSON',
      value: function fromJSON(object) {
        var _object$data = object.data,
            data = _object$data === undefined ? {} : _object$data,
            type = object.type;
  
  
        if (typeof type != 'string') {
          throw new Error('`Mark.fromJS` requires a `type` string.');
        }
  
        var mark = new Mark({
          type: type,
          data: new _immutable.Map(data)
        });
  
        return mark;
      }
  
      /**
       * Alias `fromJS`.
       */
  
    }, {
      key: 'isMark',
  
  
      /**
       * Check if `any` is a `Mark`.
       *
       * @param {Any} any
       * @return {Boolean}
       */
  
      value: function isMark(any) {
        return !!(any && any[_modelTypes2.default.MARK]);
      }
  
      /**
       * Check if `any` is a set of marks.
       *
       * @param {Any} any
       * @return {Boolean}
       */
  
    }, {
      key: 'isMarkSet',
      value: function isMarkSet(any) {
        return _immutable.Set.isSet(any) && any.every(function (item) {
          return Mark.isMark(item);
        });
      }
    }]);
  
    return Mark;
  }((0, _immutable.Record)(DEFAULTS));
  
  /**
   * Attach a pseudo-symbol for type checking.
   */
  
  Mark.fromJS = Mark.fromJSON;
  Mark.prototype[_modelTypes2.default.MARK] = true;
  
  /**
   * Memoize read methods.
   */
  
  (0, _memoize2.default)(Mark.prototype, ['getComponent'], {
    takesArguments: true
  });
  
  /**
   * Export.
   *
   * @type {Mark}
   */
  
  exports.default = Mark;