require! {'./config': {banner}, fs: {readFile, writeFile, unlink}, webpack}

list = <[
  es5
  es6.symbol
  es6.object.assign
  es6.object.is
  es6.object.set-prototype-of
  es6.object.to-string
  es6.object.statics-accept-primitives
  es6.function.name
  es6.function.has-instance
  es6.number.constructor
  es6.number.statics
  es6.math
  es6.string.from-code-point
  es6.string.raw
  es6.string.iterator
  es6.string.code-point-at
  es6.string.ends-with
  es6.string.includes
  es6.string.repeat
  es6.string.starts-with
  es6.array.from
  es6.array.of
  es6.array.iterator
  es6.array.species
  es6.array.copy-within
  es6.array.fill
  es6.array.find
  es6.array.find-index
  es6.regexp
  es6.promise
  es6.map
  es6.set
  es6.weak-map
  es6.weak-set
  es6.reflect
  es7.array.includes
  es7.string.at
  es7.string.lpad
  es7.string.rpad
  es7.regexp.escape
  es7.object.get-own-property-descriptors
  es7.object.to-array
  es7.map.to-json
  es7.set.to-json
  es7.observable
  web.immediate
  web.dom.iterable
  web.timers
  core.dict
  core.iter-helpers
  core.$for
  core.delay
  core.function.part
  core.object
  core.array.turn
  core.number.iterator
  core.number.math
  core.string.escape-html
  core.date
  core.global
  core.log
  js.array.statics
]>

experimental = <[
  es7.observable
]>

libraryBlacklist = <[
  es6.object.to-string
  es6.function.name
  es6.regexp
  es6.number.constructor
]>

module.exports = ({modules = [], blacklist = [], library = no}, next)!->
  let @ = modules.reduce ((memo, it)-> memo[it] = on; memo), {}
    check = (err)->
      if err
        next err, ''
        on

    if @exp => for experimental => @[..] = on
    for ns of @
      if @[ns]
        for name in list
          if name.indexOf("#ns.") is 0 and name not in experimental
            @[name] = on

    if library => blacklist ++= libraryBlacklist
    for ns in blacklist
      for name in list
        if name is ns or name.indexOf("#ns.") is 0
          @[name] = no

    ENTRY = "./__tmp#{ Math.random! }__.js"
    PATH = ".#{ if library => '/library' else '' }/modules/"
    err <-! writeFile ENTRY, list.filter(~> @[it]).map(-> "require('#PATH#it');" ).join '\n'
    if check err => return
    TARGET = "./__tmp#{ Math.random! }__.js"
    err, info <-! webpack entry: ENTRY, output: { path: '', filename: TARGET }
    if check err => return
    err, script <-! readFile TARGET
    if check err => return
    err <-! unlink ENTRY
    if check err => return
    err <-! unlink TARGET
    if check err => return

    next null """
      #banner
      !function(undefined){
      'use strict';
      var __e = null, __g = null;
      
      #script
      // CommonJS export
      if(typeof module != 'undefined' && module.exports)module.exports = __e;
      // RequireJS export
      else if(typeof define == 'function' && define.amd)define(function(){return __e});
      // Export to global object
      else __g.core = __e;
      }();
      """
