<commit_before>'use strict'

const electron = require('electron')
const ipcMain = electron.ipcMain
const objectsRegistry = require('./objects-registry')
const v8Util = process.atomBinding('v8_util')
const IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap

// The internal properties of Function.
const FUNCTION_PROPERTIES = [
  'length', 'name', 'arguments', 'caller', 'prototype'
]

// The remote functions in renderer processes.
// (webContentsId) => {id: Function}
let rendererFunctions = {}

// Return the description of object's members:
let getObjectMembers = function (object) {
  let names = Object.getOwnPropertyNames(object)
  // For Function, we should not override following properties even though they
  // are "own" properties.
  if (typeof object === 'function') {
    names = names.filter((name) => {
      return !FUNCTION_PROPERTIES.includes(name)
    })
  }
  // Map properties to descriptors.
  return names.map((name) => {
    let descriptor = Object.getOwnPropertyDescriptor(object, name)
    let member = {name, enumerable: descriptor.enumerable, writable: false}
    if (descriptor.get === undefined && typeof object[name] === 'function') {
      member.type = 'method'
    } else {
      if (descriptor.set || descriptor.writable) member.writable = true
      member.type = 'get'
    }
    return member
  })
}

// Return the description of object's prototype.
let getObjectPrototype = function (object) {
  let proto = Object.getPrototypeOf(object)
  if (proto === null || proto === Object.prototype) return null
  return {
    members: getObjectMembers(proto),
    proto: getObjectPrototype(proto)
  }
}

// Convert a real value into meta data.
let valueToMeta = function (sender, value, optimizeSimpleObject = false) {
  // Determine the type of value.
  let meta = { type: typeof value }
  if (Buffer.isBuffer(value)) {
    meta.type = 'buffer'
  } else if (value === null) {
    meta.type = 'value'
  } else if (Array.isArray(value)) {
    meta.type = 'array'
  } else if (value instanceof Error) {
    meta.type = 'error'
  } else if (value instanceof Date) {
    meta.type = 'date'
  } else if (meta.type === 'object') {
    // Recognize certain types of objects.
    if (value.constructor != null && value.constructor.name === 'Promise') {
      meta.type = 'promise'
    } else if (value.hasOwnProperty('callee') && value.length != null) {
      // Treat the arguments object as array.
      meta.type = 'array'
    } else if (optimizeSimpleObject && v8Util.getHiddenValue(value, 'simple')) {
      // Treat simple objects as value.
      meta.type = 'value'
    }
  }

  // Fill the meta object according to value's type.
  if (meta.type === 'array') {
    meta.members = value.map((el) => valueToMeta(sender, el))
  } else if (meta.type === 'object' || meta.type === 'function') {
    meta.name = value.constructor ? value.constructor.name : ''

    // Reference the original value if it's an object, because when it's
    // passed to renderer we would assume the renderer keeps a reference of
    // it.
    meta.id = objectsRegistry.add(sender, value)
    meta.members = getObjectMembers(value)
    meta.proto = getObjectPrototype(value)
  } else if (meta.type === 'buffer') {
    meta.value = Array.prototype.slice.call(value, 0)
  } else if (meta.type === 'promise') {
    meta.then = valueToMeta(sender, function (v) { value.then(v) })
  } else if (meta.type === 'error') {
    meta.members = plainObjectToMeta(value)

    // Error.name is not part of own properties.
    meta.members.push({
      name: 'name',
      value: value.name
    })
  } else if (meta.type === 'date') {
    meta.value = value.getTime()
  } else {
    meta.type = 'value'
    meta.value = value
  }
  return meta
}

// Convert object to meta by value.
var plainObjectToMeta = function (obj) {
  return Object.getOwnPropertyNames(obj).map(function (name) {
    return {
      name: name,
      value: obj[name]
    }
  })
}

// Convert Error into meta data.
var exceptionToMeta = function (error) {
  return {
    type: 'exception',
    message: error.message,
    stack: error.stack || error
  }
}

// Convert array of meta data from renderer into array of real values.
var unwrapArgs = function (sender, args) {
  var metaToValue
  metaToValue = function (meta) {
    var i, len, member, ref, returnValue
    switch (meta.type) {
      case 'value':
        return meta.value
      case 'remote-object':
        return objectsRegistry.get(meta.id)
      case 'array':
        return unwrapArgs(sender, meta.value)
      case 'buffer':
        return new Buffer(meta.value)
      case 'date':
        return new Date(meta.value)
      case 'promise':
        return Promise.resolve({
          then: metaToValue(meta.then)
        })
      case 'object': {
        let ret = {}
        Object.defineProperty(ret.constructor, 'name', { value: meta.name })

        ref = meta.members
        for (i = 0, len = ref.length; i < len; i++) {
          member = ref[i]
          ret[member.name] = metaToValue(member.value)
        }
        return ret
      }
      case 'function-with-return-value':
        returnValue = metaToValue(meta.value)
        return function () {
          return returnValue
        }
      case 'function': {
        // Cache the callbacks in renderer.
        let webContentsId = sender.getId()
        let callbacks = rendererFunctions[webContentsId]
        if (!callbacks) {
          callbacks = rendererFunctions[webContentsId] = new IDWeakMap()
          sender.once('render-view-deleted', function (event, id) {
            callbacks.clear()
            delete rendererFunctions[id]
          })
        }

        if (callbacks.has(meta.id)) return callbacks.get(meta.id)

        let callIntoRenderer = function (...args) {
          if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) {
            sender.send('ELECTRON_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args))
          } else {
            throw new Error(`Attempting to call a function in a renderer window that has been closed or released. Function provided here: ${meta.location}.`)
          }
        }
        v8Util.setDestructor(callIntoRenderer, function () {
          if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) {
            sender.send('ELECTRON_RENDERER_RELEASE_CALLBACK', meta.id)
          }
        })
        callbacks.set(meta.id, callIntoRenderer)
        return callIntoRenderer
      }
      default:
        throw new TypeError(`Unknown type: ${meta.type}`)
    }
  }
  return args.map(metaToValue)
}

// Call a function and send reply asynchronously if it's a an asynchronous
// style function and the caller didn't pass a callback.
var callFunction = function (event, func, caller, args) {
  var funcMarkedAsync, funcName, funcPassedCallback, ref, ret
  funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous')
  funcPassedCallback = typeof args[args.length - 1] === 'function'
  try {
    if (funcMarkedAsync && !funcPassedCallback) {
      args.push(function (ret) {
        event.returnValue = valueToMeta(event.sender, ret, true)
      })
      return func.apply(caller, args)
    } else {
      ret = func.apply(caller, args)
      event.returnValue = valueToMeta(event.sender, ret, true)
    }
  } catch (error) {
    // Catch functions thrown further down in function invocation and wrap
    // them with the function name so it's easier to trace things like
    // `Error processing argument -1.`
    funcName = ((ref = func.name) != null) ? ref : 'anonymous'
    throw new Error(`Could not call remote function '${funcName}'. Check that the function signature is correct. Underlying error: ${error.message}`)
  }
}

ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, module) {
  try {
    event.returnValue = valueToMeta(event.sender, process.mainModule.require(module))
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_GET_BUILTIN', function (event, module) {
  try {
    event.returnValue = valueToMeta(event.sender, electron[module])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_GLOBAL', function (event, name) {
  try {
    event.returnValue = valueToMeta(event.sender, global[name])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WINDOW', function (event) {
  try {
    event.returnValue = valueToMeta(event.sender, event.sender.getOwnerBrowserWindow())
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event) {
  event.returnValue = valueToMeta(event.sender, event.sender)
})

ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, id, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let constructor = objectsRegistry.get(id)

    // Call new with array of arguments.
    // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
    let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))
    event.returnValue = valueToMeta(event.sender, obj)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, id, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let func = objectsRegistry.get(id)
    return callFunction(event, func, global, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let constructor = objectsRegistry.get(id)[method]

    // Call new with array of arguments.
    let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))
    event.returnValue = valueToMeta(event.sender, obj)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let obj = objectsRegistry.get(id)
    return callFunction(event, obj[method], obj, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, value) {
  try {
    let obj = objectsRegistry.get(id)
    obj[name] = value
    event.returnValue = null
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, id, name) {
  try {
    let obj = objectsRegistry.get(id)
    event.returnValue = valueToMeta(event.sender, obj[name])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_DEREFERENCE', function (event, id) {
  return objectsRegistry.remove(event.sender.getId(), id)
})

ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, guestInstanceId) {
  try {
    let guestViewManager = require('./guest-view-manager')
    event.returnValue = valueToMeta(event.sender, guestViewManager.getGuest(guestInstanceId))
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function (event, requestId, guestInstanceId, method, ...args) {
  try {
    let guestViewManager = require('./guest-view-manager')
    let guest = guestViewManager.getGuest(guestInstanceId)
    if (requestId) {
      const responseCallback = function (result) {
        event.sender.send(`ELECTRON_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, result)
      }
      args.push(responseCallback)
    }
    guest[method].apply(guest, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})
<commit_msg>buffer, null, array etc. all belong to object<commit_after>'use strict'

const electron = require('electron')
const ipcMain = electron.ipcMain
const objectsRegistry = require('./objects-registry')
const v8Util = process.atomBinding('v8_util')
const IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap

// The internal properties of Function.
const FUNCTION_PROPERTIES = [
  'length', 'name', 'arguments', 'caller', 'prototype'
]

// The remote functions in renderer processes.
// (webContentsId) => {id: Function}
let rendererFunctions = {}

// Return the description of object's members:
let getObjectMembers = function (object) {
  let names = Object.getOwnPropertyNames(object)
  // For Function, we should not override following properties even though they
  // are "own" properties.
  if (typeof object === 'function') {
    names = names.filter((name) => {
      return !FUNCTION_PROPERTIES.includes(name)
    })
  }
  // Map properties to descriptors.
  return names.map((name) => {
    let descriptor = Object.getOwnPropertyDescriptor(object, name)
    let member = {name, enumerable: descriptor.enumerable, writable: false}
    if (descriptor.get === undefined && typeof object[name] === 'function') {
      member.type = 'method'
    } else {
      if (descriptor.set || descriptor.writable) member.writable = true
      member.type = 'get'
    }
    return member
  })
}

// Return the description of object's prototype.
let getObjectPrototype = function (object) {
  let proto = Object.getPrototypeOf(object)
  if (proto === null || proto === Object.prototype) return null
  return {
    members: getObjectMembers(proto),
    proto: getObjectPrototype(proto)
  }
}

// Convert a real value into meta data.
let valueToMeta = function (sender, value, optimizeSimpleObject = false) {
  // Determine the type of value.
  let meta = { type: typeof value }
  if (meta.type === 'object') {
    // Recognize certain types of objects.
    if (value === null) {
      meta.type = 'value'
    } else if (Buffer.isBuffer(value)) {
      meta.type = 'buffer'
    } else if (Array.isArray(value)) {
      meta.type = 'array'
    } else if (value instanceof Error) {
      meta.type = 'error'
    } else if (value instanceof Date) {
      meta.type = 'date'
    } else if (value.constructor != null && value.constructor.name === 'Promise') {
      meta.type = 'promise'
    } else if (value.hasOwnProperty('callee') && value.length != null) {
      // Treat the arguments object as array.
      meta.type = 'array'
    } else if (optimizeSimpleObject && v8Util.getHiddenValue(value, 'simple')) {
      // Treat simple objects as value.
      meta.type = 'value'
    }
  }

  // Fill the meta object according to value's type.
  if (meta.type === 'array') {
    meta.members = value.map((el) => valueToMeta(sender, el))
  } else if (meta.type === 'object' || meta.type === 'function') {
    meta.name = value.constructor ? value.constructor.name : ''

    // Reference the original value if it's an object, because when it's
    // passed to renderer we would assume the renderer keeps a reference of
    // it.
    meta.id = objectsRegistry.add(sender, value)
    meta.members = getObjectMembers(value)
    meta.proto = getObjectPrototype(value)
  } else if (meta.type === 'buffer') {
    meta.value = Array.prototype.slice.call(value, 0)
  } else if (meta.type === 'promise') {
    meta.then = valueToMeta(sender, function (v) { value.then(v) })
  } else if (meta.type === 'error') {
    meta.members = plainObjectToMeta(value)

    // Error.name is not part of own properties.
    meta.members.push({
      name: 'name',
      value: value.name
    })
  } else if (meta.type === 'date') {
    meta.value = value.getTime()
  } else {
    meta.type = 'value'
    meta.value = value
  }
  return meta
}

// Convert object to meta by value.
var plainObjectToMeta = function (obj) {
  return Object.getOwnPropertyNames(obj).map(function (name) {
    return {
      name: name,
      value: obj[name]
    }
  })
}

// Convert Error into meta data.
var exceptionToMeta = function (error) {
  return {
    type: 'exception',
    message: error.message,
    stack: error.stack || error
  }
}

// Convert array of meta data from renderer into array of real values.
var unwrapArgs = function (sender, args) {
  var metaToValue
  metaToValue = function (meta) {
    var i, len, member, ref, returnValue
    switch (meta.type) {
      case 'value':
        return meta.value
      case 'remote-object':
        return objectsRegistry.get(meta.id)
      case 'array':
        return unwrapArgs(sender, meta.value)
      case 'buffer':
        return new Buffer(meta.value)
      case 'date':
        return new Date(meta.value)
      case 'promise':
        return Promise.resolve({
          then: metaToValue(meta.then)
        })
      case 'object': {
        let ret = {}
        Object.defineProperty(ret.constructor, 'name', { value: meta.name })

        ref = meta.members
        for (i = 0, len = ref.length; i < len; i++) {
          member = ref[i]
          ret[member.name] = metaToValue(member.value)
        }
        return ret
      }
      case 'function-with-return-value':
        returnValue = metaToValue(meta.value)
        return function () {
          return returnValue
        }
      case 'function': {
        // Cache the callbacks in renderer.
        let webContentsId = sender.getId()
        let callbacks = rendererFunctions[webContentsId]
        if (!callbacks) {
          callbacks = rendererFunctions[webContentsId] = new IDWeakMap()
          sender.once('render-view-deleted', function (event, id) {
            callbacks.clear()
            delete rendererFunctions[id]
          })
        }

        if (callbacks.has(meta.id)) return callbacks.get(meta.id)

        let callIntoRenderer = function (...args) {
          if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) {
            sender.send('ELECTRON_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args))
          } else {
            throw new Error(`Attempting to call a function in a renderer window that has been closed or released. Function provided here: ${meta.location}.`)
          }
        }
        v8Util.setDestructor(callIntoRenderer, function () {
          if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) {
            sender.send('ELECTRON_RENDERER_RELEASE_CALLBACK', meta.id)
          }
        })
        callbacks.set(meta.id, callIntoRenderer)
        return callIntoRenderer
      }
      default:
        throw new TypeError(`Unknown type: ${meta.type}`)
    }
  }
  return args.map(metaToValue)
}

// Call a function and send reply asynchronously if it's a an asynchronous
// style function and the caller didn't pass a callback.
var callFunction = function (event, func, caller, args) {
  var funcMarkedAsync, funcName, funcPassedCallback, ref, ret
  funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous')
  funcPassedCallback = typeof args[args.length - 1] === 'function'
  try {
    if (funcMarkedAsync && !funcPassedCallback) {
      args.push(function (ret) {
        event.returnValue = valueToMeta(event.sender, ret, true)
      })
      return func.apply(caller, args)
    } else {
      ret = func.apply(caller, args)
      event.returnValue = valueToMeta(event.sender, ret, true)
    }
  } catch (error) {
    // Catch functions thrown further down in function invocation and wrap
    // them with the function name so it's easier to trace things like
    // `Error processing argument -1.`
    funcName = ((ref = func.name) != null) ? ref : 'anonymous'
    throw new Error(`Could not call remote function '${funcName}'. Check that the function signature is correct. Underlying error: ${error.message}`)
  }
}

ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, module) {
  try {
    event.returnValue = valueToMeta(event.sender, process.mainModule.require(module))
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_GET_BUILTIN', function (event, module) {
  try {
    event.returnValue = valueToMeta(event.sender, electron[module])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_GLOBAL', function (event, name) {
  try {
    event.returnValue = valueToMeta(event.sender, global[name])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WINDOW', function (event) {
  try {
    event.returnValue = valueToMeta(event.sender, event.sender.getOwnerBrowserWindow())
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event) {
  event.returnValue = valueToMeta(event.sender, event.sender)
})

ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, id, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let constructor = objectsRegistry.get(id)

    // Call new with array of arguments.
    // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
    let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))
    event.returnValue = valueToMeta(event.sender, obj)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, id, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let func = objectsRegistry.get(id)
    return callFunction(event, func, global, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let constructor = objectsRegistry.get(id)[method]

    // Call new with array of arguments.
    let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))
    event.returnValue = valueToMeta(event.sender, obj)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let obj = objectsRegistry.get(id)
    return callFunction(event, obj[method], obj, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, value) {
  try {
    let obj = objectsRegistry.get(id)
    obj[name] = value
    event.returnValue = null
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, id, name) {
  try {
    let obj = objectsRegistry.get(id)
    event.returnValue = valueToMeta(event.sender, obj[name])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_DEREFERENCE', function (event, id) {
  return objectsRegistry.remove(event.sender.getId(), id)
})

ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, guestInstanceId) {
  try {
    let guestViewManager = require('./guest-view-manager')
    event.returnValue = valueToMeta(event.sender, guestViewManager.getGuest(guestInstanceId))
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function (event, requestId, guestInstanceId, method, ...args) {
  try {
    let guestViewManager = require('./guest-view-manager')
    let guest = guestViewManager.getGuest(guestInstanceId)
    if (requestId) {
      const responseCallback = function (result) {
        event.sender.send(`ELECTRON_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, result)
      }
      args.push(responseCallback)
    }
    guest[method].apply(guest, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})
<|endoftext|>


<commit_before>var _ = require('lodash');
var console = require('miaow-util').console;
var mutil = require('miaow-util');
var Tapable = require('tapable');

var Compilation = require('./Compilation');
var ModuleFactory = require('./ModuleFactory');
var Resolver = require('./Resolver');
var Watcher = require('./Watcher');

function Compiler(options) {
  Tapable.call(this);
  _.bindAll(this);

  this.context = options.context;
  this.output = options.output;
  this.options = options;

  this.resolver = new Resolver(options.resolve);
}

Compiler.prototype = Object.create(Tapable.prototype);
Compiler.prototype.constructor = Compiler;

Compiler.prototype.run = function(callback) {
  this.applyPluginsAsync('run', function(err) {
    if (err) {
      return callback(err);
    }

    this.compile(callback);
  }.bind(this));
};

Compiler.prototype.watch = function(callback) {
  var watcher = new Watcher(this, callback);
  watcher.watch(callback);
};

Compiler.prototype.compile = function(callback) {
  var compiler = this;
  var compilation = new Compilation();
  compilation.factory = new ModuleFactory(this.options.modules);
  compilation.resolver = this.resolver;
  compilation.context = this.context;
  compilation.exclude = this.options.exclude;
  compilation.output = this.output;
  compilation.startTime = new Date();

  console.log('开始编译');

  this.applyPluginsAsyncSeries('compile', compilation, function(err) {
    if (err) {
      return callback(err);
    }

    compilation.seal(function(err) {
      if (err) {
        console.error('编译失败');
        return compiler.applyPluginsAsyncSeries('compile-failed', compilation, function() {
          callback(err);
        });
      }

      console.log('编译成功，编译' + _.size(compilation.modules) + '个模块，耗时' + mutil.duration(new Date() - compilation.startTime));
      compiler.applyPluginsAsyncSeries('compile-success', compilation, function(err) {
        callback(err);
      });
    });
  });
};

module.exports = Compiler;
<commit_msg>将debug参数扩展到编译对象上<commit_after>var _ = require('lodash');
var console = require('miaow-util').console;
var mutil = require('miaow-util');
var Tapable = require('tapable');

var Compilation = require('./Compilation');
var ModuleFactory = require('./ModuleFactory');
var Resolver = require('./Resolver');
var Watcher = require('./Watcher');

function Compiler(options) {
  Tapable.call(this);
  _.bindAll(this);

  this.context = options.context;
  this.output = options.output;
  this.debug = options.debug;
  this.options = options;

  this.resolver = new Resolver(options.resolve);
}

Compiler.prototype = Object.create(Tapable.prototype);
Compiler.prototype.constructor = Compiler;

Compiler.prototype.run = function(callback) {
  this.applyPluginsAsync('run', function(err) {
    if (err) {
      return callback(err);
    }

    this.compile(callback);
  }.bind(this));
};

Compiler.prototype.watch = function(callback) {
  var watcher = new Watcher(this, callback);
  watcher.watch(callback);
};

Compiler.prototype.compile = function(callback) {
  var compiler = this;
  var compilation = new Compilation();
  compilation.factory = new ModuleFactory(this.options.modules);
  compilation.resolver = this.resolver;
  compilation.context = this.context;
  compilation.exclude = this.options.exclude;
  compilation.debug = this.debug;
  compilation.output = this.output;
  compilation.startTime = new Date();

  console.log('开始编译');

  this.applyPluginsAsyncSeries('compile', compilation, function(err) {
    if (err) {
      return callback(err);
    }

    compilation.seal(function(err) {
      if (err) {
        console.error('编译失败');
        return compiler.applyPluginsAsyncSeries('compile-failed', compilation, function() {
          callback(err);
        });
      }

      console.log('编译成功，编译' + _.size(compilation.modules) + '个模块，耗时' + mutil.duration(new Date() - compilation.startTime));
      compiler.applyPluginsAsyncSeries('compile-success', compilation, function(err) {
        callback(err);
      });
    });
  });
};

module.exports = Compiler;
<|endoftext|>


<commit_before>var PhenoTips = (function (PhenoTips) {
  var widgets = PhenoTips.widgets = PhenoTips.widgets || {};

  widgets.FuzzyDatePickerDropdown = Class.create({
    initialize : function(options) {
      this.dropdown = new Element('select', {
        "name"        : options.name     || '',
        "class"       : options.cssClass || options.name || '',
        "placeholder" : options.hint     || options.name || '',
        "title"       : options.hint     || options.name || ''
      });
    },

    populate : function(values) {
      var selectedIndex = this.dropdown.selectedIndex || this._tmpSelectedIndex;
      this.dropdown.update(new Element('option', {'value' : "", "class" : "empty"}));
      var _this = this;
      values.each(function (item) {
         var optionData = {};
         optionData.value = item.value;
         if (item.cssClass) {
            optionData["class"] = item.cssClass;
         }
         //if (item.value == selectedValue) {
         //   optionData.selected = "selected";
         //}
         _this.dropdown.insert(new Element('option', optionData).update(item.text || item.value || ''));
      });
      if (this.dropdown.selectedIndex <= 0 && selectedIndex >= 0 && selectedIndex < this.dropdown.options.length) {
        this.dropdown.selectedIndex = selectedIndex;
      }
    },

    enable : function () {
      this.dropdown.enable();
      this.dropdown.focus();
      if (this.dropdown.selectedIndex <= 0 && this._tmpSelectedIndex < this.dropdown.options.length) {
        this.dropdown.selectedIndex = this._tmpSelectedIndex;
      }
    },

    disable : function () {
      this.dropdown.disable();
      this._tmpSelectedIndex = this.dropdown.selectedIndex;
      this.dropdown.selectedIndex = 0;
    },

    getElement : function() {
      return this.dropdown;
    },

    onSelect : function(callback) {
      var _this = this;
      this.dropdown.observe('change',function() {
        callback();
        _this._tmpSelectedIndex = _this.dropdown.selectedIndex;
      });
    },

    onFocus : function(callback) {
      var _this = this;
      this.dropdown.observe('focus', function() {
        callback();
        if (_this.dropdown.selectedIndex == -1 && _this._tmpSelectedIndex < _this.dropdown.options.size()) {
          _this.dropdown.selectedIndex = _this._tmpSelectedIndex;
        }
      });
    },
    onBlur : function(callback) {
      this.dropdown.observe('blur', callback);
    },

    getSelectedValue : function () {
       return (this.dropdown.selectedIndex >= 0) ? this.dropdown.options[this.dropdown.selectedIndex].value : '';
    },

    getSelectedOption : function () {
       return (this.dropdown.selectedIndex >= 0) ? this.dropdown.options[this.dropdown.selectedIndex].innerHTML : '';
    }
  });

  widgets.FuzzyDatePicker = Class.create({
    initialize : function (input) {
      if (!input) {return};
      this.__input = input;
      this.__input.hide();

      this.container = new Element('div', {'class' : 'fuzzy-date-picker'});
      this.__input.insert({after : this.container});
      this.container.insert(this.createYearDropdown());
      this.container.insert(this.createMonthDropdown());
      this.container.insert(this.createDayDropdown());

      // TODO: yearSelector's (and month's & day's) .onSelect() does not seem to fire
      //       upon programmatic update if a substitute is found can remove these hackish events
      this.container.observe("datepicker:date:changed", this.onProgrammaticUpdate.bind(this));
    },

    onProgrammaticUpdate : function() {
        this.yearSelected();
        this.monthSelected();
        this.updateDate();
    },

    createYearDropdown : function() {
      this.yearSelector = new widgets.FuzzyDatePickerDropdown({name: "year"});

      var today = new Date();
      var crtYear = today.getYear() + 1900;
      var startYear = 1900;

      var values = [];
      for (var y = crtYear; y >= startYear; --y) {
        values.push({"value" : y});
        if (y % 10 == 0) {
            values.push({"value" : (y + "s"), "cssClass" : "decade", "text" : (y + 's')});
        }
      }
      values.push({"value": "1800s"});
      values.push({"value": "1700s"});
      values.push({"value": "1600s"});

      this.yearSelector.populate(values);
      this.yearSelector.onSelect(this.yearSelected.bind(this));

      return this.yearSelector.getElement();
    },

    yearSelected : function() {
      if (this.yearSelector.getSelectedValue() > 0) {
        this.monthSelector.enable();
      } else {
        this.monthSelector.disable();
        this.daySelector.disable();
      }
      this.updateDate();
    },

    createMonthDropdown : function() {
      this.monthSelector = new widgets.FuzzyDatePickerDropdown({name: "month"});
      this.monthSelector.populate(this.getZeroPaddedValueRange(1,12));
      this.monthSelector.disable();
      this.monthSelector.onSelect(this.monthSelected.bind(this));
      return this.monthSelector.getElement();
    },

    monthSelected : function() {
      if (this.monthSelector.getSelectedValue() > 0) {
        this.daySelector.populate(this.getAvailableDays());
        this.daySelector.enable();
      } else {
        this.daySelector.disable();
      }
      this.updateDate();
    },

    createDayDropdown : function() {
      this.daySelector = new widgets.FuzzyDatePickerDropdown({name: "day"});
      this.daySelector.disable();
      this.daySelector.populate(this.getZeroPaddedValueRange(1,31));
      this.daySelector.onSelect(this.updateDate.bind(this));
      return this.daySelector.getElement();
    },

    getAvailableDays : function () {
      var year = this.yearSelector.getSelectedValue() * 1;
      var month = this.monthSelector.getSelectedValue() * 1;
      var lastDayOfMonth = 0;
      if ([1,3,5,7,8,10,12].indexOf(month) >= 0) {
        lastDayOfMonth = 31;
      } else if ([4,6,9,11].indexOf(month) >= 0) {
        lastDayOfMonth = 30
      } else if (month == 2) {
        if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
          lastDayOfMonth = 29;
        } else {
          lastDayOfMonth = 28;
        }
      }
      return this.getZeroPaddedValueRange(1, lastDayOfMonth);
    },

    getZeroPaddedValueRange : function (start, end) {
      var values = [];
      if (start <= end) {
          for (var v = start; v <= end; ++v) {
              values.push({'value': v, 'text' : ("0" + v).slice(-2)});
          }
      } else {
          for (var v = end; v <= start; --v) {
              values.push({'value': v, 'text' : ("0" + v).slice(-2)});
          }
      }
      return values;
    },

    updateDate : function () {
        var dateObject = {};

        var y = this.yearSelector.getSelectedValue();
        if (y.match(/\d\d\d\ds$/)) {
            dateObject["decade"] = y;
        } else {
            if (y != "") {
                dateObject["year"] = y;
            }
        }

        if (y > 0) {
            var m = this.monthSelector.getSelectedValue();
            if (m > 0) {
                dateObject["month"] = this.monthSelector.getSelectedOption();

                var d = this.daySelector.getSelectedValue();
                if (d > 0) {
                    dateObject["day"] = this.daySelector.getSelectedOption();
                }
            }
        }

        var newValue = JSON.stringify(dateObject);
        if (newValue != this.__input.value) {
            this.__input.value = JSON.stringify(dateObject);
            this.__input.fire("xwiki:date:changed");
        }
    }
  });

  var init = function(event) {
    ((event && event.memo.elements) || [$('body')]).each(function(element) {
      (element.hasClassName("fuzzy-date") ? [element] : element.select(".fuzzy-date")).each(function(dateInput) {
        if (!dateInput.__datePicker) {
          dateInput.__datePicker = new PhenoTips.widgets.FuzzyDatePicker(dateInput);
        }
      });
    });
    return true;
  };

  (XWiki.domIsLoaded && init()) || document.observe("xwiki:dom:loaded", init);
  document.observe("xwiki:dom:updated", init);

  // End augmentation.

  return PhenoTips;
}(PhenoTips || {}));<commit_msg>Issue #645: Add support for "Fuzzy" dates/ages in the pedigree Fixed a focusing issue<commit_after>var PhenoTips = (function (PhenoTips) {
  var widgets = PhenoTips.widgets = PhenoTips.widgets || {};

  widgets.FuzzyDatePickerDropdown = Class.create({
    initialize : function(options) {
      this.dropdown = new Element('select', {
        "name"        : options.name     || '',
        "class"       : options.cssClass || options.name || '',
        "placeholder" : options.hint     || options.name || '',
        "title"       : options.hint     || options.name || ''
      });
    },

    populate : function(values) {
      var selectedIndex = this.dropdown.selectedIndex || this._tmpSelectedIndex;
      this.dropdown.update(new Element('option', {'value' : "", "class" : "empty"}));
      var _this = this;
      values.each(function (item) {
         var optionData = {};
         optionData.value = item.value;
         if (item.cssClass) {
            optionData["class"] = item.cssClass;
         }
         //if (item.value == selectedValue) {
         //   optionData.selected = "selected";
         //}
         _this.dropdown.insert(new Element('option', optionData).update(item.text || item.value || ''));
      });
      if (this.dropdown.selectedIndex <= 0 && selectedIndex >= 0 && selectedIndex < this.dropdown.options.length) {
        this.dropdown.selectedIndex = selectedIndex;
      }
    },

    enable : function () {
      this.dropdown.enable();
      if (this.dropdown.selectedIndex <= 0 && this._tmpSelectedIndex < this.dropdown.options.length) {
        this.dropdown.selectedIndex = this._tmpSelectedIndex;
      }
    },

    disable : function () {
      this.dropdown.disable();
      this._tmpSelectedIndex = this.dropdown.selectedIndex;
      this.dropdown.selectedIndex = 0;
    },

    getElement : function() {
      return this.dropdown;
    },

    onSelect : function(callback) {
      var _this = this;
      this.dropdown.observe('change',function() {
        callback();
        _this._tmpSelectedIndex = _this.dropdown.selectedIndex;
      });
    },

    onFocus : function(callback) {
      var _this = this;
      this.dropdown.observe('focus', function() {
        callback();
        if (_this.dropdown.selectedIndex == -1 && _this._tmpSelectedIndex < _this.dropdown.options.size()) {
          _this.dropdown.selectedIndex = _this._tmpSelectedIndex;
        }
      });
    },
    onBlur : function(callback) {
      this.dropdown.observe('blur', callback);
    },

    getSelectedValue : function () {
       return (this.dropdown.selectedIndex >= 0) ? this.dropdown.options[this.dropdown.selectedIndex].value : '';
    },

    getSelectedOption : function () {
       return (this.dropdown.selectedIndex >= 0) ? this.dropdown.options[this.dropdown.selectedIndex].innerHTML : '';
    }
  });

  widgets.FuzzyDatePicker = Class.create({
    initialize : function (input) {
      if (!input) {return};
      this.__input = input;
      this.__input.hide();

      this.container = new Element('div', {'class' : 'fuzzy-date-picker'});
      this.__input.insert({after : this.container});
      this.container.insert(this.createYearDropdown());
      this.container.insert(this.createMonthDropdown());
      this.container.insert(this.createDayDropdown());

      // TODO: yearSelector's (and month's & day's) .onSelect() does not seem to fire
      //       upon programmatic update if a substitute is found can remove these hackish events
      this.container.observe("datepicker:date:changed", this.onProgrammaticUpdate.bind(this));
    },

    onProgrammaticUpdate : function() {
        this.yearSelected();
        this.monthSelected();
        this.updateDate();
    },

    createYearDropdown : function() {
      this.yearSelector = new widgets.FuzzyDatePickerDropdown({name: "year"});

      var today = new Date();
      var crtYear = today.getYear() + 1900;
      var startYear = 1900;

      var values = [];
      for (var y = crtYear; y >= startYear; --y) {
        values.push({"value" : y});
        if (y % 10 == 0) {
            values.push({"value" : (y + "s"), "cssClass" : "decade", "text" : (y + 's')});
        }
      }
      values.push({"value": "1800s"});
      values.push({"value": "1700s"});
      values.push({"value": "1600s"});

      this.yearSelector.populate(values);
      this.yearSelector.onSelect(this.yearSelected.bind(this));

      return this.yearSelector.getElement();
    },

    yearSelected : function() {
      if (this.yearSelector.getSelectedValue() > 0) {
        this.monthSelector.enable();
      } else {
        this.monthSelector.disable();
        this.daySelector.disable();
      }
      this.updateDate();
    },

    createMonthDropdown : function() {
      this.monthSelector = new widgets.FuzzyDatePickerDropdown({name: "month"});
      this.monthSelector.populate(this.getZeroPaddedValueRange(1,12));
      this.monthSelector.disable();
      this.monthSelector.onSelect(this.monthSelected.bind(this));
      return this.monthSelector.getElement();
    },

    monthSelected : function() {
      if (this.monthSelector.getSelectedValue() > 0) {
        this.daySelector.populate(this.getAvailableDays());
        this.daySelector.enable();
      } else {
        this.daySelector.disable();
      }
      this.updateDate();
    },

    createDayDropdown : function() {
      this.daySelector = new widgets.FuzzyDatePickerDropdown({name: "day"});
      this.daySelector.disable();
      this.daySelector.populate(this.getZeroPaddedValueRange(1,31));
      this.daySelector.onSelect(this.updateDate.bind(this));
      return this.daySelector.getElement();
    },

    getAvailableDays : function () {
      var year = this.yearSelector.getSelectedValue() * 1;
      var month = this.monthSelector.getSelectedValue() * 1;
      var lastDayOfMonth = 0;
      if ([1,3,5,7,8,10,12].indexOf(month) >= 0) {
        lastDayOfMonth = 31;
      } else if ([4,6,9,11].indexOf(month) >= 0) {
        lastDayOfMonth = 30
      } else if (month == 2) {
        if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
          lastDayOfMonth = 29;
        } else {
          lastDayOfMonth = 28;
        }
      }
      return this.getZeroPaddedValueRange(1, lastDayOfMonth);
    },

    getZeroPaddedValueRange : function (start, end) {
      var values = [];
      if (start <= end) {
          for (var v = start; v <= end; ++v) {
              values.push({'value': v, 'text' : ("0" + v).slice(-2)});
          }
      } else {
          for (var v = end; v <= start; --v) {
              values.push({'value': v, 'text' : ("0" + v).slice(-2)});
          }
      }
      return values;
    },

    updateDate : function () {
        var dateObject = {};

        var y = this.yearSelector.getSelectedValue();
        if (y.match(/\d\d\d\ds$/)) {
            dateObject["decade"] = y;
        } else {
            if (y != "") {
                dateObject["year"] = y;
            }
        }

        if (y > 0) {
            var m = this.monthSelector.getSelectedValue();
            if (m > 0) {
                dateObject["month"] = this.monthSelector.getSelectedOption();

                var d = this.daySelector.getSelectedValue();
                if (d > 0) {
                    dateObject["day"] = this.daySelector.getSelectedOption();
                }
            }
        }

        var newValue = JSON.stringify(dateObject);
        if (newValue != this.__input.value) {
            this.__input.value = JSON.stringify(dateObject);
            this.__input.fire("xwiki:date:changed");
        }
    }
  });

  var init = function(event) {
    ((event && event.memo.elements) || [$('body')]).each(function(element) {
      (element.hasClassName("fuzzy-date") ? [element] : element.select(".fuzzy-date")).each(function(dateInput) {
        if (!dateInput.__datePicker) {
          dateInput.__datePicker = new PhenoTips.widgets.FuzzyDatePicker(dateInput);
        }
      });
    });
    return true;
  };

  (XWiki.domIsLoaded && init()) || document.observe("xwiki:dom:loaded", init);
  document.observe("xwiki:dom:updated", init);

  // End augmentation.

  return PhenoTips;
}(PhenoTips || {}));<|endoftext|>


<commit_before>var collapsableOpenCss = "collapsable";
var collapsableClosedCss = "hidden";
var collapsableOpenImg = "/files/images/collapsableOpen.gif";
var collapsableClosedImg = "/files/images/collapsableClosed.gif";

function toggleCollapsable(id)
{
  var div = document.getElementById(id);
  var img = document.getElementById("img" + id);
  if (div.className.indexOf(collapsableClosedCss) != -1)
  {
    div.className = collapsableOpenCss;
    img.src = collapsableOpenImg;
  }
  else
  {
    div.className = collapsableClosedCss;
    img.src = collapsableClosedImg;
  }
}

function popup(window_id) {
  var window = document.getElementById(window_id);
  window.style.visibility = "visible";
}

function popdown(window_id) {
  var window = document.getElementById(window_id);
  window.style.visibility = "hidden";
}

function expandOrCollapseAll(cssClass)
{
  divs = document.getElementsByTagName("div");
  for (i = 0; i < divs.length; i++)
  {
    div = divs[i];
    if (div.className == cssClass)
    {
      toggleCollapsable(div.id);
    }
  }
}

function collapseAll()
{
  expandOrCollapseAll(collapsableOpenCss);
}

function expandAll()
{
  expandOrCollapseAll(collapsableClosedCss);
}

function symbolicLinkRename(linkName, resource)
{
  var newName = document.symbolics[linkName].value.replace(/ +/g, '');

  if (newName.length > 0)
    window.location = resource + '?responder=symlink&rename=' + linkName + '&newname=' + newName;
  else
    alert('Enter a new name first.');
}

// Allow ctrl-s to save the changes.
// Currently this alone appears to work on OS X. For windows (and linux??) use alt-s, which doesn't work on OS X!
formToSubmit = null;
function enableSaveOnControlS(control, formToSubmit)
{
  formToSubmit = formToSubmit;
  if (document.addEventListener)
  {
    document.addEventListener("keypress", keypress, false);
  }
  else if (document.attachEvent)
  {
    document.attachEvent("onkeypress", keypress);
  }
  else
  {
    document.onkeypress = keypress;
  }

}
function keypress(e)
{
  if (!e) e = event;
  if (e.keyIdentifier == "U+0053" || e.keyIdentifier == "U+0060")
  {
    suppressdefault(e, formToSubmit.keypress.checked);
    if (formToSubmit != null)
    {
      formToSubmit.submit
    }
  }
}

function doSilentRequest(url)
{
  $.get(url);
  return false;
}

$(function() {
	$('article').on("click", "tr.scenario td", function() {
		console.log(this);
		$(this).parent().toggleClass("open").next().toggle();
	});

	function validateField(re, msg) {
		var pageNameError = $(this).data("error");
		if (!re.test($(this).val())) {
			if (!pageNameError) {
				pageNameError = $(msg);
				$(this).after(pageNameError);
			}
		} else {
			if (pageNameError) {
				$(this).next().remove();
				pageNameError = undefined;
			}
		}
		$(this).data("error", pageNameError);
	}

	$('input.wikiword').keyup(function() {
		validateField.apply(this,
				[/^[A-Z](?:[a-z0-9]+[A-Z][a-z0-9]*)+$/,
		         "
The page name should be a valid WikiWord!
"]);
	});

	$('input.wikipath').keyup(function() {
		validateField.apply(this,
				[/^(?:[<>^.])?(?:[A-Z](?:[a-z0-9]+[A-Z][a-z0-9]*)+[.]?)+$/,
				 "
The page path should be a valid WikiPath.WikiWord!
"]);
	});

});<commit_msg>added onbeforeunload event to check for running test before leaving page<commit_after>var collapsableOpenCss = "collapsable";
var collapsableClosedCss = "hidden";
var collapsableOpenImg = "/files/images/collapsableOpen.gif";
var collapsableClosedImg = "/files/images/collapsableClosed.gif";

window.onbeforeunload=stopNavIfTestRunning;

function stopNavIfTestRunning(){
  var stoptestDiv = document.querySelector("#test-action a.stop");

  if (stoptestDiv){
    return "There is a test or suite currently running.  Are you sure you want to navigate away from this page?";
  }
}

function toggleCollapsable(id)
{
  var div = document.getElementById(id);
  var img = document.getElementById("img" + id);
  if (div.className.indexOf(collapsableClosedCss) != -1)
  {
    div.className = collapsableOpenCss;
    img.src = collapsableOpenImg;
  }
  else
  {
    div.className = collapsableClosedCss;
    img.src = collapsableClosedImg;
  }
}

function popup(window_id) {
  var window = document.getElementById(window_id);
  window.style.visibility = "visible";
}

function popdown(window_id) {
  var window = document.getElementById(window_id);
  window.style.visibility = "hidden";
}

function expandOrCollapseAll(cssClass)
{
  divs = document.getElementsByTagName("div");
  for (i = 0; i < divs.length; i++)
  {
    div = divs[i];
    if (div.className == cssClass)
    {
      toggleCollapsable(div.id);
    }
  }
}

function collapseAll()
{
  expandOrCollapseAll(collapsableOpenCss);
}

function expandAll()
{
  expandOrCollapseAll(collapsableClosedCss);
}

function symbolicLinkRename(linkName, resource)
{
  var newName = document.symbolics[linkName].value.replace(/ +/g, '');

  if (newName.length > 0)
    window.location = resource + '?responder=symlink&rename=' + linkName + '&newname=' + newName;
  else
    alert('Enter a new name first.');
}

// Allow ctrl-s to save the changes.
// Currently this alone appears to work on OS X. For windows (and linux??) use alt-s, which doesn't work on OS X!
formToSubmit = null;
function enableSaveOnControlS(control, formToSubmit)
{
  formToSubmit = formToSubmit;
  if (document.addEventListener)
  {
    document.addEventListener("keypress", keypress, false);
  }
  else if (document.attachEvent)
  {
    document.attachEvent("onkeypress", keypress);
  }
  else
  {
    document.onkeypress = keypress;
  }

}
function keypress(e)
{
  if (!e) e = event;
  if (e.keyIdentifier == "U+0053" || e.keyIdentifier == "U+0060")
  {
    suppressdefault(e, formToSubmit.keypress.checked);
    if (formToSubmit != null)
    {
      formToSubmit.submit
    }
  }
}

function doSilentRequest(url)
{
  $.get(url);
  return false;
}

$(function() {
	$('article').on("click", "tr.scenario td", function() {
		console.log(this);
		$(this).parent().toggleClass("open").next().toggle();
	});

	function validateField(re, msg) {
		var pageNameError = $(this).data("error");
		if (!re.test($(this).val())) {
			if (!pageNameError) {
				pageNameError = $(msg);
				$(this).after(pageNameError);
			}
		} else {
			if (pageNameError) {
				$(this).next().remove();
				pageNameError = undefined;
			}
		}
		$(this).data("error", pageNameError);
	}

	$('input.wikiword').keyup(function() {
		validateField.apply(this,
				[/^[A-Z](?:[a-z0-9]+[A-Z][a-z0-9]*)+$/,
		         "
The page name should be a valid WikiWord!
"]);
	});

	$('input.wikipath').keyup(function() {
		validateField.apply(this,
				[/^(?:[<>^.])?(?:[A-Z](?:[a-z0-9]+[A-Z][a-z0-9]*)+[.]?)+$/,
				 "
The page path should be a valid WikiPath.WikiWord!
"]);
	});

});<|endoftext|>


<commit_before>Template.ionRadio.helpers({
  inputAttrs: function () {
    var attrs = {
      type: 'radio'
    };

    if (this.name) {
      attrs.name = this.name;
    } else {
      attrs.name = 'radio-group';
    }

    if (this.value) {
      attrs.value = this.value;
    } else {
      attrs.value = '';
    }

    if (this.disabled) {
      attrs.disabled = true;
    }

    return attrs;
  }
})
<commit_msg>Update ionRadio.js<commit_after>Template.ionRadio.helpers({
  inputAttrs: function () {
    var attrs = {
      type: 'radio'
    };

    if (this.name) {
      attrs.name = this.name;
    } else {
      attrs.name = 'radio-group';
    }

    if (this.value) {
      attrs.value = this.value;
    } else {
      attrs.value = '';
    }

    if (this.disabled) {
      attrs.disabled = true;
    }

    if (this.checked) {
      attrs.checked = true;
    }

    return attrs;
  }
})
<|endoftext|>


<commit_before>exports.BattleFormats = {
   "rules": {
     effectType: 'Rule',
     onValidateTeam: function (team) {
       var problems = [];

       for (var i = 1; i < team.length; i++) {
         var pokemon = team[i];
         var j=0;
         var name = pokemon.name || pokemon.species;
         var template = this.getTemplate(pokemon.species);
         if (template.tier === 'Uber') {
             j++;
         }
         if(j>1)
            problems.push("You cannot use " + name + " as non-god.");
     }
   }
   },
};<commit_msg>Update name<commit_after>exports.BattleFormats = {
   "godclause": {
     effectType: 'Rule',
     onValidateTeam: function (team) {
       var problems = [];

       for (var i = 1; i < team.length; i++) {
         var pokemon = team[i];
         var j=0;
         var name = pokemon.name || pokemon.species;
         var template = this.getTemplate(pokemon.species);
         if (template.tier === 'Uber') {
             j++;
         }
         if(j>1)
            problems.push("You cannot use " + name + " as non-god.");
     }
   }
   },
};
<|endoftext|>


<commit_before>module.exports = {
	url: "mongodb://localhost/twitter-mean"
};<commit_msg>Deleted superfluous configuration directory<commit_after><|endoftext|>


<commit_before>var moveMarginX = function moveMarginX(element, movePixels) {
    if (element.moved === movePixels) return;
    element.moved = movePixels;
    element.moving = new Date;
    css(element, {
        transition: movePixels !== false ? "margin .1s" : '',
        userSelect: "none",
        marginLeft: movePixels ? fromOffset(movePixels) : "",
        marginRight: movePixels ? fromOffset(-movePixels) : ""
    });
    if (isArray(element.with)) {
        element.with.map(function (element) {
            moveMarginX(element, movePixels);
        });
    }
};
var moveChildrenX = function (targetBox, previousElements, followedElements, moveMargin, recover) {
    var dragTarget = drag.target;
    if (dragTarget) {
        var area = overlap(dragTarget, targetBox);
        if (area > 0) {
            var dragPosition = getScreenPosition(dragTarget);
            var dragPositionLeft = dragPosition.left;
            var currentTime = new Date;
            previousElements.map(function (element) {
                if (currentTime - element.moving < 100) return;
                var elementPosition = getScreenPosition(element);
                var elementCenter = elementPosition.left + elementPosition.width / 2;
                if (elementCenter - (element.moved || 0) <= dragPositionLeft) {
                    recover(element);
                } else {
                    moveMargin(element, dragPosition.width);
                }
            });
            var dragPositionRight = dragPosition.left + dragPosition.width;
            followedElements.map(function (element) {
                if (currentTime - element.moving < 100) return;
                var elementPosition = getScreenPosition(element);
                var elementCenter = elementPosition.left + elementPosition.width / 2;
                if (elementCenter - (element.moved || 0) <= dragPositionRight) {
                    moveMargin(element, -dragPosition.width);
                } else {
                    recover(element);
                }
            });
        } else {
            previousElements.map(recover);
            followedElements.map(recover);
        }
    } else {
        previousElements.map(recover);
        followedElements.map(recover);
    }
};
var scrollX = function (targetBox, moveChildren) {
    var dragTarget = drag.target;
    if (!dragTarget || !targetBox) return;
    var areaPosition = getScreenPosition(targetBox);
    var dragPosition = getScreenPosition(dragTarget);
    var scrollDelta = 0;
    if (dragPosition.left - 40 < areaPosition.left && dragPosition.right + 20 > areaPosition.left) {
        scrollDelta = dragPosition.left - 20 - areaPosition.left;
    } else if (dragPosition.right + 40 > areaPosition.right && dragPosition.left - 20 < areaPosition.right) {
        scrollDelta = dragPosition.right + 20 - areaPosition.right;
    }
    if (scrollDelta) {
        vscroll.X.call(targetBox, scrollDelta / 16, false);
        moveChildren();
    }
};
var scrollY = arriswise(scrollX, arguments);
var moveMarginY = arriswise(moveMarginX, arguments);
var moveChildrenY = arriswise(moveChildrenX, arguments);
var getMoveFuncs = function (child) {
    child = child instanceof Array ? child[0] : child;
    if (child && /cell|inline/i.test(getComputedStyle(child).display)) {
        return [moveMarginX, moveChildrenX, scrollX];
    } else {
        return [moveMarginY, moveChildrenY, scrollY];
    }
};
var bindTarget = function (index, element) {
    var value = new Number(index);
    value.target = element;
    return value;
};

var hooka = function (matcher, move, event, targetChild, isMovingSource) {
    var dragbox = this.dragbox;
    if (dragbox instanceof Function) {
        dragbox = dragbox.call(this);
        if (dragbox && !getTargetIn(dragbox, event.target)) return;
    }
    else {
        dragbox = this;
    }
    var that = this;

    var draggingSourceOpacity = isMovingSource !== false ? 0 : 1;

    var recover = function (element) {
        moveMargin(element, 0);
    };
    var cloneCell = function (element) {
        var targets = getTargetIn(matcher, element, false);
        if (isArray(targets)) {
            var extra = targets.slice(1);
            targets = cloneVisible(targets[0]);
            targets.extraStyles = extra.map(function (extra) {
                var style = extra.style;
                return [style.opacity, style.filter];
            });
            targets.extra = extra;
            once("remove")(targets, function () {
                var { extra, extraStyles } = this;
                extra.map(function (elem, cx) {
                    var [opacity, filter] = extraStyles[cx];
                    extend(elem.style, {
                        opacity,
                        filter
                    });
                });
                delete this.extra;
            });
            targets.with = extra.map(cloneVisible);
            extra.map(function (elem) {
                setOpacity(elem, draggingSourceOpacity);
            });
        } else {
            targets = cloneVisible(targets);
        }
        return targets;
    };
    if (event.target === this) return;
    // var targetChild = getTargetIn(matcher, event.target);
    if (!targetChild) return;
    drag(targetChild, event, false, isMovingSource);
    if (isArray(targetChild)) {
        targetChild = targetChild[0];
    }
    var targetBox, saved_opacity, saved_filter, moveMargin, moveChildren;
    var previousElements, followedElements, rebuildTargets, scroll;
    var that = this;
    var draginit = function () {
        that.setAttribute('dragchildren', '');
        if (targetBox) addClass(targetBox, 'dropping');
        if (getTargetIn(dragbox, targetChild)) {
            targetBox = targetChild.parentNode;
            previousElements = getPreviousElementSiblings(targetChild);
            followedElements = getFollowedElementSiblings(targetChild);
            saved_filter = targetBox.style.filter;
            saved_opacity = targetBox.style.opacity;
            rebuildTargets = function () { };
            [moveMargin, moveChildren, scroll] = getMoveFuncs(targetChild);
            moveChildren = moveChildren.bind(null, that, previousElements, followedElements, moveMargin, recover);
        } else {
            previousElements = [];
            followedElements = [];
            moveChildren = () => { };
            rebuildTargets = function () {
                var temp = matcher(drag.target);
                if (temp === targetBox) return;
                if (previousElements) previousElements.map(recover);
                if (followedElements) followedElements.map(recover);
                if (targetBox) {
                    removeClass(targetBox, "dropping");
                }
                targetBox = temp;
                if (!targetBox) {
                    previousElements = [];
                    followedElements = [];
                    moveChildren = () => { };
                    return;
                }
                addClass(targetBox, "dropping");
                previousElements = [].slice.call(targetBox.children, 0).reverse();
                followedElements = [];
                [moveMargin, moveChildren, scroll] = getMoveFuncs(previousElements[0]);
                moveChildren = moveChildren.bind(null, that, previousElements, followedElements, moveMargin, recover);
            };
        }
    };
    var dragfire = function () {
        that.removeAttribute('dragchildren');
        removeClass(targetBox, "dropping");
        var dst, appendSibling, delta;
        var src = previousElements.length;
        if (previousElements.length && previousElements[0].moved) for (var cx = 1, dx = previousElements.length + 1; cx < dx; cx++) {
            if (!previousElements[cx]) {
                dst = 0;
                delta = 0;
                appendSibling = appendChild.before;
            } else if (!previousElements[cx].moved) {
                dst = previousElements.length - cx;
                delta = -1;
                appendSibling = appendChild.after;
                break;
            }
        }

        if (followedElements.length && followedElements[0].moved) for (var cx = 1, dx = followedElements.length + 1; cx < dx; cx++) {
            if (!followedElements[cx]) {
                dst = followedElements.length + previousElements.length;
                delta = 0;
                appendSibling = appendChild.after;
            } else if (!followedElements[cx].moved) {
                dst = previousElements.length + cx;
                delta = 1;
                appendSibling = appendChild.before;
                break;
            }
        }
        if (appendSibling) {
            var children = targetBox.children;
            var srcElement = children[src];
            var dstElement = children[dst + delta];
            src = bindTarget(src, srcElement);
            dst = bindTarget(dst, dstElement);
            isFunction(move) && move(src, dst, dst + delta, appendSibling, targetBox);
            if (srcElement === children[src] && dstElement === children[dst + delta] && srcElement && dstElement) appendSibling(dstElement, srcElement);
        } else if (isMovingSource === false) {
            move(previousElements.length, previousElements.length, previousElements.length, null, targetBox);
        }
    };

    var offall = function () {
        offmousup();
        offtouchend();
        offdragstart();
        offtouchconcel();
    };
    var offtouchconcel = on("touchconcel")(targetChild, offall);
    var offtouchend = on("touchend")(targetChild, offall);
    var offmousup = on("mouseup")(window, offall);
    var autoScroll = function () {
        if (autoScroll.ing) return;
        if (scroll);
        autoScroll.ing = setInterval(scroll, 16);
    };
    var cancelScroll = function () {
        clearInterval(autoScroll.ing);
        autoScroll.ing = 0;
    };
    var dragmove = function (event) {
        rebuildTargets();
        moveChildren.call(this, event);
    };

    // 修改margin无效的情况
    function dragclone() {
        draginit();
        rebuildTargets();
        var _previousElements = previousElements.map(cloneCell);
        var _followedElements = followedElements.map(cloneCell);
        previousElements.splice(0, previousElements.length);
        followedElements.splice(0, followedElements.length);
        previousElements.push.apply(previousElements, _previousElements);
        followedElements.push.apply(followedElements, _followedElements);
        setOpacity(targetBox, draggingSourceOpacity);
        appendChild(document.body, previousElements);
        appendChild(document.body, followedElements);
        var offall = function () {
            offdragmove();
            offdragend();
        };
        var offdragend = on("dragend")(targetChild, function () {
            offall();
            dragfire();
            css(targetBox, { opacity: saved_opacity, filter: saved_filter });
            remove(previousElements);
            remove(followedElements);
            previousElements.map(recover);
            followedElements.map(recover);
        });
        var offdragmove = on("dragmove")(targetChild, dragmove);
    }
    // 仅修改Margin就可以实现拖拽效果
    function draglist() {
        draginit();
        rebuildTargets();
        autoScroll();
        var offall = function () {
            cancelScroll();
            offdragmove();
            offdragend();
        };
        var offdragend = on("dragend")(targetChild, function () {
            offall();
            dragfire();
            previousElements.map(e => moveMargin(e, false));
            followedElements.map(e => moveMargin(e, false));
        });
        var offdragmove = on("dragmove")(targetChild, dragmove);
    }
    if (/^table/i.test(getComputedStyle(targetChild).display)) {
        var offdragstart = on("dragstart")(targetChild, dragclone);
    } else {
        var offdragstart = on("dragstart")(targetChild, draglist);
    }
};
var hookEvent = function (matcher, move, event) {
    if (event.target === this) return;
    var targetChild = getTargetIn(matcher, event.target, false);
    if (!targetChild) return;
    hooka.call(this, matcher, move, event, targetChild);
};
function addhook() {
    var mousedownEvent, targetElement, callback, matcher, dropid, allowdrops;
    [].forEach.call(arguments, function (arg) {
        switch (typeof arg) {
            case "string":
                dropid = arg;
                break;
            case "function":
                if (!callback) {
                    callback = arg;
                } else {
                    matcher = callback;
                    callback = arg;
                }
                break;
            case "object":
                if (arg instanceof Array) {
                    allowdrops = arg;
                    break;
                }
                if (isElement(arg)) {
                    targetElement = arg;
                    break;
                }
                if (arg !== null) mousedownEvent = arg;
                break;
        }
    });
    if (!targetElement && isElement(this)) {
        targetElement = this;
    }
    if (!mousedownEvent) return;
    var target = targetElement || mousedownEvent.currentTarget;
    hooka(function (target) {
        var res = [].filter.call(allowdrops || (matcher ? matcher(target) : document.querySelectorAll("[allowdrop]")), function (child) {
            return target && overlap(child, target);
        }).filter(e => {
            var a = e.getAttribute("allowdrop");
            if (!a || !dropid) return true;
            return a === dropid;
        });
        if (res instanceof Array) {
            return res[res.length - 1];
        }
        return res;
    }, function (_, dst, _a, _b, parentNode) {
        if (isFunction(callback) && parentNode) callback(dst, parentNode);
    }, mousedownEvent, target, false);
}
function autodragchildren(target, matcher, move) {
    onmousedown(target, hookEvent.bind(target, matcher, move));
    ontouchstart(target, hookEvent.bind(target, matcher, move));
    return target;
}
autodragchildren.hook = addhook;
<commit_msg>修复autodragchildren.addhook<commit_after>var moveMarginX = function moveMarginX(element, movePixels) {
    if (element.moved === movePixels) return;
    element.moved = movePixels;
    element.moving = new Date;
    css(element, {
        transition: movePixels !== false ? "margin .1s" : '',
        userSelect: "none",
        marginLeft: movePixels ? fromOffset(movePixels) : "",
        marginRight: movePixels ? fromOffset(-movePixels) : ""
    });
    if (isArray(element.with)) {
        element.with.map(function (element) {
            moveMarginX(element, movePixels);
        });
    }
};
var moveChildrenX = function (targetBox, previousElements, followedElements, moveMargin, recover) {
    var dragTarget = drag.target;
    if (dragTarget) {
        var area = overlap(dragTarget, targetBox);
        if (area > 0) {
            var dragPosition = getScreenPosition(dragTarget);
            var dragPositionLeft = dragPosition.left;
            var currentTime = new Date;
            previousElements.map(function (element) {
                if (currentTime - element.moving < 100) return;
                var elementPosition = getScreenPosition(element);
                var elementCenter = elementPosition.left + elementPosition.width / 2;
                if (elementCenter - (element.moved || 0) <= dragPositionLeft) {
                    recover(element);
                } else {
                    moveMargin(element, dragPosition.width);
                }
            });
            var dragPositionRight = dragPosition.left + dragPosition.width;
            followedElements.map(function (element) {
                if (currentTime - element.moving < 100) return;
                var elementPosition = getScreenPosition(element);
                var elementCenter = elementPosition.left + elementPosition.width / 2;
                if (elementCenter - (element.moved || 0) <= dragPositionRight) {
                    moveMargin(element, -dragPosition.width);
                } else {
                    recover(element);
                }
            });
        } else {
            previousElements.map(recover);
            followedElements.map(recover);
        }
    } else {
        previousElements.map(recover);
        followedElements.map(recover);
    }
};
var scrollX = function (targetBox, moveChildren) {
    var dragTarget = drag.target;
    if (!dragTarget || !targetBox) return;
    var areaPosition = getScreenPosition(targetBox);
    var dragPosition = getScreenPosition(dragTarget);
    var scrollDelta = 0;
    if (dragPosition.left - 40 < areaPosition.left && dragPosition.right + 20 > areaPosition.left) {
        scrollDelta = dragPosition.left - 20 - areaPosition.left;
    } else if (dragPosition.right + 40 > areaPosition.right && dragPosition.left - 20 < areaPosition.right) {
        scrollDelta = dragPosition.right + 20 - areaPosition.right;
    }
    if (scrollDelta) {
        vscroll.X.call(targetBox, scrollDelta / 16, false);
        moveChildren();
    }
};
var scrollY = arriswise(scrollX, arguments);
var moveMarginY = arriswise(moveMarginX, arguments);
var moveChildrenY = arriswise(moveChildrenX, arguments);
var getMoveFuncs = function (child) {
    child = child instanceof Array ? child[0] : child;
    if (child && /cell|inline/i.test(getComputedStyle(child).display)) {
        return [moveMarginX, moveChildrenX, scrollX];
    } else {
        return [moveMarginY, moveChildrenY, scrollY];
    }
};
var bindTarget = function (index, element) {
    var value = new Number(index);
    value.target = element;
    return value;
};

var hooka = function (matcher, move, event, targetChild, isMovingSource) {
    var dragbox = this.dragbox;
    if (dragbox instanceof Function) {
        dragbox = dragbox.call(this);
        if (dragbox && !getTargetIn(dragbox, event.target)) return;
    }
    else {
        dragbox = this;
    }
    var that = this;

    var draggingSourceOpacity = isMovingSource !== false ? 0 : 1;

    var recover = function (element) {
        moveMargin(element, 0);
    };
    var cloneCell = function (element) {
        var targets = getTargetIn(matcher, element, false);
        if (isArray(targets)) {
            var extra = targets.slice(1);
            targets = cloneVisible(targets[0]);
            targets.extraStyles = extra.map(function (extra) {
                var style = extra.style;
                return [style.opacity, style.filter];
            });
            targets.extra = extra;
            once("remove")(targets, function () {
                var { extra, extraStyles } = this;
                extra.map(function (elem, cx) {
                    var [opacity, filter] = extraStyles[cx];
                    extend(elem.style, {
                        opacity,
                        filter
                    });
                });
                delete this.extra;
            });
            targets.with = extra.map(cloneVisible);
            extra.map(function (elem) {
                setOpacity(elem, draggingSourceOpacity);
            });
        } else {
            targets = cloneVisible(targets);
        }
        return targets;
    };
    if (event.target === this) return;
    // var targetChild = getTargetIn(matcher, event.target);
    if (!targetChild) return;
    drag(targetChild, event, false, isMovingSource);
    if (isArray(targetChild)) {
        targetChild = targetChild[0];
    }
    var targetBox, saved_opacity, saved_filter, moveMargin, moveChildren;
    var previousElements, followedElements, rebuildTargets, scroll;
    var that = this;
    var draginit = function () {
        that.setAttribute('dragchildren', '');
        if (targetBox) addClass(targetBox, 'dropping');
        if (getTargetIn(dragbox, targetChild)) {
            targetBox = targetChild.parentNode;
            previousElements = getPreviousElementSiblings(targetChild);
            followedElements = getFollowedElementSiblings(targetChild);
            saved_filter = targetBox.style.filter;
            saved_opacity = targetBox.style.opacity;
            rebuildTargets = function () { };
            [moveMargin, moveChildren, scroll] = getMoveFuncs(targetChild);
            moveChildren = moveChildren.bind(null, that, previousElements, followedElements, moveMargin, recover);
        } else {
            previousElements = [];
            followedElements = [];
            moveChildren = () => { };
            rebuildTargets = function () {
                var temp = matcher(drag.target);
                if (temp === targetBox) return;
                if (previousElements) previousElements.map(recover);
                if (followedElements) followedElements.map(recover);
                if (targetBox) {
                    removeClass(targetBox, "dropping");
                }
                targetBox = temp;
                if (!targetBox) {
                    previousElements = [];
                    followedElements = [];
                    moveChildren = () => { };
                    return;
                }
                addClass(targetBox, "dropping");
                previousElements = [].slice.call(targetBox.children, 0).reverse();
                followedElements = [];
                [moveMargin, moveChildren, scroll] = getMoveFuncs(previousElements[0]);
                moveChildren = moveChildren.bind(null, that, previousElements, followedElements, moveMargin, recover);
            };
        }
    };
    var dragfire = function () {
        that.removeAttribute('dragchildren');
        removeClass(targetBox, "dropping");
        var dst, appendSibling, delta;
        var src = previousElements.length;
        if (previousElements.length && previousElements[0].moved) for (var cx = 1, dx = previousElements.length + 1; cx < dx; cx++) {
            if (!previousElements[cx]) {
                dst = 0;
                delta = 0;
                appendSibling = appendChild.before;
            } else if (!previousElements[cx].moved) {
                dst = previousElements.length - cx;
                delta = -1;
                appendSibling = appendChild.after;
                break;
            }
        }

        if (followedElements.length && followedElements[0].moved) for (var cx = 1, dx = followedElements.length + 1; cx < dx; cx++) {
            if (!followedElements[cx]) {
                dst = followedElements.length + previousElements.length;
                delta = 0;
                appendSibling = appendChild.after;
            } else if (!followedElements[cx].moved) {
                dst = previousElements.length + cx;
                delta = 1;
                appendSibling = appendChild.before;
                break;
            }
        }
        if (appendSibling) {
            var children = targetBox.children;
            var srcElement = children[src];
            var dstElement = children[dst + delta];
            src = bindTarget(src, srcElement);
            dst = bindTarget(dst, dstElement);
            isFunction(move) && move(src, dst, dst + delta, appendSibling, targetBox);
            if (srcElement === children[src] && dstElement === children[dst + delta] && srcElement && dstElement) appendSibling(dstElement, srcElement);
        } else if (isMovingSource === false) {
            move(previousElements.length, previousElements.length, previousElements.length, null, targetBox);
        }
    };

    var offall = function () {
        offmousup();
        offtouchend();
        offdragstart();
        offtouchconcel();
    };
    var offtouchconcel = on("touchconcel")(targetChild, offall);
    var offtouchend = on("touchend")(targetChild, offall);
    var offmousup = on("mouseup")(window, offall);
    var autoScroll = function () {
        if (autoScroll.ing) return;
        if (scroll);
        autoScroll.ing = setInterval(scroll, 16);
    };
    var cancelScroll = function () {
        clearInterval(autoScroll.ing);
        autoScroll.ing = 0;
    };
    var dragmove = function (event) {
        rebuildTargets();
        moveChildren.call(this, event);
    };

    // 修改margin无效的情况
    function dragclone() {
        draginit();
        rebuildTargets();
        var _previousElements = previousElements.map(cloneCell);
        var _followedElements = followedElements.map(cloneCell);
        previousElements.splice(0, previousElements.length);
        followedElements.splice(0, followedElements.length);
        previousElements.push.apply(previousElements, _previousElements);
        followedElements.push.apply(followedElements, _followedElements);
        setOpacity(targetBox, draggingSourceOpacity);
        appendChild(document.body, previousElements);
        appendChild(document.body, followedElements);
        var offall = function () {
            offdragmove();
            offdragend();
        };
        var offdragend = on("dragend")(targetChild, function () {
            offall();
            dragfire();
            css(targetBox, { opacity: saved_opacity, filter: saved_filter });
            remove(previousElements);
            remove(followedElements);
            previousElements.map(recover);
            followedElements.map(recover);
        });
        var offdragmove = on("dragmove")(targetChild, dragmove);
    }
    // 仅修改Margin就可以实现拖拽效果
    function draglist() {
        draginit();
        rebuildTargets();
        autoScroll();
        var offall = function () {
            cancelScroll();
            offdragmove();
            offdragend();
        };
        var offdragend = on("dragend")(targetChild, function () {
            offall();
            dragfire();
            previousElements.map(e => moveMargin(e, false));
            followedElements.map(e => moveMargin(e, false));
        });
        var offdragmove = on("dragmove")(targetChild, dragmove);
    }
    if (/^table/i.test(getComputedStyle(targetChild).display)) {
        var offdragstart = on("dragstart")(targetChild, dragclone);
    } else {
        var offdragstart = on("dragstart")(targetChild, draglist);
    }
};
var hookEvent = function (matcher, move, event) {
    if (event.target === this) return;
    var targetChild = getTargetIn(matcher, event.target, false);
    if (!targetChild) return;
    hooka.call(this, matcher, move, event, targetChild);
};
function addhook() {
    var mousedownEvent, targetElement, callback, matcher, dropid, allowdrops;
    [].forEach.call(arguments, function (arg) {
        switch (typeof arg) {
            case "string":
                dropid = arg;
                break;
            case "function":
                if (!callback) {
                    callback = arg;
                } else {
                    matcher = callback;
                    callback = arg;
                }
                break;
            case "object":
                if (arg instanceof Array) {
                    allowdrops = arg;
                    break;
                }
                if (isElement(arg)) {
                    targetElement = arg;
                    break;
                }
                if (arg !== null) mousedownEvent = arg;
                break;
        }
    });
    if (!targetElement && isElement(this)) {
        targetElement = this;
    }
    if (!mousedownEvent) return;
    var target = targetElement || mousedownEvent.currentTarget;
    hooka.call(targetElement, function (target) {
        var res = [].filter.call(allowdrops || (matcher ? matcher(target) : document.querySelectorAll("[allowdrop]")), function (child) {
            return target && overlap(child, target);
        }).filter(e => {
            var a = e.getAttribute("allowdrop");
            if (!a || !dropid) return true;
            return a === dropid;
        });
        if (res instanceof Array) {
            return res[res.length - 1];
        }
        return res;
    }, function (_, dst, _a, _b, parentNode) {
        if (isFunction(callback) && parentNode) callback(dst, parentNode);
    }, mousedownEvent, target, false);
}
function autodragchildren(target, matcher, move) {
    onmousedown(target, hookEvent.bind(target, matcher, move));
    ontouchstart(target, hookEvent.bind(target, matcher, move));
    return target;
}
autodragchildren.hook = addhook;
<|endoftext|>