function parse(value, root, parent, rule, rules, rulesets, pseudo, points, declarations) {
  var index = 0;
  var offset = 0;
  var length = pseudo;
  var atrule = 0;
  var property = 0;
  var previous = 0;
  var variable = 1;
  var scanning = 1;
  var ampersand = 1;
  var character = 0;
  var type = '';
  var props = rules;
  var children = rulesets;
  var reference = rule;
  var characters = type;

  while (scanning) {
    switch (previous = character, character = next()) {
      // (
      case 40:
        if (previous != 108 && characters.charCodeAt(length - 1) == 58) {
          if (indexof(characters += replace(delimit(character), '&', '&\f'), '&\f') != -1) ampersand = -1;
          break;
        }

      // " ' [

      case 34:
      case 39:
      case 91:
        characters += delimit(character);
        break;
      // \t \n \r \s

      case 9:
      case 10:
      case 13:
      case 32:
        characters += whitespace(previous);
        break;
      // \

      case 92:
        characters += escaping(caret() - 1, 7);
        continue;
      // /

      case 47:
        switch (peek()) {
          case 42:
          case 47:
            append(comment(commenter(next(), caret()), root, parent), declarations);
            break;

          default:
            characters += '/';
        }

        break;
      // {

      case 123 * variable:
        points[index++] = strlen(characters) * ampersand;
      // } ; \0

      case 125 * variable:
      case 59:
      case 0:
        switch (character) {
          // \0 }
          case 0:
          case 125:
            scanning = 0;
          // ;

          case 59 + offset:
            if (property > 0 && strlen(characters) - length) append(property > 32 ? declaration(characters + ';', rule, parent, length - 1) : declaration(replace(characters, ' ', '') + ';', rule, parent, length - 2), declarations);
            break;
          // @ ;

          case 59:
            characters += ';';
          // { rule/at-rule

          default:
            append(reference = ruleset(characters, root, parent, index, offset, rules, points, type, props = [], children = [], length), rulesets);
            if (character === 123) if (offset === 0) parse(characters, root, reference, reference, props, rulesets, length, points, children);else switch (atrule) {
              // d m s
              case 100:
              case 109:
              case 115:
                parse(value, reference, reference, rule && append(ruleset(value, reference, reference, 0, 0, rules, points, type, rules, props = [], length), children), rules, children, length, points, rule ? props : children);
                break;

              default:
                parse(characters, reference, reference, reference, [''], children, 0, points, children);
            }
        }

        index = offset = property = 0, variable = ampersand = 1, type = characters = '', length = pseudo;
        break;
      // :

      case 58:
        length = 1 + strlen(characters), property = previous;

      default:
        if (variable < 1) if (character == 123) --variable;else if (character == 125 && variable++ == 0 && prev() == 125) continue;

        switch (characters += from(character), character * variable) {
          // &
          case 38:
            ampersand = offset > 0 ? 1 : (characters += '\f', -1);
            break;
          // ,

          case 44:
            points[index++] = (strlen(characters) - 1) * ampersand, ampersand = 1;
            break;
          // @

          case 64:
            // -
            if (peek() === 45) characters += delimit(next());
            atrule = peek(), offset = length = strlen(type = characters += identifier(caret())), character++;
            break;
          // -

          case 45:
            if (previous === 45 && strlen(characters) == 2) variable = 0;
        }

    }
  }

  return rulesets;
}
@param {string} value
@param {object} root
@param {object?} parent
@param {string[]} rule
@param {string[]} rules
@param {string[]} rulesets
@param {number[]} pseudo
@param {number[]} points
@param {string[]} declarations
@return {object}