diff --git a/demo/clients.js b/demo/clients.js
new file mode 100644
index 0000000..829cdab
--- /dev/null
+++ b/demo/clients.js
@@ -0,0 +1,37 @@
+class Client {
+ constructor(client) {
+ this.client = client
+ this.status = 'await'
+ this.name = 'anonymous'
+ this.client.emit('id', client.id)
+ }
+}
+
+class Clients {
+
+ constructor(io) {
+ this.io = io
+ this.clients = {}
+ }
+
+ debuglog() {
+ console.log('client total:', this.length)
+ }
+
+ add(client) {
+ this.clients[client.id] = new Client(client)
+ this.debuglog()
+ }
+
+ del(client) {
+ delete this.clients[client.id]
+ this.debuglog()
+ }
+
+ get length() {
+ return Object.entries(this.clients).length
+ }
+
+}
+
+module.exports = Clients
diff --git a/demo/dbclickrotate/favicon.ico b/demo/dbclickrotate/favicon.ico
new file mode 100644
index 0000000..ddaaf83
Binary files /dev/null and b/demo/dbclickrotate/favicon.ico differ
diff --git a/demo/dbclickrotate/index.html b/demo/dbclickrotate/index.html
new file mode 100644
index 0000000..b2da5e7
--- /dev/null
+++ b/demo/dbclickrotate/index.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ rotate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/dbclickrotate/main.js b/demo/dbclickrotate/main.js
new file mode 100644
index 0000000..339459a
--- /dev/null
+++ b/demo/dbclickrotate/main.js
@@ -0,0 +1,2 @@
+const ship = document.querySelector('.ship')
+ship.addEventListener('dblclick', e => e.target.parentNode.classList.toggle("vertical"))
diff --git a/demo/dbclickrotate/style.css b/demo/dbclickrotate/style.css
new file mode 100644
index 0000000..6f478b8
--- /dev/null
+++ b/demo/dbclickrotate/style.css
@@ -0,0 +1,38 @@
+body {
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.ship {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+}
+
+.ship.vertical {
+ flex-direction: column;
+}
+
+.ship span {
+ width: 40px;
+ height: 40px;
+ background-color: orange;
+}
+
+.ship .head {
+ border-radius: 20px 0 0 20px;
+}
+
+.ship .tail {
+ border-radius: 0 10px 10px 0;
+}
+
+.ship.vertical .head {
+ border-radius: 20px 20px 0 0;
+}
+
+.ship.vertical .tail {
+ border-radius: 0 0 10px 10px;
+}
diff --git a/demo/demo1/favicon.ico b/demo/demo1/favicon.ico
new file mode 100644
index 0000000..ddaaf83
Binary files /dev/null and b/demo/demo1/favicon.ico differ
diff --git a/demo/demo1/index.html b/demo/demo1/index.html
new file mode 100644
index 0000000..52250d1
--- /dev/null
+++ b/demo/demo1/index.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ Battleship
+
+
+
+
+
+ Battleship
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo1/index.js b/demo/demo1/index.js
new file mode 100644
index 0000000..e84ceff
--- /dev/null
+++ b/demo/demo1/index.js
@@ -0,0 +1,37 @@
+// elements in dom
+const playerNameInput = document.getElementById('playerNameInput')
+const playerGrid = document.getElementById('playerGrid')
+
+const player = {
+ name: localStorage.getItem('playerName') || '',
+}
+
+// init
+playerNameInput.value = player.name
+for (let i = 0; i < 100; i++) {
+ const cell = document.createElement('span')
+ cell.classList.add('cell')
+ playerGrid.appendChild(cell)
+}
+
+function start() {
+ const playerName = playerNameInput.value.trim()
+ if (playerName === '') {
+ alert('Please enter your name!')
+ playerNameInput.value = player.name || ''
+ playerNameInput.focus()
+ } else {
+ player.name = playerName
+ localStorage.setItem('playerName', playerName)
+ console.info(`player ${playerName} is starting a game`)
+ }
+}
+
+for (let ship of document.querySelectorAll('.ship')) {
+ ship.addEventListener('click', (e) => {
+ e.preventDefault()
+ console.log(e)
+ e.target.classList.toggle("v")
+ })
+}
+
diff --git a/demo/demo1/style.css b/demo/demo1/style.css
new file mode 100644
index 0000000..172fb74
--- /dev/null
+++ b/demo/demo1/style.css
@@ -0,0 +1,60 @@
+* {
+ margin: 0px;
+ padding: 0px;
+ box-sizing: border-box;
+}
+
+.grid {
+ width: 430px;
+ height: 430px;
+ padding: 5px;
+ margin: 5px;
+ background-color: darkslategray;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.grid span {
+ width: 40px;
+ height: 40px;
+ margin: 1px;
+ background-color: darkcyan;
+}
+
+.ship {
+ width: 210px;
+ height: 42px;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.ship.v {
+ width: 42px;
+ height: 210px;
+}
+
+.ship span {
+ width: 40px;
+ height: 40px;
+ margin: 1px;
+}
+
+.carrier span {
+ background-color: wheat;
+}
+
+.battleship span {
+ background-color: darkslateblue;
+}
+
+.destroyer span {
+ background-color: grey;
+}
+
+.submarine span {
+ background-color: darkslategray;
+}
+
+.patrolboat span {
+ background-color: darkgoldenrod;
+}
diff --git a/demo/dragdrop/favicon.ico b/demo/dragdrop/favicon.ico
new file mode 100644
index 0000000..ddaaf83
Binary files /dev/null and b/demo/dragdrop/favicon.ico differ
diff --git a/demo/dragdrop/index.html b/demo/dragdrop/index.html
new file mode 100644
index 0000000..bfbd1c0
--- /dev/null
+++ b/demo/dragdrop/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ dragdrop
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/dragdrop/main.js b/demo/dragdrop/main.js
new file mode 100644
index 0000000..4c06fa8
--- /dev/null
+++ b/demo/dragdrop/main.js
@@ -0,0 +1,16 @@
+const one = document.getElementById('one')
+const tow = document.getElementById('tow')
+const box = document.getElementById('box')
+
+let item = undefined
+box.addEventListener('drag', e => item = e.target)
+
+one.addEventListener('dragover', e => e.preventDefault())
+two.addEventListener('dragover', e => e.preventDefault())
+one.addEventListener('drop', drop)
+two.addEventListener('drop', drop)
+
+function drop(e) {
+ e.target.appendChild(item)
+ item = undefined
+}
diff --git a/demo/dragdrop/style.css b/demo/dragdrop/style.css
new file mode 100644
index 0000000..6583b04
--- /dev/null
+++ b/demo/dragdrop/style.css
@@ -0,0 +1,29 @@
+ body {
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ div {
+ width: 100px;
+ height: 100px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin: 0 10px;
+ }
+
+ span {
+ width: 50px;
+ height: 50px;
+ }
+
+ #one,
+ #two {
+ background-color: beige;
+ }
+
+ #box {
+ background-color: chartreuse;
+ }
diff --git a/demo/onshipgrid/favicon.ico b/demo/onshipgrid/favicon.ico
new file mode 100644
index 0000000..ddaaf83
Binary files /dev/null and b/demo/onshipgrid/favicon.ico differ
diff --git a/demo/onshipgrid/index.html b/demo/onshipgrid/index.html
new file mode 100644
index 0000000..47dba1b
--- /dev/null
+++ b/demo/onshipgrid/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ grid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/onshipgrid/main.js b/demo/onshipgrid/main.js
new file mode 100644
index 0000000..8d11b71
--- /dev/null
+++ b/demo/onshipgrid/main.js
@@ -0,0 +1,130 @@
+const grid = document.querySelector('.grid')
+const ships = document.querySelectorAll('.ship')
+const carrier = document.querySelector('.carrier') // 航空母舰
+const battleship = document.querySelector('.battleship') // 战列舰
+const cruiser = document.querySelector('.cruiser') // 巡洋舰
+const submarine = document.querySelector('.submarine') // 潜艇
+const destroyer = document.querySelector('.destroyer') // 驱逐舰
+const testButton = document.querySelector('#testButton')
+
+let playing = false
+let dragingItem = null
+
+function mod(n, w) {
+ const x = n % w
+ const y = (n - x) / w
+ return { x, y }
+}
+
+function checkIfCollision(ox, oy, currentShip) {
+ for (let ship of ships) {
+ if (ship != currentShip) {
+ const cell = ship.parentNode
+ const index = parseInt(cell.id.slice(5))
+ let { x, y } = mod(index, 10)
+ const vertical = ship.classList.contains('vertical')
+ const length = ship.children.length
+ if (vertical) {
+ const tail = y + length
+ for (; y < tail; y++) {
+ if (ox === x && oy === y) return true
+ }
+ } else {
+ const tail = x + length
+ for (; x < tail; x++) {
+ if (ox === x && oy === y) return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+function shipRotate(e) {
+ if (playing) return
+ const currentShip = e.target.parentNode
+ const length = currentShip.children.length
+ const cell = currentShip.parentNode
+ const index = parseInt(cell.id.slice(5))
+ let { x, y } = mod(index, 10)
+ const vertical = currentShip.classList.contains('vertical')
+ // TODO 检查碰撞
+ if (vertical) {
+ // 判断转为横向时是否碰撞
+ const tail = x + length - 1
+ if (tail >= 10) return // 船尾越界
+ for (x = x + 1; x <= tail; x++) {
+ if (checkIfCollision(x, y, currentShip)) return
+ }
+ } else {
+ // 判断转为竖向时是否碰撞
+ const tail = y + length - 1
+ if (tail >= 10) return // 船尾越界
+ for (y = y + 1; y <= tail; y++) {
+ if (checkIfCollision(x, y, currentShip)) return
+ }
+ }
+
+ currentShip.classList.toggle('vertical')
+}
+
+function shipMove(ship, x, y) {
+ const index = 10 * y + x
+ const vertical = ship.classList.contains('vertical')
+ // TODO 检查碰撞
+ if (vertical) { } else { }
+ const cell = document.getElementById(`cell-${index}`)
+ cell.appendChild(ship)
+}
+
+for (let ship of ships) ship.addEventListener('dblclick', shipRotate)
+
+testButton.addEventListener('click', e => {
+ playing = !playing
+ e.target.innerHTML = playing ? 'playing' : 'planning'
+})
+
+document.addEventListener('dragstart', e => {
+ if (playing || e.target.classList && !e.target.classList.contains('ship')) {
+ e.preventDefault()
+ return
+ }
+ dragingItem = e.target
+ // document.body.append(dragingItem)
+})
+document.addEventListener('dragover', e => {
+ e.preventDefault()
+ dragingItem.style.display = 'none'
+ // document.body.append(dragingItem);
+ // dragingItem.style.position = 'absolute'
+ // dragingItem.style.left = e.pageX + 'px'
+ // dragingItem.style.top = e.pageY + 'px'
+})
+function toggleCellHightlight(e) { if (e.target.classList && e.target.classList.contains('cell')) e.target.classList.toggle('hot') }
+document.addEventListener('dragenter', toggleCellHightlight)
+document.addEventListener('dragleave', toggleCellHightlight)
+document.addEventListener('drop', e => {
+ e.preventDefault()
+ if (e.target.classList.contains('cell')) {
+ e.target.classList.remove('hot')
+ e.target.appendChild(dragingItem)
+ }
+ dragingItem.style.display = 'flex'
+ // dragingItem.style.position = 'relative'
+ // dragingItem.style.left = '0px'
+ // dragingItem.style.top = '0px'
+ dragingItem = null
+})
+
+// Init the game
+for (let i = 0; i < 100; i++) {
+ const cell = document.createElement('span')
+ cell.id = `cell-${i}`
+ cell.classList.add('cell')
+ grid.appendChild(cell)
+}
+shipMove(carrier, 0, 0)
+shipMove(battleship, 0, 1)
+shipMove(cruiser, 0, 2)
+shipMove(submarine, 0, 3)
+shipMove(destroyer, 0, 4)
diff --git a/demo/onshipgrid/style.css b/demo/onshipgrid/style.css
new file mode 100644
index 0000000..e5beddc
--- /dev/null
+++ b/demo/onshipgrid/style.css
@@ -0,0 +1,106 @@
+body {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+.grid {
+ width: 420px;
+ height: 420px;
+ padding: 5px;
+ margin: 5px;
+ display: flex;
+ flex-wrap: wrap;
+ background-color: darkturquoise;
+}
+
+.grid span {
+ width: 40px;
+ height: 40px;
+ margin: 1px;
+ background-color: #eee;
+ position: relative;
+}
+
+.grid span.hot {
+ background-color: darkturquoise;
+}
+
+.ship {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ z-index: 10;
+ position: relative;
+ margin: -1px;
+}
+
+.ship.vertical {
+ flex-direction: column;
+}
+
+.carrier {
+ width: 210px;
+ height: 40px;
+}
+
+.carrier.vertical {
+ width: 40px;
+ height: 210px;
+}
+
+.battleship {
+ width: 168px;
+ height: 40px;
+}
+
+.battleship.vertical {
+ width: 40px;
+ height: 168px;
+}
+
+.cruiser,
+.submarine {
+ width: 126px;
+ height: 40px;
+}
+
+.cruiser.vertical,
+.submarine.vertical {
+ width: 40px;
+ height: 126px;
+}
+
+.destroyer {
+ width: 84px;
+ height: 40px;
+}
+
+.destroyer.vertical {
+ width: 40px;
+ height: 84px;
+}
+
+.ship span {
+ width: 40px;
+ height: 40px;
+ background-color: darkcyan;
+}
+
+.ship .head {
+ border-radius: 20px 0 0 20px;
+}
+
+.ship .tail {
+ border-radius: 0 10px 10px 0;
+}
+
+.ship.vertical .head {
+ border-radius: 20px 20px 0 0;
+}
+
+.ship.vertical .tail {
+ border-radius: 0 0 10px 10px;
+}
diff --git a/demo/public/bs.css b/demo/public/bs.css
new file mode 100644
index 0000000..a54bc78
--- /dev/null
+++ b/demo/public/bs.css
@@ -0,0 +1,35 @@
+* {
+ margin: 0px;
+ padding: 0px;
+ box-sizing: border-box;
+}
+
+body {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+#sea {
+ display: flex;
+}
+
+.player-grid {
+ width: 430px;
+ height: 430px;
+ padding: 5px;
+ margin: 5px;
+ background-color: darkslategray;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.player-grid .cell {
+ width: 40px;
+ height: 40px;
+ margin: 1px;
+ background-color: darkcyan;
+}
diff --git a/demo/public/bs.html b/demo/public/bs.html
new file mode 100644
index 0000000..663bfae
--- /dev/null
+++ b/demo/public/bs.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ Battleship
+
+
+
+
+
+
+ Battleship
+
+
+
+
diff --git a/demo/public/bs.js b/demo/public/bs.js
new file mode 100644
index 0000000..d6b0aa5
--- /dev/null
+++ b/demo/public/bs.js
@@ -0,0 +1,15 @@
+(function () {
+ const client = { id: "", io: io() }
+ client.io.on('id', id => client.id = id)
+
+ const player1Grid = document.getElementById('player1-grid')
+ const player2Grid = document.getElementById('player2-grid')
+ for (let i = 0; i < 100; i++) {
+ const div1 = document.createElement('div')
+ div1.classList.add('cell')
+ player1Grid.appendChild(div1)
+ const div2 = document.createElement('div')
+ div2.classList.add('cell')
+ player2Grid.appendChild(div2)
+ }
+})()
diff --git a/demo/public/client.js b/demo/public/client.js
new file mode 100644
index 0000000..b3324bb
--- /dev/null
+++ b/demo/public/client.js
@@ -0,0 +1,28 @@
+const canvas = document.getElementById('canvas')
+const ctx = canvas.getContext('2d')
+const ColorBackgroud = '#000'
+const CanvasWidth = 1000, CanvasHeight = 500
+const client = { id: "", io: io() }
+
+client.io.on('id', id => client.id = id)
+
+canvas.width = CanvasWidth
+canvas.height = CanvasHeight
+ctx.fillstyle = ColorBackgroud
+ctx.fillRect(0, 0, CanvasWidth, CanvasHeight)
+
+document.addEventListener('click', event => {
+ console.log(event)
+ switch (event.key) {
+ case 'ArrowUp':
+ break
+ case 'ArrowDown':
+ break
+ case 'ArrowLeft':
+ break
+ case 'ArrowRight':
+ break
+ default:
+ break
+ }
+})
diff --git a/demo/public/favicon.ico b/demo/public/favicon.ico
new file mode 100644
index 0000000..ddaaf83
Binary files /dev/null and b/demo/public/favicon.ico differ
diff --git a/demo/public/index.html b/demo/public/index.html
new file mode 100644
index 0000000..33a4345
--- /dev/null
+++ b/demo/public/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ Battleship War
+
+
+
+
+
+
+
+
Battleship War
+
+
+
+
+
diff --git a/demo/public/style.css b/demo/public/style.css
new file mode 100644
index 0000000..e27e7d4
--- /dev/null
+++ b/demo/public/style.css
@@ -0,0 +1,13 @@
+* {
+ margin: 0px;
+ padding: 0px;
+ box-sizing: border-box;
+}
+
+body {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
diff --git a/demo/public2/favicon.ico b/demo/public2/favicon.ico
new file mode 100644
index 0000000..ddaaf83
Binary files /dev/null and b/demo/public2/favicon.ico differ
diff --git a/demo/public2/index.html b/demo/public2/index.html
new file mode 100644
index 0000000..3d9df52
--- /dev/null
+++ b/demo/public2/index.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ Battleships
+
+
+
+
+
+
Battleships
+
+
+
+
+
+
+
+
+
diff --git a/demo/public2/main.js b/demo/public2/main.js
new file mode 100644
index 0000000..6679b97
--- /dev/null
+++ b/demo/public2/main.js
@@ -0,0 +1,159 @@
+document.addEventListener('DOMContentLoaded', () => {
+ const client = io()
+ const queryString = window.location.search
+ const urlParams = new URLSearchParams(queryString)
+ const playerName = document.querySelector('#playerName')
+ playerName.innerHTML = urlParams.get('name')
+ client.emit('name', playerName.innerHTML)
+
+ // Init the game
+ const playerGrid = document.querySelector('#playerGrid')
+ for (let i = 0; i < 100; i++) {
+ const cell = document.createElement('span')
+ cell.id = `playerCell${i}`
+ cell.classList.add('cell')
+ cell.dataset.index = i
+ cell.dataset.x = i % 10
+ cell.dataset.y = (i - cell.dataset.x) / 10
+ cell.classList.add('cell')
+ playerGrid.appendChild(cell)
+ }
+
+ const enemyGrid = document.querySelector('#enemyGrid')
+ for (let i = 0; i < 100; i++) {
+ const cell = document.createElement('span')
+ cell.id = `enemyCell${i}`
+ cell.classList.add('cell')
+ cell.dataset.index = i
+ cell.dataset.x = i % 10
+ cell.dataset.y = (i - cell.dataset.x) / 10
+ cell.classList.add('cell')
+ enemyGrid.appendChild(cell)
+ }
+
+ const ships = document.querySelectorAll('.ship')
+ const carrier = document.querySelector('.carrier') // 航空母舰
+ const battleship = document.querySelector('.battleship') // 战列舰
+ const cruiser = document.querySelector('.cruiser') // 巡洋舰
+ const submarine = document.querySelector('.submarine') // 潜艇
+ const destroyer = document.querySelector('.destroyer') // 驱逐舰
+
+ let playing = false
+ let dragingItem = null
+
+
+ function mod(n, w) {
+ const x = n % w
+ const y = (n - x) / w
+ return { x, y }
+ }
+
+ function checkIfCollision(ox, oy, currentShip) {
+ for (let ship of ships) {
+ if (ship != currentShip) {
+ const cell = ship.parentNode
+ const index = parseInt(cell.dataset.index)
+ let { x, y } = mod(index, 10)
+ const vertical = ship.classList.contains('vertical')
+ const length = ship.children.length
+ if (vertical) {
+ const tail = y + length
+ for (; y < tail; y++) {
+ if (ox === x && oy === y) return true
+ }
+ } else {
+ const tail = x + length
+ for (; x < tail; x++) {
+ if (ox === x && oy === y) return true
+ }
+ }
+ }
+ }
+ return false
+ }
+
+ function shipRotate(e) {
+ if (playing) return
+ const currentShip = e.target.parentNode
+ const length = currentShip.children.length
+ const cell = currentShip.parentNode
+ const index = parseInt(cell.dataset.index)
+ let { x, y } = mod(index, 10)
+ const vertical = currentShip.classList.contains('vertical')
+ // TODO 检查碰撞
+ if (vertical) {
+ // 判断转为横向时是否碰撞
+ const tail = x + length - 1
+ if (tail >= 10) return // 船尾越界
+ for (x = x + 1; x <= tail; x++) {
+ if (checkIfCollision(x, y, currentShip)) return
+ }
+ } else {
+ // 判断转为竖向时是否碰撞
+ const tail = y + length - 1
+ if (tail >= 10) return // 船尾越界
+ for (y = y + 1; y <= tail; y++) {
+ if (checkIfCollision(x, y, currentShip)) return
+ }
+ }
+
+ currentShip.classList.toggle('vertical')
+ }
+
+ function shipMove(ship, x, y) {
+ const index = 10 * y + x
+ const cell = document.getElementById(`playerCell${index}`)
+ const length = ship.children.length
+ const vertical = ship.classList.contains('vertical')
+ // TODO 检查碰撞
+ if (vertical) {
+ // 判断转为竖向时是否碰撞
+ const tail = y + length - 1
+ if (tail >= 10) return // 船尾越界
+ for (let i = y + 1; i <= tail; i++) {
+ if (checkIfCollision(x, i, ship)) return
+ }
+ } else {
+ // 判断转为横向时是否碰撞
+ const tail = x + length - 1
+ if (tail >= 10) return // 船尾越界
+ for (let i = x + 1; i <= tail; i++) {
+ if (checkIfCollision(i, y, ship)) return
+ }
+ }
+ cell.appendChild(ship)
+ }
+
+ for (let ship of ships) ship.addEventListener('dblclick', shipRotate)
+
+ document.addEventListener('dragstart', e => {
+ if (playing || e.target.classList && !e.target.classList.contains('ship')) {
+ e.preventDefault()
+ return
+ }
+ dragingItem = e.target
+ })
+ document.addEventListener('dragover', e => {
+ e.preventDefault()
+ dragingItem.style.display = 'none'
+ })
+ function toggleCellHightlight(e) { if (e.target.classList && e.target.classList.contains('cell')) e.target.classList.toggle('hot') }
+ document.addEventListener('dragenter', toggleCellHightlight)
+ document.addEventListener('dragleave', toggleCellHightlight)
+ document.addEventListener('drop', e => {
+ e.preventDefault()
+ if (e.target.classList.contains('cell')) {
+ e.target.classList.remove('hot')
+ e.target.appendChild(dragingItem)
+ }
+ dragingItem.style.display = 'flex'
+ dragingItem = null
+ })
+
+ shipMove(carrier, 1, 1)
+ shipMove(battleship, 1, 2)
+ shipMove(cruiser, 1, 3)
+ shipMove(submarine, 1, 4)
+ shipMove(destroyer, 1, 5)
+
+})
diff --git a/demo/public2/play.html b/demo/public2/play.html
new file mode 100644
index 0000000..7b15fd9
--- /dev/null
+++ b/demo/public2/play.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+ Battleships
+
+
+
+
+
+
+
+
+ You: ...
+ Status: Planning
+ Score: 0
+
+
+
+
+
+ Enemy: ...
+ Status: ...
+ Score: 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/public2/style.css b/demo/public2/style.css
new file mode 100644
index 0000000..562b686
--- /dev/null
+++ b/demo/public2/style.css
@@ -0,0 +1,150 @@
+* {
+ margin: 0px;
+ padding: 0px;
+ box-sizing: border-box;
+}
+
+body {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+body,
+input,
+select,
+button {
+ font-family: monospace;
+ font-size: 20px;
+}
+
+input,
+button {
+ border: 1px solid #333;
+ padding: 10px;
+ border-radius: 0px;
+}
+
+button {
+ cursor: pointer;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.container {
+ display: flex;
+}
+
+.row {
+ flex-direction: row;
+ margin: 1rem 0;
+ justify-content: space-between;
+}
+
+.column {
+ flex-direction: column;
+ margin: 0 1rem;
+}
+
+.grid {
+ width: 430px;
+ height: 430px;
+ padding: 5px;
+ display: flex;
+ flex-wrap: wrap;
+ background-color: #003768;
+}
+
+.grid span {
+ width: 40px;
+ height: 40px;
+ margin: 1px;
+ background-color: #3987c9;
+ position: relative;
+}
+
+.grid span.hot {
+ background-color: #7fffd4;
+}
+
+.ship {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ z-index: 10;
+ position: relative;
+ margin: -1px;
+}
+
+.ship.vertical {
+ flex-direction: column;
+}
+
+.carrier {
+ width: 210px;
+ height: 40px;
+}
+
+.carrier.vertical {
+ width: 40px;
+ height: 210px;
+}
+
+.battleship {
+ width: 168px;
+ height: 40px;
+}
+
+.battleship.vertical {
+ width: 40px;
+ height: 168px;
+}
+
+.cruiser,
+.submarine {
+ width: 126px;
+ height: 40px;
+}
+
+.cruiser.vertical,
+.submarine.vertical {
+ width: 40px;
+ height: 126px;
+}
+
+.destroyer {
+ width: 84px;
+ height: 40px;
+}
+
+.destroyer.vertical {
+ width: 40px;
+ height: 84px;
+}
+
+.ship span {
+ width: 40px;
+ height: 40px;
+ background-color: lightblue;
+}
+
+.ship .head {
+ border-radius: 20px 0 0 20px;
+}
+
+.ship .tail {
+ border-radius: 0 10px 10px 0;
+}
+
+.ship.vertical .head {
+ border-radius: 20px 20px 0 0;
+}
+
+.ship.vertical .tail {
+ border-radius: 0 0 10px 10px;
+}
diff --git a/demo/ship.js b/demo/ship.js
new file mode 100644
index 0000000..91c9dda
--- /dev/null
+++ b/demo/ship.js
@@ -0,0 +1,37 @@
+class Ship {
+ constructor(name, length) {
+ this.name = name
+ this.length = length
+ }
+}
+
+class Carrier extends Ship {
+ constructor() {
+ super('Carrier', 5)
+ }
+}
+
+class Battleship extends Ship {
+ constructor() {
+ super('Battleship', 4)
+ }
+}
+
+class Destroyer extends Ship {
+ constructor() {
+ super('Destroyer', 3)
+ }
+}
+
+class Submarine extends Ship {
+ constructor() {
+ super('Submarine', 3)
+ }
+}
+class Patrolboat extends Ship {
+ constructor() {
+ super('Patrolboat', 2)
+ }
+}
+
+module.exports = { Carrier, Battleship, Destroyer, Submarine, Patrolboat }
diff --git a/参考项目/846px-Battleships_Paper_Game.svg.png b/参考项目/846px-Battleships_Paper_Game.svg.png
new file mode 100644
index 0000000..e1a6e1b
Binary files /dev/null and b/参考项目/846px-Battleships_Paper_Game.svg.png differ
diff --git a/参考项目/BattleShip/README.md b/参考项目/BattleShip/README.md
new file mode 100644
index 0000000..faf2c98
--- /dev/null
+++ b/参考项目/BattleShip/README.md
@@ -0,0 +1,98 @@
+# Battleships!
+
+A backend implementation Battleship using JavaScript.
+
+## Setup
+
+You will need to have the `prompt-sync` module for synchronous prompting of user input:
+
+`npm install --save prompt-sync`
+
+Clone the repo, navigate to the directory, and run:
+
+ `node app.js`
+
+ Simple as that! For placing ships, enter coordinates in the form `[x,y]`, for attacking ships, use `[y,x]`
+
+## Design
+
+Battleships uses an object-oriented approach to game design:
+
+### Classes
+
+**Player**
+Has a `name`, `board`, and collection of `ships`. Giving each player a board allows us to abstract the board logic to its own class, and define a set of functions that will work regardless of the state of the current player's board.
+
+Player has one instance method on its prototype – `lost()` which makes use of ES6's `Array.prototype.every()` function to check if all ships in the collection are sunk.
+
+**Ship**
+Ships have a `name`, `length`, and `numHits`. The ship uses 4 static methods to create instances of itself:
+
+```
+Ship.aircraftCarrier = function() {
+ return new Ship(5, "aircraft carrier")
+};
+```
+
+This allows the `Player` class to have ships like so:
+
+
+```
+Player.prototype.createShips = function() {
+ return (
+ {
+ aircraftCarrier: Ship.aircraftCarrier(),
+ battleship: Ship.battleship(),
+ submarine: Ship.submarine(),
+ patrolBoat: Ship.patrolBoat()
+
+ }
+ )
+};
+```
+Ships have a `hit()` method, which increments `numHits` and checks its `sunk()` method.
+
+**Board**
+The board manages the placement of ships, checking if an attack hits or misses, and creation of the obfuscated board.
+
+Ships are represented on the board as letters. For example, aircraft carriers are represented by the letter 'a'. The board iterates over its cells and uses a switch statement to handle a successful hit:
+
+```
+if (target != 'x' && target != '~') {
+ console.log("It's a hit!");
+ switch (target) {
+ case 'a':
+ player.ships.aircraftCarrier.hit();
+ break;
+ case 'b':
+ player.ships.battleship.hit();
+ break;
+ case 's':
+ player.ships.submarine.hit();
+ break;
+ case 'p':
+ player.ships.patrolBoat.hit();
+ break;
+ }
+```
+
+`obfuscateBoard()` is used to display the 'upper' board of the player, which is essentially (for now) a record of successful hits. During a given players turn, they will see their opponents obfuscated board. Board obfuscation is accomplished by making a deep copy of the board and replacing anything other than an 'x' (a hit) with '~'
+
+```
+Board.prototype.obfuscateBoard = function() {
+ let deepCopy = JSON.parse(JSON.stringify(this.cells));
+ deepCopy.forEach( (row, i) => {
+ row.forEach( (el, j) => {
+ if (el !== 'x' && el !== '~') {
+ deepCopy[i][j] = '~';
+ }
+ });
+ });
+ return deepCopy;
+}
+```
+
+**app**
+The game driver, app.js, is not actually a class. It is a collection of functions mainly used to set up the game and maintain the rules with validation of coordinates, checking if the game is over, etc. It instantiates two players and then calls `gameSetup()` once for each player followed by `playGame()`
+
+Validation is tricky. There are many ways for a user to give bad input. `validCoords()` stops four behaviors: placing ships diagonally, placing ships out of bounds, placing ships on top of one another, placing ships in a space that is too small or large for the given ship.
diff --git a/参考项目/BattleShip/app.js b/参考项目/BattleShip/app.js
new file mode 100644
index 0000000..cde886b
--- /dev/null
+++ b/参考项目/BattleShip/app.js
@@ -0,0 +1,113 @@
+const Player = require('./player.js')
+const Board = require('./board.js')
+const readline = require('readline')
+var prompt = require('prompt-sync')({
+ autocomplete: null,
+})
+
+var player1 = new Player("Player 1")
+var player2 = new Player("Player 2")
+var currentPlayer = player1
+
+function gameSetup(player) {
+ console.log(`${player.name}, time to place your ships.`)
+ for (var el in player.ships) {
+ getInput(player.ships[el], player.ships[el].name, player)
+ }
+}
+
+function getInput(ship, shipName, player) {
+ var letter = shipName[0]
+ var pair1 = prompt(`Place your ${shipName}, start position `)
+ var pair2 = prompt(`Place your ${shipName}, end position `)
+ while (!validCoords(pair1, pair2, player, ship)) {
+ var pair1 = prompt(`Place your ${shipName}, start position `)
+ var pair2 = prompt(`Place your ${shipName}, end position `)
+ }
+ player.board.placeShip(ship, [pair1, pair2], letter)
+}
+
+function validCoords(p1, p2, player, ship) {
+ var x1 = parseInt(p1[1])
+ var y1 = parseInt(p1[3])
+ var x2 = parseInt(p2[1])
+ var y2 = parseInt(p2[3])
+
+ // Ensure coordinates in bounds.
+ if (x1 < 0 || x2 < 0 || y1 < 0 || y2 < 0) {
+ console.log("Coordinates out of bounds")
+ return false
+ }
+
+ if (x1 > 6 || x2 > 6 || y1 > 6 || y2 > 6) {
+ console.log("Coordinates out of bounds")
+ return false
+ }
+
+ // If both x coords are the same, then the y coords must be different, IE, no diagonal ships.
+ if (!(((x1 != x2) && (y1 === y2)) || ((x1 === x2) && (y1 != y2)))) {
+ console.log("Ships cannot be placed diagonally.")
+ return false
+
+ }
+
+ // Ensure space isn't already populated
+ if (x1 != x2) {
+ var len = Math.abs(x1 - y1)
+
+ for (var i = x1; i < x2; i++) {
+ if (player.board.cells[y1][i] != '~') {
+ console.log("A ship already exists there.")
+ return false
+ }
+ }
+
+ // Ensure the distance between the two coordinates is big enough to fit the whole ship.
+ if (Math.abs(x1 - x2) != ship.length) {
+ console.log("Space is too small or too large to fit ship.")
+ return false
+ }
+
+ } else {
+ var len = Math.abs(y1 - y2)
+
+ for (var i = y1; i < y2; i++) {
+ if (player.board.cells[i][x1] != '~') {
+ console.log("A ship alredy exists there.")
+ return false
+ }
+ }
+
+ if (Math.abs(y1 - y2) != ship.length) {
+ console.log("Space is too small or too large to fit ship.")
+ return false
+ }
+
+ }
+ return true
+}
+
+function getAttackCoords() {
+ return prompt('Enter attack target in the form [y,x] ')
+}
+
+function oppositePlayer() {
+ var other = (currentPlayer === player1 ? player2 : player1)
+ return other
+}
+
+function playGame() {
+ while (!currentPlayer.lost()) {
+ console.log(`${currentPlayer.name}, it's your turn!`)
+ console.log("Your opponent's board:")
+ console.log(oppositePlayer().board.obfuscateBoard())
+ var attackCoords = getAttackCoords()
+ oppositePlayer().board.hit(attackCoords, oppositePlayer())
+ currentPlayer = oppositePlayer()
+ }
+ console.log(`${currentPlayer.name} loses!`)
+}
+
+gameSetup(player1)
+gameSetup(player2)
+playGame()
diff --git a/参考项目/BattleShip/board.js b/参考项目/BattleShip/board.js
new file mode 100644
index 0000000..051a467
--- /dev/null
+++ b/参考项目/BattleShip/board.js
@@ -0,0 +1,94 @@
+"use strict"
+
+function Board(name) {
+ this.cells = this.makeBoard(7, 7)
+ this.name = name
+ this.placeShip = this.placeShip.bind(this)
+ this.obfuscateBoard = this.obfuscateBoard.bind(this)
+ this.setDefault = this.setDefault.bind(this)
+ this.setDefault()
+}
+
+Board.prototype.makeBoard = function (length) {
+ let arr = new Array(length || 0),
+ i = length
+ if (arguments.length > 1) {
+ let args = Array.prototype.slice.call(arguments, 1)
+ while (i--) arr[length - 1 - i] = this.makeBoard.apply(this, args)
+ }
+ return arr
+}
+
+Board.prototype.placeShip = function (ship, coordindates, shipSym) {
+ let x1 = parseInt(coordindates[0][1])
+ let y1 = parseInt(coordindates[0][3])
+ let x2 = parseInt(coordindates[1][1])
+ let y2 = parseInt(coordindates[1][3])
+
+ // Check if ship extends vertically or horizontally.
+ if (x1 != x2) {
+ let len = Math.abs(x1 - x2)
+ for (let i = x1; i < x2; i++) {
+ this.cells[y1][i] = shipSym
+ }
+ } else {
+ let len = Math.abs(y1 - y2)
+ for (let i = y1; i < y2; i++) {
+ this.cells[i][x1] = shipSym
+ }
+ }
+ console.log(this.cells)
+}
+
+// 5 possible outcomes: hit, miss, repeat hit, sunk, victory.
+Board.prototype.hit = function (coordindates, player) {
+ let x1 = parseInt(coordindates[1])
+ let y1 = parseInt(coordindates[3])
+ let target = this.cells[x1][y1]
+
+ if (target != 'x' && target != '~') {
+ console.log("It's a hit!")
+ switch (target) {
+ case 'a':
+ player.ships.aircraftCarrier.hit()
+ break
+ case 'b':
+ player.ships.battleship.hit()
+ break
+ case 's':
+ player.ships.submarine.hit()
+ break
+ case 'p':
+ player.ships.patrolBoat.hit()
+ break
+ }
+ // Mark cell so we know that part of the ship has been hit.
+ this.cells[x1][y1] = 'x'
+ } else if (target === 'x') {
+ console.log("You already attacked that spot!")
+ } else {
+ console.log("Missfire!")
+ }
+}
+
+// Fill the board with water tiles.
+Board.prototype.setDefault = function () {
+ this.cells.forEach(row => {
+ row.fill('~')
+ })
+}
+
+// Display board only showing spots where the player has successfully hit the opponent.
+Board.prototype.obfuscateBoard = function () {
+ let deepCopy = JSON.parse(JSON.stringify(this.cells))
+ deepCopy.forEach((row, i) => {
+ row.forEach((el, j) => {
+ if (el !== 'x' && el !== '~') {
+ deepCopy[i][j] = '~'
+ }
+ })
+ })
+ return deepCopy
+}
+
+module.exports = Board
diff --git a/参考项目/BattleShip/bundle.js b/参考项目/BattleShip/bundle.js
new file mode 100644
index 0000000..35247f3
--- /dev/null
+++ b/参考项目/BattleShip/bundle.js
@@ -0,0 +1,31257 @@
+/******/ (function (modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {}
+
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+
+/******/ // Check if module is in cache
+/******/ if (installedModules[moduleId])
+/******/ return installedModules[moduleId].exports
+
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ exports: {},
+/******/ id: moduleId,
+/******/ loaded: false
+ /******/
+}
+
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__)
+
+/******/ // Flag the module as loaded
+/******/ module.loaded = true
+
+/******/ // Return the exports of the module
+/******/ return module.exports
+ /******/
+}
+
+
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules
+
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules
+
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = ""
+
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(0)
+ /******/
+})
+/************************************************************************/
+/******/([
+/* 0 */
+/***/ function (module, exports, __webpack_require__) {
+
+ const Player = __webpack_require__(1)
+ const Board = __webpack_require__(3)
+ const readline = __webpack_require__(4)
+
+ var prompt = __webpack_require__(14)
+
+ var player1 = new Player("Player 1")
+ var player2 = new Player("Player 2")
+ console.log("Player1, time to place your ships!")
+ console.log("Player1, time to place your Aircraft Carrier!")
+ prompt.start()
+ prompt.get(['pair1', 'pair2'], function (err, result) {
+ player1.board.placeShip(player1.ships.aircraftCarrier, [result.pair1, result.pair2])
+ })
+
+ console.log("Player1, time to place your BattleShip!")
+ console.log("Player1, time to place your Submarine!")
+ console.log("Player1, time to place your Patrol Boat!")
+
+
+
+ // console.log(p.name);
+ // console.log(p.ships);
+ // console.log(p.board.cells)
+
+ /***/
+},
+/* 1 */
+/***/ function (module, exports, __webpack_require__) {
+
+ const Ship = __webpack_require__(2)
+ const Board = __webpack_require__(3)
+
+ function Player(name) {
+ this.name = name
+ this.board = new Board(this.name)
+ this.ships = this.createShips()
+ }
+
+ Player.prototype.createShips = function () {
+ return (
+ {
+ aircraftCarrier: Ship.aircraftCarrier(),
+ battleship: Ship.battleship(),
+ submarine: Ship.submarine(),
+ patrolBoat: Ship.patrolBoat()
+ }
+ )
+ }
+
+ module.exports = Player
+
+ /***/
+},
+/* 2 */
+/***/ function (module, exports) {
+
+
+ function Ship(length, type) {
+ this.length = length
+ this.name = type
+ this.numHits = 0
+ this.placed = false
+ }
+
+ Ship.aircraftCarrier = function () {
+ return new Ship(5, "aircraft carrier")
+ }
+
+ Ship.submarine = function () {
+ return new Ship(4, "submarine")
+ }
+
+ Ship.battleship = function () {
+ return new Ship(3, "battleship")
+ }
+
+ Ship.patrolBoat = function () {
+ return new Ship(2, "patrol boat")
+ }
+
+ Ship.prototype.hit = function () {
+ this.numHits += 1
+ }
+
+ Ship.prototype.placed = function () {
+ return this.placed
+ }
+
+ Ship.prototype.sunk = function () {
+ if (this.numHits === this.length) {
+ return true
+ } else {
+ return false
+ }
+ }
+
+
+ module.exports = Ship
+
+
+ /***/
+},
+/* 3 */
+/***/ function (module, exports) {
+
+ "use strict"
+
+ function Board(name) {
+ this.cells = this.makeBoard(7, 7)
+ this.name = name
+ }
+
+ Board.prototype.makeBoard = function (length) {
+ let arr = new Array(length || 0),
+ i = length
+ if (arguments.length > 1) {
+ let args = Array.prototype.slice.call(arguments, 1)
+ while (i--) arr[length - 1 - i] = this.makeBoard.apply(this, args)
+ }
+ return arr
+ }
+
+ Board.prototype.placeShip = function (ship, coordindates) {
+
+ }
+
+
+ module.exports = Board
+
+ /***/
+},
+/* 4 */
+/***/ function (module, exports, __webpack_require__) {
+
+ /* WEBPACK VAR INJECTION */(function (Buffer) {
+ var fs = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"fs\""); e.code = 'MODULE_NOT_FOUND'; throw e }())),
+ EventEmitter = __webpack_require__(9).EventEmitter,
+ util = __webpack_require__(10)
+
+ var readLine = module.exports = function (file, opts) {
+ if (!(this instanceof readLine)) return new readLine(file, opts)
+
+ EventEmitter.call(this)
+ opts = opts || {}
+ opts.maxLineLength = opts.maxLineLength || 4096 // 4K
+ opts.retainBuffer = !!opts.retainBuffer //do not convert to String prior to invoking emit 'line' event
+ var self = this,
+ lineBuffer = new Buffer(opts.maxLineLength),
+ lineLength = 0,
+ lineCount = 0,
+ byteCount = 0,
+ emit = function (lineCount, byteCount) {
+ try {
+ var line = lineBuffer.slice(0, lineLength)
+ self.emit('line', opts.retainBuffer ? line : line.toString(), lineCount, byteCount)
+ } catch (err) {
+ self.emit('error', err)
+ } finally {
+ lineLength = 0 // Empty buffer.
+ }
+ }
+ this.input = ('string' === typeof file) ? fs.createReadStream(file, opts) : file
+ this.input.on('open', function (fd) {
+ self.emit('open', fd)
+ })
+ .on('data', function (data) {
+ for (var i = 0; i < data.length; i++) {
+ if (data[i] == 10 || data[i] == 13) { // Newline char was found.
+ if (data[i] == 10) {
+ lineCount++
+ emit(lineCount, byteCount)
+ }
+ } else {
+ lineBuffer[lineLength] = data[i] // Buffer new line data.
+ lineLength++
+ }
+ byteCount++
+ }
+ })
+ .on('error', function (err) {
+ self.emit('error', err)
+ })
+ .on('end', function () {
+ // Emit last line if anything left over since EOF won't trigger it.
+ if (lineLength) {
+ lineCount++
+ emit(lineCount, byteCount)
+ }
+ self.emit('end')
+ })
+ .on('close', function () {
+ self.emit('close')
+ })
+ }
+ util.inherits(readLine, EventEmitter)
+
+ /* WEBPACK VAR INJECTION */
+}.call(exports, __webpack_require__(5).Buffer))
+
+ /***/
+},
+/* 5 */
+/***/ function (module, exports, __webpack_require__) {
+
+ /* WEBPACK VAR INJECTION */(function (Buffer, global) {/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author Feross Aboukhadijeh
+ * @license MIT
+ */
+ /* eslint-disable no-proto */
+
+ 'use strict'
+
+ var base64 = __webpack_require__(6)
+ var ieee754 = __webpack_require__(7)
+ var isArray = __webpack_require__(8)
+
+ exports.Buffer = Buffer
+ exports.SlowBuffer = SlowBuffer
+ exports.INSPECT_MAX_BYTES = 50
+ Buffer.poolSize = 8192 // not used by this implementation
+
+ var rootParent = {}
+
+ /**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ * === true Use Uint8Array implementation (fastest)
+ * === false Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Due to various browser bugs, sometimes the Object implementation will be used even
+ * when the browser supports typed arrays.
+ *
+ * Note:
+ *
+ * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
+ * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
+ * on objects.
+ *
+ * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ * incorrect length in some situations.
+
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
+ * get the Object implementation, which is slower but behaves correctly.
+ */
+ Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
+ ? global.TYPED_ARRAY_SUPPORT
+ : typedArraySupport()
+
+ function typedArraySupport() {
+ function Bar() { }
+ try {
+ var arr = new Uint8Array(1)
+ arr.foo = function () { return 42 }
+ arr.constructor = Bar
+ return arr.foo() === 42 && // typed array instances can be augmented
+ arr.constructor === Bar && // constructor can be set
+ typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+ arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+ } catch (e) {
+ return false
+ }
+ }
+
+ function kMaxLength() {
+ return Buffer.TYPED_ARRAY_SUPPORT
+ ? 0x7fffffff
+ : 0x3fffffff
+ }
+
+ /**
+ * Class: Buffer
+ * =============
+ *
+ * The Buffer constructor returns instances of `Uint8Array` that are augmented
+ * with function properties for all the node `Buffer` API functions. We use
+ * `Uint8Array` so that square bracket notation works as expected -- it returns
+ * a single octet.
+ *
+ * By augmenting the instances, we can avoid modifying the `Uint8Array`
+ * prototype.
+ */
+ function Buffer(arg) {
+ if (!(this instanceof Buffer)) {
+ // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
+ if (arguments.length > 1) return new Buffer(arg, arguments[1])
+ return new Buffer(arg)
+ }
+
+ if (!Buffer.TYPED_ARRAY_SUPPORT) {
+ this.length = 0
+ this.parent = undefined
+ }
+
+ // Common case.
+ if (typeof arg === 'number') {
+ return fromNumber(this, arg)
+ }
+
+ // Slightly less common case.
+ if (typeof arg === 'string') {
+ return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
+ }
+
+ // Unusual.
+ return fromObject(this, arg)
+ }
+
+ function fromNumber(that, length) {
+ that = allocate(that, length < 0 ? 0 : checked(length) | 0)
+ if (!Buffer.TYPED_ARRAY_SUPPORT) {
+ for (var i = 0; i < length; i++) {
+ that[i] = 0
+ }
+ }
+ return that
+ }
+
+ function fromString(that, string, encoding) {
+ if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
+
+ // Assumption: byteLength() return value is always < kMaxLength.
+ var length = byteLength(string, encoding) | 0
+ that = allocate(that, length)
+
+ that.write(string, encoding)
+ return that
+ }
+
+ function fromObject(that, object) {
+ if (Buffer.isBuffer(object)) return fromBuffer(that, object)
+
+ if (isArray(object)) return fromArray(that, object)
+
+ if (object == null) {
+ throw new TypeError('must start with number, buffer, array or string')
+ }
+
+ if (typeof ArrayBuffer !== 'undefined') {
+ if (object.buffer instanceof ArrayBuffer) {
+ return fromTypedArray(that, object)
+ }
+ if (object instanceof ArrayBuffer) {
+ return fromArrayBuffer(that, object)
+ }
+ }
+
+ if (object.length) return fromArrayLike(that, object)
+
+ return fromJsonObject(that, object)
+ }
+
+ function fromBuffer(that, buffer) {
+ var length = checked(buffer.length) | 0
+ that = allocate(that, length)
+ buffer.copy(that, 0, 0, length)
+ return that
+ }
+
+ function fromArray(that, array) {
+ var length = checked(array.length) | 0
+ that = allocate(that, length)
+ for (var i = 0; i < length; i += 1) {
+ that[i] = array[i] & 255
+ }
+ return that
+ }
+
+ // Duplicate of fromArray() to keep fromArray() monomorphic.
+ function fromTypedArray(that, array) {
+ var length = checked(array.length) | 0
+ that = allocate(that, length)
+ // Truncating the elements is probably not what people expect from typed
+ // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
+ // of the old Buffer constructor.
+ for (var i = 0; i < length; i += 1) {
+ that[i] = array[i] & 255
+ }
+ return that
+ }
+
+ function fromArrayBuffer(that, array) {
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ // Return an augmented `Uint8Array` instance, for best performance
+ array.byteLength
+ that = Buffer._augment(new Uint8Array(array))
+ } else {
+ // Fallback: Return an object instance of the Buffer class
+ that = fromTypedArray(that, new Uint8Array(array))
+ }
+ return that
+ }
+
+ function fromArrayLike(that, array) {
+ var length = checked(array.length) | 0
+ that = allocate(that, length)
+ for (var i = 0; i < length; i += 1) {
+ that[i] = array[i] & 255
+ }
+ return that
+ }
+
+ // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
+ // Returns a zero-length buffer for inputs that don't conform to the spec.
+ function fromJsonObject(that, object) {
+ var array
+ var length = 0
+
+ if (object.type === 'Buffer' && isArray(object.data)) {
+ array = object.data
+ length = checked(array.length) | 0
+ }
+ that = allocate(that, length)
+
+ for (var i = 0; i < length; i += 1) {
+ that[i] = array[i] & 255
+ }
+ return that
+ }
+
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ Buffer.prototype.__proto__ = Uint8Array.prototype
+ Buffer.__proto__ = Uint8Array
+ } else {
+ // pre-set for values that may exist in the future
+ Buffer.prototype.length = undefined
+ Buffer.prototype.parent = undefined
+ }
+
+ function allocate(that, length) {
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ // Return an augmented `Uint8Array` instance, for best performance
+ that = Buffer._augment(new Uint8Array(length))
+ that.__proto__ = Buffer.prototype
+ } else {
+ // Fallback: Return an object instance of the Buffer class
+ that.length = length
+ that._isBuffer = true
+ }
+
+ var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
+ if (fromPool) that.parent = rootParent
+
+ return that
+ }
+
+ function checked(length) {
+ // Note: cannot use `length < kMaxLength` here because that fails when
+ // length is NaN (which is otherwise coerced to zero.)
+ if (length >= kMaxLength()) {
+ throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+ 'size: 0x' + kMaxLength().toString(16) + ' bytes')
+ }
+ return length | 0
+ }
+
+ function SlowBuffer(subject, encoding) {
+ if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
+
+ var buf = new Buffer(subject, encoding)
+ delete buf.parent
+ return buf
+ }
+
+ Buffer.isBuffer = function isBuffer(b) {
+ return !!(b != null && b._isBuffer)
+ }
+
+ Buffer.compare = function compare(a, b) {
+ if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+ throw new TypeError('Arguments must be Buffers')
+ }
+
+ if (a === b) return 0
+
+ var x = a.length
+ var y = b.length
+
+ var i = 0
+ var len = Math.min(x, y)
+ while (i < len) {
+ if (a[i] !== b[i]) break
+
+ ++i
+ }
+
+ if (i !== len) {
+ x = a[i]
+ y = b[i]
+ }
+
+ if (x < y) return -1
+ if (y < x) return 1
+ return 0
+ }
+
+ Buffer.isEncoding = function isEncoding(encoding) {
+ switch (String(encoding).toLowerCase()) {
+ case 'hex':
+ case 'utf8':
+ case 'utf-8':
+ case 'ascii':
+ case 'binary':
+ case 'base64':
+ case 'raw':
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return true
+ default:
+ return false
+ }
+ }
+
+ Buffer.concat = function concat(list, length) {
+ if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
+
+ if (list.length === 0) {
+ return new Buffer(0)
+ }
+
+ var i
+ if (length === undefined) {
+ length = 0
+ for (i = 0; i < list.length; i++) {
+ length += list[i].length
+ }
+ }
+
+ var buf = new Buffer(length)
+ var pos = 0
+ for (i = 0; i < list.length; i++) {
+ var item = list[i]
+ item.copy(buf, pos)
+ pos += item.length
+ }
+ return buf
+ }
+
+ function byteLength(string, encoding) {
+ if (typeof string !== 'string') string = '' + string
+
+ var len = string.length
+ if (len === 0) return 0
+
+ // Use a for loop to avoid recursion
+ var loweredCase = false
+ for (; ;) {
+ switch (encoding) {
+ case 'ascii':
+ case 'binary':
+ // Deprecated
+ case 'raw':
+ case 'raws':
+ return len
+ case 'utf8':
+ case 'utf-8':
+ return utf8ToBytes(string).length
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return len * 2
+ case 'hex':
+ return len >>> 1
+ case 'base64':
+ return base64ToBytes(string).length
+ default:
+ if (loweredCase) return utf8ToBytes(string).length // assume utf8
+ encoding = ('' + encoding).toLowerCase()
+ loweredCase = true
+ }
+ }
+ }
+ Buffer.byteLength = byteLength
+
+ function slowToString(encoding, start, end) {
+ var loweredCase = false
+
+ start = start | 0
+ end = end === undefined || end === Infinity ? this.length : end | 0
+
+ if (!encoding) encoding = 'utf8'
+ if (start < 0) start = 0
+ if (end > this.length) end = this.length
+ if (end <= start) return ''
+
+ while (true) {
+ switch (encoding) {
+ case 'hex':
+ return hexSlice(this, start, end)
+
+ case 'utf8':
+ case 'utf-8':
+ return utf8Slice(this, start, end)
+
+ case 'ascii':
+ return asciiSlice(this, start, end)
+
+ case 'binary':
+ return binarySlice(this, start, end)
+
+ case 'base64':
+ return base64Slice(this, start, end)
+
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return utf16leSlice(this, start, end)
+
+ default:
+ if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+ encoding = (encoding + '').toLowerCase()
+ loweredCase = true
+ }
+ }
+ }
+
+ Buffer.prototype.toString = function toString() {
+ var length = this.length | 0
+ if (length === 0) return ''
+ if (arguments.length === 0) return utf8Slice(this, 0, length)
+ return slowToString.apply(this, arguments)
+ }
+
+ Buffer.prototype.equals = function equals(b) {
+ if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+ if (this === b) return true
+ return Buffer.compare(this, b) === 0
+ }
+
+ Buffer.prototype.inspect = function inspect() {
+ var str = ''
+ var max = exports.INSPECT_MAX_BYTES
+ if (this.length > 0) {
+ str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+ if (this.length > max) str += ' ... '
+ }
+ return ''
+ }
+
+ Buffer.prototype.compare = function compare(b) {
+ if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+ if (this === b) return 0
+ return Buffer.compare(this, b)
+ }
+
+ Buffer.prototype.indexOf = function indexOf(val, byteOffset) {
+ if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
+ else if (byteOffset < -0x80000000) byteOffset = -0x80000000
+ byteOffset >>= 0
+
+ if (this.length === 0) return -1
+ if (byteOffset >= this.length) return -1
+
+ // Negative offsets start from the end of the buffer
+ if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
+
+ if (typeof val === 'string') {
+ if (val.length === 0) return -1 // special case: looking for empty string always fails
+ return String.prototype.indexOf.call(this, val, byteOffset)
+ }
+ if (Buffer.isBuffer(val)) {
+ return arrayIndexOf(this, val, byteOffset)
+ }
+ if (typeof val === 'number') {
+ if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
+ return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
+ }
+ return arrayIndexOf(this, [val], byteOffset)
+ }
+
+ function arrayIndexOf(arr, val, byteOffset) {
+ var foundIndex = -1
+ for (var i = 0; byteOffset + i < arr.length; i++) {
+ if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
+ if (foundIndex === -1) foundIndex = i
+ if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
+ } else {
+ foundIndex = -1
+ }
+ }
+ return -1
+ }
+
+ throw new TypeError('val must be string, number or Buffer')
+ }
+
+ // `get` is deprecated
+ Buffer.prototype.get = function get(offset) {
+ console.log('.get() is deprecated. Access using array indexes instead.')
+ return this.readUInt8(offset)
+ }
+
+ // `set` is deprecated
+ Buffer.prototype.set = function set(v, offset) {
+ console.log('.set() is deprecated. Access using array indexes instead.')
+ return this.writeUInt8(v, offset)
+ }
+
+ function hexWrite(buf, string, offset, length) {
+ offset = Number(offset) || 0
+ var remaining = buf.length - offset
+ if (!length) {
+ length = remaining
+ } else {
+ length = Number(length)
+ if (length > remaining) {
+ length = remaining
+ }
+ }
+
+ // must be an even number of digits
+ var strLen = string.length
+ if (strLen % 2 !== 0) throw new Error('Invalid hex string')
+
+ if (length > strLen / 2) {
+ length = strLen / 2
+ }
+ for (var i = 0; i < length; i++) {
+ var parsed = parseInt(string.substr(i * 2, 2), 16)
+ if (isNaN(parsed)) throw new Error('Invalid hex string')
+ buf[offset + i] = parsed
+ }
+ return i
+ }
+
+ function utf8Write(buf, string, offset, length) {
+ return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+ }
+
+ function asciiWrite(buf, string, offset, length) {
+ return blitBuffer(asciiToBytes(string), buf, offset, length)
+ }
+
+ function binaryWrite(buf, string, offset, length) {
+ return asciiWrite(buf, string, offset, length)
+ }
+
+ function base64Write(buf, string, offset, length) {
+ return blitBuffer(base64ToBytes(string), buf, offset, length)
+ }
+
+ function ucs2Write(buf, string, offset, length) {
+ return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+ }
+
+ Buffer.prototype.write = function write(string, offset, length, encoding) {
+ // Buffer#write(string)
+ if (offset === undefined) {
+ encoding = 'utf8'
+ length = this.length
+ offset = 0
+ // Buffer#write(string, encoding)
+ } else if (length === undefined && typeof offset === 'string') {
+ encoding = offset
+ length = this.length
+ offset = 0
+ // Buffer#write(string, offset[, length][, encoding])
+ } else if (isFinite(offset)) {
+ offset = offset | 0
+ if (isFinite(length)) {
+ length = length | 0
+ if (encoding === undefined) encoding = 'utf8'
+ } else {
+ encoding = length
+ length = undefined
+ }
+ // legacy write(string, encoding, offset, length) - remove in v0.13
+ } else {
+ var swap = encoding
+ encoding = offset
+ offset = length | 0
+ length = swap
+ }
+
+ var remaining = this.length - offset
+ if (length === undefined || length > remaining) length = remaining
+
+ if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
+ throw new RangeError('attempt to write outside buffer bounds')
+ }
+
+ if (!encoding) encoding = 'utf8'
+
+ var loweredCase = false
+ for (; ;) {
+ switch (encoding) {
+ case 'hex':
+ return hexWrite(this, string, offset, length)
+
+ case 'utf8':
+ case 'utf-8':
+ return utf8Write(this, string, offset, length)
+
+ case 'ascii':
+ return asciiWrite(this, string, offset, length)
+
+ case 'binary':
+ return binaryWrite(this, string, offset, length)
+
+ case 'base64':
+ // Warning: maxLength not taken into account in base64Write
+ return base64Write(this, string, offset, length)
+
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return ucs2Write(this, string, offset, length)
+
+ default:
+ if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+ encoding = ('' + encoding).toLowerCase()
+ loweredCase = true
+ }
+ }
+ }
+
+ Buffer.prototype.toJSON = function toJSON() {
+ return {
+ type: 'Buffer',
+ data: Array.prototype.slice.call(this._arr || this, 0)
+ }
+ }
+
+ function base64Slice(buf, start, end) {
+ if (start === 0 && end === buf.length) {
+ return base64.fromByteArray(buf)
+ } else {
+ return base64.fromByteArray(buf.slice(start, end))
+ }
+ }
+
+ function utf8Slice(buf, start, end) {
+ end = Math.min(buf.length, end)
+ var res = []
+
+ var i = start
+ while (i < end) {
+ var firstByte = buf[i]
+ var codePoint = null
+ var bytesPerSequence = (firstByte > 0xEF) ? 4
+ : (firstByte > 0xDF) ? 3
+ : (firstByte > 0xBF) ? 2
+ : 1
+
+ if (i + bytesPerSequence <= end) {
+ var secondByte, thirdByte, fourthByte, tempCodePoint
+
+ switch (bytesPerSequence) {
+ case 1:
+ if (firstByte < 0x80) {
+ codePoint = firstByte
+ }
+ break
+ case 2:
+ secondByte = buf[i + 1]
+ if ((secondByte & 0xC0) === 0x80) {
+ tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+ if (tempCodePoint > 0x7F) {
+ codePoint = tempCodePoint
+ }
+ }
+ break
+ case 3:
+ secondByte = buf[i + 1]
+ thirdByte = buf[i + 2]
+ if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
+ tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+ if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
+ codePoint = tempCodePoint
+ }
+ }
+ break
+ case 4:
+ secondByte = buf[i + 1]
+ thirdByte = buf[i + 2]
+ fourthByte = buf[i + 3]
+ if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
+ tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+ if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
+ codePoint = tempCodePoint
+ }
+ }
+ }
+ }
+
+ if (codePoint === null) {
+ // we did not generate a valid codePoint so insert a
+ // replacement char (U+FFFD) and advance only 1 byte
+ codePoint = 0xFFFD
+ bytesPerSequence = 1
+ } else if (codePoint > 0xFFFF) {
+ // encode to utf16 (surrogate pair dance)
+ codePoint -= 0x10000
+ res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+ codePoint = 0xDC00 | codePoint & 0x3FF
+ }
+
+ res.push(codePoint)
+ i += bytesPerSequence
+ }
+
+ return decodeCodePointsArray(res)
+ }
+
+ // Based on http://stackoverflow.com/a/22747272/680742, the browser with
+ // the lowest limit is Chrome, with 0x10000 args.
+ // We go 1 magnitude less, for safety
+ var MAX_ARGUMENTS_LENGTH = 0x1000
+
+ function decodeCodePointsArray(codePoints) {
+ var len = codePoints.length
+ if (len <= MAX_ARGUMENTS_LENGTH) {
+ return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
+ }
+
+ // Decode in chunks to avoid "call stack size exceeded".
+ var res = ''
+ var i = 0
+ while (i < len) {
+ res += String.fromCharCode.apply(
+ String,
+ codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
+ )
+ }
+ return res
+ }
+
+ function asciiSlice(buf, start, end) {
+ var ret = ''
+ end = Math.min(buf.length, end)
+
+ for (var i = start; i < end; i++) {
+ ret += String.fromCharCode(buf[i] & 0x7F)
+ }
+ return ret
+ }
+
+ function binarySlice(buf, start, end) {
+ var ret = ''
+ end = Math.min(buf.length, end)
+
+ for (var i = start; i < end; i++) {
+ ret += String.fromCharCode(buf[i])
+ }
+ return ret
+ }
+
+ function hexSlice(buf, start, end) {
+ var len = buf.length
+
+ if (!start || start < 0) start = 0
+ if (!end || end < 0 || end > len) end = len
+
+ var out = ''
+ for (var i = start; i < end; i++) {
+ out += toHex(buf[i])
+ }
+ return out
+ }
+
+ function utf16leSlice(buf, start, end) {
+ var bytes = buf.slice(start, end)
+ var res = ''
+ for (var i = 0; i < bytes.length; i += 2) {
+ res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+ }
+ return res
+ }
+
+ Buffer.prototype.slice = function slice(start, end) {
+ var len = this.length
+ start = ~~start
+ end = end === undefined ? len : ~~end
+
+ if (start < 0) {
+ start += len
+ if (start < 0) start = 0
+ } else if (start > len) {
+ start = len
+ }
+
+ if (end < 0) {
+ end += len
+ if (end < 0) end = 0
+ } else if (end > len) {
+ end = len
+ }
+
+ if (end < start) end = start
+
+ var newBuf
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ newBuf = Buffer._augment(this.subarray(start, end))
+ } else {
+ var sliceLen = end - start
+ newBuf = new Buffer(sliceLen, undefined)
+ for (var i = 0; i < sliceLen; i++) {
+ newBuf[i] = this[i + start]
+ }
+ }
+
+ if (newBuf.length) newBuf.parent = this.parent || this
+
+ return newBuf
+ }
+
+ /*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+ function checkOffset(offset, ext, length) {
+ if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+ if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+ }
+
+ Buffer.prototype.readUIntLE = function readUIntLE(offset, byteLength, noAssert) {
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+ var val = this[offset]
+ var mul = 1
+ var i = 0
+ while (++i < byteLength && (mul *= 0x100)) {
+ val += this[offset + i] * mul
+ }
+
+ return val
+ }
+
+ Buffer.prototype.readUIntBE = function readUIntBE(offset, byteLength, noAssert) {
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) {
+ checkOffset(offset, byteLength, this.length)
+ }
+
+ var val = this[offset + --byteLength]
+ var mul = 1
+ while (byteLength > 0 && (mul *= 0x100)) {
+ val += this[offset + --byteLength] * mul
+ }
+
+ return val
+ }
+
+ Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 1, this.length)
+ return this[offset]
+ }
+
+ Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 2, this.length)
+ return this[offset] | (this[offset + 1] << 8)
+ }
+
+ Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 2, this.length)
+ return (this[offset] << 8) | this[offset + 1]
+ }
+
+ Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+
+ return ((this[offset]) |
+ (this[offset + 1] << 8) |
+ (this[offset + 2] << 16)) +
+ (this[offset + 3] * 0x1000000)
+ }
+
+ Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+
+ return (this[offset] * 0x1000000) +
+ ((this[offset + 1] << 16) |
+ (this[offset + 2] << 8) |
+ this[offset + 3])
+ }
+
+ Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) {
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+ var val = this[offset]
+ var mul = 1
+ var i = 0
+ while (++i < byteLength && (mul *= 0x100)) {
+ val += this[offset + i] * mul
+ }
+ mul *= 0x80
+
+ if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+ return val
+ }
+
+ Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) {
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+ var i = byteLength
+ var mul = 1
+ var val = this[offset + --i]
+ while (i > 0 && (mul *= 0x100)) {
+ val += this[offset + --i] * mul
+ }
+ mul *= 0x80
+
+ if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+ return val
+ }
+
+ Buffer.prototype.readInt8 = function readInt8(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 1, this.length)
+ if (!(this[offset] & 0x80)) return (this[offset])
+ return ((0xff - this[offset] + 1) * -1)
+ }
+
+ Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 2, this.length)
+ var val = this[offset] | (this[offset + 1] << 8)
+ return (val & 0x8000) ? val | 0xFFFF0000 : val
+ }
+
+ Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 2, this.length)
+ var val = this[offset + 1] | (this[offset] << 8)
+ return (val & 0x8000) ? val | 0xFFFF0000 : val
+ }
+
+ Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+
+ return (this[offset]) |
+ (this[offset + 1] << 8) |
+ (this[offset + 2] << 16) |
+ (this[offset + 3] << 24)
+ }
+
+ Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+
+ return (this[offset] << 24) |
+ (this[offset + 1] << 16) |
+ (this[offset + 2] << 8) |
+ (this[offset + 3])
+ }
+
+ Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+ return ieee754.read(this, offset, true, 23, 4)
+ }
+
+ Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+ return ieee754.read(this, offset, false, 23, 4)
+ }
+
+ Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 8, this.length)
+ return ieee754.read(this, offset, true, 52, 8)
+ }
+
+ Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 8, this.length)
+ return ieee754.read(this, offset, false, 52, 8)
+ }
+
+ function checkInt(buf, value, offset, ext, max, min) {
+ if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
+ if (value > max || value < min) throw new RangeError('value is out of bounds')
+ if (offset + ext > buf.length) throw new RangeError('index out of range')
+ }
+
+ Buffer.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength, noAssert) {
+ value = +value
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+ var mul = 1
+ var i = 0
+ this[offset] = value & 0xFF
+ while (++i < byteLength && (mul *= 0x100)) {
+ this[offset + i] = (value / mul) & 0xFF
+ }
+
+ return offset + byteLength
+ }
+
+ Buffer.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength, noAssert) {
+ value = +value
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+ var i = byteLength - 1
+ var mul = 1
+ this[offset + i] = value & 0xFF
+ while (--i >= 0 && (mul *= 0x100)) {
+ this[offset + i] = (value / mul) & 0xFF
+ }
+
+ return offset + byteLength
+ }
+
+ Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+ if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+ this[offset] = (value & 0xff)
+ return offset + 1
+ }
+
+ function objectWriteUInt16(buf, value, offset, littleEndian) {
+ if (value < 0) value = 0xffff + value + 1
+ for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
+ buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+ (littleEndian ? i : 1 - i) * 8
+ }
+ }
+
+ Buffer.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value & 0xff)
+ this[offset + 1] = (value >>> 8)
+ } else {
+ objectWriteUInt16(this, value, offset, true)
+ }
+ return offset + 2
+ }
+
+ Buffer.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value >>> 8)
+ this[offset + 1] = (value & 0xff)
+ } else {
+ objectWriteUInt16(this, value, offset, false)
+ }
+ return offset + 2
+ }
+
+ function objectWriteUInt32(buf, value, offset, littleEndian) {
+ if (value < 0) value = 0xffffffff + value + 1
+ for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
+ buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+ }
+ }
+
+ Buffer.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset + 3] = (value >>> 24)
+ this[offset + 2] = (value >>> 16)
+ this[offset + 1] = (value >>> 8)
+ this[offset] = (value & 0xff)
+ } else {
+ objectWriteUInt32(this, value, offset, true)
+ }
+ return offset + 4
+ }
+
+ Buffer.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value >>> 24)
+ this[offset + 1] = (value >>> 16)
+ this[offset + 2] = (value >>> 8)
+ this[offset + 3] = (value & 0xff)
+ } else {
+ objectWriteUInt32(this, value, offset, false)
+ }
+ return offset + 4
+ }
+
+ Buffer.prototype.writeIntLE = function writeIntLE(value, offset, byteLength, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) {
+ var limit = Math.pow(2, 8 * byteLength - 1)
+
+ checkInt(this, value, offset, byteLength, limit - 1, -limit)
+ }
+
+ var i = 0
+ var mul = 1
+ var sub = value < 0 ? 1 : 0
+ this[offset] = value & 0xFF
+ while (++i < byteLength && (mul *= 0x100)) {
+ this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+ }
+
+ return offset + byteLength
+ }
+
+ Buffer.prototype.writeIntBE = function writeIntBE(value, offset, byteLength, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) {
+ var limit = Math.pow(2, 8 * byteLength - 1)
+
+ checkInt(this, value, offset, byteLength, limit - 1, -limit)
+ }
+
+ var i = byteLength - 1
+ var mul = 1
+ var sub = value < 0 ? 1 : 0
+ this[offset + i] = value & 0xFF
+ while (--i >= 0 && (mul *= 0x100)) {
+ this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+ }
+
+ return offset + byteLength
+ }
+
+ Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+ if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+ if (value < 0) value = 0xff + value + 1
+ this[offset] = (value & 0xff)
+ return offset + 1
+ }
+
+ Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value & 0xff)
+ this[offset + 1] = (value >>> 8)
+ } else {
+ objectWriteUInt16(this, value, offset, true)
+ }
+ return offset + 2
+ }
+
+ Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value >>> 8)
+ this[offset + 1] = (value & 0xff)
+ } else {
+ objectWriteUInt16(this, value, offset, false)
+ }
+ return offset + 2
+ }
+
+ Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value & 0xff)
+ this[offset + 1] = (value >>> 8)
+ this[offset + 2] = (value >>> 16)
+ this[offset + 3] = (value >>> 24)
+ } else {
+ objectWriteUInt32(this, value, offset, true)
+ }
+ return offset + 4
+ }
+
+ Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+ if (value < 0) value = 0xffffffff + value + 1
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value >>> 24)
+ this[offset + 1] = (value >>> 16)
+ this[offset + 2] = (value >>> 8)
+ this[offset + 3] = (value & 0xff)
+ } else {
+ objectWriteUInt32(this, value, offset, false)
+ }
+ return offset + 4
+ }
+
+ function checkIEEE754(buf, value, offset, ext, max, min) {
+ if (value > max || value < min) throw new RangeError('value is out of bounds')
+ if (offset + ext > buf.length) throw new RangeError('index out of range')
+ if (offset < 0) throw new RangeError('index out of range')
+ }
+
+ function writeFloat(buf, value, offset, littleEndian, noAssert) {
+ if (!noAssert) {
+ checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+ }
+ ieee754.write(buf, value, offset, littleEndian, 23, 4)
+ return offset + 4
+ }
+
+ Buffer.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) {
+ return writeFloat(this, value, offset, true, noAssert)
+ }
+
+ Buffer.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) {
+ return writeFloat(this, value, offset, false, noAssert)
+ }
+
+ function writeDouble(buf, value, offset, littleEndian, noAssert) {
+ if (!noAssert) {
+ checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+ }
+ ieee754.write(buf, value, offset, littleEndian, 52, 8)
+ return offset + 8
+ }
+
+ Buffer.prototype.writeDoubleLE = function writeDoubleLE(value, offset, noAssert) {
+ return writeDouble(this, value, offset, true, noAssert)
+ }
+
+ Buffer.prototype.writeDoubleBE = function writeDoubleBE(value, offset, noAssert) {
+ return writeDouble(this, value, offset, false, noAssert)
+ }
+
+ // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+ Buffer.prototype.copy = function copy(target, targetStart, start, end) {
+ if (!start) start = 0
+ if (!end && end !== 0) end = this.length
+ if (targetStart >= target.length) targetStart = target.length
+ if (!targetStart) targetStart = 0
+ if (end > 0 && end < start) end = start
+
+ // Copy 0 bytes; we're done
+ if (end === start) return 0
+ if (target.length === 0 || this.length === 0) return 0
+
+ // Fatal error conditions
+ if (targetStart < 0) {
+ throw new RangeError('targetStart out of bounds')
+ }
+ if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+ if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+ // Are we oob?
+ if (end > this.length) end = this.length
+ if (target.length - targetStart < end - start) {
+ end = target.length - targetStart + start
+ }
+
+ var len = end - start
+ var i
+
+ if (this === target && start < targetStart && targetStart < end) {
+ // descending copy from end
+ for (i = len - 1; i >= 0; i--) {
+ target[i + targetStart] = this[i + start]
+ }
+ } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
+ // ascending copy from start
+ for (i = 0; i < len; i++) {
+ target[i + targetStart] = this[i + start]
+ }
+ } else {
+ target._set(this.subarray(start, start + len), targetStart)
+ }
+
+ return len
+ }
+
+ // fill(value, start=0, end=buffer.length)
+ Buffer.prototype.fill = function fill(value, start, end) {
+ if (!value) value = 0
+ if (!start) start = 0
+ if (!end) end = this.length
+
+ if (end < start) throw new RangeError('end < start')
+
+ // Fill 0 bytes; we're done
+ if (end === start) return
+ if (this.length === 0) return
+
+ if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
+ if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
+
+ var i
+ if (typeof value === 'number') {
+ for (i = start; i < end; i++) {
+ this[i] = value
+ }
+ } else {
+ var bytes = utf8ToBytes(value.toString())
+ var len = bytes.length
+ for (i = start; i < end; i++) {
+ this[i] = bytes[i % len]
+ }
+ }
+
+ return this
+ }
+
+ /**
+ * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
+ * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
+ */
+ Buffer.prototype.toArrayBuffer = function toArrayBuffer() {
+ if (typeof Uint8Array !== 'undefined') {
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ return (new Buffer(this)).buffer
+ } else {
+ var buf = new Uint8Array(this.length)
+ for (var i = 0, len = buf.length; i < len; i += 1) {
+ buf[i] = this[i]
+ }
+ return buf.buffer
+ }
+ } else {
+ throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
+ }
+ }
+
+ // HELPER FUNCTIONS
+ // ================
+
+ var BP = Buffer.prototype
+
+ /**
+ * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
+ */
+ Buffer._augment = function _augment(arr) {
+ arr.constructor = Buffer
+ arr._isBuffer = true
+
+ // save reference to original Uint8Array set method before overwriting
+ arr._set = arr.set
+
+ // deprecated
+ arr.get = BP.get
+ arr.set = BP.set
+
+ arr.write = BP.write
+ arr.toString = BP.toString
+ arr.toLocaleString = BP.toString
+ arr.toJSON = BP.toJSON
+ arr.equals = BP.equals
+ arr.compare = BP.compare
+ arr.indexOf = BP.indexOf
+ arr.copy = BP.copy
+ arr.slice = BP.slice
+ arr.readUIntLE = BP.readUIntLE
+ arr.readUIntBE = BP.readUIntBE
+ arr.readUInt8 = BP.readUInt8
+ arr.readUInt16LE = BP.readUInt16LE
+ arr.readUInt16BE = BP.readUInt16BE
+ arr.readUInt32LE = BP.readUInt32LE
+ arr.readUInt32BE = BP.readUInt32BE
+ arr.readIntLE = BP.readIntLE
+ arr.readIntBE = BP.readIntBE
+ arr.readInt8 = BP.readInt8
+ arr.readInt16LE = BP.readInt16LE
+ arr.readInt16BE = BP.readInt16BE
+ arr.readInt32LE = BP.readInt32LE
+ arr.readInt32BE = BP.readInt32BE
+ arr.readFloatLE = BP.readFloatLE
+ arr.readFloatBE = BP.readFloatBE
+ arr.readDoubleLE = BP.readDoubleLE
+ arr.readDoubleBE = BP.readDoubleBE
+ arr.writeUInt8 = BP.writeUInt8
+ arr.writeUIntLE = BP.writeUIntLE
+ arr.writeUIntBE = BP.writeUIntBE
+ arr.writeUInt16LE = BP.writeUInt16LE
+ arr.writeUInt16BE = BP.writeUInt16BE
+ arr.writeUInt32LE = BP.writeUInt32LE
+ arr.writeUInt32BE = BP.writeUInt32BE
+ arr.writeIntLE = BP.writeIntLE
+ arr.writeIntBE = BP.writeIntBE
+ arr.writeInt8 = BP.writeInt8
+ arr.writeInt16LE = BP.writeInt16LE
+ arr.writeInt16BE = BP.writeInt16BE
+ arr.writeInt32LE = BP.writeInt32LE
+ arr.writeInt32BE = BP.writeInt32BE
+ arr.writeFloatLE = BP.writeFloatLE
+ arr.writeFloatBE = BP.writeFloatBE
+ arr.writeDoubleLE = BP.writeDoubleLE
+ arr.writeDoubleBE = BP.writeDoubleBE
+ arr.fill = BP.fill
+ arr.inspect = BP.inspect
+ arr.toArrayBuffer = BP.toArrayBuffer
+
+ return arr
+ }
+
+ var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
+
+ function base64clean(str) {
+ // Node strips out invalid characters like \n and \t from the string, base64-js does not
+ str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+ // Node converts strings with length < 2 to ''
+ if (str.length < 2) return ''
+ // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
+ while (str.length % 4 !== 0) {
+ str = str + '='
+ }
+ return str
+ }
+
+ function stringtrim(str) {
+ if (str.trim) return str.trim()
+ return str.replace(/^\s+|\s+$/g, '')
+ }
+
+ function toHex(n) {
+ if (n < 16) return '0' + n.toString(16)
+ return n.toString(16)
+ }
+
+ function utf8ToBytes(string, units) {
+ units = units || Infinity
+ var codePoint
+ var length = string.length
+ var leadSurrogate = null
+ var bytes = []
+
+ for (var i = 0; i < length; i++) {
+ codePoint = string.charCodeAt(i)
+
+ // is surrogate component
+ if (codePoint > 0xD7FF && codePoint < 0xE000) {
+ // last char was a lead
+ if (!leadSurrogate) {
+ // no lead yet
+ if (codePoint > 0xDBFF) {
+ // unexpected trail
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ continue
+ } else if (i + 1 === length) {
+ // unpaired lead
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ continue
+ }
+
+ // valid lead
+ leadSurrogate = codePoint
+
+ continue
+ }
+
+ // 2 leads in a row
+ if (codePoint < 0xDC00) {
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ leadSurrogate = codePoint
+ continue
+ }
+
+ // valid surrogate pair
+ codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
+ } else if (leadSurrogate) {
+ // valid bmp char, but last char was a lead
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ }
+
+ leadSurrogate = null
+
+ // encode utf8
+ if (codePoint < 0x80) {
+ if ((units -= 1) < 0) break
+ bytes.push(codePoint)
+ } else if (codePoint < 0x800) {
+ if ((units -= 2) < 0) break
+ bytes.push(
+ codePoint >> 0x6 | 0xC0,
+ codePoint & 0x3F | 0x80
+ )
+ } else if (codePoint < 0x10000) {
+ if ((units -= 3) < 0) break
+ bytes.push(
+ codePoint >> 0xC | 0xE0,
+ codePoint >> 0x6 & 0x3F | 0x80,
+ codePoint & 0x3F | 0x80
+ )
+ } else if (codePoint < 0x110000) {
+ if ((units -= 4) < 0) break
+ bytes.push(
+ codePoint >> 0x12 | 0xF0,
+ codePoint >> 0xC & 0x3F | 0x80,
+ codePoint >> 0x6 & 0x3F | 0x80,
+ codePoint & 0x3F | 0x80
+ )
+ } else {
+ throw new Error('Invalid code point')
+ }
+ }
+
+ return bytes
+ }
+
+ function asciiToBytes(str) {
+ var byteArray = []
+ for (var i = 0; i < str.length; i++) {
+ // Node's code seems to be doing this and not & 0x7F..
+ byteArray.push(str.charCodeAt(i) & 0xFF)
+ }
+ return byteArray
+ }
+
+ function utf16leToBytes(str, units) {
+ var c, hi, lo
+ var byteArray = []
+ for (var i = 0; i < str.length; i++) {
+ if ((units -= 2) < 0) break
+
+ c = str.charCodeAt(i)
+ hi = c >> 8
+ lo = c % 256
+ byteArray.push(lo)
+ byteArray.push(hi)
+ }
+
+ return byteArray
+ }
+
+ function base64ToBytes(str) {
+ return base64.toByteArray(base64clean(str))
+ }
+
+ function blitBuffer(src, dst, offset, length) {
+ for (var i = 0; i < length; i++) {
+ if ((i + offset >= dst.length) || (i >= src.length)) break
+ dst[i + offset] = src[i]
+ }
+ return i
+ }
+
+ /* WEBPACK VAR INJECTION */
+}.call(exports, __webpack_require__(5).Buffer, (function () { return this }())))
+
+ /***/
+},
+/* 6 */
+/***/ function (module, exports, __webpack_require__) {
+
+ var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+ ; (function (exports) {
+ 'use strict'
+
+ var Arr = (typeof Uint8Array !== 'undefined')
+ ? Uint8Array
+ : Array
+
+ var PLUS = '+'.charCodeAt(0)
+ var SLASH = '/'.charCodeAt(0)
+ var NUMBER = '0'.charCodeAt(0)
+ var LOWER = 'a'.charCodeAt(0)
+ var UPPER = 'A'.charCodeAt(0)
+ var PLUS_URL_SAFE = '-'.charCodeAt(0)
+ var SLASH_URL_SAFE = '_'.charCodeAt(0)
+
+ function decode(elt) {
+ var code = elt.charCodeAt(0)
+ if (code === PLUS ||
+ code === PLUS_URL_SAFE)
+ return 62 // '+'
+ if (code === SLASH ||
+ code === SLASH_URL_SAFE)
+ return 63 // '/'
+ if (code < NUMBER)
+ return -1 //no match
+ if (code < NUMBER + 10)
+ return code - NUMBER + 26 + 26
+ if (code < UPPER + 26)
+ return code - UPPER
+ if (code < LOWER + 26)
+ return code - LOWER + 26
+ }
+
+ function b64ToByteArray(b64) {
+ var i, j, l, tmp, placeHolders, arr
+
+ if (b64.length % 4 > 0) {
+ throw new Error('Invalid string. Length must be a multiple of 4')
+ }
+
+ // the number of equal signs (place holders)
+ // if there are two placeholders, than the two characters before it
+ // represent one byte
+ // if there is only one, then the three characters before it represent 2 bytes
+ // this is just a cheap hack to not do indexOf twice
+ var len = b64.length
+ placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
+
+ // base64 is 4/3 + up to two characters of the original data
+ arr = new Arr(b64.length * 3 / 4 - placeHolders)
+
+ // if there are placeholders, only get up to the last complete 4 chars
+ l = placeHolders > 0 ? b64.length - 4 : b64.length
+
+ var L = 0
+
+ function push(v) {
+ arr[L++] = v
+ }
+
+ for (i = 0, j = 0; i < l; i += 4, j += 3) {
+ tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
+ push((tmp & 0xFF0000) >> 16)
+ push((tmp & 0xFF00) >> 8)
+ push(tmp & 0xFF)
+ }
+
+ if (placeHolders === 2) {
+ tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
+ push(tmp & 0xFF)
+ } else if (placeHolders === 1) {
+ tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
+ push((tmp >> 8) & 0xFF)
+ push(tmp & 0xFF)
+ }
+
+ return arr
+ }
+
+ function uint8ToBase64(uint8) {
+ var i,
+ extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
+ output = "",
+ temp, length
+
+ function encode(num) {
+ return lookup.charAt(num)
+ }
+
+ function tripletToBase64(num) {
+ return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
+ }
+
+ // go through the array every three bytes, we'll deal with trailing stuff later
+ for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
+ temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+ output += tripletToBase64(temp)
+ }
+
+ // pad the end with zeros, but make sure to not forget the extra bytes
+ switch (extraBytes) {
+ case 1:
+ temp = uint8[uint8.length - 1]
+ output += encode(temp >> 2)
+ output += encode((temp << 4) & 0x3F)
+ output += '=='
+ break
+ case 2:
+ temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
+ output += encode(temp >> 10)
+ output += encode((temp >> 4) & 0x3F)
+ output += encode((temp << 2) & 0x3F)
+ output += '='
+ break
+ }
+
+ return output
+ }
+
+ exports.toByteArray = b64ToByteArray
+ exports.fromByteArray = uint8ToBase64
+ }(false ? (this.base64js = {}) : exports))
+
+
+ /***/
+},
+/* 7 */
+/***/ function (module, exports) {
+
+ exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+ var e, m
+ var eLen = nBytes * 8 - mLen - 1
+ var eMax = (1 << eLen) - 1
+ var eBias = eMax >> 1
+ var nBits = -7
+ var i = isLE ? (nBytes - 1) : 0
+ var d = isLE ? -1 : 1
+ var s = buffer[offset + i]
+
+ i += d
+
+ e = s & ((1 << (-nBits)) - 1)
+ s >>= (-nBits)
+ nBits += eLen
+ for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) { }
+
+ m = e & ((1 << (-nBits)) - 1)
+ e >>= (-nBits)
+ nBits += mLen
+ for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) { }
+
+ if (e === 0) {
+ e = 1 - eBias
+ } else if (e === eMax) {
+ return m ? NaN : ((s ? -1 : 1) * Infinity)
+ } else {
+ m = m + Math.pow(2, mLen)
+ e = e - eBias
+ }
+ return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+ }
+
+ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+ var e, m, c
+ var eLen = nBytes * 8 - mLen - 1
+ var eMax = (1 << eLen) - 1
+ var eBias = eMax >> 1
+ var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+ var i = isLE ? 0 : (nBytes - 1)
+ var d = isLE ? 1 : -1
+ var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+ value = Math.abs(value)
+
+ if (isNaN(value) || value === Infinity) {
+ m = isNaN(value) ? 1 : 0
+ e = eMax
+ } else {
+ e = Math.floor(Math.log(value) / Math.LN2)
+ if (value * (c = Math.pow(2, -e)) < 1) {
+ e--
+ c *= 2
+ }
+ if (e + eBias >= 1) {
+ value += rt / c
+ } else {
+ value += rt * Math.pow(2, 1 - eBias)
+ }
+ if (value * c >= 2) {
+ e++
+ c /= 2
+ }
+
+ if (e + eBias >= eMax) {
+ m = 0
+ e = eMax
+ } else if (e + eBias >= 1) {
+ m = (value * c - 1) * Math.pow(2, mLen)
+ e = e + eBias
+ } else {
+ m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+ e = 0
+ }
+ }
+
+ for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) { }
+
+ e = (e << mLen) | m
+ eLen += mLen
+ for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) { }
+
+ buffer[offset + i - d] |= s * 128
+ }
+
+
+ /***/
+},
+/* 8 */
+/***/ function (module, exports) {
+
+ var toString = {}.toString
+
+ module.exports = Array.isArray || function (arr) {
+ return toString.call(arr) == '[object Array]'
+ }
+
+
+ /***/
+},
+/* 9 */
+/***/ function (module, exports) {
+
+ // Copyright Joyent, Inc. and other Node contributors.
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a
+ // copy of this software and associated documentation files (the
+ // "Software"), to deal in the Software without restriction, including
+ // without limitation the rights to use, copy, modify, merge, publish,
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
+ // persons to whom the Software is furnished to do so, subject to the
+ // following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included
+ // in all copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ function EventEmitter() {
+ this._events = this._events || {}
+ this._maxListeners = this._maxListeners || undefined
+ }
+ module.exports = EventEmitter
+
+ // Backwards-compat with node 0.10.x
+ EventEmitter.EventEmitter = EventEmitter
+
+ EventEmitter.prototype._events = undefined
+ EventEmitter.prototype._maxListeners = undefined
+
+ // By default EventEmitters will print a warning if more than 10 listeners are
+ // added to it. This is a useful default which helps finding memory leaks.
+ EventEmitter.defaultMaxListeners = 10
+
+ // Obviously not all Emitters should be limited to 10. This function allows
+ // that to be increased. Set to zero for unlimited.
+ EventEmitter.prototype.setMaxListeners = function (n) {
+ if (!isNumber(n) || n < 0 || isNaN(n))
+ throw TypeError('n must be a positive number')
+ this._maxListeners = n
+ return this
+ }
+
+ EventEmitter.prototype.emit = function (type) {
+ var er, handler, len, args, i, listeners
+
+ if (!this._events)
+ this._events = {}
+
+ // If there is no 'error' event listener then throw.
+ if (type === 'error') {
+ if (!this._events.error ||
+ (isObject(this._events.error) && !this._events.error.length)) {
+ er = arguments[1]
+ if (er instanceof Error) {
+ throw er // Unhandled 'error' event
+ } else {
+ // At least give some kind of context to the user
+ var err = new Error('Uncaught, unspecified "error" event. (' + er + ')')
+ err.context = er
+ throw err
+ }
+ }
+ }
+
+ handler = this._events[type]
+
+ if (isUndefined(handler))
+ return false
+
+ if (isFunction(handler)) {
+ switch (arguments.length) {
+ // fast cases
+ case 1:
+ handler.call(this)
+ break
+ case 2:
+ handler.call(this, arguments[1])
+ break
+ case 3:
+ handler.call(this, arguments[1], arguments[2])
+ break
+ // slower
+ default:
+ args = Array.prototype.slice.call(arguments, 1)
+ handler.apply(this, args)
+ }
+ } else if (isObject(handler)) {
+ args = Array.prototype.slice.call(arguments, 1)
+ listeners = handler.slice()
+ len = listeners.length
+ for (i = 0; i < len; i++)
+ listeners[i].apply(this, args)
+ }
+
+ return true
+ }
+
+ EventEmitter.prototype.addListener = function (type, listener) {
+ var m
+
+ if (!isFunction(listener))
+ throw TypeError('listener must be a function')
+
+ if (!this._events)
+ this._events = {}
+
+ // To avoid recursion in the case that type === "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (this._events.newListener)
+ this.emit('newListener', type,
+ isFunction(listener.listener) ?
+ listener.listener : listener)
+
+ if (!this._events[type])
+ // Optimize the case of one listener. Don't need the extra array object.
+ this._events[type] = listener
+ else if (isObject(this._events[type]))
+ // If we've already got an array, just append.
+ this._events[type].push(listener)
+ else
+ // Adding the second element, need to change to array.
+ this._events[type] = [this._events[type], listener]
+
+ // Check for listener leak
+ if (isObject(this._events[type]) && !this._events[type].warned) {
+ if (!isUndefined(this._maxListeners)) {
+ m = this._maxListeners
+ } else {
+ m = EventEmitter.defaultMaxListeners
+ }
+
+ if (m && m > 0 && this._events[type].length > m) {
+ this._events[type].warned = true
+ console.error('(node) warning: possible EventEmitter memory ' +
+ 'leak detected. %d listeners added. ' +
+ 'Use emitter.setMaxListeners() to increase limit.',
+ this._events[type].length)
+ if (typeof console.trace === 'function') {
+ // not supported in IE 10
+ console.trace()
+ }
+ }
+ }
+
+ return this
+ }
+
+ EventEmitter.prototype.on = EventEmitter.prototype.addListener
+
+ EventEmitter.prototype.once = function (type, listener) {
+ if (!isFunction(listener))
+ throw TypeError('listener must be a function')
+
+ var fired = false
+
+ function g() {
+ this.removeListener(type, g)
+
+ if (!fired) {
+ fired = true
+ listener.apply(this, arguments)
+ }
+ }
+
+ g.listener = listener
+ this.on(type, g)
+
+ return this
+ }
+
+ // emits a 'removeListener' event iff the listener was removed
+ EventEmitter.prototype.removeListener = function (type, listener) {
+ var list, position, length, i
+
+ if (!isFunction(listener))
+ throw TypeError('listener must be a function')
+
+ if (!this._events || !this._events[type])
+ return this
+
+ list = this._events[type]
+ length = list.length
+ position = -1
+
+ if (list === listener ||
+ (isFunction(list.listener) && list.listener === listener)) {
+ delete this._events[type]
+ if (this._events.removeListener)
+ this.emit('removeListener', type, listener)
+
+ } else if (isObject(list)) {
+ for (i = length; i-- > 0;) {
+ if (list[i] === listener ||
+ (list[i].listener && list[i].listener === listener)) {
+ position = i
+ break
+ }
+ }
+
+ if (position < 0)
+ return this
+
+ if (list.length === 1) {
+ list.length = 0
+ delete this._events[type]
+ } else {
+ list.splice(position, 1)
+ }
+
+ if (this._events.removeListener)
+ this.emit('removeListener', type, listener)
+ }
+
+ return this
+ }
+
+ EventEmitter.prototype.removeAllListeners = function (type) {
+ var key, listeners
+
+ if (!this._events)
+ return this
+
+ // not listening for removeListener, no need to emit
+ if (!this._events.removeListener) {
+ if (arguments.length === 0)
+ this._events = {}
+ else if (this._events[type])
+ delete this._events[type]
+ return this
+ }
+
+ // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ for (key in this._events) {
+ if (key === 'removeListener') continue
+ this.removeAllListeners(key)
+ }
+ this.removeAllListeners('removeListener')
+ this._events = {}
+ return this
+ }
+
+ listeners = this._events[type]
+
+ if (isFunction(listeners)) {
+ this.removeListener(type, listeners)
+ } else if (listeners) {
+ // LIFO order
+ while (listeners.length)
+ this.removeListener(type, listeners[listeners.length - 1])
+ }
+ delete this._events[type]
+
+ return this
+ }
+
+ EventEmitter.prototype.listeners = function (type) {
+ var ret
+ if (!this._events || !this._events[type])
+ ret = []
+ else if (isFunction(this._events[type]))
+ ret = [this._events[type]]
+ else
+ ret = this._events[type].slice()
+ return ret
+ }
+
+ EventEmitter.prototype.listenerCount = function (type) {
+ if (this._events) {
+ var evlistener = this._events[type]
+
+ if (isFunction(evlistener))
+ return 1
+ else if (evlistener)
+ return evlistener.length
+ }
+ return 0
+ }
+
+ EventEmitter.listenerCount = function (emitter, type) {
+ return emitter.listenerCount(type)
+ }
+
+ function isFunction(arg) {
+ return typeof arg === 'function'
+ }
+
+ function isNumber(arg) {
+ return typeof arg === 'number'
+ }
+
+ function isObject(arg) {
+ return typeof arg === 'object' && arg !== null
+ }
+
+ function isUndefined(arg) {
+ return arg === void 0
+ }
+
+
+ /***/
+},
+/* 10 */
+/***/ function (module, exports, __webpack_require__) {
+
+ /* WEBPACK VAR INJECTION */(function (global, process) {// Copyright Joyent, Inc. and other Node contributors.
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a
+ // copy of this software and associated documentation files (the
+ // "Software"), to deal in the Software without restriction, including
+ // without limitation the rights to use, copy, modify, merge, publish,
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
+ // persons to whom the Software is furnished to do so, subject to the
+ // following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included
+ // in all copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ var formatRegExp = /%[sdj%]/g
+ exports.format = function (f) {
+ if (!isString(f)) {
+ var objects = []
+ for (var i = 0; i < arguments.length; i++) {
+ objects.push(inspect(arguments[i]))
+ }
+ return objects.join(' ')
+ }
+
+ var i = 1
+ var args = arguments
+ var len = args.length
+ var str = String(f).replace(formatRegExp, function (x) {
+ if (x === '%%') return '%'
+ if (i >= len) return x
+ switch (x) {
+ case '%s': return String(args[i++])
+ case '%d': return Number(args[i++])
+ case '%j':
+ try {
+ return JSON.stringify(args[i++])
+ } catch (_) {
+ return '[Circular]'
+ }
+ default:
+ return x
+ }
+ })
+ for (var x = args[i]; i < len; x = args[++i]) {
+ if (isNull(x) || !isObject(x)) {
+ str += ' ' + x
+ } else {
+ str += ' ' + inspect(x)
+ }
+ }
+ return str
+ }
+
+
+ // Mark that a method should not be used.
+ // Returns a modified function which warns once by default.
+ // If --no-deprecation is set, then it is a no-op.
+ exports.deprecate = function (fn, msg) {
+ // Allow for deprecating things in the process of starting up.
+ if (isUndefined(global.process)) {
+ return function () {
+ return exports.deprecate(fn, msg).apply(this, arguments)
+ }
+ }
+
+ if (process.noDeprecation === true) {
+ return fn
+ }
+
+ var warned = false
+ function deprecated() {
+ if (!warned) {
+ if (process.throwDeprecation) {
+ throw new Error(msg)
+ } else if (process.traceDeprecation) {
+ console.trace(msg)
+ } else {
+ console.error(msg)
+ }
+ warned = true
+ }
+ return fn.apply(this, arguments)
+ }
+
+ return deprecated
+ }
+
+
+ var debugs = {}
+ var debugEnviron
+ exports.debuglog = function (set) {
+ if (isUndefined(debugEnviron))
+ debugEnviron = process.env.NODE_DEBUG || ''
+ set = set.toUpperCase()
+ if (!debugs[set]) {
+ if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+ var pid = process.pid
+ debugs[set] = function () {
+ var msg = exports.format.apply(exports, arguments)
+ console.error('%s %d: %s', set, pid, msg)
+ }
+ } else {
+ debugs[set] = function () { }
+ }
+ }
+ return debugs[set]
+ }
+
+
+ /**
+ * Echos the value of a value. Trys to print the value out
+ * in the best way possible given the different types.
+ *
+ * @param {Object} obj The object to print out.
+ * @param {Object} opts Optional options object that alters the output.
+ */
+ /* legacy: obj, showHidden, depth, colors*/
+ function inspect(obj, opts) {
+ // default options
+ var ctx = {
+ seen: [],
+ stylize: stylizeNoColor
+ }
+ // legacy...
+ if (arguments.length >= 3) ctx.depth = arguments[2]
+ if (arguments.length >= 4) ctx.colors = arguments[3]
+ if (isBoolean(opts)) {
+ // legacy...
+ ctx.showHidden = opts
+ } else if (opts) {
+ // got an "options" object
+ exports._extend(ctx, opts)
+ }
+ // set default options
+ if (isUndefined(ctx.showHidden)) ctx.showHidden = false
+ if (isUndefined(ctx.depth)) ctx.depth = 2
+ if (isUndefined(ctx.colors)) ctx.colors = false
+ if (isUndefined(ctx.customInspect)) ctx.customInspect = true
+ if (ctx.colors) ctx.stylize = stylizeWithColor
+ return formatValue(ctx, obj, ctx.depth)
+ }
+ exports.inspect = inspect
+
+
+ // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+ inspect.colors = {
+ 'bold': [1, 22],
+ 'italic': [3, 23],
+ 'underline': [4, 24],
+ 'inverse': [7, 27],
+ 'white': [37, 39],
+ 'grey': [90, 39],
+ 'black': [30, 39],
+ 'blue': [34, 39],
+ 'cyan': [36, 39],
+ 'green': [32, 39],
+ 'magenta': [35, 39],
+ 'red': [31, 39],
+ 'yellow': [33, 39]
+ }
+
+ // Don't use 'blue' not visible on cmd.exe
+ inspect.styles = {
+ 'special': 'cyan',
+ 'number': 'yellow',
+ 'boolean': 'yellow',
+ 'undefined': 'grey',
+ 'null': 'bold',
+ 'string': 'green',
+ 'date': 'magenta',
+ // "name": intentionally not styling
+ 'regexp': 'red'
+ }
+
+
+ function stylizeWithColor(str, styleType) {
+ var style = inspect.styles[styleType]
+
+ if (style) {
+ return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+ '\u001b[' + inspect.colors[style][1] + 'm'
+ } else {
+ return str
+ }
+ }
+
+
+ function stylizeNoColor(str, styleType) {
+ return str
+ }
+
+
+ function arrayToHash(array) {
+ var hash = {}
+
+ array.forEach(function (val, idx) {
+ hash[val] = true
+ })
+
+ return hash
+ }
+
+
+ function formatValue(ctx, value, recurseTimes) {
+ // Provide a hook for user-specified inspect functions.
+ // Check that value is an object with an inspect function on it
+ if (ctx.customInspect &&
+ value &&
+ isFunction(value.inspect) &&
+ // Filter out the util module, it's inspect function is special
+ value.inspect !== exports.inspect &&
+ // Also filter out any prototype objects using the circular check.
+ !(value.constructor && value.constructor.prototype === value)) {
+ var ret = value.inspect(recurseTimes, ctx)
+ if (!isString(ret)) {
+ ret = formatValue(ctx, ret, recurseTimes)
+ }
+ return ret
+ }
+
+ // Primitive types cannot have properties
+ var primitive = formatPrimitive(ctx, value)
+ if (primitive) {
+ return primitive
+ }
+
+ // Look up the keys of the object.
+ var keys = Object.keys(value)
+ var visibleKeys = arrayToHash(keys)
+
+ if (ctx.showHidden) {
+ keys = Object.getOwnPropertyNames(value)
+ }
+
+ // IE doesn't make error fields non-enumerable
+ // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
+ if (isError(value)
+ && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
+ return formatError(value)
+ }
+
+ // Some type of object without properties can be shortcutted.
+ if (keys.length === 0) {
+ if (isFunction(value)) {
+ var name = value.name ? ': ' + value.name : ''
+ return ctx.stylize('[Function' + name + ']', 'special')
+ }
+ if (isRegExp(value)) {
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp')
+ }
+ if (isDate(value)) {
+ return ctx.stylize(Date.prototype.toString.call(value), 'date')
+ }
+ if (isError(value)) {
+ return formatError(value)
+ }
+ }
+
+ var base = '', array = false, braces = ['{', '}']
+
+ // Make Array say that they are Array
+ if (isArray(value)) {
+ array = true
+ braces = ['[', ']']
+ }
+
+ // Make functions say that they are functions
+ if (isFunction(value)) {
+ var n = value.name ? ': ' + value.name : ''
+ base = ' [Function' + n + ']'
+ }
+
+ // Make RegExps say that they are RegExps
+ if (isRegExp(value)) {
+ base = ' ' + RegExp.prototype.toString.call(value)
+ }
+
+ // Make dates with properties first say the date
+ if (isDate(value)) {
+ base = ' ' + Date.prototype.toUTCString.call(value)
+ }
+
+ // Make error with message first say the error
+ if (isError(value)) {
+ base = ' ' + formatError(value)
+ }
+
+ if (keys.length === 0 && (!array || value.length == 0)) {
+ return braces[0] + base + braces[1]
+ }
+
+ if (recurseTimes < 0) {
+ if (isRegExp(value)) {
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp')
+ } else {
+ return ctx.stylize('[Object]', 'special')
+ }
+ }
+
+ ctx.seen.push(value)
+
+ var output
+ if (array) {
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys)
+ } else {
+ output = keys.map(function (key) {
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array)
+ })
+ }
+
+ ctx.seen.pop()
+
+ return reduceToSingleString(output, base, braces)
+ }
+
+
+ function formatPrimitive(ctx, value) {
+ if (isUndefined(value))
+ return ctx.stylize('undefined', 'undefined')
+ if (isString(value)) {
+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+ .replace(/'/g, "\\'")
+ .replace(/\\"/g, '"') + '\''
+ return ctx.stylize(simple, 'string')
+ }
+ if (isNumber(value))
+ return ctx.stylize('' + value, 'number')
+ if (isBoolean(value))
+ return ctx.stylize('' + value, 'boolean')
+ // For some reason typeof null is "object", so special case here.
+ if (isNull(value))
+ return ctx.stylize('null', 'null')
+ }
+
+
+ function formatError(value) {
+ return '[' + Error.prototype.toString.call(value) + ']'
+ }
+
+
+ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+ var output = []
+ for (var i = 0, l = value.length; i < l; ++i) {
+ if (hasOwnProperty(value, String(i))) {
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+ String(i), true))
+ } else {
+ output.push('')
+ }
+ }
+ keys.forEach(function (key) {
+ if (!key.match(/^\d+$/)) {
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+ key, true))
+ }
+ })
+ return output
+ }
+
+
+ function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+ var name, str, desc
+ desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }
+ if (desc.get) {
+ if (desc.set) {
+ str = ctx.stylize('[Getter/Setter]', 'special')
+ } else {
+ str = ctx.stylize('[Getter]', 'special')
+ }
+ } else {
+ if (desc.set) {
+ str = ctx.stylize('[Setter]', 'special')
+ }
+ }
+ if (!hasOwnProperty(visibleKeys, key)) {
+ name = '[' + key + ']'
+ }
+ if (!str) {
+ if (ctx.seen.indexOf(desc.value) < 0) {
+ if (isNull(recurseTimes)) {
+ str = formatValue(ctx, desc.value, null)
+ } else {
+ str = formatValue(ctx, desc.value, recurseTimes - 1)
+ }
+ if (str.indexOf('\n') > -1) {
+ if (array) {
+ str = str.split('\n').map(function (line) {
+ return ' ' + line
+ }).join('\n').substr(2)
+ } else {
+ str = '\n' + str.split('\n').map(function (line) {
+ return ' ' + line
+ }).join('\n')
+ }
+ }
+ } else {
+ str = ctx.stylize('[Circular]', 'special')
+ }
+ }
+ if (isUndefined(name)) {
+ if (array && key.match(/^\d+$/)) {
+ return str
+ }
+ name = JSON.stringify('' + key)
+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+ name = name.substr(1, name.length - 2)
+ name = ctx.stylize(name, 'name')
+ } else {
+ name = name.replace(/'/g, "\\'")
+ .replace(/\\"/g, '"')
+ .replace(/(^"|"$)/g, "'")
+ name = ctx.stylize(name, 'string')
+ }
+ }
+
+ return name + ': ' + str
+ }
+
+
+ function reduceToSingleString(output, base, braces) {
+ var numLinesEst = 0
+ var length = output.reduce(function (prev, cur) {
+ numLinesEst++
+ if (cur.indexOf('\n') >= 0) numLinesEst++
+ return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1
+ }, 0)
+
+ if (length > 60) {
+ return braces[0] +
+ (base === '' ? '' : base + '\n ') +
+ ' ' +
+ output.join(',\n ') +
+ ' ' +
+ braces[1]
+ }
+
+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]
+ }
+
+
+ // NOTE: These type checking functions intentionally don't use `instanceof`
+ // because it is fragile and can be easily faked with `Object.create()`.
+ function isArray(ar) {
+ return Array.isArray(ar)
+ }
+ exports.isArray = isArray
+
+ function isBoolean(arg) {
+ return typeof arg === 'boolean'
+ }
+ exports.isBoolean = isBoolean
+
+ function isNull(arg) {
+ return arg === null
+ }
+ exports.isNull = isNull
+
+ function isNullOrUndefined(arg) {
+ return arg == null
+ }
+ exports.isNullOrUndefined = isNullOrUndefined
+
+ function isNumber(arg) {
+ return typeof arg === 'number'
+ }
+ exports.isNumber = isNumber
+
+ function isString(arg) {
+ return typeof arg === 'string'
+ }
+ exports.isString = isString
+
+ function isSymbol(arg) {
+ return typeof arg === 'symbol'
+ }
+ exports.isSymbol = isSymbol
+
+ function isUndefined(arg) {
+ return arg === void 0
+ }
+ exports.isUndefined = isUndefined
+
+ function isRegExp(re) {
+ return isObject(re) && objectToString(re) === '[object RegExp]'
+ }
+ exports.isRegExp = isRegExp
+
+ function isObject(arg) {
+ return typeof arg === 'object' && arg !== null
+ }
+ exports.isObject = isObject
+
+ function isDate(d) {
+ return isObject(d) && objectToString(d) === '[object Date]'
+ }
+ exports.isDate = isDate
+
+ function isError(e) {
+ return isObject(e) &&
+ (objectToString(e) === '[object Error]' || e instanceof Error)
+ }
+ exports.isError = isError
+
+ function isFunction(arg) {
+ return typeof arg === 'function'
+ }
+ exports.isFunction = isFunction
+
+ function isPrimitive(arg) {
+ return arg === null ||
+ typeof arg === 'boolean' ||
+ typeof arg === 'number' ||
+ typeof arg === 'string' ||
+ typeof arg === 'symbol' || // ES6 symbol
+ typeof arg === 'undefined'
+ }
+ exports.isPrimitive = isPrimitive
+
+ exports.isBuffer = __webpack_require__(12)
+
+ function objectToString(o) {
+ return Object.prototype.toString.call(o)
+ }
+
+
+ function pad(n) {
+ return n < 10 ? '0' + n.toString(10) : n.toString(10)
+ }
+
+
+ var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+ 'Oct', 'Nov', 'Dec']
+
+ // 26 Feb 16:19:34
+ function timestamp() {
+ var d = new Date()
+ var time = [pad(d.getHours()),
+ pad(d.getMinutes()),
+ pad(d.getSeconds())].join(':')
+ return [d.getDate(), months[d.getMonth()], time].join(' ')
+ }
+
+
+ // log is just a thin wrapper to console.log that prepends a timestamp
+ exports.log = function () {
+ console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments))
+ }
+
+
+ /**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be rewritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ *
+ * @param {function} ctor Constructor function which needs to inherit the
+ * prototype.
+ * @param {function} superCtor Constructor function to inherit prototype from.
+ */
+ exports.inherits = __webpack_require__(13)
+
+ exports._extend = function (origin, add) {
+ // Don't do anything if add isn't an object
+ if (!add || !isObject(add)) return origin
+
+ var keys = Object.keys(add)
+ var i = keys.length
+ while (i--) {
+ origin[keys[i]] = add[keys[i]]
+ }
+ return origin
+ }
+
+ function hasOwnProperty(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop)
+ }
+
+ /* WEBPACK VAR INJECTION */
+}.call(exports, (function () { return this }()), __webpack_require__(11)))
+
+ /***/
+},
+/* 11 */
+/***/ function (module, exports) {
+
+ // shim for using process in browser
+ var process = module.exports = {}
+
+ // cached from whatever global is present so that test runners that stub it
+ // don't break things. But we need to wrap it in a try catch in case it is
+ // wrapped in strict mode code which doesn't define any globals. It's inside a
+ // function because try/catches deoptimize in certain engines.
+
+ var cachedSetTimeout
+ var cachedClearTimeout;
+
+ (function () {
+ try {
+ cachedSetTimeout = setTimeout
+ } catch (e) {
+ cachedSetTimeout = function () {
+ throw new Error('setTimeout is not defined')
+ }
+ }
+ try {
+ cachedClearTimeout = clearTimeout
+ } catch (e) {
+ cachedClearTimeout = function () {
+ throw new Error('clearTimeout is not defined')
+ }
+ }
+ }())
+ function runTimeout(fun) {
+ if (cachedSetTimeout === setTimeout) {
+ //normal enviroments in sane situations
+ return setTimeout(fun, 0)
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedSetTimeout(fun, 0)
+ } catch (e) {
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedSetTimeout.call(null, fun, 0)
+ } catch (e) {
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+ return cachedSetTimeout.call(this, fun, 0)
+ }
+ }
+
+
+ }
+ function runClearTimeout(marker) {
+ if (cachedClearTimeout === clearTimeout) {
+ //normal enviroments in sane situations
+ return clearTimeout(marker)
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedClearTimeout(marker)
+ } catch (e) {
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedClearTimeout.call(null, marker)
+ } catch (e) {
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+ // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+ return cachedClearTimeout.call(this, marker)
+ }
+ }
+
+
+
+ }
+ var queue = []
+ var draining = false
+ var currentQueue
+ var queueIndex = -1
+
+ function cleanUpNextTick() {
+ if (!draining || !currentQueue) {
+ return
+ }
+ draining = false
+ if (currentQueue.length) {
+ queue = currentQueue.concat(queue)
+ } else {
+ queueIndex = -1
+ }
+ if (queue.length) {
+ drainQueue()
+ }
+ }
+
+ function drainQueue() {
+ if (draining) {
+ return
+ }
+ var timeout = runTimeout(cleanUpNextTick)
+ draining = true
+
+ var len = queue.length
+ while (len) {
+ currentQueue = queue
+ queue = []
+ while (++queueIndex < len) {
+ if (currentQueue) {
+ currentQueue[queueIndex].run()
+ }
+ }
+ queueIndex = -1
+ len = queue.length
+ }
+ currentQueue = null
+ draining = false
+ runClearTimeout(timeout)
+ }
+
+ process.nextTick = function (fun) {
+ var args = new Array(arguments.length - 1)
+ if (arguments.length > 1) {
+ for (var i = 1; i < arguments.length; i++) {
+ args[i - 1] = arguments[i]
+ }
+ }
+ queue.push(new Item(fun, args))
+ if (queue.length === 1 && !draining) {
+ runTimeout(drainQueue)
+ }
+ }
+
+ // v8 likes predictible objects
+ function Item(fun, array) {
+ this.fun = fun
+ this.array = array
+ }
+ Item.prototype.run = function () {
+ this.fun.apply(null, this.array)
+ }
+ process.title = 'browser'
+ process.browser = true
+ process.env = {}
+ process.argv = []
+ process.version = '' // empty string to avoid regexp issues
+ process.versions = {}
+
+ function noop() { }
+
+ process.on = noop
+ process.addListener = noop
+ process.once = noop
+ process.off = noop
+ process.removeListener = noop
+ process.removeAllListeners = noop
+ process.emit = noop
+
+ process.binding = function (name) {
+ throw new Error('process.binding is not supported')
+ }
+
+ process.cwd = function () { return '/' }
+ process.chdir = function (dir) {
+ throw new Error('process.chdir is not supported')
+ }
+ process.umask = function () { return 0 }
+
+
+ /***/
+},
+/* 12 */
+/***/ function (module, exports) {
+
+ module.exports = function isBuffer(arg) {
+ return arg && typeof arg === 'object'
+ && typeof arg.copy === 'function'
+ && typeof arg.fill === 'function'
+ && typeof arg.readUInt8 === 'function'
+ }
+
+ /***/
+},
+/* 13 */
+/***/ function (module, exports) {
+
+ if (typeof Object.create === 'function') {
+ // implementation from standard node.js 'util' module
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ ctor.prototype = Object.create(superCtor.prototype, {
+ constructor: {
+ value: ctor,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ })
+ }
+ } else {
+ // old school shim for old browsers
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ var TempCtor = function () { }
+ TempCtor.prototype = superCtor.prototype
+ ctor.prototype = new TempCtor()
+ ctor.prototype.constructor = ctor
+ }
+ }
+
+
+ /***/
+},
+/* 14 */
+/***/ function (module, exports, __webpack_require__) {
+
+ /* WEBPACK VAR INJECTION */(function (module, process) {/*
+ * prompt.js: Simple prompt for prompting information from the command line
+ *
+ * (C) 2010, Nodejitsu Inc.
+ *
+ */
+
+ var events = __webpack_require__(9),
+ readline = __webpack_require__(4),
+ utile = __webpack_require__(16),
+ async = utile.async,
+ read = __webpack_require__(53),
+ validate = __webpack_require__(72).validate,
+ winston = __webpack_require__(73),
+ colors = __webpack_require__(147)
+
+ //
+ // Monkey-punch readline.Interface to work-around
+ // https://github.com/joyent/node/issues/3860
+ //
+ readline.Interface.prototype.setPrompt = function (prompt, length) {
+ this._prompt = prompt
+ if (length) {
+ this._promptLength = length
+ } else {
+ var lines = prompt.split(/[\r\n]/)
+ var lastLine = lines[lines.length - 1]
+ this._promptLength = lastLine.replace(/\u001b\[(\d+(;\d+)*)?m/g, '').length
+ }
+ }
+
+ //
+ // Expose version using `pkginfo`
+ //
+ __webpack_require__(160)(module, 'version')
+
+ var stdin, stdout, history = []
+ var prompt = module.exports = Object.create(events.EventEmitter.prototype)
+ var logger = prompt.logger = new winston.Logger({
+ transports: [new (winston.transports.Console)()]
+ })
+
+ prompt.started = false
+ prompt.paused = false
+ prompt.stopped = true
+ prompt.allowEmpty = false
+ prompt.message = 'prompt'
+ prompt.delimiter = ': '
+ prompt.colors = true
+
+ //
+ // Create an empty object for the properties
+ // known to `prompt`
+ //
+ prompt.properties = {}
+
+ //
+ // Setup the default winston logger to use
+ // the `cli` levels and colors.
+ //
+ logger.cli()
+
+ //
+ // ### function start (options)
+ // #### @options {Object} **Optional** Options to consume by prompt
+ // Starts the prompt by listening to the appropriate events on `options.stdin`
+ // and `options.stdout`. If no streams are supplied, then `process.stdin`
+ // and `process.stdout` are used, respectively.
+ //
+ prompt.start = function (options) {
+ if (prompt.started) {
+ return
+ }
+
+ options = options || {}
+ stdin = options.stdin || process.stdin
+ stdout = options.stdout || process.stdout
+
+ //
+ // By default: Remember the last `10` prompt property /
+ // answer pairs and don't allow empty responses globally.
+ //
+ prompt.memory = options.memory || 10
+ prompt.allowEmpty = options.allowEmpty || false
+ prompt.message = options.message || prompt.message
+ prompt.delimiter = options.delimiter || prompt.delimiter
+ prompt.colors = options.colors || prompt.colors
+
+ if (process.platform !== 'win32') {
+ // windows falls apart trying to deal with SIGINT
+ process.on('SIGINT', function () {
+ stdout.write('\n')
+ process.exit(1)
+ })
+ }
+
+ prompt.emit('start')
+ prompt.started = true
+ prompt.stopped = false
+ return prompt
+ }
+
+ //
+ // ### function pause ()
+ // Pauses input coming in from stdin
+ //
+ prompt.pause = function () {
+ if (!prompt.started || prompt.stopped || prompt.paused) {
+ return
+ }
+
+ stdin.pause()
+ prompt.emit('pause')
+ prompt.paused = true
+ return prompt
+ }
+
+ //
+ // ### function stop ()
+ // Stops input coming in from stdin
+ //
+ prompt.stop = function () {
+ if (prompt.stopped || !prompt.started) {
+ return
+ }
+
+ stdin.destroy()
+ prompt.emit('stop')
+ prompt.stopped = true
+ prompt.started = false
+ prompt.paused = false
+ return prompt
+ }
+
+ //
+ // ### function resume ()
+ // Resumes input coming in from stdin
+ //
+ prompt.resume = function () {
+ if (!prompt.started || !prompt.paused) {
+ return
+ }
+
+ stdin.resume()
+ prompt.emit('resume')
+ prompt.paused = false
+ return prompt
+ }
+
+ //
+ // ### function history (search)
+ // #### @search {Number|string} Index or property name to find.
+ // Returns the `property:value` pair from within the prompts
+ // `history` array.
+ //
+ prompt.history = function (search) {
+ if (typeof search === 'number') {
+ return history[search] || {}
+ }
+
+ var names = history.map(function (pair) {
+ return typeof pair.property === 'string'
+ ? pair.property
+ : pair.property.name
+ })
+
+ if (!~names.indexOf(search)) {
+ return null
+ }
+
+ return history.filter(function (pair) {
+ return typeof pair.property === 'string'
+ ? pair.property === search
+ : pair.property.name === search
+ })[0]
+ }
+
+ //
+ // ### function get (schema, callback)
+ // #### @schema {Array|Object|string} Set of variables to get input for.
+ // #### @callback {function} Continuation to pass control to when complete.
+ // Gets input from the user via stdin for the specified message(s) `msg`.
+ //
+ prompt.get = function (schema, callback) {
+ //
+ // Transforms a full JSON-schema into an array describing path and sub-schemas.
+ // Used for iteration purposes.
+ //
+ function untangle(schema, path) {
+ var results = []
+ path = path || []
+
+ if (schema.properties) {
+ //
+ // Iterate over the properties in the schema and use recursion
+ // to process sub-properties.
+ //
+ Object.keys(schema.properties).forEach(function (key) {
+ var obj = {}
+ obj[key] = schema.properties[key]
+
+ //
+ // Concat a sub-untangling to the results.
+ //
+ results = results.concat(untangle(obj[key], path.concat(key)))
+ })
+
+ // Return the results.
+ return results
+ }
+
+ //
+ // This is a schema "leaf".
+ //
+ return {
+ path: path,
+ schema: schema
+ }
+ }
+
+ //
+ // Iterate over the values in the schema, represented as
+ // a legit single-property object subschemas. Accepts `schema`
+ // of the forms:
+ //
+ // 'prop-name'
+ //
+ // ['string-name', { path: ['or-well-formed-subschema'], properties: ... }]
+ //
+ // { path: ['or-well-formed-subschema'], properties: ... ] }
+ //
+ // { properties: { 'schema-with-no-path' } }
+ //
+ // And transforms them all into
+ //
+ // { path: ['path', 'to', 'property'], properties: { path: { to: ...} } }
+ //
+ function iterate(schema, get, done) {
+ var iterator = [],
+ result = {}
+
+ if (typeof schema === 'string') {
+ //
+ // We can iterate over a single string.
+ //
+ iterator.push({
+ path: [schema],
+ schema: prompt.properties[schema.toLowerCase()] || {}
+ })
+ }
+ else if (Array.isArray(schema)) {
+ //
+ // An array of strings and/or single-prop schema and/or no-prop schema.
+ //
+ iterator = schema.map(function (element) {
+ if (typeof element === 'string') {
+ return {
+ path: [element],
+ schema: prompt.properties[element.toLowerCase()] || {}
+ }
+ }
+ else if (element.properties) {
+ return {
+ path: [Object.keys(element.properties)[0]],
+ schema: element.properties[Object.keys(element.properties)[0]]
+ }
+ }
+ else if (element.path && element.schema) {
+ return element
+ }
+ else {
+ return {
+ path: [element.name || 'question'],
+ schema: element
+ }
+ }
+ })
+ }
+ else if (schema.properties) {
+ //
+ // Or a complete schema `untangle` it for use.
+ //
+ iterator = untangle(schema)
+ }
+ else {
+ //
+ // Or a partial schema and path.
+ // TODO: Evaluate need for this option.
+ //
+ iterator = [{
+ schema: schema.schema ? schema.schema : schema,
+ path: schema.path || [schema.name || 'question']
+ }]
+ }
+
+ //
+ // Now, iterate and assemble the result.
+ //
+ async.forEachSeries(iterator, function (branch, next) {
+ get(branch, function assembler(err, line) {
+ if (err) {
+ return next(err)
+ }
+
+ function build(path, line) {
+ var obj = {}
+ if (path.length) {
+ obj[path[0]] = build(path.slice(1), line)
+ return obj
+ }
+
+ return line
+ }
+
+ function attach(obj, attr) {
+ var keys
+ if (typeof attr !== 'object' || attr instanceof Array) {
+ return attr
+ }
+
+ keys = Object.keys(attr)
+ if (keys.length) {
+ if (!obj[keys[0]]) {
+ obj[keys[0]] = {}
+ }
+ obj[keys[0]] = attach(obj[keys[0]], attr[keys[0]])
+ }
+
+ return obj
+ }
+
+ result = attach(result, build(branch.path, line))
+ next()
+ })
+ }, function (err) {
+ return err ? done(err) : done(null, result)
+ })
+ }
+
+ iterate(schema, function get(target, next) {
+ prompt.getInput(target, function (err, line) {
+ return err ? next(err) : next(null, line)
+ })
+ }, callback)
+
+ return prompt
+ }
+
+ //
+ // ### function confirm (msg, callback)
+ // #### @msg {Array|Object|string} set of message to confirm
+ // #### @callback {function} Continuation to pass control to when complete.
+ // Confirms a single or series of messages by prompting the user for a Y/N response.
+ // Returns `true` if ALL messages are answered in the affirmative, otherwise `false`
+ //
+ // `msg` can be a string, or object (or array of strings/objects).
+ // An object may have the following properties:
+ //
+ // {
+ // description: 'yes/no' // message to prompt user
+ // pattern: /^[yntf]{1}/i // optional - regex defining acceptable responses
+ // yes: /^[yt]{1}/i // optional - regex defining `affirmative` responses
+ // message: 'yes/no' // optional - message to display for invalid responses
+ // }
+ //
+ prompt.confirm = function (/* msg, options, callback */) {
+ var args = Array.prototype.slice.call(arguments),
+ msg = args.shift(),
+ callback = args.pop(),
+ opts = args.shift(),
+ vars = !Array.isArray(msg) ? [msg] : msg,
+ RX_Y = /^[yt]{1}/i,
+ RX_YN = /^[yntf]{1}/i
+
+ function confirm(target, next) {
+ var yes = target.yes || RX_Y,
+ options = utile.mixin({
+ description: typeof target === 'string' ? target : target.description || 'yes/no',
+ pattern: target.pattern || RX_YN,
+ name: 'confirm',
+ message: target.message || 'yes/no'
+ }, opts || {})
+
+
+ prompt.get([options], function (err, result) {
+ next(err ? false : yes.test(result[options.name]))
+ })
+ }
+
+ async.rejectSeries(vars, confirm, function (result) {
+ callback(null, result.length === 0)
+ })
+ }
+
+
+ // Variables needed outside of getInput for multiline arrays.
+ var tmp = []
+
+
+ // ### function getInput (prop, callback)
+ // #### @prop {Object|string} Variable to get input for.
+ // #### @callback {function} Continuation to pass control to when complete.
+ // Gets input from the user via stdin for the specified message `msg`.
+ //
+ prompt.getInput = function (prop, callback) {
+ var schema = prop.schema || prop,
+ propName = prop.path && prop.path.join(':') || prop,
+ storedSchema = prompt.properties[propName.toLowerCase()],
+ delim = prompt.delimiter,
+ defaultLine,
+ against,
+ hidden,
+ length,
+ valid,
+ name,
+ raw,
+ msg
+
+ //
+ // If there is a stored schema for `propName` in `propmpt.properties`
+ // then use it.
+ //
+ if (schema instanceof Object && !Object.keys(schema).length &&
+ typeof storedSchema !== 'undefined') {
+ schema = storedSchema
+ }
+
+ //
+ // Build a proper validation schema if we just have a string
+ // and no `storedSchema`.
+ //
+ if (typeof prop === 'string' && !storedSchema) {
+ schema = {}
+ }
+
+ schema = convert(schema)
+ defaultLine = schema.default
+ name = prop.description || schema.description || propName
+ raw = prompt.colors
+ ? [colors.grey(name), colors.grey(delim)]
+ : [name, delim]
+
+ if (prompt.message)
+ raw.unshift(prompt.message, delim)
+
+ prop = {
+ schema: schema,
+ path: propName.split(':')
+ }
+
+ //
+ // If the schema has no `properties` value then set
+ // it to an object containing the current schema
+ // for `propName`.
+ //
+ if (!schema.properties) {
+ schema = (function () {
+ var obj = { properties: {} }
+ obj.properties[propName] = schema
+ return obj
+ })()
+ }
+
+ //
+ // Handle overrides here.
+ // TODO: Make overrides nestable
+ //
+ if (prompt.override && prompt.override[propName]) {
+ if (prompt._performValidation(name, prop, prompt.override, schema, -1, callback)) {
+ return callback(null, prompt.override[propName])
+ }
+
+ delete prompt.override[propName]
+ }
+
+ //
+ // Check if we should skip this prompt
+ //
+ if (typeof prop.schema.ask === 'function' &&
+ !prop.schema.ask()) {
+ return callback(null, prop.schema.default || '')
+ }
+
+ var type = (schema.properties && schema.properties[propName] &&
+ schema.properties[propName].type || '').toLowerCase().trim(),
+ wait = type === 'array'
+
+ if (type === 'array') {
+ length = prop.schema.maxItems
+ if (length) {
+ msg = (tmp.length + 1).toString() + '/' + length.toString()
+ }
+ else {
+ msg = (tmp.length + 1).toString()
+ }
+ msg += delim
+ raw.push(prompt.colors ? msg.grey : msg)
+ }
+
+ //
+ // Calculate the raw length and colorize the prompt
+ //
+ length = raw.join('').length
+ raw[0] = raw[0]
+ msg = raw.join('')
+
+ if (schema.help) {
+ schema.help.forEach(function (line) {
+ logger.help(line)
+ })
+ }
+
+ //
+ // Emit a "prompting" event
+ //
+ prompt.emit('prompt', prop)
+
+ //
+ // If there is no default line, set it to an empty string
+ //
+ if (typeof defaultLine === 'undefined') {
+ defaultLine = ''
+ }
+
+ //
+ // set to string for readline ( will not accept Numbers )
+ //
+ defaultLine = defaultLine.toString()
+
+ //
+ // Make the actual read
+ //
+ read({
+ prompt: msg,
+ silent: prop.schema && prop.schema.hidden,
+ replace: prop.schema && prop.schema.replace,
+ default: defaultLine,
+ input: stdin,
+ output: stdout
+ }, function (err, line) {
+ if (err && wait === false) {
+ return callback(err)
+ }
+
+ var against = {},
+ numericInput,
+ isValid
+
+ if (line !== '') {
+
+ if (schema.properties[propName]) {
+ var type = (schema.properties[propName].type || '').toLowerCase().trim() || undefined
+
+ //
+ // If type is some sort of numeric create a Number object to pass to revalidator
+ //
+ if (type === 'number' || type === 'integer') {
+ line = Number(line)
+ }
+
+ //
+ // Attempt to parse input as a boolean if the schema expects a boolean
+ //
+ if (type == 'boolean') {
+ if (line.toLowerCase() === "true" || line.toLowerCase() === 't') {
+ line = true
+ } else if (line.toLowerCase() === "false" || line.toLowerCase() === 'f') {
+ line = false
+ }
+ }
+
+ //
+ // If the type is an array, wait for the end. Fixes #54
+ //
+ if (type == 'array') {
+ var length = prop.schema.maxItems
+ if (err) {
+ if (err.message == 'canceled') {
+ wait = false
+ stdout.write('\n')
+ }
+ }
+ else {
+ if (length) {
+ if (tmp.length + 1 < length) {
+ isValid = false
+ wait = true
+ }
+ else {
+ isValid = true
+ wait = false
+ }
+ }
+ else {
+ isValid = false
+ wait = true
+ }
+ tmp.push(line)
+ }
+ line = tmp
+ }
+ }
+
+ against[propName] = line
+ }
+
+ if (prop && prop.schema.before) {
+ line = prop.schema.before(line)
+ }
+
+ // Validate
+ if (isValid === undefined) isValid = prompt._performValidation(name, prop, against, schema, line, callback)
+
+ if (!isValid) {
+ return prompt.getInput(prop, callback)
+ }
+
+ //
+ // Log the resulting line, append this `property:value`
+ // pair to the history for `prompt` and respond to
+ // the callback.
+ //
+ logger.input(line.yellow)
+ prompt._remember(propName, line)
+ callback(null, line)
+
+ // Make sure `tmp` is emptied
+ tmp = []
+ })
+ }
+
+ //
+ // ### function performValidation (name, prop, against, schema, line, callback)
+ // #### @name {Object} Variable name
+ // #### @prop {Object|string} Variable to get input for.
+ // #### @against {Object} Input
+ // #### @schema {Object} Validation schema
+ // #### @line {String|Boolean} Input line
+ // #### @callback {function} Continuation to pass control to when complete.
+ // Perfoms user input validation, print errors if needed and returns value according to validation
+ //
+ prompt._performValidation = function (name, prop, against, schema, line, callback) {
+ var numericInput, valid, msg
+ try {
+ valid = validate(against, schema)
+ }
+ catch (err) {
+ return (line !== -1) ? callback(err) : false
+ }
+
+ if (!valid.valid) {
+ if (prop.schema.message) {
+ logger.error(prop.schema.message)
+ } else {
+ msg = line !== -1 ? 'Invalid input for ' : 'Invalid command-line input for '
+
+ if (prompt.colors) {
+ logger.error(msg + name.grey)
+ }
+ else {
+ logger.error(msg + name)
+ }
+ }
+
+ prompt.emit('invalid', prop, line)
+ }
+
+ return valid.valid
+ }
+
+ //
+ // ### function addProperties (obj, properties, callback)
+ // #### @obj {Object} Object to add properties to
+ // #### @properties {Array} List of properties to get values for
+ // #### @callback {function} Continuation to pass control to when complete.
+ // Prompts the user for values each of the `properties` if `obj` does not already
+ // have a value for the property. Responds with the modified object.
+ //
+ prompt.addProperties = function (obj, properties, callback) {
+ properties = properties.filter(function (prop) {
+ return typeof obj[prop] === 'undefined'
+ })
+
+ if (properties.length === 0) {
+ return callback(obj)
+ }
+
+ prompt.get(properties, function (err, results) {
+ if (err) {
+ return callback(err)
+ }
+ else if (!results) {
+ return callback(null, obj)
+ }
+
+ function putNested(obj, path, value) {
+ var last = obj, key
+
+ while (path.length > 1) {
+ key = path.shift()
+ if (!last[key]) {
+ last[key] = {}
+ }
+
+ last = last[key]
+ }
+
+ last[path.shift()] = value
+ }
+
+ Object.keys(results).forEach(function (key) {
+ putNested(obj, key.split('.'), results[key])
+ })
+
+ callback(null, obj)
+ })
+
+ return prompt
+ }
+
+ //
+ // ### @private function _remember (property, value)
+ // #### @property {Object|string} Property that the value is in response to.
+ // #### @value {string} User input captured by `prompt`.
+ // Prepends the `property:value` pair into the private `history` Array
+ // for `prompt` so that it can be accessed later.
+ //
+ prompt._remember = function (property, value) {
+ history.unshift({
+ property: property,
+ value: value
+ })
+
+ //
+ // If the length of the `history` Array
+ // has exceeded the specified length to remember,
+ // `prompt.memory`, truncate it.
+ //
+ if (history.length > prompt.memory) {
+ history.splice(prompt.memory, history.length - prompt.memory)
+ }
+ }
+
+ //
+ // ### @private function convert (schema)
+ // #### @schema {Object} Schema for a property
+ // Converts the schema into new format if it is in old format
+ //
+ function convert(schema) {
+ var newProps = Object.keys(validate.messages),
+ newSchema = false,
+ key
+
+ newProps = newProps.concat(['description', 'dependencies'])
+
+ for (key in schema) {
+ if (newProps.indexOf(key) > 0) {
+ newSchema = true
+ break
+ }
+ }
+
+ if (!newSchema || schema.validator || schema.warning || typeof schema.empty !== 'undefined') {
+ schema.description = schema.message
+ schema.message = schema.warning
+
+ if (typeof schema.validator === 'function') {
+ schema.conform = schema.validator
+ } else {
+ schema.pattern = schema.validator
+ }
+
+ if (typeof schema.empty !== 'undefined') {
+ schema.required = !(schema.empty)
+ }
+
+ delete schema.warning
+ delete schema.validator
+ delete schema.empty
+ }
+
+ return schema
+ }
+
+ /* WEBPACK VAR INJECTION */
+}.call(exports, __webpack_require__(15)(module), __webpack_require__(11)))
+
+ /***/
+},
+/* 15 */
+/***/ function (module, exports) {
+
+ module.exports = function (module) {
+ if (!module.webpackPolyfill) {
+ module.deprecate = function () { }
+ module.paths = []
+ // module.parent = undefined by default
+ module.children = []
+ module.webpackPolyfill = 1
+ }
+ return module
+ }
+
+
+ /***/
+},
+/* 16 */
+/***/ function (module, exports, __webpack_require__) {
+
+ /*
+ * index.js: Top-level include for the `utile` module.
+ *
+ * (C) 2011, Charlie Robbins & the Contributors
+ * MIT LICENSE
+ *
+ */
+
+ var fs = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"fs\""); e.code = 'MODULE_NOT_FOUND'; throw e }())),
+ path = __webpack_require__(17),
+ util = __webpack_require__(10)
+
+ var utile = module.exports
+
+ //
+ // Extend the `utile` object with all methods from the
+ // core node `util` methods.
+ //
+ Object.keys(util).forEach(function (key) {
+ utile[key] = util[key]
+ })
+
+ Object.defineProperties(utile, {
+
+ //
+ // ### function async
+ // Simple wrapper to `require('async')`.
+ //
+ 'async': {
+ get: function () {
+ return utile.async = __webpack_require__(18)
+ }
+ },
+
+ //
+ // ### function inflect
+ // Simple wrapper to `require('i')`.
+ //
+ 'inflect': {
+ get: function () {
+ return utile.inflect = __webpack_require__(20)()
+ }
+ },
+
+ //
+ // ### function mkdirp
+ // Simple wrapper to `require('mkdirp')`
+ //
+ 'mkdirp': {
+ get: function () {
+ return utile.mkdirp = __webpack_require__(26)
+ }
+ },
+
+ //
+ // ### function deepEqual
+ // Simple wrapper to `require('deep-equal')`
+ // Remark: deepEqual is 4x faster then using assert.deepEqual
+ // see: https://gist.github.com/2790507
+ //
+ 'deepEqual': {
+ get: function () {
+ return utile.deepEqual = __webpack_require__(27)
+ }
+ },
+
+ //
+ // ### function rimraf
+ // Simple wrapper to `require('rimraf')`
+ //
+ 'rimraf': {
+ get: function () {
+ return utile.rimraf = __webpack_require__(30)
+ }
+ },
+
+ //
+ // ### function cpr
+ // Simple wrapper to `require('ncp').ncp`
+ //
+ 'cpr': {
+ get: function () {
+ return utile.cpr = __webpack_require__(47).ncp
+ }
+ },
+
+ //
+ // ### @file {Object}
+ // Lazy-loaded `file` module
+ //
+ 'file': {
+ get: function () {
+ return utile.file = __webpack_require__(48)
+ }
+ },
+
+ //
+ // ### @args {Object}
+ // Lazy-loaded `args` module
+ //
+ 'args': {
+ get: function () {
+ return utile.args = __webpack_require__(49)
+ }
+ },
+
+ //
+ // ### @base64 {Object}
+ // Lazy-loaded `base64` object
+ //
+ 'base64': {
+ get: function () {
+ return utile.base64 = __webpack_require__(50)
+ }
+ },
+
+ //
+ // ### @format {Object}
+ // Lazy-loaded `format` object
+ //
+ 'format': {
+ get: function () {
+ return utile.format = __webpack_require__(51)
+ }
+ }
+
+ })
+
+
+ //
+ // ### function rargs(_args)
+ // #### _args {Arguments} Original function arguments
+ //
+ // Top-level method will accept a javascript "arguments" object
+ // (the actual keyword "arguments" inside any scope) and return
+ // back an Array.
+ //
+ utile.rargs = function (_args, slice) {
+ if (!slice) {
+ slice = 0
+ }
+
+ var len = (_args || []).length,
+ args = new Array(len - slice),
+ i
+
+ //
+ // Convert the raw `_args` to a proper Array.
+ //
+ for (i = slice; i < len; i++) {
+ args[i - slice] = _args[i]
+ }
+
+ return args
+ }
+
+ //
+ // ### function each (obj, iterator)
+ // #### @obj {Object} Object to iterate over
+ // #### @iterator {function} Continuation to use on each key. `function (value, key, object)`
+ // Iterate over the keys of an object.
+ //
+ utile.each = function (obj, iterator) {
+ Object.keys(obj).forEach(function (key) {
+ iterator(obj[key], key, obj)
+ })
+ }
+
+ //
+ // ### function find (o)
+ //
+ //
+ utile.find = function (obj, pred) {
+ var value, key
+
+ for (key in obj) {
+ value = obj[key]
+ if (pred(value, key)) {
+ return value
+ }
+ }
+ }
+
+ //
+ // ### function pad (str, len, chr)
+ // ### @str {String} String to pad
+ // ### @len {Number} Number of chars to pad str with
+ // ### @chr {String} Optional replacement character, defaults to empty space
+ // Appends chr to str until it reaches a length of len
+ //
+ utile.pad = function pad(str, len, chr) {
+ var s
+ if (!chr) {
+ chr = ' '
+ }
+ str = str || ''
+ s = str
+ if (str.length < len) {
+ for (var i = 0; i < (len - str.length); i++) {
+ s += chr
+ }
+ }
+ return s
+ }
+
+ //
+ // ### function path (obj, path, value)
+ // ### @obj {Object} Object to insert value into
+ // ### @path {Array} List of nested keys to insert value at
+ // Retreives a value from given Object, `obj`, located at the
+ // nested keys, `path`.
+ //
+ utile.path = function (obj, path) {
+ var key, i
+
+ for (i in path) {
+ if (typeof obj === 'undefined') {
+ return undefined
+ }
+
+ key = path[i]
+ obj = obj[key]
+ }
+
+ return obj
+ }
+
+ //
+ // ### function createPath (obj, path, value)
+ // ### @obj {Object} Object to insert value into
+ // ### @path {Array} List of nested keys to insert value at
+ // ### @value {*} Value to insert into the object.
+ // Inserts the `value` into the given Object, `obj`, creating
+ // any keys in `path` along the way if necessary.
+ //
+ utile.createPath = function (obj, path, value) {
+ var key, i
+
+ for (i in path) {
+ key = path[i]
+ if (!obj[key]) {
+ obj[key] = ((+i + 1 === path.length) ? value : {})
+ }
+
+ obj = obj[key]
+ }
+ }
+
+ //
+ // ### function mixin (target [source0, source1, ...])
+ // Copies enumerable properties from `source0 ... sourceN`
+ // onto `target` and returns the resulting object.
+ //
+ utile.mixin = function (target) {
+ utile.rargs(arguments, 1).forEach(function (o) {
+ Object.getOwnPropertyNames(o).forEach(function (attr) {
+ var getter = Object.getOwnPropertyDescriptor(o, attr).get,
+ setter = Object.getOwnPropertyDescriptor(o, attr).set
+
+ if (!getter && !setter) {
+ target[attr] = o[attr]
+ }
+ else {
+ Object.defineProperty(target, attr, {
+ get: getter,
+ set: setter
+ })
+ }
+ })
+ })
+
+ return target
+ }
+
+
+ //
+ // ### function capitalize (str)
+ // #### @str {string} String to capitalize
+ // Capitalizes the specified `str`.
+ //
+ utile.capitalize = utile.inflect.camelize
+
+ //
+ // ### function escapeRegExp (str)
+ // #### @str {string} String to be escaped
+ // Escape string for use in Javascript regex
+ //
+ utile.escapeRegExp = function (str) {
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
+ }
+
+ //
+ // ### function randomString (length)
+ // #### @length {integer} The number of bits for the random base64 string returned to contain
+ // randomString returns a pseude-random ASCII string (subset)
+ // the return value is a string of length ⌈bits/6⌉ of characters
+ // from the base64 alphabet.
+ //
+ utile.randomString = function (length) {
+ var chars, rand, i, ret, mod, bits
+
+ chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-'
+ ret = ''
+ // standard 4
+ mod = 4
+ // default is 16
+ bits = length * mod || 64
+
+ // in v8, Math.random() yields 32 pseudo-random bits (in spidermonkey it gives 53)
+ while (bits > 0) {
+ // 32-bit integer
+ rand = Math.floor(Math.random() * 0x100000000)
+ //we use the top bits
+ for (i = 26; i > 0 && bits > 0; i -= mod, bits -= mod) {
+ ret += chars[0x3F & rand >>> i]
+ }
+ }
+
+ return ret
+ }
+
+ //
+ // ### function filter (object, test)
+ // #### @obj {Object} Object to iterate over
+ // #### @pred {function} Predicate applied to each property. `function (value, key, object)`
+ // Returns an object with properties from `obj` which satisfy
+ // the predicate `pred`
+ //
+ utile.filter = function (obj, pred) {
+ var copy
+ if (Array.isArray(obj)) {
+ copy = []
+ utile.each(obj, function (val, key) {
+ if (pred(val, key, obj)) {
+ copy.push(val)
+ }
+ })
+ }
+ else {
+ copy = {}
+ utile.each(obj, function (val, key) {
+ if (pred(val, key, obj)) {
+ copy[key] = val
+ }
+ })
+ }
+ return copy
+ }
+
+ //
+ // ### function requireDir (directory)
+ // #### @directory {string} Directory to require
+ // Requires all files and directories from `directory`, returning an object
+ // with keys being filenames (without trailing `.js`) and respective values
+ // being return values of `require(filename)`.
+ //
+ utile.requireDir = function (directory) {
+ var result = {},
+ files = fs.readdirSync(directory)
+
+ files.forEach(function (file) {
+ if (file.substr(-3) === '.js') {
+ file = file.substr(0, file.length - 3)
+ }
+ result[file] = __webpack_require__(52)(path.resolve(directory, file))
+ })
+ return result
+ }
+
+ //
+ // ### function requireDirLazy (directory)
+ // #### @directory {string} Directory to require
+ // Lazily requires all files and directories from `directory`, returning an
+ // object with keys being filenames (without trailing `.js`) and respective
+ // values (getters) being return values of `require(filename)`.
+ //
+ utile.requireDirLazy = function (directory) {
+ var result = {},
+ files = fs.readdirSync(directory)
+
+ files.forEach(function (file) {
+ if (file.substr(-3) === '.js') {
+ file = file.substr(0, file.length - 3)
+ }
+ Object.defineProperty(result, file, {
+ get: function () {
+ return result[file] = __webpack_require__(52)(path.resolve(directory, file))
+ }
+ })
+ })
+
+ return result
+ }
+
+ //
+ // ### function clone (object, filter)
+ // #### @object {Object} Object to clone
+ // #### @filter {Function} Filter to be used
+ // Shallow clones the specified object.
+ //
+ utile.clone = function (object, filter) {
+ return Object.keys(object).reduce(filter ? function (obj, k) {
+ if (filter(k)) obj[k] = object[k]
+ return obj
+ } : function (obj, k) {
+ obj[k] = object[k]
+ return obj
+ }, {})
+ }
+
+ //
+ // ### function camelToUnderscore (obj)
+ // #### @obj {Object} Object to convert keys on.
+ // Converts all keys of the type `keyName` to `key_name` on the
+ // specified `obj`.
+ //
+ utile.camelToUnderscore = function (obj) {
+ if (typeof obj !== 'object' || obj === null) {
+ return obj
+ }
+
+ if (Array.isArray(obj)) {
+ obj.forEach(utile.camelToUnderscore)
+ return obj
+ }
+
+ Object.keys(obj).forEach(function (key) {
+ var k = utile.inflect.underscore(key)
+ if (k !== key) {
+ obj[k] = obj[key]
+ delete obj[key]
+ key = k
+ }
+ utile.camelToUnderscore(obj[key])
+ })
+
+ return obj
+ }
+
+ //
+ // ### function underscoreToCamel (obj)
+ // #### @obj {Object} Object to convert keys on.
+ // Converts all keys of the type `key_name` to `keyName` on the
+ // specified `obj`.
+ //
+ utile.underscoreToCamel = function (obj) {
+ if (typeof obj !== 'object' || obj === null) {
+ return obj
+ }
+
+ if (Array.isArray(obj)) {
+ obj.forEach(utile.underscoreToCamel)
+ return obj
+ }
+
+ Object.keys(obj).forEach(function (key) {
+ var k = utile.inflect.camelize(key, false)
+ if (k !== key) {
+ obj[k] = obj[key]
+ delete obj[key]
+ key = k
+ }
+ utile.underscoreToCamel(obj[key])
+ })
+
+ return obj
+ }
+
+
+ /***/
+},
+/* 17 */
+/***/ function (module, exports, __webpack_require__) {
+
+ /* WEBPACK VAR INJECTION */(function (process) {// Copyright Joyent, Inc. and other Node contributors.
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a
+ // copy of this software and associated documentation files (the
+ // "Software"), to deal in the Software without restriction, including
+ // without limitation the rights to use, copy, modify, merge, publish,
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
+ // persons to whom the Software is furnished to do so, subject to the
+ // following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included
+ // in all copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ // resolves . and .. elements in a path array with directory names there
+ // must be no slashes, empty elements, or device names (c:\) in the array
+ // (so also no leading and trailing slashes - it does not distinguish
+ // relative and absolute paths)
+ function normalizeArray(parts, allowAboveRoot) {
+ // if the path tries to go above the root, `up` ends up > 0
+ var up = 0
+ for (var i = parts.length - 1; i >= 0; i--) {
+ var last = parts[i]
+ if (last === '.') {
+ parts.splice(i, 1)
+ } else if (last === '..') {
+ parts.splice(i, 1)
+ up++
+ } else if (up) {
+ parts.splice(i, 1)
+ up--
+ }
+ }
+
+ // if the path is allowed to go above the root, restore leading ..s
+ if (allowAboveRoot) {
+ for (; up--; up) {
+ parts.unshift('..')
+ }
+ }
+
+ return parts
+ }
+
+ // Split a filename into [root, dir, basename, ext], unix version
+ // 'root' is just a slash, or nothing.
+ var splitPathRe =
+ /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/
+ var splitPath = function (filename) {
+ return splitPathRe.exec(filename).slice(1)
+ }
+
+ // path.resolve([from ...], to)
+ // posix version
+ exports.resolve = function () {
+ var resolvedPath = '',
+ resolvedAbsolute = false
+
+ for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+ var path = (i >= 0) ? arguments[i] : process.cwd()
+
+ // Skip empty and invalid entries
+ if (typeof path !== 'string') {
+ throw new TypeError('Arguments to path.resolve must be strings')
+ } else if (!path) {
+ continue
+ }
+
+ resolvedPath = path + '/' + resolvedPath
+ resolvedAbsolute = path.charAt(0) === '/'
+ }
+
+ // At this point the path should be resolved to a full absolute path, but
+ // handle relative paths to be safe (might happen when process.cwd() fails)
+
+ // Normalize the path
+ resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function (p) {
+ return !!p
+ }), !resolvedAbsolute).join('/')
+
+ return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'
+ }
+
+ // path.normalize(path)
+ // posix version
+ exports.normalize = function (path) {
+ var isAbsolute = exports.isAbsolute(path),
+ trailingSlash = substr(path, -1) === '/'
+
+ // Normalize the path
+ path = normalizeArray(filter(path.split('/'), function (p) {
+ return !!p
+ }), !isAbsolute).join('/')
+
+ if (!path && !isAbsolute) {
+ path = '.'
+ }
+ if (path && trailingSlash) {
+ path += '/'
+ }
+
+ return (isAbsolute ? '/' : '') + path
+ }
+
+ // posix version
+ exports.isAbsolute = function (path) {
+ return path.charAt(0) === '/'
+ }
+
+ // posix version
+ exports.join = function () {
+ var paths = Array.prototype.slice.call(arguments, 0)
+ return exports.normalize(filter(paths, function (p, index) {
+ if (typeof p !== 'string') {
+ throw new TypeError('Arguments to path.join must be strings')
+ }
+ return p
+ }).join('/'))
+ }
+
+
+ // path.relative(from, to)
+ // posix version
+ exports.relative = function (from, to) {
+ from = exports.resolve(from).substr(1)
+ to = exports.resolve(to).substr(1)
+
+ function trim(arr) {
+ var start = 0
+ for (; start < arr.length; start++) {
+ if (arr[start] !== '') break
+ }
+
+ var end = arr.length - 1
+ for (; end >= 0; end--) {
+ if (arr[end] !== '') break
+ }
+
+ if (start > end) return []
+ return arr.slice(start, end - start + 1)
+ }
+
+ var fromParts = trim(from.split('/'))
+ var toParts = trim(to.split('/'))
+
+ var length = Math.min(fromParts.length, toParts.length)
+ var samePartsLength = length
+ for (var i = 0; i < length; i++) {
+ if (fromParts[i] !== toParts[i]) {
+ samePartsLength = i
+ break
+ }
+ }
+
+ var outputParts = []
+ for (var i = samePartsLength; i < fromParts.length; i++) {
+ outputParts.push('..')
+ }
+
+ outputParts = outputParts.concat(toParts.slice(samePartsLength))
+
+ return outputParts.join('/')
+ }
+
+ exports.sep = '/'
+ exports.delimiter = ':'
+
+ exports.dirname = function (path) {
+ var result = splitPath(path),
+ root = result[0],
+ dir = result[1]
+
+ if (!root && !dir) {
+ // No dirname whatsoever
+ return '.'
+ }
+
+ if (dir) {
+ // It has a dirname, strip trailing slash
+ dir = dir.substr(0, dir.length - 1)
+ }
+
+ return root + dir
+ }
+
+
+ exports.basename = function (path, ext) {
+ var f = splitPath(path)[2]
+ // TODO: make this comparison case-insensitive on windows?
+ if (ext && f.substr(-1 * ext.length) === ext) {
+ f = f.substr(0, f.length - ext.length)
+ }
+ return f
+ }
+
+
+ exports.extname = function (path) {
+ return splitPath(path)[3]
+ }
+
+ function filter(xs, f) {
+ if (xs.filter) return xs.filter(f)
+ var res = []
+ for (var i = 0; i < xs.length; i++) {
+ if (f(xs[i], i, xs)) res.push(xs[i])
+ }
+ return res
+ }
+
+ // String.prototype.substr - negative index don't work in IE8
+ var substr = 'ab'.substr(-1) === 'b'
+ ? function (str, start, len) { return str.substr(start, len) }
+ : function (str, start, len) {
+ if (start < 0) start = str.length + start
+ return str.substr(start, len)
+ }
+
+
+ /* WEBPACK VAR INJECTION */
+}.call(exports, __webpack_require__(11)))
+
+ /***/
+},
+/* 18 */
+/***/ function (module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function (process, setImmediate) {/*!
+ * async
+ * https://github.com/caolan/async
+ *
+ * Copyright 2010-2014 Caolan McMahon
+ * Released under the MIT license
+ */
+ /*jshint onevar: false, indent:4 */
+ /*global setImmediate: false, setTimeout: false, console: false */
+ (function () {
+
+ var async = {}
+
+ // global on the server, window in the browser
+ var root, previous_async
+
+ root = this
+ if (root != null) {
+ previous_async = root.async
+ }
+
+ async.noConflict = function () {
+ root.async = previous_async
+ return async
+ }
+
+ function only_once(fn) {
+ var called = false
+ return function () {
+ if (called) throw new Error("Callback was already called.")
+ called = true
+ fn.apply(root, arguments)
+ }
+ }
+
+ //// cross-browser compatiblity functions ////
+
+ var _toString = Object.prototype.toString
+
+ var _isArray = Array.isArray || function (obj) {
+ return _toString.call(obj) === '[object Array]'
+ }
+
+ var _each = function (arr, iterator) {
+ for (var i = 0; i < arr.length; i += 1) {
+ iterator(arr[i], i, arr)
+ }
+ }
+
+ var _map = function (arr, iterator) {
+ if (arr.map) {
+ return arr.map(iterator)
+ }
+ var results = []
+ _each(arr, function (x, i, a) {
+ results.push(iterator(x, i, a))
+ })
+ return results
+ }
+
+ var _reduce = function (arr, iterator, memo) {
+ if (arr.reduce) {
+ return arr.reduce(iterator, memo)
+ }
+ _each(arr, function (x, i, a) {
+ memo = iterator(memo, x, i, a)
+ })
+ return memo
+ }
+
+ var _keys = function (obj) {
+ if (Object.keys) {
+ return Object.keys(obj)
+ }
+ var keys = []
+ for (var k in obj) {
+ if (obj.hasOwnProperty(k)) {
+ keys.push(k)
+ }
+ }
+ return keys
+ }
+
+ //// exported async module functions ////
+
+ //// nextTick implementation with browser-compatible fallback ////
+ if (typeof process === 'undefined' || !(process.nextTick)) {
+ if (typeof setImmediate === 'function') {
+ async.nextTick = function (fn) {
+ // not a direct alias for IE10 compatibility
+ setImmediate(fn)
+ }
+ async.setImmediate = async.nextTick
+ }
+ else {
+ async.nextTick = function (fn) {
+ setTimeout(fn, 0)
+ }
+ async.setImmediate = async.nextTick
+ }
+ }
+ else {
+ async.nextTick = process.nextTick
+ if (typeof setImmediate !== 'undefined') {
+ async.setImmediate = function (fn) {
+ // not a direct alias for IE10 compatibility
+ setImmediate(fn)
+ }
+ }
+ else {
+ async.setImmediate = async.nextTick
+ }
+ }
+
+ async.each = function (arr, iterator, callback) {
+ callback = callback || function () { }
+ if (!arr.length) {
+ return callback()
+ }
+ var completed = 0
+ _each(arr, function (x) {
+ iterator(x, only_once(done))
+ })
+ function done(err) {
+ if (err) {
+ callback(err)
+ callback = function () { }
+ }
+ else {
+ completed += 1
+ if (completed >= arr.length) {
+ callback()
+ }
+ }
+ }
+ }
+ async.forEach = async.each
+
+ async.eachSeries = function (arr, iterator, callback) {
+ callback = callback || function () { }
+ if (!arr.length) {
+ return callback()
+ }
+ var completed = 0
+ var iterate = function () {
+ iterator(arr[completed], function (err) {
+ if (err) {
+ callback(err)
+ callback = function () { }
+ }
+ else {
+ completed += 1
+ if (completed >= arr.length) {
+ callback()
+ }
+ else {
+ iterate()
+ }
+ }
+ })
+ }
+ iterate()
+ }
+ async.forEachSeries = async.eachSeries
+
+ async.eachLimit = function (arr, limit, iterator, callback) {
+ var fn = _eachLimit(limit)
+ fn.apply(null, [arr, iterator, callback])
+ }
+ async.forEachLimit = async.eachLimit
+
+ var _eachLimit = function (limit) {
+
+ return function (arr, iterator, callback) {
+ callback = callback || function () { }
+ if (!arr.length || limit <= 0) {
+ return callback()
+ }
+ var completed = 0
+ var started = 0
+ var running = 0;
+
+ (function replenish() {
+ if (completed >= arr.length) {
+ return callback()
+ }
+
+ while (running < limit && started < arr.length) {
+ started += 1
+ running += 1
+ iterator(arr[started - 1], function (err) {
+ if (err) {
+ callback(err)
+ callback = function () { }
+ }
+ else {
+ completed += 1
+ running -= 1
+ if (completed >= arr.length) {
+ callback()
+ }
+ else {
+ replenish()
+ }
+ }
+ })
+ }
+ })()
+ }
+ }
+
+
+ var doParallel = function (fn) {
+ return function () {
+ var args = Array.prototype.slice.call(arguments)
+ return fn.apply(null, [async.each].concat(args))
+ }
+ }
+ var doParallelLimit = function (limit, fn) {
+ return function () {
+ var args = Array.prototype.slice.call(arguments)
+ return fn.apply(null, [_eachLimit(limit)].concat(args))
+ }
+ }
+ var doSeries = function (fn) {
+ return function () {
+ var args = Array.prototype.slice.call(arguments)
+ return fn.apply(null, [async.eachSeries].concat(args))
+ }
+ }
+
+
+ var _asyncMap = function (eachfn, arr, iterator, callback) {
+ arr = _map(arr, function (x, i) {
+ return { index: i, value: x }
+ })
+ if (!callback) {
+ eachfn(arr, function (x, callback) {
+ iterator(x.value, function (err) {
+ callback(err)
+ })
+ })
+ } else {
+ var results = []
+ eachfn(arr, function (x, callback) {
+ iterator(x.value, function (err, v) {
+ results[x.index] = v
+ callback(err)
+ })
+ }, function (err) {
+ callback(err, results)
+ })
+ }
+ }
+ async.map = doParallel(_asyncMap)
+ async.mapSeries = doSeries(_asyncMap)
+ async.mapLimit = function (arr, limit, iterator, callback) {
+ return _mapLimit(limit)(arr, iterator, callback)
+ }
+
+ var _mapLimit = function (limit) {
+ return doParallelLimit(limit, _asyncMap)
+ }
+
+ // reduce only has a series version, as doing reduce in parallel won't
+ // work in many situations.
+ async.reduce = function (arr, memo, iterator, callback) {
+ async.eachSeries(arr, function (x, callback) {
+ iterator(memo, x, function (err, v) {
+ memo = v
+ callback(err)
+ })
+ }, function (err) {
+ callback(err, memo)
+ })
+ }
+ // inject alias
+ async.inject = async.reduce
+ // foldl alias
+ async.foldl = async.reduce
+
+ async.reduceRight = function (arr, memo, iterator, callback) {
+ var reversed = _map(arr, function (x) {
+ return x
+ }).reverse()
+ async.reduce(reversed, memo, iterator, callback)
+ }
+ // foldr alias
+ async.foldr = async.reduceRight
+
+ var _filter = function (eachfn, arr, iterator, callback) {
+ var results = []
+ arr = _map(arr, function (x, i) {
+ return { index: i, value: x }
+ })
+ eachfn(arr, function (x, callback) {
+ iterator(x.value, function (v) {
+ if (v) {
+ results.push(x)
+ }
+ callback()
+ })
+ }, function (err) {
+ callback(_map(results.sort(function (a, b) {
+ return a.index - b.index
+ }), function (x) {
+ return x.value
+ }))
+ })
+ }
+ async.filter = doParallel(_filter)
+ async.filterSeries = doSeries(_filter)
+ // select alias
+ async.select = async.filter
+ async.selectSeries = async.filterSeries
+
+ var _reject = function (eachfn, arr, iterator, callback) {
+ var results = []
+ arr = _map(arr, function (x, i) {
+ return { index: i, value: x }
+ })
+ eachfn(arr, function (x, callback) {
+ iterator(x.value, function (v) {
+ if (!v) {
+ results.push(x)
+ }
+ callback()
+ })
+ }, function (err) {
+ callback(_map(results.sort(function (a, b) {
+ return a.index - b.index
+ }), function (x) {
+ return x.value
+ }))
+ })
+ }
+ async.reject = doParallel(_reject)
+ async.rejectSeries = doSeries(_reject)
+
+ var _detect = function (eachfn, arr, iterator, main_callback) {
+ eachfn(arr, function (x, callback) {
+ iterator(x, function (result) {
+ if (result) {
+ main_callback(x)
+ main_callback = function () { }
+ }
+ else {
+ callback()
+ }
+ })
+ }, function (err) {
+ main_callback()
+ })
+ }
+ async.detect = doParallel(_detect)
+ async.detectSeries = doSeries(_detect)
+
+ async.some = function (arr, iterator, main_callback) {
+ async.each(arr, function (x, callback) {
+ iterator(x, function (v) {
+ if (v) {
+ main_callback(true)
+ main_callback = function () { }
+ }
+ callback()
+ })
+ }, function (err) {
+ main_callback(false)
+ })
+ }
+ // any alias
+ async.any = async.some
+
+ async.every = function (arr, iterator, main_callback) {
+ async.each(arr, function (x, callback) {
+ iterator(x, function (v) {
+ if (!v) {
+ main_callback(false)
+ main_callback = function () { }
+ }
+ callback()
+ })
+ }, function (err) {
+ main_callback(true)
+ })
+ }
+ // all alias
+ async.all = async.every
+
+ async.sortBy = function (arr, iterator, callback) {
+ async.map(arr, function (x, callback) {
+ iterator(x, function (err, criteria) {
+ if (err) {
+ callback(err)
+ }
+ else {
+ callback(null, { value: x, criteria: criteria })
+ }
+ })
+ }, function (err, results) {
+ if (err) {
+ return callback(err)
+ }
+ else {
+ var fn = function (left, right) {
+ var a = left.criteria, b = right.criteria
+ return a < b ? -1 : a > b ? 1 : 0
+ }
+ callback(null, _map(results.sort(fn), function (x) {
+ return x.value
+ }))
+ }
+ })
+ }
+
+ async.auto = function (tasks, callback) {
+ callback = callback || function () { }
+ var keys = _keys(tasks)
+ var remainingTasks = keys.length
+ if (!remainingTasks) {
+ return callback()
+ }
+
+ var results = {}
+
+ var listeners = []
+ var addListener = function (fn) {
+ listeners.unshift(fn)
+ }
+ var removeListener = function (fn) {
+ for (var i = 0; i < listeners.length; i += 1) {
+ if (listeners[i] === fn) {
+ listeners.splice(i, 1)
+ return
+ }
+ }
+ }
+ var taskComplete = function () {
+ remainingTasks--
+ _each(listeners.slice(0), function (fn) {
+ fn()
+ })
+ }
+
+ addListener(function () {
+ if (!remainingTasks) {
+ var theCallback = callback
+ // prevent final callback from calling itself if it errors
+ callback = function () { }
+
+ theCallback(null, results)
+ }
+ })
+
+ _each(keys, function (k) {
+ var task = _isArray(tasks[k]) ? tasks[k] : [tasks[k]]
+ var taskCallback = function (err) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ if (args.length <= 1) {
+ args = args[0]
+ }
+ if (err) {
+ var safeResults = {}
+ _each(_keys(results), function (rkey) {
+ safeResults[rkey] = results[rkey]
+ })
+ safeResults[k] = args
+ callback(err, safeResults)
+ // stop subsequent errors hitting callback multiple times
+ callback = function () { }
+ }
+ else {
+ results[k] = args
+ async.setImmediate(taskComplete)
+ }
+ }
+ var requires = task.slice(0, Math.abs(task.length - 1)) || []
+ var ready = function () {
+ return _reduce(requires, function (a, x) {
+ return (a && results.hasOwnProperty(x))
+ }, true) && !results.hasOwnProperty(k)
+ }
+ if (ready()) {
+ task[task.length - 1](taskCallback, results)
+ }
+ else {
+ var listener = function () {
+ if (ready()) {
+ removeListener(listener)
+ task[task.length - 1](taskCallback, results)
+ }
+ }
+ addListener(listener)
+ }
+ })
+ }
+
+ async.retry = function (times, task, callback) {
+ var DEFAULT_TIMES = 5
+ var attempts = []
+ // Use defaults if times not passed
+ if (typeof times === 'function') {
+ callback = task
+ task = times
+ times = DEFAULT_TIMES
+ }
+ // Make sure times is a number
+ times = parseInt(times, 10) || DEFAULT_TIMES
+ var wrappedTask = function (wrappedCallback, wrappedResults) {
+ var retryAttempt = function (task, finalAttempt) {
+ return function (seriesCallback) {
+ task(function (err, result) {
+ seriesCallback(!err || finalAttempt, { err: err, result: result })
+ }, wrappedResults)
+ }
+ }
+ while (times) {
+ attempts.push(retryAttempt(task, !(times -= 1)))
+ }
+ async.series(attempts, function (done, data) {
+ data = data[data.length - 1];
+ (wrappedCallback || callback)(data.err, data.result)
+ })
+ }
+ // If a callback is passed, run this as a controll flow
+ return callback ? wrappedTask() : wrappedTask
+ }
+
+ async.waterfall = function (tasks, callback) {
+ callback = callback || function () { }
+ if (!_isArray(tasks)) {
+ var err = new Error('First argument to waterfall must be an array of functions')
+ return callback(err)
+ }
+ if (!tasks.length) {
+ return callback()
+ }
+ var wrapIterator = function (iterator) {
+ return function (err) {
+ if (err) {
+ callback.apply(null, arguments)
+ callback = function () { }
+ }
+ else {
+ var args = Array.prototype.slice.call(arguments, 1)
+ var next = iterator.next()
+ if (next) {
+ args.push(wrapIterator(next))
+ }
+ else {
+ args.push(callback)
+ }
+ async.setImmediate(function () {
+ iterator.apply(null, args)
+ })
+ }
+ }
+ }
+ wrapIterator(async.iterator(tasks))()
+ }
+
+ var _parallel = function (eachfn, tasks, callback) {
+ callback = callback || function () { }
+ if (_isArray(tasks)) {
+ eachfn.map(tasks, function (fn, callback) {
+ if (fn) {
+ fn(function (err) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ if (args.length <= 1) {
+ args = args[0]
+ }
+ callback.call(null, err, args)
+ })
+ }
+ }, callback)
+ }
+ else {
+ var results = {}
+ eachfn.each(_keys(tasks), function (k, callback) {
+ tasks[k](function (err) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ if (args.length <= 1) {
+ args = args[0]
+ }
+ results[k] = args
+ callback(err)
+ })
+ }, function (err) {
+ callback(err, results)
+ })
+ }
+ }
+
+ async.parallel = function (tasks, callback) {
+ _parallel({ map: async.map, each: async.each }, tasks, callback)
+ }
+
+ async.parallelLimit = function (tasks, limit, callback) {
+ _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback)
+ }
+
+ async.series = function (tasks, callback) {
+ callback = callback || function () { }
+ if (_isArray(tasks)) {
+ async.mapSeries(tasks, function (fn, callback) {
+ if (fn) {
+ fn(function (err) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ if (args.length <= 1) {
+ args = args[0]
+ }
+ callback.call(null, err, args)
+ })
+ }
+ }, callback)
+ }
+ else {
+ var results = {}
+ async.eachSeries(_keys(tasks), function (k, callback) {
+ tasks[k](function (err) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ if (args.length <= 1) {
+ args = args[0]
+ }
+ results[k] = args
+ callback(err)
+ })
+ }, function (err) {
+ callback(err, results)
+ })
+ }
+ }
+
+ async.iterator = function (tasks) {
+ var makeCallback = function (index) {
+ var fn = function () {
+ if (tasks.length) {
+ tasks[index].apply(null, arguments)
+ }
+ return fn.next()
+ }
+ fn.next = function () {
+ return (index < tasks.length - 1) ? makeCallback(index + 1) : null
+ }
+ return fn
+ }
+ return makeCallback(0)
+ }
+
+ async.apply = function (fn) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ return function () {
+ return fn.apply(
+ null, args.concat(Array.prototype.slice.call(arguments))
+ )
+ }
+ }
+
+ var _concat = function (eachfn, arr, fn, callback) {
+ var r = []
+ eachfn(arr, function (x, cb) {
+ fn(x, function (err, y) {
+ r = r.concat(y || [])
+ cb(err)
+ })
+ }, function (err) {
+ callback(err, r)
+ })
+ }
+ async.concat = doParallel(_concat)
+ async.concatSeries = doSeries(_concat)
+
+ async.whilst = function (test, iterator, callback) {
+ if (test()) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err)
+ }
+ async.whilst(test, iterator, callback)
+ })
+ }
+ else {
+ callback()
+ }
+ }
+
+ async.doWhilst = function (iterator, test, callback) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err)
+ }
+ var args = Array.prototype.slice.call(arguments, 1)
+ if (test.apply(null, args)) {
+ async.doWhilst(iterator, test, callback)
+ }
+ else {
+ callback()
+ }
+ })
+ }
+
+ async.until = function (test, iterator, callback) {
+ if (!test()) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err)
+ }
+ async.until(test, iterator, callback)
+ })
+ }
+ else {
+ callback()
+ }
+ }
+
+ async.doUntil = function (iterator, test, callback) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err)
+ }
+ var args = Array.prototype.slice.call(arguments, 1)
+ if (!test.apply(null, args)) {
+ async.doUntil(iterator, test, callback)
+ }
+ else {
+ callback()
+ }
+ })
+ }
+
+ async.queue = function (worker, concurrency) {
+ if (concurrency === undefined) {
+ concurrency = 1
+ }
+ function _insert(q, data, pos, callback) {
+ if (!q.started) {
+ q.started = true
+ }
+ if (!_isArray(data)) {
+ data = [data]
+ }
+ if (data.length == 0) {
+ // call drain immediately if there are no tasks
+ return async.setImmediate(function () {
+ if (q.drain) {
+ q.drain()
+ }
+ })
+ }
+ _each(data, function (task) {
+ var item = {
+ data: task,
+ callback: typeof callback === 'function' ? callback : null
+ }
+
+ if (pos) {
+ q.tasks.unshift(item)
+ } else {
+ q.tasks.push(item)
+ }
+
+ if (q.saturated && q.tasks.length === q.concurrency) {
+ q.saturated()
+ }
+ async.setImmediate(q.process)
+ })
+ }
+
+ var workers = 0
+ var q = {
+ tasks: [],
+ concurrency: concurrency,
+ saturated: null,
+ empty: null,
+ drain: null,
+ started: false,
+ paused: false,
+ push: function (data, callback) {
+ _insert(q, data, false, callback)
+ },
+ kill: function () {
+ q.drain = null
+ q.tasks = []
+ },
+ unshift: function (data, callback) {
+ _insert(q, data, true, callback)
+ },
+ process: function () {
+ if (!q.paused && workers < q.concurrency && q.tasks.length) {
+ var task = q.tasks.shift()
+ if (q.empty && q.tasks.length === 0) {
+ q.empty()
+ }
+ workers += 1
+ var next = function () {
+ workers -= 1
+ if (task.callback) {
+ task.callback.apply(task, arguments)
+ }
+ if (q.drain && q.tasks.length + workers === 0) {
+ q.drain()
+ }
+ q.process()
+ }
+ var cb = only_once(next)
+ worker(task.data, cb)
+ }
+ },
+ length: function () {
+ return q.tasks.length
+ },
+ running: function () {
+ return workers
+ },
+ idle: function () {
+ return q.tasks.length + workers === 0
+ },
+ pause: function () {
+ if (q.paused === true) { return }
+ q.paused = true
+ },
+ resume: function () {
+ if (q.paused === false) { return }
+ q.paused = false
+ // Need to call q.process once per concurrent
+ // worker to preserve full concurrency after pause
+ for (var w = 1; w <= q.concurrency; w++) {
+ async.setImmediate(q.process)
+ }
+ }
+ }
+ return q
+ }
+
+ async.priorityQueue = function (worker, concurrency) {
+
+ function _compareTasks(a, b) {
+ return a.priority - b.priority
+ };
+
+ function _binarySearch(sequence, item, compare) {
+ var beg = -1,
+ end = sequence.length - 1
+ while (beg < end) {
+ var mid = beg + ((end - beg + 1) >>> 1)
+ if (compare(item, sequence[mid]) >= 0) {
+ beg = mid
+ } else {
+ end = mid - 1
+ }
+ }
+ return beg
+ }
+
+ function _insert(q, data, priority, callback) {
+ if (!q.started) {
+ q.started = true
+ }
+ if (!_isArray(data)) {
+ data = [data]
+ }
+ if (data.length == 0) {
+ // call drain immediately if there are no tasks
+ return async.setImmediate(function () {
+ if (q.drain) {
+ q.drain()
+ }
+ })
+ }
+ _each(data, function (task) {
+ var item = {
+ data: task,
+ priority: priority,
+ callback: typeof callback === 'function' ? callback : null
+ }
+
+ q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item)
+
+ if (q.saturated && q.tasks.length === q.concurrency) {
+ q.saturated()
+ }
+ async.setImmediate(q.process)
+ })
+ }
+
+ // Start with a normal queue
+ var q = async.queue(worker, concurrency)
+
+ // Override push to accept second parameter representing priority
+ q.push = function (data, priority, callback) {
+ _insert(q, data, priority, callback)
+ }
+
+ // Remove unshift function
+ delete q.unshift
+
+ return q
+ }
+
+ async.cargo = function (worker, payload) {
+ var working = false,
+ tasks = []
+
+ var cargo = {
+ tasks: tasks,
+ payload: payload,
+ saturated: null,
+ empty: null,
+ drain: null,
+ drained: true,
+ push: function (data, callback) {
+ if (!_isArray(data)) {
+ data = [data]
+ }
+ _each(data, function (task) {
+ tasks.push({
+ data: task,
+ callback: typeof callback === 'function' ? callback : null
+ })
+ cargo.drained = false
+ if (cargo.saturated && tasks.length === payload) {
+ cargo.saturated()
+ }
+ })
+ async.setImmediate(cargo.process)
+ },
+ process: function process() {
+ if (working) return
+ if (tasks.length === 0) {
+ if (cargo.drain && !cargo.drained) cargo.drain()
+ cargo.drained = true
+ return
+ }
+
+ var ts = typeof payload === 'number'
+ ? tasks.splice(0, payload)
+ : tasks.splice(0, tasks.length)
+
+ var ds = _map(ts, function (task) {
+ return task.data
+ })
+
+ if (cargo.empty) cargo.empty()
+ working = true
+ worker(ds, function () {
+ working = false
+
+ var args = arguments
+ _each(ts, function (data) {
+ if (data.callback) {
+ data.callback.apply(null, args)
+ }
+ })
+
+ process()
+ })
+ },
+ length: function () {
+ return tasks.length
+ },
+ running: function () {
+ return working
+ }
+ }
+ return cargo
+ }
+
+ var _console_fn = function (name) {
+ return function (fn) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ fn.apply(null, args.concat([function (err) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ if (typeof console !== 'undefined') {
+ if (err) {
+ if (console.error) {
+ console.error(err)
+ }
+ }
+ else if (console[name]) {
+ _each(args, function (x) {
+ console[name](x)
+ })
+ }
+ }
+ }]))
+ }
+ }
+ async.log = _console_fn('log')
+ async.dir = _console_fn('dir')
+ /*async.info = _console_fn('info');
+ async.warn = _console_fn('warn');
+ async.error = _console_fn('error');*/
+
+ async.memoize = function (fn, hasher) {
+ var memo = {}
+ var queues = {}
+ hasher = hasher || function (x) {
+ return x
+ }
+ var memoized = function () {
+ var args = Array.prototype.slice.call(arguments)
+ var callback = args.pop()
+ var key = hasher.apply(null, args)
+ if (key in memo) {
+ async.nextTick(function () {
+ callback.apply(null, memo[key])
+ })
+ }
+ else if (key in queues) {
+ queues[key].push(callback)
+ }
+ else {
+ queues[key] = [callback]
+ fn.apply(null, args.concat([function () {
+ memo[key] = arguments
+ var q = queues[key]
+ delete queues[key]
+ for (var i = 0, l = q.length; i < l; i++) {
+ q[i].apply(null, arguments)
+ }
+ }]))
+ }
+ }
+ memoized.memo = memo
+ memoized.unmemoized = fn
+ return memoized
+ }
+
+ async.unmemoize = function (fn) {
+ return function () {
+ return (fn.unmemoized || fn).apply(null, arguments)
+ }
+ }
+
+ async.times = function (count, iterator, callback) {
+ var counter = []
+ for (var i = 0; i < count; i++) {
+ counter.push(i)
+ }
+ return async.map(counter, iterator, callback)
+ }
+
+ async.timesSeries = function (count, iterator, callback) {
+ var counter = []
+ for (var i = 0; i < count; i++) {
+ counter.push(i)
+ }
+ return async.mapSeries(counter, iterator, callback)
+ }
+
+ async.seq = function (/* functions... */) {
+ var fns = arguments
+ return function () {
+ var that = this
+ var args = Array.prototype.slice.call(arguments)
+ var callback = args.pop()
+ async.reduce(fns, args, function (newargs, fn, cb) {
+ fn.apply(that, newargs.concat([function () {
+ var err = arguments[0]
+ var nextargs = Array.prototype.slice.call(arguments, 1)
+ cb(err, nextargs)
+ }]))
+ },
+ function (err, results) {
+ callback.apply(that, [err].concat(results))
+ })
+ }
+ }
+
+ async.compose = function (/* functions... */) {
+ return async.seq.apply(null, Array.prototype.reverse.call(arguments))
+ }
+
+ var _applyEach = function (eachfn, fns /*args...*/) {
+ var go = function () {
+ var that = this
+ var args = Array.prototype.slice.call(arguments)
+ var callback = args.pop()
+ return eachfn(fns, function (fn, cb) {
+ fn.apply(that, args.concat([cb]))
+ },
+ callback)
+ }
+ if (arguments.length > 2) {
+ var args = Array.prototype.slice.call(arguments, 2)
+ return go.apply(this, args)
+ }
+ else {
+ return go
+ }
+ }
+ async.applyEach = doParallel(_applyEach)
+ async.applyEachSeries = doSeries(_applyEach)
+
+ async.forever = function (fn, callback) {
+ function next(err) {
+ if (err) {
+ if (callback) {
+ return callback(err)
+ }
+ throw err
+ }
+ fn(next)
+ }
+ next()
+ }
+
+ // Node.js
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports = async
+ }
+ // AMD / RequireJS
+ else if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
+ return async
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))
+ }
+ // included directly via
+
+
+
+
+
+
+
+