(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(['exports'], factory);
  } else if (typeof exports !== "undefined") {
    factory(exports);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod.exports);
    global.token = mod.exports;
  }
})(this, function (exports) {
  'use strict';

  Object.defineProperty(exports, "__esModule", {
    value: true
  });

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

  var Token = function () {
    /**
     * Create a Token instance.
     * @param {number} type The lexical type of the Token.
     * @param {number} start The start index of the text corresponding to the
     * Token in the CSS text.
     * @param {number} end The end index of the text corresponding to the Token
     * in the CSS text.
     */

    function Token(type, start, end) {
      _classCallCheck(this, Token);

      this.type = type;
      this.start = start;
      this.end = end;
      this.previous = null;
      this.next = null;
    }

    /**
     * Test if the Token matches a given numeric type. Types match if the bitwise
     * AND of the Token's type and the argument type are equivalent to the
     * argument type.
     * @param {number} type The numeric type to test for equivalency with the
     * Token.
     */


    Token.prototype.is = function is(type) {
      return (this.type & type) === type;
    };

    return Token;
  }();

  /**
   * An enumeration of Token types.
   * @type {object}
   * @default
   * @static
   */
  Token.type = {
    none: 0,
    whitespace: 1,
    string: 2,
    comment: 4,
    word: 8,
    boundary: 16,
    propertyBoundary: 32,
    // Special cases for boundary:
    openParenthesis: 64 | 16,
    closeParenthesis: 128 | 16,
    at: 256 | 16,
    openBrace: 512 | 16,
    // [};] are property boundaries:
    closeBrace: 1024 | 32 | 16,
    semicolon: 2048 | 32 | 16,
    // : is a chimaeric abomination:
    // foo:bar{}
    // foo:bar;
    colon: 4096 | 16 | 8
  };

  /**
   * A mapping of boundary token text to their corresponding types.
   * @type {object}
   * @default
   * @const
   */
  var boundaryTokenTypes = {
    '(': Token.type.openParenthesis,
    ')': Token.type.closeParenthesis,
    ':': Token.type.colon,
    '@': Token.type.at,
    '{': Token.type.openBrace,
    '}': Token.type.closeBrace,
    ';': Token.type.semicolon,
    '-': Token.type.hyphen,
    '_': Token.type.underscore
  };

  exports.Token = Token;
  exports.boundaryTokenTypes = boundaryTokenTypes;
});