code:
'use strict'

let Declaration = require('./declaration')
let tokenizer = require('./tokenize')
let Comment = require('./comment')
let AtRule = require('./at-rule')
let Root = require('./root')
let Rule = require('./rule')

const SAFE_COMMENT_NEIGHBOR = {
  empty: true,
  space: true
}

function findLastWithPosition(tokens) {
  for (let i = tokens.length - 1; i >= 0; i--) {
    let token = tokens[i]
    let pos = token[3] || token[2]
    if (pos) return pos
  }
}

class Parser {
  constructor(input) {
    this.input = input

    this.root = new Root()
    this.current = this.root
    this.spaces = ''
    this.semicolon = false

    this.createTokenizer()
    this.root.source = { input, start: { column: 1, line: 1, offset: 0 } }
  }

  atrule(token) {
    let node = new AtRule()
    node.name = token[1].slice(1)
    if (node.name === '') {
      this.unnamedAtrule(node, token)
    }
    this.init(node, token[2])

    let type
    let prev
    let shift
    let last = false
    let open = false
    let params = []
    let brackets = []

    while (!this.tokenizer.endOfFile()) {
      token = this.tokenizer.nextToken()
      type = token[0]

      if (type === '(' || type === '[') {
        brackets.push(type === '(' ? ')' : ']')
      } else if (type === '{' && brackets.length > 0) {
        brackets.push('}')
      } else if (type === brackets[brackets.length - 1]) {
        brackets.pop()
      }

      if (brackets.length === 0) {
        if (type === ';') {
          node.source.end = this.getPosition(token[2])
          node.source.end.offset++
          this.semicolon = true
          break
        } else if (type === '{') {
          open = true
          break
        } else if (type === '}') {
          if (params.length > 0) {
            shift = params.length - 1
            prev = params[shift]
            while (prev && prev[0] === 'space') {
              prev = params[--shift]
            }
            if (prev) {
              node.source.end = this.getPosition(prev[3] || prev[2])
              node.source.end.offset++
            }
          }
          this.end(token)
          break
        } else {
          params.push(token)
        }
      } else {
        params.push(token)
      }

      if (this.tokenizer.endOfFile()) {
        last = true
        break
      }
    }

    node.raws.between = this.spacesAndCommentsFromEnd(params)
    if (params.length) {
      node.raws.afterName = this.spacesAndCommentsFromStart(params)
      this.raw(node, 'params', params)
      if (last) {
        token = params[params.length - 1]
        node.source.end = this.getPosition(token[3] || token[2])
        node.source.end.offset++
        this.spaces = node.raws.between
        node.raws.between = ''
      }
    } else {
      node.raws.afterName = ''
      node.params = ''
    }

    if (open) {
      node.nodes = []
      this.current = node
    }
  }

  checkMissedSemicolon(tokens) {
    let colon = this.colon(tokens)
    if (colon === false) return

    let founded = 0
    let token
    for (let j = colon - 1; j >= 0; j--) {
      token = tokens[j]
      if (token[0] !== 'space') {
        founded += 1
        if (founded === 2) break
      }
    }
    // If the token is a word, e.g. `!important`, `red` or any other valid property's value.
    // Then we need to return the colon after that word token. [3] is the "end" colon of that word.
    // And because we need it after that one we do +1 to get the next one.
    throw this.input.error(
      'Missed semicolon',
      token[0] === 'word' ? token[3] + 1 : token[2]
    )
  }

  colon(tokens) {
    let brackets = 0
    let token, type, prev
    for (let [i, element] of tokens.entries()) {
      token = element
      type = token[0]

      if (type === '(') {
        brackets += 1
      }
      if (type === ')') {
        brackets -= 1
      }
      if (brackets === 0 && type === ':') {
        if (!prev) {
          this.doubleColon(token)
        } else if (prev[0] === 'word' && prev[1] === 'progid') {
          continue
        } else {
          return i
        }
      }

      prev = token
    }
    return false
  }

  comment(token) {
    let node = new Comment()
    this.init(node, token[2])
    node.source.end = this.getPosition(token[3] || token[2])
    node.source.end.offset++

    let text = token[1].slice(2, -2)
    if (/^\s*$/.test(text)) {
      node.text = ''
      node.raws.left = text
      node.raws.right = ''
    } else {
      let match = text.match(/^(\s*)([^]*\S)(\s*)$/)
      node.text = match[2]
      node.raws.left = match[1]
      node.raws.right = match[3]
    }
  }

  createTokenizer() {
    this.tokenizer = tokenizer(this.input)
  }

  decl(tokens, customProperty) {
    let node = new Declaration()
    this.init(node, tokens[0][2])

    let last = tokens[tokens.length - 1]
    if (last[0] === ';') {
      this.semicolon = true
      tokens.pop()
    }

    node.source.end = this.getPosition(
      last[3] || last[2] || findLastWithPosition(tokens)
    )
    node.source.end.offset++

    while (tokens[0][0] !== 'word') {
      if (tokens.length === 1) this.unknownWord(tokens)
      node.raws.before += tokens.shift()[1]
    }
    node.source.start = this.getPosition(tokens[0][2])

    node.prop = ''
    while (tokens.length) {
      let type = tokens[0][0]
      if (type === ':' || type === 'space' || type === 'comment') {
        break
      }
      node.prop += tokens.shift()[1]
    }

    node.raws.between = ''

    let token
    while (tokens.length) {
      token = tokens.shift()

      if (token[0] === ':') {
        node.raws.between += token[1]
        break
      } else {
        if (token[0] === 'word' && /\w/.test(token[1])) {
          this.unknownWord([token])
        }
        node.raws.between += token[1]
      }
    }

    if (node.prop[0] === '_' || node.prop[0] === '*') {
      node.raws.before += node.prop[0]
      node.prop = node.prop.slice(1)
    }

    let firstSpaces = []
    let next
    while (tokens.length) {
      next = tokens[0][0]
      if (next !== 'space' && next !== 'comment') break
      firstSpaces.push(tokens.shift())
    }

    this.precheckMissedSemicolon(tokens)

    for (let i = tokens.length - 1; i >= 0; i--) {
      token = tokens[i]
      if (token[1].toLowerCase() === '!important') {
        node.important = true
        let string = this.stringFrom(tokens, i)
        string = this.spacesFromEnd(tokens) + string
        if (string !== ' !important') node.raws.important = string
        break
      } else if (token[1].toLowerCase() === 'important') {
        let cache = tokens.slice(0)
        let str = ''
        for (let j = i; j > 0; j--) {
          let type = cache[j][0]
          if (str.trim().indexOf('!') === 0 && type !== 'space') {
            break
          }
          str = cache.pop()[1] + str
        }
        if (str.trim().indexOf('!') === 0) {
          node.important = true
          node.raws.important = str
          tokens = cache
        }
      }

      if (token[0] !== 'space' && token[0] !== 'comment') {
        break
      }
    }

    let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment')

    if (hasWord) {
      node.raws.between += firstSpaces.map(i => i[1]).join('')
      firstSpaces = []
    }
    this.raw(node, 'value', firstSpaces.concat(tokens), customProperty)

    if (node.value.includes(':') && !customProperty) {
      this.checkMissedSemicolon(tokens)
    }
  }

  doubleColon(token) {
    throw this.input.error(
      'Double colon',
      { offset: token[2] },
      { offset: token[2] + token[1].length }
    )
  }

  emptyRule(token) {
    let node = new Rule()
    this.init(node, token[2])
    node.selector = ''
    node.raws.between = ''
    this.current = node
  }

  end(token) {
    if (this.current.nodes && this.current.nodes.length) {
      this.current.raws.semicolon = this.semicolon
    }
    this.semicolon = false

    this.current.raws.after = (this.current.raws.after || '') + this.spaces
    this.spaces = ''

    if (this.current.parent) {
      this.current.source.end = this.getPosition(token[2])
      this.current.source.end.offset++
      this.current = this.current.parent
    } else {
      this.unexpectedClose(token)
    }
  }

  endFile() {
    if (this.current.parent) this.unclosedBlock()
    if (this.current.nodes && this.current.nodes.length) {
      this.current.raws.semicolon = this.semicolon
    }
    this.current.raws.after = (this.current.raws.after || '') + this.spaces
    this.root.source.end = this.getPosition(this.tokenizer.position())
  }

  freeSemicolon(token) {
    this.spaces += token[1]
    if (this.current.nodes) {
      let prev = this.current.nodes[this.current.nodes.length - 1]
      if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) {
        prev.raws.ownSemicolon = this.spaces
        this.spaces = ''
      }
    }
  }

  // Helpers

  getPosition(offset) {
    let pos = this.input.fromOffset(offset)
    return {
      column: pos.col,
      line: pos.line,
      offset
    }
  }

  init(node, offset) {
    this.current.push(node)
    node.source = {
      input: this.input,
      start: this.getPosition(offset)
    }
    node.raws.before = this.spaces
    this.spaces = ''
    if (node.type !== 'comment') this.semicolon = false
  }

  other(start) {
    let end = false
    let type = null
    let colon = false
    let bracket = null
    let brackets = []
    let customProperty = start[1].startsWith('--')

    let tokens = []
    let token = start
    while (token) {
      type = token[0]
      tokens.push(token)

      if (type === '(' || type === '[') {
        if (!bracket) bracket = token
        brackets.push(type === '(' ? ')' : ']')
      } else if (customProperty && colon && type === '{') {
        if (!bracket) bracket = token
        brackets.push('}')
      } else if (brackets.length === 0) {
        if (type === ';') {
          if (colon) {
            this.decl(tokens, customProperty)
            return
          } else {
            break
          }
        } else if (type === '{') {
          this.rule(tokens)
          return
        } else if (type === '}') {
          this.tokenizer.back(tokens.pop())
          end = true
          break
        } else if (type === ':') {
          colon = true
        }
      } else if (type === brackets[brackets.length - 1]) {
        brackets.pop()
        if (brackets.length === 0) bracket = null
      }

      token = this.tokenizer.nextToken()
    }

    if (this.tokenizer.endOfFile()) end = true
    if (brackets.length > 0) this.unclosedBracket(bracket)

    if (end && colon) {
      if (!customProperty) {
        while (tokens.length) {
          token = tokens[tokens.length - 1][0]
          if (token !== 'space' && token !== 'comment') break
          this.tokenizer.back(tokens.pop())
        }
      }
      this.decl(tokens, customProperty)
    } else {
      this.unknownWord(tokens)
    }
  }

  parse() {
    let token
    while (!this.tokenizer.endOfFile()) {
      token = this.tokenizer.nextToken()

      switch (token[0]) {
        case 'space':
          this.spaces += token[1]
          break

        case ';':
          this.freeSemicolon(token)
          break

        case '}':
          this.end(token)
          break

        case 'comment':
          this.comment(token)
          break

        case 'at-word':
          this.atrule(token)
          break

        case '{':
          this.emptyRule(token)
          break

        default:
          this.other(token)
          break
      }
    }
    this.endFile()
  }

  precheckMissedSemicolon(/* tokens */) {
    // Hook for Safe Parser
  }

  raw(node, prop, tokens, customProperty) {
    let token, type
    let length = tokens.length
    let value = ''
    let clean = true
    let next, prev

    for (let i = 0; i < length; i += 1) {
      token = tokens[i]
      type = token[0]
      if (type === 'space' && i === length - 1 && !customProperty) {
        clean = false
      } else if (type === 'comment') {
        prev = tokens[i - 1] ? tokens[i - 1][0] : 'empty'
        next = tokens[i + 1] ? tokens[i + 1][0] : 'empty'
        if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) {
          if (value.slice(-1) === ',') {
            clean = false
          } else {
            value += token[1]
          }
        } else {
          clean = false
        }
      } else {
        value += token[1]
      }
    }
    if (!clean) {
      let raw = tokens.reduce((all, i) => all + i[1], '')
      node.raws[prop] = { raw, value }
    }
    node[prop] = value
  }

  rule(tokens) {
    tokens.pop()

    let node = new Rule()
    this.init(node, tokens[0][2])

    node.raws.between = this.spacesAndCommentsFromEnd(tokens)
    this.raw(node, 'selector', tokens)
    this.current = node
  }

  spacesAndCommentsFromEnd(tokens) {
    let lastTokenType
    let spaces = ''
    while (tokens.length) {
      lastTokenType = tokens[tokens.length - 1][0]
      if (lastTokenType !== 'space' && lastTokenType !== 'comment') break
      spaces = tokens.pop()[1] + spaces
    }
    return spaces
  }

  // Errors

  spacesAndCommentsFromStart(tokens) {
    let next
    let spaces = ''
    while (tokens.length) {
      next = tokens[0][0]
      if (next !== 'space' && next !== 'comment') break
      spaces += tokens.shift()[1]
    }
    return spaces
  }

  spacesFromEnd(tokens) {
    let lastTokenType
    let spaces = ''
    while (tokens.length) {
      lastTokenType = tokens[tokens.length - 1][0]
      if (lastTokenType !== 'space') break
      spaces = tokens.pop()[1] + spaces
    }
    return spaces
  }

  stringFrom(tokens, from) {
    let result = ''
    for (let i = from; i < tokens.length; i++) {
      result += tokens[i][1]
    }
    tokens.splice(from, tokens.length - from)
    return result
  }

  unclosedBlock() {
    let pos = this.current.source.start
    throw this.input.error('Unclosed block', pos.line, pos.column)
  }

  unclosedBracket(bracket) {
    throw this.input.error(
      'Unclosed bracket',
      { offset: bracket[2] },
      { offset: bracket[2] + 1 }
    )
  }

  unexpectedClose(token) {
    throw this.input.error(
      'Unexpected }',
      { offset: token[2] },
      { offset: token[2] + 1 }
    )
  }

  unknownWord(tokens) {
    throw this.input.error(
      'Unknown word',
      { offset: tokens[0][2] },
      { offset: tokens[0][2] + tokens[0][1].length }
    )
  }

  unnamedAtrule(node, token) {
    throw this.input.error(
      'At-rule without name',
      { offset: token[2] },
      { offset: token[2] + token[1].length }
    )
  }
}

module.exports = Parser


code:
export {
  // postcss function / namespace
  default,

  // Value exports from postcss.mjs
  stringify,
  fromJSON,
  // @ts-expect-error This value exists, but it’s untyped.
  plugin,
  parse,
  list,

  document,
  comment,
  atRule,
  rule,
  decl,
  root,

  CssSyntaxError,
  Declaration,
  Container,
  Processor,
  Document,
  Comment,
  Warning,
  AtRule,
  Result,
  Input,
  Rule,
  Root,
  Node,

  // Type-only exports
  AcceptedPlugin,
  AnyNode,
  AtRuleProps,
  Builder,
  ChildNode,
  ChildProps,
  CommentProps,
  ContainerProps,
  DeclarationProps,
  DocumentProps,
  FilePosition,
  Helpers,
  JSONHydrator,
  Message,
  NodeErrorOptions,
  NodeProps,
  OldPlugin,
  Parser,
  Plugin,
  PluginCreator,
  Position,
  Postcss,
  ProcessOptions,
  RootProps,
  RuleProps,
  Source,
  SourceMap,
  SourceMapOptions,
  Stringifier,
  Syntax,
  TransformCallback,
  Transformer,
  WarningOptions,

  // This is a class, but it’s not re-exported. That’s why it’s exported as type-only here.
  type LazyResult,

} from './postcss.js'

license: mit


code:
import { RawSourceMap, SourceMapGenerator } from 'source-map-js'

import AtRule, { AtRuleProps } from './at-rule.js'
import Comment, { CommentProps } from './comment.js'
import Container, { ContainerProps } from './container.js'
import CssSyntaxError from './css-syntax-error.js'
import Declaration, { DeclarationProps } from './declaration.js'
import Document, { DocumentProps } from './document.js'
import Input, { FilePosition } from './input.js'
import LazyResult from './lazy-result.js'
import list from './list.js'
import Node, {
  AnyNode,
  ChildNode,
  ChildProps,
  NodeErrorOptions,
  NodeProps,
  Position,
  Source
} from './node.js'
import Processor from './processor.js'
import Result, { Message } from './result.js'
import Root, { RootProps } from './root.js'
import Rule, { RuleProps } from './rule.js'
import Warning, { WarningOptions } from './warning.js'

type DocumentProcessor = (
  document: Document,
  helper: postcss.Helpers
) => Promise<void> | void
type RootProcessor = (root: Root, helper: postcss.Helpers) => Promise<void> | void
type DeclarationProcessor = (
  decl: Declaration,
  helper: postcss.Helpers
) => Promise<void> | void
type RuleProcessor = (rule: Rule, helper: postcss.Helpers) => Promise<void> | void
type AtRuleProcessor = (atRule: AtRule, helper: postcss.Helpers) => Promise<void> | void
type CommentProcessor = (
  comment: Comment,
  helper: postcss.Helpers
) => Promise<void> | void

interface Processors {
  /**
   * Will be called on all`AtRule` nodes.
   *
   * Will be called again on node or children changes.
   */
  AtRule?: { [name: string]: AtRuleProcessor } | AtRuleProcessor

  /**
   * Will be called on all `AtRule` nodes, when all children will be processed.
   *
   * Will be called again on node or children changes.
   */
  AtRuleExit?: { [name: string]: AtRuleProcessor } | AtRuleProcessor

  /**
   * Will be called on all `Comment` nodes.
   *
   * Will be called again on node or children changes.
   */
  Comment?: CommentProcessor

  /**
   * Will be called on all `Comment` nodes after listeners
   * for `Comment` event.
   *
   * Will be called again on node or children changes.
   */
  CommentExit?: CommentProcessor

  /**
   * Will be called on all `Declaration` nodes after listeners
   * for `Declaration` event.
   *
   * Will be called again on node or children changes.
   */
  Declaration?: { [prop: string]: DeclarationProcessor } | DeclarationProcessor

  /**
   * Will be called on all `Declaration` nodes.
   *
   * Will be called again on node or children changes.
   */
  DeclarationExit?:
    | { [prop: string]: DeclarationProcessor }
    | DeclarationProcessor

  /**
   * Will be called on `Document` node.
   *
   * Will be called again on children changes.
   */
  Document?: DocumentProcessor

  /**
   * Will be called on `Document` node, when all children will be processed.
   *
   * Will be called again on children changes.
   */
  DocumentExit?: DocumentProcessor

  /**
   * Will be called on `Root` node once.
   */
  Once?: RootProcessor

  /**
   * Will be called on `Root` node once, when all children will be processed.
   */
  OnceExit?: RootProcessor

  /**
   * Will be called on `Root` node.
   *
   * Will be called again on children changes.
   */
  Root?: RootProcessor

  /**
   * Will be called on `Root` node, when all children will be processed.
   *
   * Will be called again on children changes.
   */
  RootExit?: RootProcessor

  /**
   * Will be called on all `Rule` nodes.
   *
   * Will be called again on node or children changes.
   */
  Rule?: RuleProcessor

  /**
   * Will be called on all `Rule` nodes, when all children will be processed.
   *
   * Will be called again on node or children changes.
   */
  RuleExit?: RuleProcessor
}

declare namespace postcss {
  export {
    AnyNode,
    AtRule,
    AtRuleProps,
    ChildNode,
    ChildProps,
    Comment,
    CommentProps,
    Container,
    ContainerProps,
    CssSyntaxError,
    Declaration,
    DeclarationProps,
    Document,
    DocumentProps,
    FilePosition,
    Input,
    LazyResult,
    list,
    Message,
    Node,
    NodeErrorOptions,
    NodeProps,
    Position,
    Processor,
    Result,
    Root,
    RootProps,
    Rule,
    RuleProps,
    Source,
    Warning,
    WarningOptions
  }

  export type SourceMap = SourceMapGenerator & {
    toJSON(): RawSourceMap
  }

  export type Helpers = { postcss: Postcss; result: Result } & Postcss

  export interface Plugin extends Processors {
    postcssPlugin: string
    prepare?: (result: Result) => Processors
  }

  export interface PluginCreator<PluginOptions> {
    (opts?: PluginOptions): Plugin | Processor
    postcss: true
  }

  export interface Transformer extends TransformCallback {
    postcssPlugin: string
    postcssVersion: string
  }

  export interface TransformCallback {
    (root: Root, result: Result): Promise<void> | void
  }

  export interface OldPlugin<T> extends Transformer {
    (opts?: T): Transformer
    postcss: Transformer
  }

  export type AcceptedPlugin =
    | {
        postcss: Processor | TransformCallback
      }
    | OldPlugin<any>
    | Plugin
    | PluginCreator<any>
    | Processor
    | TransformCallback

  export interface Parser<RootNode = Document | Root> {
    (
      css: { toString(): string } | string,
      opts?: Pick<ProcessOptions, 'from' | 'map'>
    ): RootNode
  }

  export interface Builder {
    (part: string, node?: AnyNode, type?: 'end' | 'start'): void
  }

  export interface Stringifier {
    (node: AnyNode, builder: Builder): void
  }

  export interface JSONHydrator {
    (data: object): Node
    (data: object[]): Node[]
  }

  export interface Syntax<RootNode = Document | Root> {
    /**
     * Function to generate AST by string.
     */
    parse?: Parser<RootNode>

    /**
     * Class to generate string by AST.
     */
    stringify?: Stringifier
  }

  export interface SourceMapOptions {
    /**
     * Use absolute path in generated source map.
     */
    absolute?: boolean

    /**
     * Indicates that PostCSS should add annotation comments to the CSS.
     * By default, PostCSS will always add a comment with a path
     * to the source map. PostCSS will not add annotations to CSS files
     * that do not contain any comments.
     *
     * By default, PostCSS presumes that you want to save the source map as
     * `opts.to + '.map'` and will use this path in the annotation comment.
     * A different path can be set by providing a string value for annotation.
     *
     * If you have set `inline: true`, annotation cannot be disabled.
     */
    annotation?: ((file: string, root: Root) => string) | boolean | string

    /**
     * Override `from` in map’s sources.
     */
    from?: string

    /**
     * Indicates that the source map should be embedded in the output CSS
     * as a Base64-encoded comment. By default, it is `true`.
     * But if all previous maps are external, not inline, PostCSS will not embed
     * the map even if you do not set this option.
     *
     * If you have an inline source map, the result.map property will be empty,
     * as the source map will be contained within the text of `result.css`.
     */
    inline?: boolean

    /**
     * Source map content from a previous processing step (e.g., Sass).
     *
     * PostCSS will try to read the previous source map
     * automatically (based on comments within the source CSS), but you can use
     * this option to identify it manually.
     *
     * If desired, you can omit the previous map with prev: `false`.
     */
    prev?: ((file: string) => string) | boolean | object | string

    /**
     * Indicates that PostCSS should set the origin content (e.g., Sass source)
     * of the source map. By default, it is true. But if all previous maps do not
     * contain sources content, PostCSS will also leave it out even if you
     * do not set this option.
     */
    sourcesContent?: boolean
  }

  export interface ProcessOptions<RootNode = Document | Root> {
    /**
     * The path of the CSS source file. You should always set `from`,
     * because it is used in source map generation and syntax error messages.
     */
    from?: string | undefined

    /**
     * Source map options
     */
    map?: boolean | SourceMapOptions

    /**
     * Function to generate AST by string.
     */
    parser?: Parser<RootNode> | Syntax<RootNode>

    /**
     * Class to generate string by AST.
     */
    stringifier?: Stringifier | Syntax<RootNode>

    /**
     * Object with parse and stringify.
     */
    syntax?: Syntax<RootNode>

    /**
     * The path where you'll put the output CSS file. You should always set `to`
     * to generate correct source maps.
     */
    to?: string
  }

  export type Postcss = typeof postcss

  /**
   * Default function to convert a node tree into a CSS string.
   */
  export let stringify: Stringifier

  /**
   * Parses source css and returns a new `Root` or `Document` node,
   * which contains the source CSS nodes.
   *
   * ```js
   * // Simple CSS concatenation with source map support
   * const root1 = postcss.parse(css1, { from: file1 })
   * const root2 = postcss.parse(css2, { from: file2 })
   * root1.append(root2).toResult().css
   * ```
   */
  export let parse: Parser<Root>

  /**
   * Rehydrate a JSON AST (from `Node#toJSON`) back into the AST classes.
   *
   * ```js
   * const json = root.toJSON()
   * // save to file, send by network, etc
   * const root2  = postcss.fromJSON(json)
   * ```
   */
  export let fromJSON: JSONHydrator

  /**
   * Creates a new `Comment` node.
   *
   * @param defaults Properties for the new node.
   * @return New comment node
   */
  export function comment(defaults?: CommentProps): Comment

  /**
   * Creates a new `AtRule` node.
   *
   * @param defaults Properties for the new node.
   * @return New at-rule node.
   */
  export function atRule(defaults?: AtRuleProps): AtRule

  /**
   * Creates a new `Declaration` node.
   *
   * @param defaults Properties for the new node.
   * @return New declaration node.
   */
  export function decl(defaults?: DeclarationProps): Declaration

  /**
   * Creates a new `Rule` node.
   *
   * @param default Properties for the new node.
   * @return New rule node.
   */
  export function rule(defaults?: RuleProps): Rule

  /**
   * Creates a new `Root` node.
   *
   * @param defaults Properties for the new node.
   * @return New root node.
   */
  export function root(defaults?: RootProps): Root

  /**
   * Creates a new `Document` node.
   *
   * @param defaults Properties for the new node.
   * @return New document node.
   */
  export function document(defaults?: DocumentProps): Document

  export { postcss as default }
}

/**
 * Create a new `Processor` instance that will apply `plugins`
 * as CSS processors.
 *
 * ```js
 * let postcss = require('postcss')
 *
 * postcss(plugins).process(css, { from, to }).then(result => {
 *   console.log(result.css)
 * })
 * ```
 *
 * @param plugins PostCSS plugins.
 * @return Processor to process multiple CSS.
 */
declare function postcss(plugins?: postcss.AcceptedPlugin[]): Processor
declare function postcss(...plugins: postcss.AcceptedPlugin[]): Processor

export = postcss


code:
'use strict'

let CssSyntaxError = require('./css-syntax-error')
let Declaration = require('./declaration')
let LazyResult = require('./lazy-result')
let Container = require('./container')
let Processor = require('./processor')
let stringify = require('./stringify')
let fromJSON = require('./fromJSON')
let Document = require('./document')
let Warning = require('./warning')
let Comment = require('./comment')
let AtRule = require('./at-rule')
let Result = require('./result.js')
let Input = require('./input')
let parse = require('./parse')
let list = require('./list')
let Rule = require('./rule')
let Root = require('./root')
let Node = require('./node')

function postcss(...plugins) {
  if (plugins.length === 1 && Array.isArray(plugins[0])) {
    plugins = plugins[0]
  }
  return new Processor(plugins)
}

postcss.plugin = function plugin(name, initializer) {
  let warningPrinted = false
  function creator(...args) {
    // eslint-disable-next-line no-console
    if (console && console.warn && !warningPrinted) {
      warningPrinted = true
      // eslint-disable-next-line no-console
      console.warn(
        name +
          ': postcss.plugin was deprecated. Migration guide:\n' +
          'https://evilmartians.com/chronicles/postcss-8-plugin-migration'
      )
      if (process.env.LANG && process.env.LANG.startsWith('cn')) {
        /* c8 ignore next 7 */
        // eslint-disable-next-line no-console
        console.warn(
          name +
            ': 里面 postcss.plugin 被弃用. 迁移指南:\n' +
            'https://www.w3ctech.com/topic/2226'
        )
      }
    }
    let transformer = initializer(...args)
    transformer.postcssPlugin = name
    transformer.postcssVersion = new Processor().version
    return transformer
  }

  let cache
  Object.defineProperty(creator, 'postcss', {
    get() {
      if (!cache) cache = creator()
      return cache
    }
  })

  creator.process = function (css, processOpts, pluginOpts) {
    return postcss([creator(pluginOpts)]).process(css, processOpts)
  }

  return creator
}

postcss.stringify = stringify
postcss.parse = parse
postcss.fromJSON = fromJSON
postcss.list = list

postcss.comment = defaults => new Comment(defaults)
postcss.atRule = defaults => new AtRule(defaults)
postcss.decl = defaults => new Declaration(defaults)
postcss.rule = defaults => new Rule(defaults)
postcss.root = defaults => new Root(defaults)
postcss.document = defaults => new Document(defaults)

postcss.CssSyntaxError = CssSyntaxError
postcss.Declaration = Declaration
postcss.Container = Container
postcss.Processor = Processor
postcss.Document = Document
postcss.Comment = Comment
postcss.Warning = Warning
postcss.AtRule = AtRule
postcss.Result = Result
postcss.Input = Input
postcss.Rule = Rule
postcss.Root = Root
postcss.Node = Node

LazyResult.registerPostcss(postcss)

module.exports = postcss
postcss.default = postcss


code:
import postcss from './postcss.js'

export default postcss

export const stringify = postcss.stringify
export const fromJSON = postcss.fromJSON
export const plugin = postcss.plugin
export const parse = postcss.parse
export const list = postcss.list

export const document = postcss.document
export const comment = postcss.comment
export const atRule = postcss.atRule
export const rule = postcss.rule
export const decl = postcss.decl
export const root = postcss.root

export const CssSyntaxError = postcss.CssSyntaxError
export const Declaration = postcss.Declaration
export const Container = postcss.Container
export const Processor = postcss.Processor
export const Document = postcss.Document
export const Comment = postcss.Comment
export const Warning = postcss.Warning
export const AtRule = postcss.AtRule
export const Result = postcss.Result
export const Input = postcss.Input
export const Rule = postcss.Rule
export const Root = postcss.Root
export const Node = postcss.Node


code:
import { SourceMapConsumer } from 'source-map-js'

import { ProcessOptions } from './postcss.js'

declare namespace PreviousMap {
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  export { PreviousMap_ as default }
}

/**
 * Source map information from input CSS.
 * For example, source map after Sass compiler.
 *
 * This class will automatically find source map in input CSS or in file system
 * near input file (according `from` option).
 *
 * ```js
 * const root = parse(css, { from: 'a.sass.css' })
 * root.input.map //=> PreviousMap
 * ```
 */
declare class PreviousMap_ {
  /**
   * `sourceMappingURL` content.
   */
  annotation?: string

  /**
   * The CSS source identifier. Contains `Input#file` if the user
   * set the `from` option, or `Input#id` if they did not.
   */
  file?: string

  /**
   * Was source map inlined by data-uri to input CSS.
   */
  inline: boolean

  /**
   * Path to source map file.
   */
  mapFile?: string

  /**
   * The directory with source map file, if source map is in separated file.
   */
  root?: string

  /**
   * Source map file content.
   */
  text?: string

  /**
   * @param css  Input CSS source.
   * @param opts Process options.
   */
  constructor(css: string, opts?: ProcessOptions)

  /**
   * Create a instance of `SourceMapGenerator` class
   * from the `source-map` library to work with source map information.
   *
   * It is lazy method, so it will create object only on first call
   * and then it will use cache.
   *
   * @return Object with source map information.
   */
  consumer(): SourceMapConsumer

  /**
   * Does source map contains `sourcesContent` with input source text.
   *
   * @return Is `sourcesContent` present.
   */
  withContent(): boolean
}

declare class PreviousMap extends PreviousMap_ {}

export = PreviousMap


code:
'use strict'

let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js')
let { existsSync, readFileSync } = require('fs')
let { dirname, join } = require('path')

function fromBase64(str) {
  if (Buffer) {
    return Buffer.from(str, 'base64').toString()
  } else {
    /* c8 ignore next 2 */
    return window.atob(str)
  }
}

class PreviousMap {
  constructor(css, opts) {
    if (opts.map === false) return
    this.loadAnnotation(css)
    this.inline = this.startWith(this.annotation, 'data:')

    let prev = opts.map ? opts.map.prev : undefined
    let text = this.loadMap(opts.from, prev)
    if (!this.mapFile && opts.from) {
      this.mapFile = opts.from
    }
    if (this.mapFile) this.root = dirname(this.mapFile)
    if (text) this.text = text
  }

  consumer() {
    if (!this.consumerCache) {
      this.consumerCache = new SourceMapConsumer(this.text)
    }
    return this.consumerCache
  }

  decodeInline(text) {
    let baseCharsetUri = /^data:application\/json;charset=utf-?8;base64,/
    let baseUri = /^data:application\/json;base64,/
    let charsetUri = /^data:application\/json;charset=utf-?8,/
    let uri = /^data:application\/json,/

    if (charsetUri.test(text) || uri.test(text)) {
      return decodeURIComponent(text.substr(RegExp.lastMatch.length))
    }

    if (baseCharsetUri.test(text) || baseUri.test(text)) {
      return fromBase64(text.substr(RegExp.lastMatch.length))
    }

    let encoding = text.match(/data:application\/json;([^,]+),/)[1]
    throw new Error('Unsupported source map encoding ' + encoding)
  }

  getAnnotationURL(sourceMapString) {
    return sourceMapString.replace(/^\/\*\s*# sourceMappingURL=/, '').trim()
  }

  isMap(map) {
    if (typeof map !== 'object') return false
    return (
      typeof map.mappings === 'string' ||
      typeof map._mappings === 'string' ||
      Array.isArray(map.sections)
    )
  }

  loadAnnotation(css) {
    let comments = css.match(/\/\*\s*# sourceMappingURL=/gm)
    if (!comments) return

    // sourceMappingURLs from comments, strings, etc.
    let start = css.lastIndexOf(comments.pop())
    let end = css.indexOf('*/', start)

    if (start > -1 && end > -1) {
      // Locate the last sourceMappingURL to avoid pickin
      this.annotation = this.getAnnotationURL(css.substring(start, end))
    }
  }

  loadFile(path) {
    this.root = dirname(path)
    if (existsSync(path)) {
      this.mapFile = path
      return readFileSync(path, 'utf-8').toString().trim()
    }
  }

  loadMap(file, prev) {
    if (prev === false) return false

    if (prev) {
      if (typeof prev === 'string') {
        return prev
      } else if (typeof prev === 'function') {
        let prevPath = prev(file)
        if (prevPath) {
          let map = this.loadFile(prevPath)
          if (!map) {
            throw new Error(
              'Unable to load previous source map: ' + prevPath.toString()
            )
          }
          return map
        }
      } else if (prev instanceof SourceMapConsumer) {
        return SourceMapGenerator.fromSourceMap(prev).toString()
      } else if (prev instanceof SourceMapGenerator) {
        return prev.toString()
      } else if (this.isMap(prev)) {
        return JSON.stringify(prev)
      } else {
        throw new Error(
          'Unsupported previous source map format: ' + prev.toString()
        )
      }
    } else if (this.inline) {
      return this.decodeInline(this.annotation)
    } else if (this.annotation) {
      let map = this.annotation
      if (file) map = join(dirname(file), map)
      return this.loadFile(map)
    }
  }

  startWith(string, start) {
    if (!string) return false
    return string.substr(0, start.length) === start
  }

  withContent() {
    return !!(
      this.consumer().sourcesContent &&
      this.consumer().sourcesContent.length > 0
    )
  }
}

module.exports = PreviousMap
PreviousMap.default = PreviousMap


code:
import Document from './document.js'
import LazyResult from './lazy-result.js'
import NoWorkResult from './no-work-result.js'
import {
  AcceptedPlugin,
  Plugin,
  ProcessOptions,
  TransformCallback,
  Transformer
} from './postcss.js'
import Result from './result.js'
import Root from './root.js'

declare namespace Processor {
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  export { Processor_ as default }
}

/**
 * Contains plugins to process CSS. Create one `Processor` instance,
 * initialize its plugins, and then use that instance on numerous CSS files.
 *
 * ```js
 * const processor = postcss([autoprefixer, postcssNested])
 * processor.process(css1).then(result => console.log(result.css))
 * processor.process(css2).then(result => console.log(result.css))
 * ```
 */
declare class Processor_ {
  /**
   * Plugins added to this processor.
   *
   * ```js
   * const processor = postcss([autoprefixer, postcssNested])
   * processor.plugins.length //=> 2
   * ```
   */
  plugins: (Plugin | TransformCallback | Transformer)[]

  /**
   * Current PostCSS version.
   *
   * ```js
   * if (result.processor.version.split('.')[0] !== '6') {
   *   throw new Error('This plugin works only with PostCSS 6')
   * }
   * ```
   */
  version: string

  /**
   * @param plugins PostCSS plugins
   */
  constructor(plugins?: AcceptedPlugin[])

  /**
   * Parses source CSS and returns a `LazyResult` Promise proxy.
   * Because some plugins can be asynchronous it doesn’t make
   * any transformations. Transformations will be applied
   * in the `LazyResult` methods.
   *
   * ```js
   * processor.process(css, { from: 'a.css', to: 'a.out.css' })
   *   .then(result => {
   *      console.log(result.css)
   *   })
   * ```
   *
   * @param css String with input CSS or any object with a `toString()` method,
   *            like a Buffer. Optionally, send a `Result` instance
   *            and the processor will take the `Root` from it.
   * @param opts Options.
   * @return Promise proxy.
   */
  process(
    css: { toString(): string } | LazyResult | Result | Root | string
  ): LazyResult | NoWorkResult
  process<RootNode extends Document | Root = Root>(
    css: { toString(): string } | LazyResult | Result | Root | string,
    options: ProcessOptions<RootNode>
  ): LazyResult<RootNode>

  /**
   * Adds a plugin to be used as a CSS processor.
   *
   * PostCSS plugin can be in 4 formats:
   * * A plugin in `Plugin` format.
   * * A plugin creator function with `pluginCreator.postcss = true`.
   *   PostCSS will call this function without argument to get plugin.
   * * A function. PostCSS will pass the function a {@link Root}
   *   as the first argument and current `Result` instance
   *   as the second.
   * * Another `Processor` instance. PostCSS will copy plugins
   *   from that instance into this one.
   *
   * Plugins can also be added by passing them as arguments when creating
   * a `postcss` instance (see [`postcss(plugins)`]).
   *
   * Asynchronous plugins should return a `Promise` instance.
   *
   * ```js
   * const processor = postcss()
   *   .use(autoprefixer)
   *   .use(postcssNested)
   * ```
   *
   * @param plugin PostCSS plugin or `Processor` with plugins.
   * @return Current processor to make methods chain.
   */
  use(plugin: AcceptedPlugin): this
}

declare class Processor extends Processor_ {}

export = Processor


code:
'use strict'

let NoWorkResult = require('./no-work-result')
let LazyResult = require('./lazy-result')
let Document = require('./document')
let Root = require('./root')

class Processor {
  constructor(plugins = []) {
    this.version = '8.4.39'
    this.plugins = this.normalize(plugins)
  }

  normalize(plugins) {
    let normalized = []
    for (let i of plugins) {
      if (i.postcss === true) {
        i = i()
      } else if (i.postcss) {
        i = i.postcss
      }

      if (typeof i === 'object' && Array.isArray(i.plugins)) {
        normalized = normalized.concat(i.plugins)
      } else if (typeof i === 'object' && i.postcssPlugin) {
        normalized.push(i)
      } else if (typeof i === 'function') {
        normalized.push(i)
      } else if (typeof i === 'object' && (i.parse || i.stringify)) {
        if (process.env.NODE_ENV !== 'production') {
          throw new Error(
            'PostCSS syntaxes cannot be used as plugins. Instead, please use ' +
              'one of the syntax/parser/stringifier options as outlined ' +
              'in your PostCSS runner documentation.'
          )
        }
      } else {
        throw new Error(i + ' is not a PostCSS plugin')
      }
    }
    return normalized
  }

  process(css, opts = {}) {
    if (
      !this.plugins.length &&
      !opts.parser &&
      !opts.stringifier &&
      !opts.syntax
    ) {
      return new NoWorkResult(this, css, opts)
    } else {
      return new LazyResult(this, css, opts)
    }
  }

  use(plugin) {
    this.plugins = this.plugins.concat(this.normalize([plugin]))
    return this
  }
}

module.exports = Processor
Processor.default = Processor

Root.registerProcessor(Processor)
Document.registerProcessor(Processor)


code:
import {
  Document,
  Node,
  Plugin,
  ProcessOptions,
  Root,
  SourceMap,
  TransformCallback,
  Warning,
  WarningOptions
} from './postcss.js'
import Processor from './processor.js'

declare namespace Result {
  export interface Message {
    [others: string]: any

    /**
     * Source PostCSS plugin name.
     */
    plugin?: string

    /**
     * Message type.
     */
    type: string
  }

  export interface ResultOptions extends ProcessOptions {
    /**
     * The CSS node that was the source of the warning.
     */
    node?: Node

    /**
     * Name of plugin that created this warning. `Result#warn` will fill it
     * automatically with `Plugin#postcssPlugin` value.
     */
    plugin?: string
  }

  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  export { Result_ as default }
}

/**
 * Provides the result of the PostCSS transformations.
 *
 * A Result instance is returned by `LazyResult#then`
 * or `Root#toResult` methods.
 *
 * ```js
 * postcss([autoprefixer]).process(css).then(result => {
 *  console.log(result.css)
 * })
 * ```
 *
 * ```js
 * const result2 = postcss.parse(css).toResult()
 * ```
 */
declare class Result_<RootNode = Document | Root> {
  /**
   * A CSS string representing of `Result#root`.
   *
   * ```js
   * postcss.parse('a{}').toResult().css //=> "a{}"
   * ```
   */
  css: string

  /**
   * Last runned PostCSS plugin.
   */
  lastPlugin: Plugin | TransformCallback

  /**
   * An instance of `SourceMapGenerator` class from the `source-map` library,
   * representing changes to the `Result#root` instance.
   *
   * ```js
   * result.map.toJSON() //=> { version: 3, file: 'a.css', … }
   * ```
   *
   * ```js
   * if (result.map) {
   *   fs.writeFileSync(result.opts.to + '.map', result.map.toString())
   * }
   * ```
   */
  map: SourceMap

  /**
   * Contains messages from plugins (e.g., warnings or custom messages).
   * Each message should have type and plugin properties.
   *
   * ```js
   * AtRule: {
   *   import: (atRule, { result }) {
   *     const importedFile = parseImport(atRule)
   *     result.messages.push({
   *       type: 'dependency',
   *       plugin: 'postcss-import',
   *       file: importedFile,
   *       parent: result.opts.from
   *     })
   *   }
   * }
   * ```
   */
  messages: Result.Message[]

  /**
   * Options from the `Processor#process` or `Root#toResult` call
   * that produced this Result instance.]
   *
   * ```js
   * root.toResult(opts).opts === opts
   * ```
   */
  opts: Result.ResultOptions

  /**
   * The Processor instance used for this transformation.
   *
   * ```js
   * for (const plugin of result.processor.plugins) {
   *   if (plugin.postcssPlugin === 'postcss-bad') {
   *     throw 'postcss-good is incompatible with postcss-bad'
   *   }
   * })
   * ```
   */
  processor: Processor

  /**
   * Root node after all transformations.
   *
   * ```js
   * root.toResult().root === root
   * ```
   */
  root: RootNode

  /**
   * @param processor Processor used for this transformation.
   * @param root      Root node after all transformations.
   * @param opts      Options from the `Processor#process` or `Root#toResult`.
   */
  constructor(processor: Processor, root: RootNode, opts: Result.ResultOptions)

  /**
   * Returns for `Result#css` content.
   *
   * ```js
   * result + '' === result.css
   * ```
   *
   * @return String representing of `Result#root`.
   */
  toString(): string

  /**
   * Creates an instance of `Warning` and adds it to `Result#messages`.
   *
   * ```js
   * if (decl.important) {
   *   result.warn('Avoid !important', { node: decl, word: '!important' })
   * }
   * ```
   *
   * @param text Warning message.
   * @param opts Warning options.
   * @return Created warning.
   */
  warn(message: string, options?: WarningOptions): Warning

  /**
   * Returns warnings from plugins. Filters `Warning` instances
   * from `Result#messages`.
   *
   * ```js
   * result.warnings().forEach(warn => {
   *   console.warn(warn.toString())
   * })
   * ```
   *
   * @return Warnings from plugins.
   */
  warnings(): Warning[]

  /**
   * An alias for the `Result#css` property.
   * Use it with syntaxes that generate non-CSS output.
   *
   * ```js
   * result.css === result.content
   * ```
   */
  get content(): string
}

declare class Result<RootNode = Document | Root> extends Result_<RootNode> {}

export = Result


code:
'use strict'

let Warning = require('./warning')

class Result {
  constructor(processor, root, opts) {
    this.processor = processor
    this.messages = []
    this.root = root
    this.opts = opts
    this.css = undefined
    this.map = undefined
  }

  toString() {
    return this.css
  }

  warn(text, opts = {}) {
    if (!opts.plugin) {
      if (this.lastPlugin && this.lastPlugin.postcssPlugin) {
        opts.plugin = this.lastPlugin.postcssPlugin
      }
    }

    let warning = new Warning(text, opts)
    this.messages.push(warning)

    return warning
  }

  warnings() {
    return this.messages.filter(i => i.type === 'warning')
  }

  get content() {
    return this.css
  }
}

module.exports = Result
Result.default = Result


code:
import Container, { ContainerProps } from './container.js'
import Document from './document.js'
import { ProcessOptions } from './postcss.js'
import Result from './result.js'

declare namespace Root {
  export interface RootRaws extends Record<string, any> {
    /**
     * The space symbols after the last child to the end of file.
     */
    after?: string

    /**
     * Non-CSS code after `Root`, when `Root` is inside `Document`.
     *
     * **Experimental:** some aspects of this node could change within minor
     * or patch version releases.
     */
    codeAfter?: string

    /**
     * Non-CSS code before `Root`, when `Root` is inside `Document`.
     *
     * **Experimental:** some aspects of this node could change within minor
     * or patch version releases.
     */
    codeBefore?: string

    /**
     * Is the last child has an (optional) semicolon.
     */
    semicolon?: boolean
  }

  export interface RootProps extends ContainerProps {
    /**
     * Information used to generate byte-to-byte equal node string
     * as it was in the origin input.
     * */
    raws?: RootRaws
  }

  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  export { Root_ as default }
}

/**
 * Represents a CSS file and contains all its parsed nodes.
 *
 * ```js
 * const root = postcss.parse('a{color:black} b{z-index:2}')
 * root.type         //=> 'root'
 * root.nodes.length //=> 2
 * ```
 */
declare class Root_ extends Container {
  nodes: NonNullable<Container['nodes']>
  parent: Document | undefined
  raws: Root.RootRaws
  type: 'root'

  constructor(defaults?: Root.RootProps)

  assign(overrides: object | Root.RootProps): this
  clone(overrides?: Partial<Root.RootProps>): Root
  cloneAfter(overrides?: Partial<Root.RootProps>): Root
  cloneBefore(overrides?: Partial<Root.RootProps>): Root

  /**
   * Returns a `Result` instance representing the root’s CSS.
   *
   * ```js
   * const root1 = postcss.parse(css1, { from: 'a.css' })
   * const root2 = postcss.parse(css2, { from: 'b.css' })
   * root1.append(root2)
   * const result = root1.toResult({ to: 'all.css', map: true })
   * ```
   *
   * @param opts Options.
   * @return Result with current root’s CSS.
   */
  toResult(options?: ProcessOptions): Result
}

declare class Root extends Root_ {}

export = Root


code:
'use strict'

let Container = require('./container')

let LazyResult, Processor

class Root extends Container {
  constructor(defaults) {
    super(defaults)
    this.type = 'root'
    if (!this.nodes) this.nodes = []
  }

  normalize(child, sample, type) {
    let nodes = super.normalize(child)

    if (sample) {
      if (type === 'prepend') {
        if (this.nodes.length > 1) {
          sample.raws.before = this.nodes[1].raws.before
        } else {
          delete sample.raws.before
        }
      } else if (this.first !== sample) {
        for (let node of nodes) {
          node.raws.before = sample.raws.before
        }
      }
    }

    return nodes
  }

  removeChild(child, ignore) {
    let index = this.index(child)

    if (!ignore && index === 0 && this.nodes.length > 1) {
      this.nodes[1].raws.before = this.nodes[index].raws.before
    }

    return super.removeChild(child)
  }

  toResult(opts = {}) {
    let lazy = new LazyResult(new Processor(), this, opts)
    return lazy.stringify()
  }
}

Root.registerLazyResult = dependant => {
  LazyResult = dependant
}

Root.registerProcessor = dependant => {
  Processor = dependant
}

module.exports = Root
Root.default = Root

Container.registerRoot(Root)


code:
import Container, {
  ContainerProps,
  ContainerWithChildren
} from './container.js'

declare namespace Rule {
  export interface RuleRaws extends Record<string, unknown> {
    /**
     * The space symbols after the last child of the node to the end of the node.
     */
    after?: string

    /**
     * The space symbols before the node. It also stores `*`
     * and `_` symbols before the declaration (IE hack).
     */
    before?: string

    /**
     * The symbols between the selector and `{` for rules.
     */
    between?: string

    /**
     * Contains `true` if there is semicolon after rule.
     */
    ownSemicolon?: string

    /**
     * The rule’s selector with comments.
     */
    selector?: {
      raw: string
      value: string
    }

    /**
     * Contains `true` if the last child has an (optional) semicolon.
     */
    semicolon?: boolean
  }

  export interface RuleProps extends ContainerProps {
    /** Information used to generate byte-to-byte equal node string as it was in the origin input. */
    raws?: RuleRaws
    /** Selector or selectors of the rule. */
    selector?: string
    /** Selectors of the rule represented as an array of strings. */
    selectors?: string[]
  }

  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  export { Rule_ as default }
}

/**
 * Represents a CSS rule: a selector followed by a declaration block.
 *
 * ```js
 * Once (root, { Rule }) {
 *   let a = new Rule({ selector: 'a' })
 *   a.append(…)
 *   root.append(a)
 * }
 * ```
 *
 * ```js
 * const root = postcss.parse('a{}')
 * const rule = root.first
 * rule.type       //=> 'rule'
 * rule.toString() //=> 'a{}'
 * ```
 */
declare class Rule_ extends Container {
  nodes: NonNullable<Container['nodes']>
  parent: ContainerWithChildren | undefined
  raws: Rule.RuleRaws
  /**
   * The rule’s full selector represented as a string.
   *
   * ```js
   * const root = postcss.parse('a, b { }')
   * const rule = root.first
   * rule.selector //=> 'a, b'
   * ```
   */
  selector: string

  /**
   * An array containing the rule’s individual selectors.
   * Groups of selectors are split at commas.
   *
   * ```js
   * const root = postcss.parse('a, b { }')
   * const rule = root.first
   *
   * rule.selector  //=> 'a, b'
   * rule.selectors //=> ['a', 'b']
   *
   * rule.selectors = ['a', 'strong']
   * rule.selector //=> 'a, strong'
   * ```
   */
  selectors: string[]

  type: 'rule'

  constructor(defaults?: Rule.RuleProps)
  assign(overrides: object | Rule.RuleProps): this
  clone(overrides?: Partial<Rule.RuleProps>): Rule
  cloneAfter(overrides?: Partial<Rule.RuleProps>): Rule
  cloneBefore(overrides?: Partial<Rule.RuleProps>): Rule
}

declare class Rule extends Rule_ {}

export = Rule


code:
'use strict'

let Container = require('./container')
let list = require('./list')

class Rule extends Container {
  constructor(defaults) {
    super(defaults)
    this.type = 'rule'
    if (!this.nodes) this.nodes = []
  }

  get selectors() {
    return list.comma(this.selector)
  }

  set selectors(values) {
    let match = this.selector ? this.selector.match(/,\s*/) : null
    let sep = match ? match[0] : ',' + this.raw('between', 'beforeOpen')
    this.selector = values.join(sep)
  }
}

module.exports = Rule
Rule.default = Rule

Container.registerRule(Rule)


code:
import {
  AnyNode,
  AtRule,
  Builder,
  Comment,
  Container,
  Declaration,
  Document,
  Root,
  Rule
} from './postcss.js'

declare namespace Stringifier {
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  export { Stringifier_ as default }
}

declare class Stringifier_ {
  builder: Builder
  constructor(builder: Builder)
  atrule(node: AtRule, semicolon?: boolean): void
  beforeAfter(node: AnyNode, detect: 'after' | 'before'): string
  block(node: AnyNode, start: string): void
  body(node: Container): void
  comment(node: Comment): void
  decl(node: Declaration, semicolon?: boolean): void
  document(node: Document): void
  raw(node: AnyNode, own: null | string, detect?: string): string
  rawBeforeClose(root: Root): string | undefined
  rawBeforeComment(root: Root, node: Comment): string | undefined
  rawBeforeDecl(root: Root, node: Declaration): string | undefined
  rawBeforeOpen(root: Root): string | undefined
  rawBeforeRule(root: Root): string | undefined
  rawColon(root: Root): string | undefined
  rawEmptyBody(root: Root): string | undefined
  rawIndent(root: Root): string | undefined
  rawSemicolon(root: Root): boolean | undefined
  rawValue(node: AnyNode, prop: string): string
  root(node: Root): void
  rule(node: Rule): void
  stringify(node: AnyNode, semicolon?: boolean): void
}

declare class Stringifier extends Stringifier_ {}

export = Stringifier


code:
'use strict'

const DEFAULT_RAW = {
  after: '\n',
  beforeClose: '\n',
  beforeComment: '\n',
  beforeDecl: '\n',
  beforeOpen: ' ',
  beforeRule: '\n',
  colon: ': ',
  commentLeft: ' ',
  commentRight: ' ',
  emptyBody: '',
  indent: '    ',
  semicolon: false
}

function capitalize(str) {
  return str[0].toUpperCase() + str.slice(1)
}

class Stringifier {
  constructor(builder) {
    this.builder = builder
  }

  atrule(node, semicolon) {
    let name = '@' + node.name
    let params = node.params ? this.rawValue(node, 'params') : ''

    if (typeof node.raws.afterName !== 'undefined') {
      name += node.raws.afterName
    } else if (params) {
      name += ' '
    }

    if (node.nodes) {
      this.block(node, name + params)
    } else {
      let end = (node.raws.between || '') + (semicolon ? ';' : '')
      this.builder(name + params + end, node)
    }
  }

  beforeAfter(node, detect) {
    let value
    if (node.type === 'decl') {
      value = this.raw(node, null, 'beforeDecl')
    } else if (node.type === 'comment') {
      value = this.raw(node, null, 'beforeComment')
    } else if (detect === 'before') {
      value = this.raw(node, null, 'beforeRule')
    } else {
      value = this.raw(node, null, 'beforeClose')
    }

    let buf = node.parent
    let depth = 0
    while (buf && buf.type !== 'root') {
      depth += 1
      buf = buf.parent
    }

    if (value.includes('\n')) {
      let indent = this.raw(node, null, 'indent')
      if (indent.length) {
        for (let step = 0; step < depth; step++) value += indent
      }
    }

    return value
  }

  block(node, start) {
    let between = this.raw(node, 'between', 'beforeOpen')
    this.builder(start + between + '{', node, 'start')

    let after
    if (node.nodes && node.nodes.length) {
      this.body(node)
      after = this.raw(node, 'after')
    } else {
      after = this.raw(node, 'after', 'emptyBody')
    }

    if (after) this.builder(after)
    this.builder('}', node, 'end')
  }

  body(node) {
    let last = node.nodes.length - 1
    while (last > 0) {
      if (node.nodes[last].type !== 'comment') break
      last -= 1
    }

    let semicolon = this.raw(node, 'semicolon')
    for (let i = 0; i < node.nodes.length; i++) {
      let child = node.nodes[i]
      let before = this.raw(child, 'before')
      if (before) this.builder(before)
      this.stringify(child, last !== i || semicolon)
    }
  }

  comment(node) {
    let left = this.raw(node, 'left', 'commentLeft')
    let right = this.raw(node, 'right', 'commentRight')
    this.builder('/*' + left + node.text + right + '*/', node)
  }

  decl(node, semicolon) {
    let between = this.raw(node, 'between', 'colon')
    let string = node.prop + between + this.rawValue(node, 'value')

    if (node.important) {
      string += node.raws.important || ' !important'
    }

    if (semicolon) string += ';'
    this.builder(string, node)
  }

  document(node) {
    this.body(node)
  }

  raw(node, own, detect) {
    let value
    if (!detect) detect = own

    // Already had
    if (own) {
      value = node.raws[own]
      if (typeof value !== 'undefined') return value
    }

    let parent = node.parent

    if (detect === 'before') {
      // Hack for first rule in CSS
      if (!parent || (parent.type === 'root' && parent.first === node)) {
        return ''
      }

      // `root` nodes in `document` should use only their own raws
      if (parent && parent.type === 'document') {
        return ''
      }
    }

    // Floating child without parent
    if (!parent) return DEFAULT_RAW[detect]

    // Detect style by other nodes
    let root = node.root()
    if (!root.rawCache) root.rawCache = {}
    if (typeof root.rawCache[detect] !== 'undefined') {
      return root.rawCache[detect]
    }

    if (detect === 'before' || detect === 'after') {
      return this.beforeAfter(node, detect)
    } else {
      let method = 'raw' + capitalize(detect)
      if (this[method]) {
        value = this[method](root, node)
      } else {
        root.walk(i => {
          value = i.raws[own]
          if (typeof value !== 'undefined') return false
        })
      }
    }

    if (typeof value === 'undefined') value = DEFAULT_RAW[detect]

    root.rawCache[detect] = value
    return value
  }

  rawBeforeClose(root) {
    let value
    root.walk(i => {
      if (i.nodes && i.nodes.length > 0) {
        if (typeof i.raws.after !== 'undefined') {
          value = i.raws.after
          if (value.includes('\n')) {
            value = value.replace(/[^\n]+$/, '')
          }
          return false
        }
      }
    })
    if (value) value = value.replace(/\S/g, '')
    return value
  }

  rawBeforeComment(root, node) {
    let value
    root.walkComments(i => {
      if (typeof i.raws.before !== 'undefined') {
        value = i.raws.before
        if (value.includes('\n')) {
          value = value.replace(/[^\n]+$/, '')
        }
        return false
      }
    })
    if (typeof value === 'undefined') {
      value = this.raw(node, null, 'beforeDecl')
    } else if (value) {
      value = value.replace(/\S/g, '')
    }
    return value
  }

  rawBeforeDecl(root, node) {
    let value
    root.walkDecls(i => {
      if (typeof i.raws.before !== 'undefined') {
        value = i.raws.before
        if (value.includes('\n')) {
          value = value.replace(/[^\n]+$/, '')
        }
        return false
      }
    })
    if (typeof value === 'undefined') {
      value = this.raw(node, null, 'beforeRule')
    } else if (value) {
      value = value.replace(/\S/g, '')
    }
    return value
  }

  rawBeforeOpen(root) {
    let value
    root.walk(i => {
      if (i.type !== 'decl') {
        value = i.raws.between
        if (typeof value !== 'undefined') return false
      }
    })
    return value
  }

  rawBeforeRule(root) {
    let value
    root.walk(i => {
      if (i.nodes && (i.parent !== root || root.first !== i)) {
        if (typeof i.raws.before !== 'undefined') {
          value = i.raws.before
          if (value.includes('\n')) {
            value = value.replace(/[^\n]+$/, '')
          }
          return false
        }
      }
    })
    if (value) value = value.replace(/\S/g, '')
    return value
  }

  rawColon(root) {
    let value
    root.walkDecls(i => {
      if (typeof i.raws.between !== 'undefined') {
        value = i.raws.between.replace(/[^\s:]/g, '')
        return false
      }
    })
    return value
  }

  rawEmptyBody(root) {
    let value
    root.walk(i => {
      if (i.nodes && i.nodes.length === 0) {
        value = i.raws.after
        if (typeof value !== 'undefined') return false
      }
    })
    return value
  }

  rawIndent(root) {
    if (root.raws.indent) return root.raws.indent
    let value
    root.walk(i => {
      let p = i.parent
      if (p && p !== root && p.parent && p.parent === root) {
        if (typeof i.raws.before !== 'undefined') {
          let parts = i.raws.before.split('\n')
          value = parts[parts.length - 1]
          value = value.replace(/\S/g, '')
          return false
        }
      }
    })
    return value
  }

  rawSemicolon(root) {
    let value
    root.walk(i => {
      if (i.nodes && i.nodes.length && i.last.type === 'decl') {
        value = i.raws.semicolon
        if (typeof value !== 'undefined') return false
      }
    })
    return value
  }

  rawValue(node, prop) {
    let value = node[prop]
    let raw = node.raws[prop]
    if (raw && raw.value === value) {
      return raw.raw
    }

    return value
  }

  root(node) {
    this.body(node)
    if (node.raws.after) this.builder(node.raws.after)
  }

  rule(node) {
    this.block(node, this.rawValue(node, 'selector'))
    if (node.raws.ownSemicolon) {
      this.builder(node.raws.ownSemicolon, node, 'end')
    }
  }

  stringify(node, semicolon) {
    /* c8 ignore start */
    if (!this[node.type]) {
      throw new Error(
        'Unknown AST node type ' +
          node.type +
          '. ' +
          'Maybe you need to change PostCSS stringifier.'
      )
    }
    /* c8 ignore stop */
    this[node.type](node, semicolon)
  }
}

module.exports = Stringifier
Stringifier.default = Stringifier


code:
import { Stringifier } from './postcss.js'

interface Stringify extends Stringifier {
  default: Stringify
}

declare const stringify: Stringify

export = stringify


code:
'use strict'

let Stringifier = require('./stringifier')

function stringify(node, builder) {
  let str = new Stringifier(builder)
  str.stringify(node)
}

module.exports = stringify
stringify.default = stringify


code:
'use strict'

module.exports.isClean = Symbol('isClean')

module.exports.my = Symbol('my')


code:
'use strict'

let pico = require('picocolors')

let tokenizer = require('./tokenize')

let Input

function registerInput(dependant) {
  Input = dependant
}

const HIGHLIGHT_THEME = {
  ';': pico.yellow,
  ':': pico.yellow,
  '(': pico.cyan,
  ')': pico.cyan,
  '[': pico.yellow,
  ']': pico.yellow,
  '{': pico.yellow,
  '}': pico.yellow,
  'at-word': pico.cyan,
  'brackets': pico.cyan,
  'call': pico.cyan,
  'class': pico.yellow,
  'comment': pico.gray,
  'hash': pico.magenta,
  'string': pico.green
}

function getTokenType([type, value], processor) {
  if (type === 'word') {
    if (value[0] === '.') {
      return 'class'
    }
    if (value[0] === '#') {
      return 'hash'
    }
  }

  if (!processor.endOfFile()) {
    let next = processor.nextToken()
    processor.back(next)
    if (next[0] === 'brackets' || next[0] === '(') return 'call'
  }

  return type
}

function terminalHighlight(css) {
  let processor = tokenizer(new Input(css), { ignoreErrors: true })
  let result = ''
  while (!processor.endOfFile()) {
    let token = processor.nextToken()
    let color = HIGHLIGHT_THEME[getTokenType(token, processor)]
    if (color) {
      result += token[1]
        .split(/\r?\n/)
        .map(i => color(i))
        .join('\n')
    } else {
      result += token[1]
    }
  }
  return result
}

terminalHighlight.registerInput = registerInput

module.exports = terminalHighlight


code:
'use strict'

const SINGLE_QUOTE = "'".charCodeAt(0)
const DOUBLE_QUOTE = '"'.charCodeAt(0)
const BACKSLASH = '\\'.charCodeAt(0)
const SLASH = '/'.charCodeAt(0)
const NEWLINE = '\n'.charCodeAt(0)
const SPACE = ' '.charCodeAt(0)
const FEED = '\f'.charCodeAt(0)
const TAB = '\t'.charCodeAt(0)
const CR = '\r'.charCodeAt(0)
const OPEN_SQUARE = '['.charCodeAt(0)
const CLOSE_SQUARE = ']'.charCodeAt(0)
const OPEN_PARENTHESES = '('.charCodeAt(0)
const CLOSE_PARENTHESES = ')'.charCodeAt(0)
const OPEN_CURLY = '{'.charCodeAt(0)
const CLOSE_CURLY = '}'.charCodeAt(0)
const SEMICOLON = ';'.charCodeAt(0)
const ASTERISK = '*'.charCodeAt(0)
const COLON = ':'.charCodeAt(0)
const AT = '@'.charCodeAt(0)

const RE_AT_END = /[\t\n\f\r "#'()/;[\\\]{}]/g
const RE_WORD_END = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g
const RE_BAD_BRACKET = /.[\r\n"'(/\\]/
const RE_HEX_ESCAPE = /[\da-f]/i

module.exports = function tokenizer(input, options = {}) {
  let css = input.css.valueOf()
  let ignore = options.ignoreErrors

  let code, next, quote, content, escape
  let escaped, escapePos, prev, n, currentToken

  let length = css.length
  let pos = 0
  let buffer = []
  let returned = []

  function position() {
    return pos
  }

  function unclosed(what) {
    throw input.error('Unclosed ' + what, pos)
  }

  function endOfFile() {
    return returned.length === 0 && pos >= length
  }

  function nextToken(opts) {
    if (returned.length) return returned.pop()
    if (pos >= length) return

    let ignoreUnclosed = opts ? opts.ignoreUnclosed : false

    code = css.charCodeAt(pos)

    switch (code) {
      case NEWLINE:
      case SPACE:
      case TAB:
      case CR:
      case FEED: {
        next = pos
        do {
          next += 1
          code = css.charCodeAt(next)
        } while (
          code === SPACE ||
          code === NEWLINE ||
          code === TAB ||
          code === CR ||
          code === FEED
        )

        currentToken = ['space', css.slice(pos, next)]
        pos = next - 1
        break
      }

      case OPEN_SQUARE:
      case CLOSE_SQUARE:
      case OPEN_CURLY:
      case CLOSE_CURLY:
      case COLON:
      case SEMICOLON:
      case CLOSE_PARENTHESES: {
        let controlChar = String.fromCharCode(code)
        currentToken = [controlChar, controlChar, pos]
        break
      }

      case OPEN_PARENTHESES: {
        prev = buffer.length ? buffer.pop()[1] : ''
        n = css.charCodeAt(pos + 1)
        if (
          prev === 'url' &&
          n !== SINGLE_QUOTE &&
          n !== DOUBLE_QUOTE &&
          n !== SPACE &&
          n !== NEWLINE &&
          n !== TAB &&
          n !== FEED &&
          n !== CR
        ) {
          next = pos
          do {
            escaped = false
            next = css.indexOf(')', next + 1)
            if (next === -1) {
              if (ignore || ignoreUnclosed) {
                next = pos
                break
              } else {
                unclosed('bracket')
              }
            }
            escapePos = next
            while (css.charCodeAt(escapePos - 1) === BACKSLASH) {
              escapePos -= 1
              escaped = !escaped
            }
          } while (escaped)

          currentToken = ['brackets', css.slice(pos, next + 1), pos, next]

          pos = next
        } else {
          next = css.indexOf(')', pos + 1)
          content = css.slice(pos, next + 1)

          if (next === -1 || RE_BAD_BRACKET.test(content)) {
            currentToken = ['(', '(', pos]
          } else {
            currentToken = ['brackets', content, pos, next]
            pos = next
          }
        }

        break
      }

      case SINGLE_QUOTE:
      case DOUBLE_QUOTE: {
        quote = code === SINGLE_QUOTE ? "'" : '"'
        next = pos
        do {
          escaped = false
          next = css.indexOf(quote, next + 1)
          if (next === -1) {
            if (ignore || ignoreUnclosed) {
              next = pos + 1
              break
            } else {
              unclosed('string')
            }
          }
          escapePos = next
          while (css.charCodeAt(escapePos - 1) === BACKSLASH) {
            escapePos -= 1
            escaped = !escaped
          }
        } while (escaped)

        currentToken = ['string', css.slice(pos, next + 1), pos, next]
        pos = next
        break
      }

      case AT: {
        RE_AT_END.lastIndex = pos + 1
        RE_AT_END.test(css)
        if (RE_AT_END.lastIndex === 0) {
          next = css.length - 1
        } else {
          next = RE_AT_END.lastIndex - 2
        }

        currentToken = ['at-word', css.slice(pos, next + 1), pos, next]

        pos = next
        break
      }

      case BACKSLASH: {
        next = pos
        escape = true
        while (css.charCodeAt(next + 1) === BACKSLASH) {
          next += 1
          escape = !escape
        }
        code = css.charCodeAt(next + 1)
        if (
          escape &&
          code !== SLASH &&
          code !== SPACE &&
          code !== NEWLINE &&
          code !== TAB &&
          code !== CR &&
          code !== FEED
        ) {
          next += 1
          if (RE_HEX_ESCAPE.test(css.charAt(next))) {
            while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) {
              next += 1
            }
            if (css.charCodeAt(next + 1) === SPACE) {
              next += 1
            }
          }
        }

        currentToken = ['word', css.slice(pos, next + 1), pos, next]

        pos = next
        break
      }

      default: {
        if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) {
          next = css.indexOf('*/', pos + 2) + 1
          if (next === 0) {
            if (ignore || ignoreUnclosed) {
              next = css.length
            } else {
              unclosed('comment')
            }
          }

          currentToken = ['comment', css.slice(pos, next + 1), pos, next]
          pos = next
        } else {
          RE_WORD_END.lastIndex = pos + 1
          RE_WORD_END.test(css)
          if (RE_WORD_END.lastIndex === 0) {
            next = css.length - 1
          } else {
            next = RE_WORD_END.lastIndex - 2
          }

          currentToken = ['word', css.slice(pos, next + 1), pos, next]
          buffer.push(currentToken)
          pos = next
        }

        break
      }
    }

    pos++
    return currentToken
  }

  function back(token) {
    returned.push(token)
  }

  return {
    back,
    endOfFile,
    nextToken,
    position
  }
}


code:
/* eslint-disable no-console */
'use strict'

let printed = {}

module.exports = function warnOnce(message) {
  if (printed[message]) return
  printed[message] = true

  if (typeof console !== 'undefined' && console.warn) {
    console.warn(message)
  }
}


code:
import { RangePosition } from './css-syntax-error.js'
import Node from './node.js'

declare namespace Warning {
  export interface WarningOptions {
    /**
     * End position, exclusive, in CSS node string that caused the warning.
     */
    end?: RangePosition

    /**
     * End index, exclusive, in CSS node string that caused the warning.
     */
    endIndex?: number

    /**
     * Start index, inclusive, in CSS node string that caused the warning.
     */
    index?: number

    /**
     * CSS node that caused the warning.
     */
    node?: Node

    /**
     * Name of the plugin that created this warning. `Result#warn` fills
     * this property automatically.
     */
    plugin?: string

    /**
     * Start position, inclusive, in CSS node string that caused the warning.
     */
    start?: RangePosition

    /**
     * Word in CSS source that caused the warning.
     */
    word?: string
  }

  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  export { Warning_ as default }
}

/**
 * Represents a plugin’s warning. It can be created using `Node#warn`.
 *
 * ```js
 * if (decl.important) {
 *   decl.warn(result, 'Avoid !important', { word: '!important' })
 * }
 * ```
 */
declare class Warning_ {
  /**
   * Column for inclusive start position in the input file with this warning’s source.
   *
   * ```js
   * warning.column //=> 6
   * ```
   */
  column: number

  /**
   * Column for exclusive end position in the input file with this warning’s source.
   *
   * ```js
   * warning.endColumn //=> 4
   * ```
   */
  endColumn?: number

  /**
   * Line for exclusive end position in the input file with this warning’s source.
   *
   * ```js
   * warning.endLine //=> 6
   * ```
   */
  endLine?: number

  /**
   * Line for inclusive start position in the input file with this warning’s source.
   *
   * ```js
   * warning.line //=> 5
   * ```
   */
  line: number

  /**
   * Contains the CSS node that caused the warning.
   *
   * ```js
   * warning.node.toString() //=> 'color: white !important'
   * ```
   */
  node: Node

  /**
   * The name of the plugin that created this warning.
   * When you call `Node#warn` it will fill this property automatically.
   *
   * ```js
   * warning.plugin //=> 'postcss-important'
   * ```
   */
  plugin: string

  /**
   * The warning message.
   *
   * ```js
   * warning.text //=> 'Try to avoid !important'
   * ```
   */
  text: string

  /**
   * Type to filter warnings from `Result#messages`.
   * Always equal to `"warning"`.
   */
  type: 'warning'

  /**
   * @param text Warning message.
   * @param opts Warning options.
   */
  constructor(text: string, opts?: Warning.WarningOptions)

  /**
   * Returns a warning position and message.
   *
   * ```js
   * warning.toString() //=> 'postcss-lint:a.css:10:14: Avoid !important'
   * ```
   *
   * @return Warning position and message.
   */
  toString(): string
}

declare class Warning extends Warning_ {}

export = Warning


code:
'use strict'

class Warning {
  constructor(text, opts = {}) {
    this.type = 'warning'
    this.text = text

    if (opts.node && opts.node.source) {
      let range = opts.node.rangeBy(opts)
      this.line = range.start.line
      this.column = range.start.column
      this.endLine = range.end.line
      this.endColumn = range.end.column
    }

    for (let opt in opts) this[opt] = opts[opt]
  }

  toString() {
    if (this.node) {
      return this.node.error(this.text, {
        index: this.index,
        plugin: this.plugin,
        word: this.word
      }).message
    }

    if (this.plugin) {
      return this.plugin + ': ' + this.text
    }

    return this.text
  }
}

module.exports = Warning
Warning.default = Warning


postcss

description: Tool for transforming styles with JS plugins

keywords:
css
postcss
rework
preprocessor
parser
source map
transform
manipulation
transpiler

type: opencollective

type: tidelift

type: github

author: Andrey Sitnik <andrey@sitnik.ru>

license: MIT

repository: postcss/postcss


code:
# 1.2.1
- fix version

# 1.2.0
- add `List.remove`
- build with LiveScript 1.6.0
- update dependencies
- remove coverage calculation

# 1.1.2
- add `Func.memoize`
- fix `zip-all` and `zip-with-all` corner case (no input)
- build with LiveScript 1.4.0

# 1.1.1
- curry `unique-by`, `minimum-by`

# 1.1.0
- added `List` functions: `maximum-by`, `minimum-by`, `unique-by`
- added `List` functions: `at`, `elem-index`, `elem-indices`, `find-index`, `find-indices`
- added `Str` functions: `capitalize`, `camelize`, `dasherize`
- added `Func` function: `over` - eg. ``same-length = (==) `over` (.length)``
- exported `Str.repeat` through main `prelude` object
- fixed definition of `foldr` and `foldr1`, the new correct definition is backwards incompatible with the old, incorrect one
- fixed issue with `fix`
- improved code coverage

# 1.0.3
- build browser versions

# 1.0.2
- bug fix for `flatten` - slight change with bug fix, flattens arrays only, not array-like objects

# 1.0.1
- bug fixes for `drop-while` and `take-while`

# 1.0.0
* massive update - separated functions into separate modules
* functions do not accept multiple types anymore - use different versions in their respective modules in some cases (eg. `Obj.map`), or use `chars` or `values` in other cases to transform into a list
* objects are no longer transformed into functions, simply use `(obj.)` in LiveScript to do that
* browser version now using browserify - use `prelude = require('prelude-ls')`
* added `compact`, `split`, `flatten`, `difference`, `intersection`, `union`, `count-by`, `group-by`, `chars`, `unchars`, `apply`
* added `lists-to-obj` which takes a list of keys and list of values and zips them up into an object, and the converse `obj-to-lists`
* added `pairs-to-obj` which takes a list of pairs (2 element lists) and creates an object, and the converse `obj-to-pairs`
* removed `cons`, `append` - use the concat operator
* removed `compose` - use the compose operator
* removed `obj-to-func` - use partially applied access (eg. `(obj.)`)
* removed `length` - use `(.length)`
* `sort-by` renamed to `sort-with`
* added new `sort-by`
* removed `compare` - just use the new `sort-by`
* `break-it` renamed `break-list`, (`Str.break-str` for the string version)
* added `Str.repeat` which creates a new string by repeating the input n times
* `unfold` as alias to `unfoldr` is no longer used
* fixed up style and compiled with LiveScript 1.1.1
* use Make instead of Slake
* greatly improved tests

# 0.6.0
* fixed various bugs
* added `fix`, a fixpoint (Y combinator) for anonymous recursive functions
* added `unfoldr` (alias `unfold`)
* calling `replicate` with a string now returns a list of strings
* removed `partial`, just use native partial application in LiveScript using the `_` placeholder, or currying
* added `sort`, `sortBy`, and `compare`

# 0.5.0
* removed `lookup` - use (.prop)
* removed `call` - use (.func arg1, arg2)
* removed `pluck` - use map (.prop), xs
* fixed buys wtih `head` and `last`
* added non-minifed browser version, as `prelude-browser.js`
* renamed `prelude-min.js` to `prelude-browser-min.js`
* renamed `zip` to `zipAll`
* renamed `zipWith` to `zipAllWith`
* added `zip`, a curried zip that takes only two arguments
* added `zipWith`, a curried zipWith that takes only two arguments

# 0.4.0
* added `parition` function
* added `curry` function
* removed `elem` function (use `in`)
* removed `notElem` function (use `not in`)

# 0.3.0
* added `listToObject`
* added `unique`
* added `objToFunc`
* added support for using strings in map and the like
* added support for using objects in map and the like
* added ability to use objects instead of functions in certain cases
* removed `error` (just use throw)
* added `tau` constant
* added `join`
* added `values`
* added `keys`
* added `partial`
* renamed `log` to `ln`
* added alias to `head`: `first`
* added `installPrelude` helper

# 0.2.0
* removed functions that simply warp operators as you can now use operators as functions in LiveScript
* `min/max` are now curried and take only 2 arguments
* added `call`

# 0.1.0
* initial public release


code:
# prelude.ls [![Build Status](https://travis-ci.org/gkz/prelude-ls.png?branch=master)](https://travis-ci.org/gkz/prelude-ls)

is a functionally oriented utility library. It is powerful and flexible. Almost all of its functions are curried. It is written in, and is the recommended base library for, LiveScript.

See **[the prelude.ls site](http://preludels.com)** for examples, a reference, and more.

You can install via npm `npm install prelude-ls`

### Development

`make test` to test

`make build` to build `lib` from `src`

`make build-browser` to build browser versions


code:
// Generated by LiveScript 1.6.0
var apply, curry, flip, fix, over, memoize, toString$ = {}.toString;
apply = curry$(function(f, list){
  return f.apply(null, list);
});
curry = function(f){
  return curry$(f);
};
flip = curry$(function(f, x, y){
  return f(y, x);
});
fix = function(f){
  return function(g){
    return function(){
      return f(g(g)).apply(null, arguments);
    };
  }(function(g){
    return function(){
      return f(g(g)).apply(null, arguments);
    };
  });
};
over = curry$(function(f, g, x, y){
  return f(g(x), g(y));
});
memoize = function(f){
  var memo;
  memo = {};
  return function(){
    var args, res$, i$, to$, key, arg;
    res$ = [];
    for (i$ = 0, to$ = arguments.length; i$ < to$; ++i$) {
      res$.push(arguments[i$]);
    }
    args = res$;
    key = (function(){
      var i$, ref$, len$, results$ = [];
      for (i$ = 0, len$ = (ref$ = args).length; i$ < len$; ++i$) {
        arg = ref$[i$];
        results$.push(arg + toString$.call(arg).slice(8, -1));
      }
      return results$;
    }()).join('');
    return memo[key] = key in memo
      ? memo[key]
      : f.apply(null, args);
  };
};
module.exports = {
  curry: curry,
  flip: flip,
  fix: fix,
  apply: apply,
  over: over,
  memoize: memoize
};
function curry$(f, bound){
  var context,
  _curry = function(args) {
    return f.length > 1 ? function(){
      var params = args ? args.concat() : [];
      context = bound ? context || this : this;
      return params.push.apply(params, arguments) <
          f.length && arguments.length ?
        _curry.call(context, params) : f.apply(context, params);
    } : f;
  };
  return _curry();
}


code:
// Generated by LiveScript 1.6.0
var each, map, compact, filter, reject, remove, partition, find, head, first, tail, last, initial, empty, reverse, unique, uniqueBy, fold, foldl, fold1, foldl1, foldr, foldr1, unfoldr, concat, concatMap, flatten, difference, intersection, union, countBy, groupBy, andList, orList, any, all, sort, sortWith, sortBy, sum, product, mean, average, maximum, minimum, maximumBy, minimumBy, scan, scanl, scan1, scanl1, scanr, scanr1, slice, take, drop, splitAt, takeWhile, dropWhile, span, breakList, zip, zipWith, zipAll, zipAllWith, at, elemIndex, elemIndices, findIndex, findIndices, toString$ = {}.toString;
each = curry$(function(f, xs){
  var i$, len$, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    f(x);
  }
  return xs;
});
map = curry$(function(f, xs){
  var i$, len$, x, results$ = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    results$.push(f(x));
  }
  return results$;
});
compact = function(xs){
  var i$, len$, x, results$ = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (x) {
      results$.push(x);
    }
  }
  return results$;
};
filter = curry$(function(f, xs){
  var i$, len$, x, results$ = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (f(x)) {
      results$.push(x);
    }
  }
  return results$;
});
reject = curry$(function(f, xs){
  var i$, len$, x, results$ = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (!f(x)) {
      results$.push(x);
    }
  }
  return results$;
});
remove = curry$(function(el, xs){
  var i, x$;
  i = elemIndex(el, xs);
  x$ = xs.slice();
  if (i != null) {
    x$.splice(i, 1);
  }
  return x$;
});
partition = curry$(function(f, xs){
  var passed, failed, i$, len$, x;
  passed = [];
  failed = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    (f(x) ? passed : failed).push(x);
  }
  return [passed, failed];
});
find = curry$(function(f, xs){
  var i$, len$, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (f(x)) {
      return x;
    }
  }
});
head = first = function(xs){
  return xs[0];
};
tail = function(xs){
  if (!xs.length) {
    return;
  }
  return xs.slice(1);
};
last = function(xs){
  return xs[xs.length - 1];
};
initial = function(xs){
  if (!xs.length) {
    return;
  }
  return xs.slice(0, -1);
};
empty = function(xs){
  return !xs.length;
};
reverse = function(xs){
  return xs.concat().reverse();
};
unique = function(xs){
  var result, i$, len$, x;
  result = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (!in$(x, result)) {
      result.push(x);
    }
  }
  return result;
};
uniqueBy = curry$(function(f, xs){
  var seen, i$, len$, x, val, results$ = [];
  seen = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    val = f(x);
    if (in$(val, seen)) {
      continue;
    }
    seen.push(val);
    results$.push(x);
  }
  return results$;
});
fold = foldl = curry$(function(f, memo, xs){
  var i$, len$, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    memo = f(memo, x);
  }
  return memo;
});
fold1 = foldl1 = curry$(function(f, xs){
  return fold(f, xs[0], xs.slice(1));
});
foldr = curry$(function(f, memo, xs){
  var i$, x;
  for (i$ = xs.length - 1; i$ >= 0; --i$) {
    x = xs[i$];
    memo = f(x, memo);
  }
  return memo;
});
foldr1 = curry$(function(f, xs){
  return foldr(f, xs[xs.length - 1], xs.slice(0, -1));
});
unfoldr = curry$(function(f, b){
  var result, x, that;
  result = [];
  x = b;
  while ((that = f(x)) != null) {
    result.push(that[0]);
    x = that[1];
  }
  return result;
});
concat = function(xss){
  return [].concat.apply([], xss);
};
concatMap = curry$(function(f, xs){
  var x;
  return [].concat.apply([], (function(){
    var i$, ref$, len$, results$ = [];
    for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) {
      x = ref$[i$];
      results$.push(f(x));
    }
    return results$;
  }()));
});
flatten = function(xs){
  var x;
  return [].concat.apply([], (function(){
    var i$, ref$, len$, results$ = [];
    for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) {
      x = ref$[i$];
      if (toString$.call(x).slice(8, -1) === 'Array') {
        results$.push(flatten(x));
      } else {
        results$.push(x);
      }
    }
    return results$;
  }()));
};
difference = function(xs){
  var yss, res$, i$, to$, results, len$, x, j$, len1$, ys;
  res$ = [];
  for (i$ = 1, to$ = arguments.length; i$ < to$; ++i$) {
    res$.push(arguments[i$]);
  }
  yss = res$;
  results = [];
  outer: for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    for (j$ = 0, len1$ = yss.length; j$ < len1$; ++j$) {
      ys = yss[j$];
      if (in$(x, ys)) {
        continue outer;
      }
    }
    results.push(x);
  }
  return results;
};
intersection = function(xs){
  var yss, res$, i$, to$, results, len$, x, j$, len1$, ys;
  res$ = [];
  for (i$ = 1, to$ = arguments.length; i$ < to$; ++i$) {
    res$.push(arguments[i$]);
  }
  yss = res$;
  results = [];
  outer: for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    for (j$ = 0, len1$ = yss.length; j$ < len1$; ++j$) {
      ys = yss[j$];
      if (!in$(x, ys)) {
        continue outer;
      }
    }
    results.push(x);
  }
  return results;
};
union = function(){
  var xss, res$, i$, to$, results, len$, xs, j$, len1$, x;
  res$ = [];
  for (i$ = 0, to$ = arguments.length; i$ < to$; ++i$) {
    res$.push(arguments[i$]);
  }
  xss = res$;
  results = [];
  for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) {
    xs = xss[i$];
    for (j$ = 0, len1$ = xs.length; j$ < len1$; ++j$) {
      x = xs[j$];
      if (!in$(x, results)) {
        results.push(x);
      }
    }
  }
  return results;
};
countBy = curry$(function(f, xs){
  var results, i$, len$, x, key;
  results = {};
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    key = f(x);
    if (key in results) {
      results[key] += 1;
    } else {
      results[key] = 1;
    }
  }
  return results;
});
groupBy = curry$(function(f, xs){
  var results, i$, len$, x, key;
  results = {};
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    key = f(x);
    if (key in results) {
      results[key].push(x);
    } else {
      results[key] = [x];
    }
  }
  return results;
});
andList = function(xs){
  var i$, len$, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (!x) {
      return false;
    }
  }
  return true;
};
orList = function(xs){
  var i$, len$, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (x) {
      return true;
    }
  }
  return false;
};
any = curry$(function(f, xs){
  var i$, len$, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (f(x)) {
      return true;
    }
  }
  return false;
});
all = curry$(function(f, xs){
  var i$, len$, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    if (!f(x)) {
      return false;
    }
  }
  return true;
});
sort = function(xs){
  return xs.concat().sort(function(x, y){
    if (x > y) {
      return 1;
    } else if (x < y) {
      return -1;
    } else {
      return 0;
    }
  });
};
sortWith = curry$(function(f, xs){
  return xs.concat().sort(f);
});
sortBy = curry$(function(f, xs){
  return xs.concat().sort(function(x, y){
    if (f(x) > f(y)) {
      return 1;
    } else if (f(x) < f(y)) {
      return -1;
    } else {
      return 0;
    }
  });
});
sum = function(xs){
  var result, i$, len$, x;
  result = 0;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    result += x;
  }
  return result;
};
product = function(xs){
  var result, i$, len$, x;
  result = 1;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    result *= x;
  }
  return result;
};
mean = average = function(xs){
  var sum, i$, len$, x;
  sum = 0;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    x = xs[i$];
    sum += x;
  }
  return sum / xs.length;
};
maximum = function(xs){
  var max, i$, ref$, len$, x;
  max = xs[0];
  for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) {
    x = ref$[i$];
    if (x > max) {
      max = x;
    }
  }
  return max;
};
minimum = function(xs){
  var min, i$, ref$, len$, x;
  min = xs[0];
  for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) {
    x = ref$[i$];
    if (x < min) {
      min = x;
    }
  }
  return min;
};
maximumBy = curry$(function(f, xs){
  var max, i$, ref$, len$, x;
  max = xs[0];
  for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) {
    x = ref$[i$];
    if (f(x) > f(max)) {
      max = x;
    }
  }
  return max;
});
minimumBy = curry$(function(f, xs){
  var min, i$, ref$, len$, x;
  min = xs[0];
  for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) {
    x = ref$[i$];
    if (f(x) < f(min)) {
      min = x;
    }
  }
  return min;
});
scan = scanl = curry$(function(f, memo, xs){
  var last, x;
  last = memo;
  return [memo].concat((function(){
    var i$, ref$, len$, results$ = [];
    for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) {
      x = ref$[i$];
      results$.push(last = f(last, x));
    }
    return results$;
  }()));
});
scan1 = scanl1 = curry$(function(f, xs){
  if (!xs.length) {
    return;
  }
  return scan(f, xs[0], xs.slice(1));
});
scanr = curry$(function(f, memo, xs){
  xs = xs.concat().reverse();
  return scan(f, memo, xs).reverse();
});
scanr1 = curry$(function(f, xs){
  if (!xs.length) {
    return;
  }
  xs = xs.concat().reverse();
  return scan(f, xs[0], xs.slice(1)).reverse();
});
slice = curry$(function(x, y, xs){
  return xs.slice(x, y);
});
take = curry$(function(n, xs){
  if (n <= 0) {
    return xs.slice(0, 0);
  } else {
    return xs.slice(0, n);
  }
});
drop = curry$(function(n, xs){
  if (n <= 0) {
    return xs;
  } else {
    return xs.slice(n);
  }
});
splitAt = curry$(function(n, xs){
  return [take(n, xs), drop(n, xs)];
});
takeWhile = curry$(function(p, xs){
  var len, i;
  len = xs.length;
  if (!len) {
    return xs;
  }
  i = 0;
  while (i < len && p(xs[i])) {
    i += 1;
  }
  return xs.slice(0, i);
});
dropWhile = curry$(function(p, xs){
  var len, i;
  len = xs.length;
  if (!len) {
    return xs;
  }
  i = 0;
  while (i < len && p(xs[i])) {
    i += 1;
  }
  return xs.slice(i);
});
span = curry$(function(p, xs){
  return [takeWhile(p, xs), dropWhile(p, xs)];
});
breakList = curry$(function(p, xs){
  return span(compose$(p, not$), xs);
});
zip = curry$(function(xs, ys){
  var result, len, i$, len$, i, x;
  result = [];
  len = ys.length;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    i = i$;
    x = xs[i$];
    if (i === len) {
      break;
    }
    result.push([x, ys[i]]);
  }
  return result;
});
zipWith = curry$(function(f, xs, ys){
  var result, len, i$, len$, i, x;
  result = [];
  len = ys.length;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    i = i$;
    x = xs[i$];
    if (i === len) {
      break;
    }
    result.push(f(x, ys[i]));
  }
  return result;
});
zipAll = function(){
  var xss, res$, i$, to$, minLength, len$, xs, ref$, i, lresult$, j$, results$ = [];
  res$ = [];
  for (i$ = 0, to$ = arguments.length; i$ < to$; ++i$) {
    res$.push(arguments[i$]);
  }
  xss = res$;
  minLength = undefined;
  for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) {
    xs = xss[i$];
    minLength <= (ref$ = xs.length) || (minLength = ref$);
  }
  for (i$ = 0; i$ < minLength; ++i$) {
    i = i$;
    lresult$ = [];
    for (j$ = 0, len$ = xss.length; j$ < len$; ++j$) {
      xs = xss[j$];
      lresult$.push(xs[i]);
    }
    results$.push(lresult$);
  }
  return results$;
};
zipAllWith = function(f){
  var xss, res$, i$, to$, minLength, len$, xs, ref$, i, results$ = [];
  res$ = [];
  for (i$ = 1, to$ = arguments.length; i$ < to$; ++i$) {
    res$.push(arguments[i$]);
  }
  xss = res$;
  minLength = undefined;
  for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) {
    xs = xss[i$];
    minLength <= (ref$ = xs.length) || (minLength = ref$);
  }
  for (i$ = 0; i$ < minLength; ++i$) {
    i = i$;
    results$.push(f.apply(null, (fn$())));
  }
  return results$;
  function fn$(){
    var i$, ref$, len$, results$ = [];
    for (i$ = 0, len$ = (ref$ = xss).length; i$ < len$; ++i$) {
      xs = ref$[i$];
      results$.push(xs[i]);
    }
    return results$;
  }
};
at = curry$(function(n, xs){
  if (n < 0) {
    return xs[xs.length + n];
  } else {
    return xs[n];
  }
});
elemIndex = curry$(function(el, xs){
  var i$, len$, i, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    i = i$;
    x = xs[i$];
    if (x === el) {
      return i;
    }
  }
});
elemIndices = curry$(function(el, xs){
  var i$, len$, i, x, results$ = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    i = i$;
    x = xs[i$];
    if (x === el) {
      results$.push(i);
    }
  }
  return results$;
});
findIndex = curry$(function(f, xs){
  var i$, len$, i, x;
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    i = i$;
    x = xs[i$];
    if (f(x)) {
      return i;
    }
  }
});
findIndices = curry$(function(f, xs){
  var i$, len$, i, x, results$ = [];
  for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
    i = i$;
    x = xs[i$];
    if (f(x)) {
      results$.push(i);
    }
  }
  return results$;
});
module.exports = {
  each: each,
  map: map,
  filter: filter,
  compact: compact,
  reject: reject,
  remove: remove,
  partition: partition,
  find: find,
  head: head,
  first: first,
  tail: tail,
  last: last,
  initial: initial,
  empty: empty,
  reverse: reverse,
  difference: difference,
  intersection: intersection,
  union: union,
  countBy: countBy,
  groupBy: groupBy,
  fold: fold,
  fold1: fold1,
  foldl: foldl,
  foldl1: foldl1,
  foldr: foldr,
  foldr1: foldr1,
  unfoldr: unfoldr,
  andList: andList,
  orList: orList,
  any: any,
  all: all,
  unique: unique,
  uniqueBy: uniqueBy,
  sort: sort,
  sortWith: sortWith,
  sortBy: sortBy,
  sum: sum,
  product: product,
  mean: mean,
  average: average,
  concat: concat,
  concatMap: concatMap,
  flatten: flatten,
  maximum: maximum,
  minimum: minimum,
  maximumBy: maximumBy,
  minimumBy: minimumBy,
  scan: scan,
  scan1: scan1,
  scanl: scanl,
  scanl1: scanl1,
  scanr: scanr,
  scanr1: scanr1,
  slice: slice,
  take: take,
  drop: drop,
  splitAt: splitAt,
  takeWhile: takeWhile,
  dropWhile: dropWhile,
  span: span,
  breakList: breakList,
  zip: zip,
  zipWith: zipWith,
  zipAll: zipAll,
  zipAllWith: zipAllWith,
  at: at,
  elemIndex: elemIndex,
  elemIndices: elemIndices,
  findIndex: findIndex,
  findIndices: findIndices
};
function curry$(f, bound){
  var context,
  _curry = function(args) {
    return f.length > 1 ? function(){
      var params = args ? args.concat() : [];
      context = bound ? context || this : this;
      return params.push.apply(params, arguments) <
          f.length && arguments.length ?
        _curry.call(context, params) : f.apply(context, params);
    } : f;
  };
  return _curry();
}
function in$(x, xs){
  var i = -1, l = xs.length >>> 0;
  while (++i < l) if (x === xs[i]) return true;
  return false;
}
function compose$() {
  var functions = arguments;
  return function() {
    var i, result;
    result = functions[0].apply(this, arguments);
    for (i = 1; i < functions.length; ++i) {
      result = functions[i](result);
    }
    return result;
  };
}
function not$(x){ return !x; }