<commit_before>"use strict";

/*  ------------------------------------------------------------------------ */

const [processPath, , exchangeId = null, exchangeSymbol = null] = process.argv.filter (x => !x.startsWith ('--'))
const verbose = process.argv.includes ('--verbose') || false

/*  ------------------------------------------------------------------------ */

const ccxt      = require ('./ccxt')
const countries = require ('./countries')

/*  ------------------------------------------------------------------------ */

const asTable   = require ('as-table')
const util      = require ('util')
const log       = require ('ololog')
const ansi      = require ('ansicolor').nice;
const fs        = require ('fs')

/*  ------------------------------------------------------------------------ */

const warn = log.bright.yellow.error // .error goes to stderr

/*  ------------------------------------------------------------------------ */

process.on ('uncaughtException',  e => { log.bright.red.error (e); process.exit (1) })
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })

/*  ------------------------------------------------------------------------ */

log.bright ('\nTESTING', { exchange: exchangeId, symbol: exchangeSymbol || 'all' }, '\n')

/*  ------------------------------------------------------------------------ */

let proxies = [
    '',
    'https://cors-anywhere.herokuapp.com/',
    'https://crossorigin.me/',
    // 'http://cors-proxy.htmldriven.com/?url=', // we don't want this for now
]

/*  ------------------------------------------------------------------------ */

const exchange = new (ccxt)[exchangeId] ({ verbose: verbose })

//-----------------------------------------------------------------------------

let apiKeys = JSON.parse (fs.readFileSync ('./keys.json', 'utf8'))[exchangeId]

Object.assign (exchange, apiKeys)

if (exchange.urls['test'])
    exchange.urls['api'] = exchange.urls['test']; // move to testnet/sandbox if possible

const verboseList = [ ];
if (verboseList.indexOf (exchange.id) >= 0) {
    exchange.verbose = true
}

//-----------------------------------------------------------------------------

var countryName = function (code) {
    return ((typeof countries[code] !== 'undefined') ? countries[code] : code)
}

//-----------------------------------------------------------------------------

let sleep = (ms) => new Promise (resolve => setTimeout (resolve, ms));

//-----------------------------------------------------------------------------

let human_value = function (price) {
    return typeof price == 'undefined' ? 'N/A' : price
}

//-----------------------------------------------------------------------------

let testExchangeSymbolTicker = async (exchange, symbol) => {
    await sleep (exchange.rateLimit)
    log (exchange.id.green, symbol.green, 'fetching ticker...')
    let ticker = await exchange.fetchTicker (symbol)
    log (exchange.id.green, symbol.green, 'ticker',
        ticker['datetime'],
        'high: '    + human_value (ticker['high']),
        'low: '     + human_value (ticker['low']),
        'bid: '     + human_value (ticker['bid']),
        'ask: '     + human_value (ticker['ask']),
        'volume: '  + human_value (ticker['quoteVolume']))

    if (ticker['bid'] > ticker['ask'])
        log (this.id, symbol, 'ticker', 'bid is greater than ask!')

    return ticker;
}

let testExchangeSymbolOrderbook = async (exchange, symbol) => {
    await sleep (exchange.rateLimit)
    log (exchange.id.green, symbol.green, 'fetching order book...')
    let orderbook = await exchange.fetchOrderBook (symbol)
    log (exchange.id.green, symbol.green,
        orderbook['datetime'],
        'bid: '       + ((orderbook.bids.length > 0) ? human_value (orderbook.bids[0][0]) : 'N/A'),
        'bidVolume: ' + ((orderbook.bids.length > 0) ? human_value (orderbook.bids[0][1]) : 'N/A'),
        'ask: '       + ((orderbook.asks.length > 0) ? human_value (orderbook.asks[0][0]) : 'N/A'),
        'askVolume: ' + ((orderbook.asks.length > 0) ? human_value (orderbook.asks[0][1]) : 'N/A'))

    let bids = orderbook.bids
    if (bids.length > 1) {
        let first = 0
        let last = bids.length - 1
        if (bids[first][0] < bids[last][0])
            log (exchange.id, symbol, 'bids reversed!'.red.bright, bids[first][0], bids[last][0])
        else if (bids[first][0] > bids[last][0])
            log (exchange.id.green, symbol.green, 'bids ok')
    }
    let asks = orderbook.asks
    if (asks.length > 1) {
        let first = 0
        let last = asks.length - 1
        if (asks[first][0] > asks[last][0])
            log (exchange.id, symbol, 'asks reversed!'.red.bright, asks[first][0], asks[last][0])
        else if (asks[first][0] < asks[last][0])
            log (exchange.id.green, symbol.green, 'asks ok')
    }

    if (bids.length && asks.length)
        if (bids[0][0] > asks[0][0])
            log (this.id, symbol, 'order book', 'bid is greater than ask!'.red.bright)

    return orderbook
}

//-----------------------------------------------------------------------------

let testExchangeSymbolTrades = async (exchange, symbol) => {
    log (exchange.id.green, symbol.green, 'fetching trades...')
    let trades = await exchange.fetchTrades (symbol)
    log (exchange.id.green, symbol.green, 'fetched', Object.values (trades).length.toString ().green, 'trades')
    return trades
}

//-----------------------------------------------------------------------------

let testExchangeSymbol = async (exchange, symbol) => {

    await sleep (exchange.rateLimit)
    await testExchangeSymbolTicker (exchange, symbol)

    if (exchange.hasFetchTickers) {

        log (exchange.id.green, 'fetching all tickers at once...')
        let tickers = await exchange.fetchTickers ()
        log (exchange.id.green, 'fetched', Object.keys (tickers).length.toString ().green, 'tickers')

    } else {

        log (exchange.id.green, 'fetching all tickers at once not supported')
    }

    if (exchange.hasFetchOHLCV) {

        try {

            log (exchange.id.green, symbol.green, 'fetching OHLCV...')
            let ohlcv = await exchange.fetchOHLCV (symbol)
            log (exchange.id.green, symbol.green, 'fetched', Object.keys (ohlcv).length.toString ().green, 'OHLCVs')

        } catch (e) {

            if (e instanceof ccxt.ExchangeError) {
                warn (exchange.id, '[Exchange Error] ' + e.message)
            } else if (e instanceof ccxt.NotSupported) {
                warn (exchange.id, '[Not Supported] ' + e.message)
            } else {
                throw e;
            }
        }

    } else {

        log (exchange.id.green, 'fetching OHLCV not supported')
    }

    if (exchange.id == 'coinmarketcap') {

        log (await exchange.fetchTickers ());
        log (await exchange.fetchGlobal ());

    } else {

        await testExchangeSymbolOrderbook (exchange, symbol)

        try {

            await testExchangeSymbolTrades (exchange, symbol)

        } catch (e) {

            if (e instanceof ccxt.ExchangeError) {
                warn (exchange.id, '[Exchange Error] ' + e.message)
            } else if (e instanceof ccxt.NotSupported) {
                warn (exchange.id, '[Not Supported] ' + e.message)
            } else {
                throw e;
            }
        }
    }
}

//-----------------------------------------------------------------------------

let testExchangeFetchOrders = async (exchange) => {

    await sleep (exchange.rateLimit)

    try {

        log (exchange.id.green, 'fetching orders...')
        let orders = await exchange.fetchOrders ()
        log (exchange.id.green, 'fetched', orders.length.toString ().green, 'orders')

    } catch (e) {

        if (e instanceof ccxt.ExchangeError) {
            warn (exchange.id, '[Exchange Error] ' + e.message)
        } else if (e instanceof ccxt.NotSupported) {
            warn (exchange.id, '[Not Supported] ' + e.message)
        } else {
            throw e;
        }
    }
}

//-----------------------------------------------------------------------------

let testExchangeBalance = async (exchange, symbol) => {

    await sleep (exchange.rateLimit)
    log (exchange.id.green, 'fetching balance...')
    let balance = await exchange.fetchBalance ()

    let currencies = [
        'USD',
        'CNY',
        'EUR',
        'BTC',
        'ETH',
        'JPY',
        'LTC',
        'DASH',
        'DOGE',
        'UAH',
        'RUB',
    ]

    if ('info' in balance) {

        let result = currencies
            .filter (currency => (currency in balance) &&
                (typeof balance[currency]['total'] != 'undefined'))

        if (result.length > 0) {
            result = result.map (currency => currency + ': ' + human_value (balance[currency]['total']))
            if (exchange.currencies.length > result.length)
                result = result.join (', ') + ' + more...'
            else
                result = result.join (', ')

        } else {

            result = 'zero balance'
        }

        log (exchange.id.green, result)

    } else {

        log (exchange.id.green, exchange.omit (balance, 'info'))
    }
}

//-----------------------------------------------------------------------------

let loadExchange = async exchange => {

    let markets  = await exchange.loadMarkets ()

    let symbols = [
        'BTC/CNY',
        'BTC/USD',
        'BTC/EUR',
        'BTC/ETH',
        'ETH/BTC',
        'BTC/JPY',
        'ETH/EUR',
        'ETH/JPY',
        'ETH/CNY',
        'LTC/CNY',
        'DASH/BTC',
        'DOGE/BTC',
        'BTC/AUD',
        'BTC/PLN',
        'USD/SLL',
        'BTC/RUB',
        'BTC/UAH',
        'LTC/BTC',
    ]

    let result = exchange.symbols.filter (symbol => symbols.indexOf (symbol) >= 0)
    if (result.length > 0)
        if (exchange.symbols.length > result.length)
            result = result.join (', ') + ' + more...'
        else
            result = result.join (', ')
    log (exchange.id.green, exchange.symbols.length.toString ().bright.green, 'symbols', result)
}

//-----------------------------------------------------------------------------

let testExchange = async exchange => {

    await loadExchange (exchange)

    let delay = exchange.rateLimit
    let symbol = exchange.symbols[0]
    let symbols = [
        'BTC/USD',
        'BTC/CNY',
        'BTC/EUR',
        'BTC/ETH',
        'ETH/BTC',
        'BTC/JPY',
        'LTC/BTC',
    ]
    for (let s in symbols) {
        if (exchange.symbols.includes (symbols[s])) {
            symbol = symbols[s]
            break
        }
    }

    log.green ('SYMBOL:', symbol)
    if ((symbol.indexOf ('.d') < 0)) {
        await testExchangeSymbol (exchange, symbol)
    }

    if (!exchange.apiKey || (exchange.apiKey.length < 1))
        return true

    await testExchangeBalance (exchange)

    if (exchange.hasFetchOrders) {

            await testExchangeFetchOrders (exchange);

    } else {

        log (exchange.id.green, 'fetching orders not supported')
    }

    // sleep (delay)
    // try {
    //     let marketSellOrder =
    //         await exchange.createMarketSellOrder (exchange.symbols[0], 1)
    //     console.log (exchange.id, 'ok', marketSellOrder)
    // } catch (e) {
    //     console.log (exchange.id, 'error', 'market sell', e)
    // }

    // sleep (delay)
    // try {
    //     let marketBuyOrder = await exchange.createMarketBuyOrder (exchange.symbols[0], 1)
    //     console.log (exchange.id, 'ok', marketBuyOrder)
    // } catch (e) {
    //     console.log (exchange.id, 'error', 'market buy', e)
    // }

    // sleep (delay)
    // try {
    //     let limitSellOrder = await exchange.createLimitSellOrder (exchange.symbols[0], 1, 3000)
    //     console.log (exchange.id, 'ok', limitSellOrder)
    // } catch (e) {
    //     console.log (exchange.id, 'error', 'limit sell', e)
    // }

    // sleep (delay)
    // try {
    //     let limitBuyOrder = await exchange.createLimitBuyOrder (exchange.symbols[0], 1, 3000)
    //     console.log (exchange.id, 'ok', limitBuyOrder)
    // } catch (e) {
    //     console.log (exchange.id, 'error', 'limit buy', e)
    // }

}

//-----------------------------------------------------------------------------

let printExchangesTable = function () {
    let astable = asTable.configure ({ delimiter: ' | ' })
    console.log (astable (Object.values (exchanges).map (exchange => {
        let website = Array.isArray (exchange.urls.www) ?
            exchange.urls.www[0] :
            exchange.urls.www
        let countries = Array.isArray (exchange.countries) ?
            exchange.countries.map (countryName).join (', ') :
            countryName (exchange.countries)
        let doc = Array.isArray (exchange.urls.doc) ?
            exchange.urls.doc[0] :
            exchange.urls.doc
        return {
            'id':        exchange.id,
            'name':      exchange.name,
            'countries': countries,
        }
    })))
}

//-----------------------------------------------------------------------------

let tryAllProxies = async function (exchange, proxies) {

    let currentProxy = 0
    let maxRetries   = proxies.length

    // a special case for ccex
    if (exchange.id == 'ccex')
        currentProxy = 1

    for (let numRetries = 0; numRetries < maxRetries; numRetries++) {

        try {

            exchange.proxy = proxies[currentProxy]
            await testExchange (exchange)
            break

        } catch (e) {

            currentProxy = ++currentProxy % proxies.length
            if (e instanceof ccxt.DDoSProtection) {
                warn (exchange.id, '[DDoS Protection] ' + e.message)
            } else if (e instanceof ccxt.RequestTimeout) {
                warn (exchange.id, '[Request Timeout] ' + e.message)
            } else if (e instanceof ccxt.AuthenticationError) {
                warn (exchange.id, '[Authentication Error] ' + e.message)
            } else if (e instanceof ccxt.ExchangeNotAvailable) {
                warn (exchange.id, '[Exchange Not Available] ' + e.message)
            } else if (e instanceof ccxt.NotSupported) {
                warn (exchange.id, '[Not Supported] ' + e.message)
            } else if (e instanceof ccxt.ExchangeError) {
                warn (exchange.id, '[Exchange Error] ' + e.message)
            } else {
                throw e;
            }
        }
    }
}

//-----------------------------------------------------------------------------

;(async function test () {

    // printExchangesTable ()

    if (exchangeSymbol) {

        await loadExchange (exchange)
        await (exchangeSymbol == 'balance') ?
            testExchangeBalance (exchange) :
            testExchangeSymbol (exchange, exchangeSymbol)

    } else {

        await tryAllProxies (exchange, proxies)
    }

    process.exit ()

}) ()

<commit_msg>removed unneeded sleeps from test.js (now we have enableRateLimit: true which does automatic management of this)<commit_after>"use strict";

/*  ------------------------------------------------------------------------ */

const [processPath, , exchangeId = null, exchangeSymbol = null] = process.argv.filter (x => !x.startsWith ('--'))
const verbose = process.argv.includes ('--verbose') || false

/*  ------------------------------------------------------------------------ */

const ccxt      = require ('./ccxt')
const countries = require ('./countries')

/*  ------------------------------------------------------------------------ */

const asTable   = require ('as-table')
const util      = require ('util')
const log       = require ('ololog')
const ansi      = require ('ansicolor').nice;
const fs        = require ('fs')

/*  ------------------------------------------------------------------------ */

const warn = log.bright.yellow.error // .error goes to stderr

/*  ------------------------------------------------------------------------ */

process.on ('uncaughtException',  e => { log.bright.red.error (e); process.exit (1) })
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })

/*  ------------------------------------------------------------------------ */

log.bright ('\nTESTING', { exchange: exchangeId, symbol: exchangeSymbol || 'all' }, '\n')

/*  ------------------------------------------------------------------------ */

let proxies = [
    '',
    'https://cors-anywhere.herokuapp.com/',
    'https://crossorigin.me/',
    // 'http://cors-proxy.htmldriven.com/?url=', // we don't want this for now
]

/*  ------------------------------------------------------------------------ */

const exchange = new (ccxt)[exchangeId] ({ verbose: verbose, enabledRateLimit: true })

//-----------------------------------------------------------------------------

let apiKeys = JSON.parse (fs.readFileSync ('./keys.json', 'utf8'))[exchangeId]

Object.assign (exchange, apiKeys)

if (exchange.urls['test'])
    exchange.urls['api'] = exchange.urls['test']; // move to testnet/sandbox if possible

const verboseList = [ ];
if (verboseList.indexOf (exchange.id) >= 0) {
    exchange.verbose = true
}

//-----------------------------------------------------------------------------

var countryName = function (code) {
    return ((typeof countries[code] !== 'undefined') ? countries[code] : code)
}

//-----------------------------------------------------------------------------

let human_value = function (price) {
    return typeof price == 'undefined' ? 'N/A' : price
}

//-----------------------------------------------------------------------------

let testExchangeSymbolTicker = async (exchange, symbol) => {
    log (exchange.id.green, symbol.green, 'fetching ticker...')
    let ticker = await exchange.fetchTicker (symbol)
    log (exchange.id.green, symbol.green, 'ticker',
        ticker['datetime'],
        'high: '    + human_value (ticker['high']),
        'low: '     + human_value (ticker['low']),
        'bid: '     + human_value (ticker['bid']),
        'ask: '     + human_value (ticker['ask']),
        'volume: '  + human_value (ticker['quoteVolume']))

    if (ticker['bid'] > ticker['ask'])
        log (this.id, symbol, 'ticker', 'bid is greater than ask!')

    return ticker;
}

let testExchangeSymbolOrderbook = async (exchange, symbol) => {
    log (exchange.id.green, symbol.green, 'fetching order book...')
    let orderbook = await exchange.fetchOrderBook (symbol)
    log (exchange.id.green, symbol.green,
        orderbook['datetime'],
        'bid: '       + ((orderbook.bids.length > 0) ? human_value (orderbook.bids[0][0]) : 'N/A'),
        'bidVolume: ' + ((orderbook.bids.length > 0) ? human_value (orderbook.bids[0][1]) : 'N/A'),
        'ask: '       + ((orderbook.asks.length > 0) ? human_value (orderbook.asks[0][0]) : 'N/A'),
        'askVolume: ' + ((orderbook.asks.length > 0) ? human_value (orderbook.asks[0][1]) : 'N/A'))

    let bids = orderbook.bids
    if (bids.length > 1) {
        let first = 0
        let last = bids.length - 1
        if (bids[first][0] < bids[last][0])
            log (exchange.id, symbol, 'bids reversed!'.red.bright, bids[first][0], bids[last][0])
        else if (bids[first][0] > bids[last][0])
            log (exchange.id.green, symbol.green, 'bids ok')
    }
    let asks = orderbook.asks
    if (asks.length > 1) {
        let first = 0
        let last = asks.length - 1
        if (asks[first][0] > asks[last][0])
            log (exchange.id, symbol, 'asks reversed!'.red.bright, asks[first][0], asks[last][0])
        else if (asks[first][0] < asks[last][0])
            log (exchange.id.green, symbol.green, 'asks ok')
    }

    if (bids.length && asks.length)
        if (bids[0][0] > asks[0][0])
            log (this.id, symbol, 'order book', 'bid is greater than ask!'.red.bright)

    return orderbook
}

//-----------------------------------------------------------------------------

let testExchangeSymbolTrades = async (exchange, symbol) => {
    log (exchange.id.green, symbol.green, 'fetching trades...')
    let trades = await exchange.fetchTrades (symbol)
    log (exchange.id.green, symbol.green, 'fetched', Object.values (trades).length.toString ().green, 'trades')
    return trades
}

//-----------------------------------------------------------------------------

let testExchangeSymbol = async (exchange, symbol) => {

    await testExchangeSymbolTicker (exchange, symbol)

    if (exchange.hasFetchTickers) {

        log (exchange.id.green, 'fetching all tickers at once...')
        let tickers = await exchange.fetchTickers ()
        log (exchange.id.green, 'fetched', Object.keys (tickers).length.toString ().green, 'tickers')

    } else {

        log (exchange.id.green, 'fetching all tickers at once not supported')
    }

    if (exchange.hasFetchOHLCV) {

        try {

            log (exchange.id.green, symbol.green, 'fetching OHLCV...')
            let ohlcv = await exchange.fetchOHLCV (symbol)
            log (exchange.id.green, symbol.green, 'fetched', Object.keys (ohlcv).length.toString ().green, 'OHLCVs')

        } catch (e) {

            if (e instanceof ccxt.ExchangeError) {
                warn (exchange.id, '[Exchange Error] ' + e.message)
            } else if (e instanceof ccxt.NotSupported) {
                warn (exchange.id, '[Not Supported] ' + e.message)
            } else {
                throw e;
            }
        }

    } else {

        log (exchange.id.green, 'fetching OHLCV not supported')
    }

    if (exchange.id == 'coinmarketcap') {

        log (await exchange.fetchTickers ());
        log (await exchange.fetchGlobal ());

    } else {

        await testExchangeSymbolOrderbook (exchange, symbol)

        try {

            await testExchangeSymbolTrades (exchange, symbol)

        } catch (e) {

            if (e instanceof ccxt.ExchangeError) {
                warn (exchange.id, '[Exchange Error] ' + e.message)
            } else if (e instanceof ccxt.NotSupported) {
                warn (exchange.id, '[Not Supported] ' + e.message)
            } else {
                throw e;
            }
        }
    }
}

//-----------------------------------------------------------------------------

let testExchangeFetchOrders = async (exchange) => {

    try {

        log (exchange.id.green, 'fetching orders...')
        let orders = await exchange.fetchOrders ()
        log (exchange.id.green, 'fetched', orders.length.toString ().green, 'orders')

    } catch (e) {

        if (e instanceof ccxt.ExchangeError) {
            warn (exchange.id, '[Exchange Error] ' + e.message)
        } else if (e instanceof ccxt.NotSupported) {
            warn (exchange.id, '[Not Supported] ' + e.message)
        } else {
            throw e;
        }
    }
}

//-----------------------------------------------------------------------------

let testExchangeBalance = async (exchange, symbol) => {

    log (exchange.id.green, 'fetching balance...')
    let balance = await exchange.fetchBalance ()

    let currencies = [
        'USD',
        'CNY',
        'EUR',
        'BTC',
        'ETH',
        'JPY',
        'LTC',
        'DASH',
        'DOGE',
        'UAH',
        'RUB',
    ]

    if ('info' in balance) {

        let result = currencies
            .filter (currency => (currency in balance) &&
                (typeof balance[currency]['total'] != 'undefined'))

        if (result.length > 0) {
            result = result.map (currency => currency + ': ' + human_value (balance[currency]['total']))
            if (exchange.currencies.length > result.length)
                result = result.join (', ') + ' + more...'
            else
                result = result.join (', ')

        } else {

            result = 'zero balance'
        }

        log (exchange.id.green, result)

    } else {

        log (exchange.id.green, exchange.omit (balance, 'info'))
    }
}

//-----------------------------------------------------------------------------

let loadExchange = async exchange => {

    let markets  = await exchange.loadMarkets ()

    let symbols = [
        'BTC/CNY',
        'BTC/USD',
        'BTC/EUR',
        'BTC/ETH',
        'ETH/BTC',
        'BTC/JPY',
        'ETH/EUR',
        'ETH/JPY',
        'ETH/CNY',
        'LTC/CNY',
        'DASH/BTC',
        'DOGE/BTC',
        'BTC/AUD',
        'BTC/PLN',
        'USD/SLL',
        'BTC/RUB',
        'BTC/UAH',
        'LTC/BTC',
    ]

    let result = exchange.symbols.filter (symbol => symbols.indexOf (symbol) >= 0)
    if (result.length > 0)
        if (exchange.symbols.length > result.length)
            result = result.join (', ') + ' + more...'
        else
            result = result.join (', ')
    log (exchange.id.green, exchange.symbols.length.toString ().bright.green, 'symbols', result)
}

//-----------------------------------------------------------------------------

let testExchange = async exchange => {

    await loadExchange (exchange)

    let delay = exchange.rateLimit
    let symbol = exchange.symbols[0]
    let symbols = [
        'BTC/USD',
        'BTC/CNY',
        'BTC/EUR',
        'BTC/ETH',
        'ETH/BTC',
        'BTC/JPY',
        'LTC/BTC',
    ]
    for (let s in symbols) {
        if (exchange.symbols.includes (symbols[s])) {
            symbol = symbols[s]
            break
        }
    }

    log.green ('SYMBOL:', symbol)
    if ((symbol.indexOf ('.d') < 0)) {
        await testExchangeSymbol (exchange, symbol)
    }

    if (!exchange.apiKey || (exchange.apiKey.length < 1))
        return true

    await testExchangeBalance (exchange)

    if (exchange.hasFetchOrders) {

            await testExchangeFetchOrders (exchange);

    } else {

        log (exchange.id.green, 'fetching orders not supported')
    }

    // try {
    //     let marketSellOrder =
    //         await exchange.createMarketSellOrder (exchange.symbols[0], 1)
    //     console.log (exchange.id, 'ok', marketSellOrder)
    // } catch (e) {
    //     console.log (exchange.id, 'error', 'market sell', e)
    // }

    // try {
    //     let marketBuyOrder = await exchange.createMarketBuyOrder (exchange.symbols[0], 1)
    //     console.log (exchange.id, 'ok', marketBuyOrder)
    // } catch (e) {
    //     console.log (exchange.id, 'error', 'market buy', e)
    // }

    // try {
    //     let limitSellOrder = await exchange.createLimitSellOrder (exchange.symbols[0], 1, 3000)
    //     console.log (exchange.id, 'ok', limitSellOrder)
    // } catch (e) {
    //     console.log (exchange.id, 'error', 'limit sell', e)
    // }

    // try {
    //     let limitBuyOrder = await exchange.createLimitBuyOrder (exchange.symbols[0], 1, 3000)
    //     console.log (exchange.id, 'ok', limitBuyOrder)
    // } catch (e) {
    //     console.log (exchange.id, 'error', 'limit buy', e)
    // }

}

//-----------------------------------------------------------------------------

let printExchangesTable = function () {
    let astable = asTable.configure ({ delimiter: ' | ' })
    console.log (astable (Object.values (exchanges).map (exchange => {
        let website = Array.isArray (exchange.urls.www) ?
            exchange.urls.www[0] :
            exchange.urls.www
        let countries = Array.isArray (exchange.countries) ?
            exchange.countries.map (countryName).join (', ') :
            countryName (exchange.countries)
        let doc = Array.isArray (exchange.urls.doc) ?
            exchange.urls.doc[0] :
            exchange.urls.doc
        return {
            'id':        exchange.id,
            'name':      exchange.name,
            'countries': countries,
        }
    })))
}

//-----------------------------------------------------------------------------

let tryAllProxies = async function (exchange, proxies) {

    let currentProxy = 0
    let maxRetries   = proxies.length

    // a special case for ccex
    if (exchange.id == 'ccex')
        currentProxy = 1

    for (let numRetries = 0; numRetries < maxRetries; numRetries++) {

        try {

            exchange.proxy = proxies[currentProxy]
            await testExchange (exchange)
            break

        } catch (e) {

            currentProxy = ++currentProxy % proxies.length
            if (e instanceof ccxt.DDoSProtection) {
                warn (exchange.id, '[DDoS Protection] ' + e.message)
            } else if (e instanceof ccxt.RequestTimeout) {
                warn (exchange.id, '[Request Timeout] ' + e.message)
            } else if (e instanceof ccxt.AuthenticationError) {
                warn (exchange.id, '[Authentication Error] ' + e.message)
            } else if (e instanceof ccxt.ExchangeNotAvailable) {
                warn (exchange.id, '[Exchange Not Available] ' + e.message)
            } else if (e instanceof ccxt.NotSupported) {
                warn (exchange.id, '[Not Supported] ' + e.message)
            } else if (e instanceof ccxt.ExchangeError) {
                warn (exchange.id, '[Exchange Error] ' + e.message)
            } else {
                throw e;
            }
        }
    }
}

//-----------------------------------------------------------------------------

;(async function test () {

    // printExchangesTable ()

    if (exchangeSymbol) {

        await loadExchange (exchange)
        await (exchangeSymbol == 'balance') ?
            testExchangeBalance (exchange) :
            testExchangeSymbol (exchange, exchangeSymbol)

    } else {

        await tryAllProxies (exchange, proxies)
    }

    process.exit ()

}) ()

<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-17 11:15:28<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>"use strict";
{
  const sg = require('./lib.js');
  const navigable = new Set([
    'A',
    'BUTTON'
  ]);
  const test = {
    run
  };

  module.exports = test;

  Object.assign( self, { test } );

  // one possible test
  function validate( must_find, found ) {
    found = new Set(found);
    const okay = [...must_find].every( el => found.has( el ) );
    return okay;
  }

  // helpers

    function inc( el ) {
      const n = parseFloat( el.innerText );
      el.innerText = n + 1;
    }

    function zero( el ) {
      el.innerText = 0;
    }
  // we could also make another test that tests if it
  // somehow not too general
  function run() {
    console.log("Running tests...");
    const set = new Set();
    let found = [];
    document.addEventListener('click', e => {
      if ( navigable.has( e.target.tagName ) ) {
        e.preventDefault();
      }
    });
    document.addEventListener('mouseup', e => {
      if( e.target.id == 'generalize' ) {
        const negation = negate.checked;
        console.log('neg', negation);
        const sel = sg.generalize( [...set], { negation } );
        generalized_selector.innerText = sel || 'n/a';
        found.forEach( el => {
          el.style.filter = "none";
          el.style.background = "none";
        });
        found = Array.from( document.querySelectorAll(sel) );
        found_count.innerText = found.length;
        const result = validate( set, found );
        console.log(" Test result?", result );
        console.log( sel, set, found );
        Array.from( set ).forEach( el => {
          el.style.outline = "3px dashed lime";
        });
        found.forEach( el => {
          el.style.filter = "sepia(1)";
          el.style.background = "lime";
        });
      } else if ( e.target.id == 'clear' ) {
        Array.from( set ).forEach( el => {
          el.style.outline = "none";
        });
        found.forEach( el => {
          el.style.filter = "none";
          el.style.background = "none";
        });
        set.clear();
        found_count.innerText = 'n/a';
        zero( positive_example_count );
        zero( negative_example_count );
        generalized_selector.innerText = 'n/a';
      } else {
        if ( e.target.matches( 'article#testcontrols, article#testcontrols *' ) ) {
          return;
        }
        set.add( e.target );
        if ( negate.checked ) {
          inc( negative_example_count );
        } else {
          inc( positive_example_count );
        }
        console.log(e.target.dataset.outline);
        e.target.style.outline = "2px solid lime";
      }
    });
  }
}
<commit_msg>Fixed a few bugs in the testing interface<commit_after>"use strict";
{
  const sg = require('./lib.js');
  const navigable = new Set([
    'A',
    'BUTTON'
  ]);
  const test = {
    run
  };

  module.exports = test;

  Object.assign( self, { test } );

  // one possible test
  function validate( must_find, found ) {
    found = new Set(found);
    const okay = [...must_find].every( el => found.has( el ) );
    return okay;
  }

  // helpers

    function inc( el ) {
      const n = parseFloat( el.innerText );
      el.innerText = n + 1;
    }

    function zero( el ) {
      el.innerText = 0;
    }
  // we could also make another test that tests if it
  // somehow not too general
  function run() {
    console.log("Running tests...");
    const set = new Set();
    let found = [];
    document.addEventListener('click', e => {
      if ( navigable.has( e.target.tagName ) ) {
        e.preventDefault();
      }
    });
    document.addEventListener('mouseup', e => {
      if( e.target.id == 'generalize' ) {
        const negation = negate.checked;
        console.log('neg', negation);
        const sel = sg.generalize( [...set], { negation } );
        generalized_selector.innerText = sel || 'n/a';
        found.forEach( el => {
          el.style.filter = "none";
          el.style.background = "none";
        });
        found = Array.from( document.querySelectorAll(sel) );
        found_count.innerText = found.length;
        const result = validate( set, found );
        console.log(" Test result?", result );
        console.log( sel, set, found );
        Array.from( set ).forEach( el => {
          el.style.outline = "3px dashed lime";
        });
        found.forEach( el => {
          el.style.filter = "sepia(1)";
          el.style.background = "lime";
        });
      } else if ( e.target.id == 'clear' ) {
        Array.from( set ).forEach( el => {
          el.style.outline = "none";
        });
        found.forEach( el => {
          el.style.filter = "none";
          el.style.background = "none";
        });
        set.clear();
        found_count.innerText = 'n/a';
        zero( positive_example_count );
        zero( negative_example_count );
        generalized_selector.innerText = 'n/a';
      } else {
        if ( !( e.target instanceof HTMLElement ) || e.target.matches( 'article#testcontrols, article#testcontrols *' ) ) {
          return;
        }
        set.add( e.target );
        if ( negate.checked ) {
          inc( negative_example_count );
        } else {
          inc( positive_example_count );
        }
        if ( e.target.style ) {
          e.target.style.outline = "2px solid lime";
        }
      }
    });
  }
}
<|endoftext|>


<commit_before>
console.log("test123")

console.log("helloWorld")<commit_msg>add semicolon<commit_after>
console.log("test123");

console.log("helloWorld")<|endoftext|>


<commit_before>/*eslint-env mocha*/
"use strict";

var assert = require("assert");
var _ = require("lodash");
var sut = require("./index");
var lib = require("./lib");
var quick_check = function (describe_string, it_string, it_func) {
  return describe(describe_string, function () {
    return _.times(500, function (n) {
      n = n + 1;
      return it(it_string + " (try #" + n + ")", function () { return it_func; });
    });
  });
};

describe("javascript-commitment", function () {
  describe("lib.to_number", function () {
    it("converts a String to a Number", function () {
      assert.strictEqual(lib.to_number("10"), 10);
      assert.strictEqual(lib.to_number("45682"), 45682);
    });
  });
  describe("lib.random_integer", function () {
    quick_check("produces a random number x", "with 93 < x < 100",
    function () {
      var result = lib.random_integer(94, 99);
      assert.strictEqual((result < 100), true);
      assert.strictEqual((result > 93), true);
    });
  });
  describe("lib.replace_xnumx", function () {
    quick_check("replaces XNUMX with a random integer x", "with 0 < x < 1000",
    function () {
      var result = parseInt(lib.replace_xnumx(null, ""), 10);
      assert.strictEqual((result < 1000), true);
      assert.strictEqual((result > 0), true);
    });
    quick_check("replaces XNUM3X with a random integer x", "with 0 < x < 4",
    function () {
      var result = parseInt(lib.replace_xnumx(null, "3"), 10);
      assert.strictEqual((result < 4), true);
      assert.strictEqual((result > 0), true);
    });
    quick_check("replaces XNUM,5X with a random integer x", "with 0 < x < 6",
    function () {
      var result = parseInt(lib.replace_xnumx(null, ",5"), 10);
      assert.strictEqual((result < 6), true);
      assert.strictEqual((result > 0), true);
    });
    quick_check("replaces XNUM600,X with a random integer x", "with 599 < x < 1000",
    function () {
      var result = parseInt(lib.replace_xnumx(null, "600,"), 10);
      assert.strictEqual((result < 1000), true);
      assert.strictEqual((result > 599), true);
    });
    quick_check("replaces XNUM600,670X with a random integer x", "with 599 < x < 671",
    function () {
      var result = parseInt(lib.replace_xnumx(null, "600,670"), 10);
      assert.strictEqual((result < 671), true);
      assert.strictEqual((result > 599), true);
    });
  });
  quick_check("whatThe", "returns a random message and its link", function () {
    var response = sut.whatThe();
    var message = response.message;
    var permalink = response.permalink;
    assert.strictEqual(_.isString(message), true);
    assert.strictEqual(_.isString(permalink), true);
    assert.strictEqual(permalink.indexOf("http://whatthecommit.com/"), 0);
    assert.strictEqual(message.indexOf("XNAMEX"), -1);
    assert.strictEqual(message.indexOf("XUPPERNAMEX"), -1);
    assert.strictEqual(message.indexOf("XLOWERNAMEX"), -1);
    assert.strictEqual(message.match(/XNUM([0-9,]*)X/g), null);
  });
});
<commit_msg>test(quick_check): add sanity check on number of tests executed<commit_after>/*eslint-env mocha*/
"use strict";

var assert = require("assert");
var _ = require("lodash");
var sut = require("./index");
var lib = require("./lib");
var quick_check = function (describe_string, it_string, it_func) {
  return describe(describe_string, function () {
    var times = 500;
    var counter;
    before(function () {
      counter = 0;
    });
    after(function () {
      assert.strictEqual(counter, times);
    });
    return _.times(times, function (n) {
      n = n + 1;
      return it(it_string + " (try #" + n + ")", function () {
        it_func();
        counter = counter + 1;
      });
    });
  });
};

describe("javascript-commitment", function () {
  describe("lib.to_number", function () {
    it("converts a String to a Number", function () {
      assert.strictEqual(lib.to_number("10"), 10);
      assert.strictEqual(lib.to_number("45682"), 45682);
    });
  });
  describe("lib.random_integer", function () {
    quick_check("produces a random number x", "with 93 < x < 100",
    function () {
      var result = lib.random_integer(94, 99);
      assert.strictEqual((result < 100), true);
      assert.strictEqual((result > 93), true);
    });
  });
  describe("lib.replace_xnumx", function () {
    quick_check("replaces XNUMX with a random integer x", "with 0 < x < 1000",
    function () {
      var result = parseInt(lib.replace_xnumx(null, ""), 10);
      assert.strictEqual((result < 1000), true);
      assert.strictEqual((result > 0), true);
    });
    quick_check("replaces XNUM3X with a random integer x", "with 0 < x < 4",
    function () {
      var result = parseInt(lib.replace_xnumx(null, "3"), 10);
      assert.strictEqual((result < 4), true);
      assert.strictEqual((result > 0), true);
    });
    quick_check("replaces XNUM,5X with a random integer x", "with 0 < x < 6",
    function () {
      var result = parseInt(lib.replace_xnumx(null, ",5"), 10);
      assert.strictEqual((result < 6), true);
      assert.strictEqual((result > 0), true);
    });
    quick_check("replaces XNUM600,X with a random integer x", "with 599 < x < 1000",
    function () {
      var result = parseInt(lib.replace_xnumx(null, "600,"), 10);
      assert.strictEqual((result < 1000), true);
      assert.strictEqual((result > 599), true);
    });
    quick_check("replaces XNUM600,670X with a random integer x", "with 599 < x < 671",
    function () {
      var result = parseInt(lib.replace_xnumx(null, "600,670"), 10);
      assert.strictEqual((result < 671), true);
      assert.strictEqual((result > 599), true);
    });
  });
  quick_check("whatThe", "returns a random message and its link", function () {
    var response = sut.whatThe();
    var message = response.message;
    var permalink = response.permalink;
    assert.strictEqual(_.isString(message), true);
    assert.strictEqual(_.isString(permalink), true);
    assert.strictEqual(permalink.indexOf("http://whatthecommit.com/"), 0);
    assert.strictEqual(message.indexOf("XNAMEX"), -1);
    assert.strictEqual(message.indexOf("XUPPERNAMEX"), -1);
    assert.strictEqual(message.indexOf("XLOWERNAMEX"), -1);
    assert.strictEqual(message.match(/XNUM([0-9,]*)X/g), null);
  });
});
<|endoftext|>


<commit_before>(function(factory){
  if (typeof define !== "undefined" && define.cmd) {
    define(function(require, exports, module){
      var TouchObject = require("touch");
      factory(TouchObject);
    });
  } else {
    factory(TouchObject);
  }
}(function(TouchObject){

  window.onload = function(){
    var testDiv = document.getElementById("testDiv");
    var divObj = new TouchObject(testDiv);
    document.querySelector("#touchType").innerHTML = divObj.touchType;

    divObj.addEventListener("swipeStart", function(e){
      document.querySelector("#evtName").innerHTML = "swipeStart";
      printEvent(e);
    });
    divObj.addEventListener("swipeLeft", function(e){
      document.querySelector("#evtName").innerHTML = "swipeLeft";
    });
    divObj.addEventListener("swipeRight", function(e){
      document.querySelector("#evtName").innerHTML = "swipeRight";
    })

    divObj.addEventListener("swipeUp", function(e){
      document.querySelector("#evtName").innerHTML = "swipeUp";
    })
    divObj.addEventListener("swipeDown", function(e){
      document.querySelector("#evtName").innerHTML = "swipeDown";
    })

    divObj.addEventListener("swipeProgress", function(e) {
      document.querySelector("#evtName").innerHTML = "swipeProgress";
      printEvent(e);
    });
    divObj.addEventListener("swipeCancel", function(e) {
      document.querySelector("#evtName").innerHTML = "swipeCancel";
    });

    divObj.addEventListener("tap", function(e) {
      document.querySelector("#evtName").innerHTML = "tap";
      printEvent(e);
    });

    function printEvent(event) {
      document.querySelector("#movedX").innerHTML = (event.detail && typeof event.detail.movedPageX !== "undefined") ? parseInt(event.detail.movedPageX) + "px" : " ";
      document.querySelector("#movedY").innerHTML = (event.detail && typeof event.detail.movedPageY !== "undefined") ? parseInt(event.detail.movedPageY) + "px" : " ";
      document.querySelector("#clientX").innerHTML = (typeof event.clientX !== "undefined") ? parseInt(event.clientX) + "px" : " ";
      document.querySelector("#clientY").innerHTML = (typeof event.clientY !== "undefined") ? parseInt(event.clientY) + "px" : " ";
    }
    /*
    setTimeout(function(){
      divObj.dispose();
      log("dispose");
      setTimeout(function(){
        divObj.bindEvents();
        log("Restarted.");
      }, 5000);
    }, 6000);
    */
  };
}));<commit_msg>Update test.js<commit_after>(function(factory){
  if (typeof define !== "undefined" && define.cmd) {
    define(function(require, exports, module){
      var TouchObject = require("touch");
      factory(TouchObject);
    });
  } else {
    factory(TouchObject);
  }
}(function(TouchObject){

  window.onload = function(){
    var testDiv = document.getElementById("testDiv");
    var divObj = new TouchObject(testDiv);
    document.querySelector("#touchType").innerHTML = divObj.touchType;

    divObj.addEventListener("swipeStart", function(e){
      document.querySelector("#evtName").innerHTML = "swipeStart";
      printEvent(e);
    });
    divObj.addEventListener("swipeLeft", function(e){
      document.querySelector("#evtName").innerHTML = "swipeLeft";
    });
    divObj.addEventListener("swipeRight", function(e){
      document.querySelector("#evtName").innerHTML = "swipeRight";
    })

    divObj.addEventListener("swipeUp", function(e){
      document.querySelector("#evtName").innerHTML = "swipeUp";
    })
    divObj.addEventListener("swipeDown", function(e){
      document.querySelector("#evtName").innerHTML = "swipeDown";
    })

    divObj.addEventListener("swipeProgress", function(e) {
      document.querySelector("#evtName").innerHTML = "swipeProgress";
      printEvent(e);
    });
    divObj.addEventListener("swipeCancel", function(e) {
      document.querySelector("#evtName").innerHTML = "swipeCancel";
      printEvent(e);
    });

    divObj.addEventListener("tap", function(e) {
      document.querySelector("#evtName").innerHTML = "tap";
      printEvent(e);
    });

    function printEvent(event) {
      document.querySelector("#movedX").innerHTML = (event.detail && typeof event.detail.movedPageX !== "undefined") ? parseInt(event.detail.movedPageX) + "px" : " ";
      document.querySelector("#movedY").innerHTML = (event.detail && typeof event.detail.movedPageY !== "undefined") ? parseInt(event.detail.movedPageY) + "px" : " ";
      document.querySelector("#clientX").innerHTML = (typeof event.clientX !== "undefined") ? parseInt(event.clientX) + "px" : " ";
      document.querySelector("#clientY").innerHTML = (typeof event.clientY !== "undefined") ? parseInt(event.clientY) + "px" : " ";
    }
    /*
    setTimeout(function(){
      divObj.dispose();
      log("dispose");
      setTimeout(function(){
        divObj.bindEvents();
        log("Restarted.");
      }, 5000);
    }, 6000);
    */
  };
}));<|endoftext|>


<commit_before>var assert = require("assert")

console.log("1..4")

function test_local(swf) {
  var stdin_line = "hello"
  var exit_code = 123

  var timeout = setTimeout(function () {
    test(swf, function () {
      assert.fail("timeout")
    })
  }, 5000)

  require("child_process").exec([
    "echo", stdin_line, "|",
    "bin/flashplayer-stdio", swf, exit_code
  ].join(" "), function (error, stdout, stderr) {
    clearTimeout(timeout)
    test(swf, function () {
      assert.equal(stdout, stdin_line + "\n")
      assert.equal(stderr, stdin_line.toUpperCase() + "\n")
      assert.equal(error.code, exit_code)
    })
  })
}

function test_web(swf, port) {
  var flashplayer, timeout

  require("http").createServer(function () {
    test_passed(swf)
    flashplayer.kill()
    clearTimeout(timeout)
    this.close()
  }).listen(port, function () {
    flashplayer = start_flashplayer(swf, { port: port })
    timeout = setTimeout(function () {
      test(swf, function () {
        assert.fail("timeout")
      })
    }, 5000)
  })
}

function start_flashplayer(swf, parameters) {
  var executable = "/Applications/Flash Player Debugger.app/" +
    "Contents/MacOS/Flash Player Debugger"

  return require("child_process").spawn(executable, [
    swf + "?" + stringify_query_parameters(parameters || {})
  ])
}

function stringify_query_parameters(parameters) {
  return Object.keys(parameters || {}).map(function (name) {
    return name + "=" + parameters[name]
  }).join("&")
}

//----------------------------------------------------------

function test(name, callback) {
  try {
    callback()
    test_passed(name)
  } catch (error) {
    test_failed(name)
    throw error
  }
}

function test_passed(name) {
  console.log("ok - " + name)
}

function test_failed(name) {
  console.log("not ok - " + name)
}

//----------------------------------------------------------

test_web("test_web_flash.swf", 56788)
test_web("test_web_flex.swf", 56789)

test_local("test_local_flash.swf")
test_local("test_local_flex.swf")
<commit_msg>Refactor test.js.<commit_after>var assert = require("assert")

console.log("1..4")

function test_local(swf) {
  var stdin_line = "hello"
  var exit_code = 123

  with_timeout(
    function (callback) {
      require("child_process").exec([
        "echo", stdin_line, "|",
        "bin/flashplayer-stdio", swf, exit_code
      ].join(" "), callback)
    }, function (error, stdout, stderr) {
      test(swf, function () {
        assert.equal(stdout, stdin_line + "\n")
        assert.equal(stderr, stdin_line.toUpperCase() + "\n")
        assert.equal(error.code, exit_code)
      })
    }, function () {
      test(swf, function () {
        assert.fail("timeout")
      })
    }
  )
}

function test_web(swf, port) {
  var flashplayer

  with_timeout(
    function (callback) {
      require("http").createServer(function () {
        flashplayer.kill()
        this.close()
        callback()
      }).listen(port, function () {
        flashplayer = start_flashplayer(swf, { port: port })
      })
    }, function () {
      test_passed(swf)
    }, function () {
      test(swf, function () {
        assert.fail("timeout")
      })
    }
  )
}

function start_flashplayer(swf, parameters) {
  var executable = "/Applications/Flash Player Debugger.app/" +
    "Contents/MacOS/Flash Player Debugger"

  return require("child_process").spawn(executable, [
    swf + "?" + stringify_query_parameters(parameters || {})
  ])
}

function stringify_query_parameters(parameters) {
  return Object.keys(parameters || {}).map(function (name) {
    return name + "=" + parameters[name]
  }).join("&")
}

function with_timeout(body, callback, errback) {
  var timeout = setTimeout(function () {
    errback()
    callback = null
  }, 5000)

  body(function () {
    clearTimeout(timeout)

    if (callback) {
      callback.apply(null, arguments)
    }
  })
}

//----------------------------------------------------------

function test(name, callback) {
  try {
    callback()
    test_passed(name)
  } catch (error) {
    test_failed(name)
    throw error
  }
}

function test_passed(name) {
  console.log("ok - " + name)
}

function test_failed(name) {
  console.log("not ok - " + name)
}

//----------------------------------------------------------

test_web("test_web_flash.swf", 56788)
test_web("test_web_flex.swf", 56789)

test_local("test_local_flash.swf")
test_local("test_local_flex.swf")
<|endoftext|>


<commit_before>var resmetrylib=require('./index.js');
var host='mqtt://localhost:1883';
//Standard settings available in npm package mqtt
var settings={
  protocolId: 'MQIsdp',
  protocolVersion: 3
};
var resmetry= new resmetrylib();
//Connect to mqtt server with given credentials
resmetry.connect(host,settings);
//Get mqtt client for advanced operations, Refer npm package mqtt for more information
//However message event is handled by the package
var mqtt=resmetry.getMQTTClient();
mqtt.on('connect',function(){
  console.log('Connected');
})
//Making a request to topic 'request' with message 'send me details' whose expected result goes to topic response with options
var options={qos:2};
//Options are standard options available for publishing in npm package mqtt
resmetry.request('request','send me details',options,'response',function(err,response){
  console.log('Response:'+response);
});
<commit_msg>Updated test<commit_after>var resmetrylib=require('./index.js');
var host='mqtt://localhost';
//Standard settings available in npm package mqtt
var settings={
  protocolId: 'MQIsdp',
  protocolVersion: 3
};
var resmetry= new resmetrylib();
//Connect to mqtt server with given credentials
resmetry.connect(host,settings);
//Get mqtt client for advanced operations, Refer npm package mqtt for more information
//However message event is handled by the package
var mqtt=resmetry.getMQTTClient();
mqtt.on('connect',function(){
  console.log('Connected');
})
//Making a request to topic 'request' with message 'send me details' whose expected result goes to topic response with options
var options={qos:2};
//Options are standard options available for publishing in npm package mqtt
resmetry.request('request','send me details',options,'response',function(err,response){
  console.log('Response:'+response);
});
<|endoftext|>


<commit_before>var util = require ('util');

// Setup
// $ env PIWIK_URL= PIWIK_TOKEN= PIWIK_SITEID= npm test
var url = process.env.PIWIK_URL || null;
var token = process.env.PIWIK_TOKEN || null;
var siteId = process.env.PIWIK_SITEID || null;
var timeout = process.env.PIWIK_TIMEOUT || 5000;

var piwik = require ('./') .setup (url, token, timeout);

// handle exits
var errors = 0;
process.on ('exit', function () {
  if (errors === 0) {
    console.log ('\n\033[1mDONE, no errors.\033[0m\n');
    process.exit (0);
  } else {
    console.log ('\n\033[1mFAIL, '+ errors +' error'+ (errors > 1 ? 's' : '') +' occurred!\033[0m\n');
    process.exit (1);
  }
});

// prevent errors from killing the process
process.on ('uncaughtException', function (err) {
  console.log ();
  console.error (err.stack);
  console.trace ();
  console.log ();
  errors++;
});

// Queue to prevent flooding
var queue = [];
var next = 0;

function doNext () {
  next++;
  if (queue [next]) {
    queue [next] ();
  }
}

// doTest( passErr, 'methods', [
//   ['feeds', typeof feeds === 'object']
// ])
function doTest (err, label, tests) {
  if (err instanceof Error) {
    console.error (label +': \033[1m\033[31mERROR\033[0m\n');
    console.error (util.inspect (err, false, 10, true));
    console.log ();
    console.error (err.stack);
    console.log ();
    errors++;
  } else {
    var testErrors = [];
    for (var i = 0; i < tests.length; i++) {
      if (tests [i] [1] !== true) {
        testErrors.push (tests [i] [0]);
        errors++;
      }
    }

    if(testErrors.length === 0) {
      console.log (label +': \033[1m\033[32mok\033[0m');
    } else {
      console.error (label +': \033[1m\033[31mfailed\033[0m ('+ testErrors.join (', ') +')');
    }
  }

  doNext ();
}

// ! API access
queue.push (function () {
  piwik.api (
    {method: 'API.getPiwikVersion'},
    function (err) {
      if (err) {
        console.log ('API access: failed ('+ err.message +')');
        console.log (err.stack);
        errors++;
        process.exit (1);
      } else {
        console.log ('API access: \033[1m\033[32mok\033[0m');
        doNext ();
      }
    }
  );
});

// ! Track one
queue.push (function () {
  piwik.track (
    {
      idsite: siteId,
      url: 'https://www.npmjs.com/package/piwik',
      cvar: {'1': ['node test', process.version]}
    },
    function (err, data) {
      doTest (err, 'track one', [
        ['data type', typeof data === 'object'],
        ['data.status', data && data.status === 'success'],
        ['data.tracked', data && data.tracked === 1]
      ]);
    }
  );
});

// ! Track multi
queue.push (function () {
  piwik.track (
    [
      {
        idsite: siteId,
        url: 'https://www.npmjs.com/package/piwik',
        cvar: {'1': ['node test', process.version]}
      },
      {
        idsite: siteId,
        url: 'https://github.com/fvdm/nodejs-piwik',
        cvar: {'1': ['node test', process.version]}
      }
    ],
    function (err, data) {
      doTest (err, 'track multi', [
        ['data type', typeof data === 'object'],
        ['data.status', data && data.status === 'success'],
        ['data.tracked', data && data.tracked === 2]
      ]);
    }
  );
});

// ! API
queue.push (function () {
  piwik.api (
    {
      method: 'Actions.getPageUrls',
      idSite: siteId,
      period: 'day',
      date: 'year'
    },
    function (err, data) {
      doTest (err, 'api', [
        ['data type', data instanceof Array],
        ['data length', data && data.length >= 1],
        ['item type', data && data [0] instanceof Object],
        ['item label', data && data [0] && typeof data [0] .label === 'string']
      ]);
    }
  );
});

// Start the tests
console.log ('Running tests...\n');
queue [0] ();
<commit_msg>Test: fixed date range error<commit_after>var util = require ('util');

// Setup
// $ env PIWIK_URL= PIWIK_TOKEN= PIWIK_SITEID= npm test
var url = process.env.PIWIK_URL || null;
var token = process.env.PIWIK_TOKEN || null;
var siteId = process.env.PIWIK_SITEID || null;
var timeout = process.env.PIWIK_TIMEOUT || 5000;

var piwik = require ('./') .setup (url, token, timeout);

// handle exits
var errors = 0;
process.on ('exit', function () {
  if (errors === 0) {
    console.log ('\n\033[1mDONE, no errors.\033[0m\n');
    process.exit (0);
  } else {
    console.log ('\n\033[1mFAIL, '+ errors +' error'+ (errors > 1 ? 's' : '') +' occurred!\033[0m\n');
    process.exit (1);
  }
});

// prevent errors from killing the process
process.on ('uncaughtException', function (err) {
  console.log ();
  console.error (err.stack);
  console.trace ();
  console.log ();
  errors++;
});

// Queue to prevent flooding
var queue = [];
var next = 0;

function doNext () {
  next++;
  if (queue [next]) {
    queue [next] ();
  }
}

// doTest( passErr, 'methods', [
//   ['feeds', typeof feeds === 'object']
// ])
function doTest (err, label, tests) {
  if (err instanceof Error) {
    console.error (label +': \033[1m\033[31mERROR\033[0m\n');
    console.error (util.inspect (err, false, 10, true));
    console.log ();
    console.error (err.stack);
    console.log ();
    errors++;
  } else {
    var testErrors = [];
    for (var i = 0; i < tests.length; i++) {
      if (tests [i] [1] !== true) {
        testErrors.push (tests [i] [0]);
        errors++;
      }
    }

    if(testErrors.length === 0) {
      console.log (label +': \033[1m\033[32mok\033[0m');
    } else {
      console.error (label +': \033[1m\033[31mfailed\033[0m ('+ testErrors.join (', ') +')');
    }
  }

  doNext ();
}

// ! API access
queue.push (function () {
  piwik.api (
    {method: 'API.getPiwikVersion'},
    function (err) {
      if (err) {
        console.log ('API access: failed ('+ err.message +')');
        console.log (err.stack);
        errors++;
        process.exit (1);
      } else {
        console.log ('API access: \033[1m\033[32mok\033[0m');
        doNext ();
      }
    }
  );
});

// ! Track one
queue.push (function () {
  piwik.track (
    {
      idsite: siteId,
      url: 'https://www.npmjs.com/package/piwik',
      cvar: {'1': ['node test', process.version]}
    },
    function (err, data) {
      doTest (err, 'track one', [
        ['data type', typeof data === 'object'],
        ['data.status', data && data.status === 'success'],
        ['data.tracked', data && data.tracked === 1]
      ]);
    }
  );
});

// ! Track multi
queue.push (function () {
  piwik.track (
    [
      {
        idsite: siteId,
        url: 'https://www.npmjs.com/package/piwik',
        cvar: {'1': ['node test', process.version]}
      },
      {
        idsite: siteId,
        url: 'https://github.com/fvdm/nodejs-piwik',
        cvar: {'1': ['node test', process.version]}
      }
    ],
    function (err, data) {
      doTest (err, 'track multi', [
        ['data type', typeof data === 'object'],
        ['data.status', data && data.status === 'success'],
        ['data.tracked', data && data.tracked === 2]
      ]);
    }
  );
});

// ! API
queue.push (function () {
  piwik.api (
    {
      method: 'Actions.getPageUrls',
      idSite: siteId,
      period: 'year',
      date: 'today'
    },
    function (err, data) {
      doTest (err, 'api', [
        ['data type', data instanceof Array],
        ['data length', data && data.length >= 1],
        ['item type', data && data [0] instanceof Object],
        ['item label', data && data [0] && typeof data [0] .label === 'string']
      ]);
    }
  );
});

// Start the tests
console.log ('Running tests...\n');
queue [0] ();
<|endoftext|>


<commit_before>import React from 'react'
import { Redirect, Route, Switch } from 'react-router-dom'
import { MuiThemeProvider as V0MuiThemeProvider } from 'material-ui'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import defaultThemeLegacy from 'js/theme/default'
import withPageviewTracking from 'js/analytics/withPageviewTracking'
import { isInEuropeanUnion } from 'js/utils/client-location'
import {
  registerConsentCallback,
  saveConsentUpdateEventToLocalStorage,
  unregisterConsentCallback,
} from 'js/ads/consentManagement'
import DashboardView from 'js/components/Dashboard/DashboardView'
import AuthenticationView from 'js/components/Authentication/AuthenticationView'
import SettingsPageComponent from 'js/components/Settings/SettingsPageComponent'
import FirstTabView from 'js/components/Dashboard/FirstTabView'
import PostUninstallView from 'js/components/Dashboard/PostUninstallView'

const legacyMuiTheme = getMuiTheme(defaultThemeLegacy)

class App extends React.Component {
  constructor(props) {
    super(props)
    this.consentChangeCallback = null
  }

  async componentDidMount() {
    var isEU
    try {
      isEU = await isInEuropeanUnion()
    } catch (e) {
      isEU = false
    }
    if (isEU) {
      this.consentChangeCallback = this.handleDataConsentDecision.bind(this)
      registerConsentCallback(this.consentChangeCallback)
    }
  }

  componentWillUnmount() {
    if (this.consentChangeCallback) {
      unregisterConsentCallback(this.consentChangeCallback)
    }
  }

  async handleDataConsentDecision() {
    // Store the consent data. We'll log it to the server with
    // the user's ID after the user authenticates.
    saveConsentUpdateEventToLocalStorage()
  }

  render() {
    // @material-ui-1-todo: remove legacy theme provider
    return (
      <V0MuiThemeProvider muiTheme={legacyMuiTheme}>
        <div
          style={{
            position: 'absolute',
            top: 0,
            right: 0,
            bottom: 0,
            left: 0,
            margin: 0,
            padding: 0,
            border: 'none',
          }}
        >
          <Switch>
            <Route exact path="/newtab/" component={DashboardView} />
            <Route path="/newtab/settings/" component={SettingsPageComponent} />
            <Route path="/newtab/account/" component={SettingsPageComponent} />
            <Route path="/newtab/profile/" component={SettingsPageComponent} />
            <Route exact path="/newtab/first-tab/" component={FirstTabView} />
            <Route
              exact
              path="/newtab/uninstalled/"
              component={PostUninstallView}
            />
            <Route path="/newtab/auth/" component={AuthenticationView} />
            <Redirect from="*" to="/newtab/" />
          </Switch>
        </div>
      </V0MuiThemeProvider>
    )
  }
}

export default withPageviewTracking(App)
<commit_msg>Lazy-load new tab app routes<commit_after>import React, { Suspense, lazy } from 'react'
import { Redirect, Route, Switch } from 'react-router-dom'
import { MuiThemeProvider as V0MuiThemeProvider } from 'material-ui'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import defaultThemeLegacy from 'js/theme/default'
import withPageviewTracking from 'js/analytics/withPageviewTracking'
import { isInEuropeanUnion } from 'js/utils/client-location'
import {
  registerConsentCallback,
  saveConsentUpdateEventToLocalStorage,
  unregisterConsentCallback,
} from 'js/ads/consentManagement'
import FullPageLoader from 'js/components/General/FullPageLoader'

const DashboardView = lazy(() =>
  import('js/components/Dashboard/DashboardView')
)
const AuthenticationView = lazy(() =>
  import('js/components/Authentication/AuthenticationView')
)
const SettingsPageComponent = lazy(() =>
  import('js/components/Settings/SettingsPageComponent')
)
const FirstTabView = lazy(() => import('js/components/Dashboard/FirstTabView'))
const PostUninstallView = lazy(() =>
  import('js/components/Dashboard/PostUninstallView')
)

const legacyMuiTheme = getMuiTheme(defaultThemeLegacy)

class App extends React.Component {
  constructor(props) {
    super(props)
    this.consentChangeCallback = null
  }

  async componentDidMount() {
    var isEU
    try {
      isEU = await isInEuropeanUnion()
    } catch (e) {
      isEU = false
    }
    if (isEU) {
      this.consentChangeCallback = this.handleDataConsentDecision.bind(this)
      registerConsentCallback(this.consentChangeCallback)
    }
  }

  componentWillUnmount() {
    if (this.consentChangeCallback) {
      unregisterConsentCallback(this.consentChangeCallback)
    }
  }

  async handleDataConsentDecision() {
    // Store the consent data. We'll log it to the server with
    // the user's ID after the user authenticates.
    saveConsentUpdateEventToLocalStorage()
  }

  render() {
    // @material-ui-1-todo: remove legacy theme provider
    return (
      <V0MuiThemeProvider muiTheme={legacyMuiTheme}>
        <div
          style={{
            position: 'absolute',
            top: 0,
            right: 0,
            bottom: 0,
            left: 0,
            margin: 0,
            padding: 0,
            border: 'none',
          }}
        >
          <Suspense fallback={<FullPageLoader delay={350} />}>
            <Switch>
              <Route exact path="/newtab/" component={DashboardView} />
              <Route
                path="/newtab/settings/"
                component={SettingsPageComponent}
              />
              <Route
                path="/newtab/account/"
                component={SettingsPageComponent}
              />
              <Route
                path="/newtab/profile/"
                component={SettingsPageComponent}
              />
              <Route exact path="/newtab/first-tab/" component={FirstTabView} />
              <Route
                exact
                path="/newtab/uninstalled/"
                component={PostUninstallView}
              />
              <Route path="/newtab/auth/" component={AuthenticationView} />
              <Redirect from="*" to="/newtab/" />
            </Switch>
          </Suspense>
        </div>
      </V0MuiThemeProvider>
    )
  }
}

export default withPageviewTracking(App)
<|endoftext|>


<commit_before>/*jshint bitwise: true */
/*jslint bitwise: true */
/*global $:false, Spinner:false*/

/**
 * gplusraffle - Google API PHP OAuth 2.0 and FusionTables client based raffle
 * management system
 *
 * Webapp Client Controller
 *
 * @package gplusraffle
 * @copyright Gael Abadin 2014
 * @license MIT Expat
 * @version v0.1.1-beta
 *
 */

/*
 * Processing dots animation
 */
/* (Replaced by spinner animation)
function processingDots(){
//dots animation shown while the server processes the request
    "use strict";
    var dots = document.getElementById('dots');
    if ($(dots).text().length < 3) {
        $(dots).text($(dots).text()+'.');
    } else {
        $(dots).text('.');
    }
}
*/

/**
 * Send a request to the web server
 */
function requestAndProcessPageJSONData(request){
    "use strict";
    var xmlhttp, //intervalID = window.setInterval(processingDots,1000),
        opts, target, spinner, data, params, response, subtitle;
    if (request.hasOwnProperty('subtitle')){
        subtitle = request.subtitle;
        delete request.subtitle; // this is bad design.
    }
    //$("#postAjaxContent").hide();
    //$("#preAjaxContent").show();
    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
            //window.clearInterval(intervalID);
            spinner.stop();
            if (xmlhttp.responseText) {
                //console.log(xmlhttp.responseText);
                data=JSON.parse(xmlhttp.responseText);
                    if (
                        typeof data === 'object'
                    ){
                        if (
                            data.hasOwnProperty('data') &&
                                typeof data.data === 'object' &&
                                data.data.hasOwnProperty('columns')
                        ){
                            //generate and dump table on #dataTable div
                            dumpTable(data,'dataTable','theMotherOfAllTables');
                            //initialize datatables features and styling
                            fireDataTables('theMotherOfAllTables');
                        }
                        if (data.hasOwnProperty('execTime')){
                            //set output text on some other fields
                            $('#execTime').text(data.execTime);
                        } else {
                            $('#execTime').text('');
                        }
                    }
                //set the url to reflect the parameters of the JSON acquired
                //path = /^([\w\W]*\/)\d+\/\d+\/\d+(\/[\w\W]*)$/.exec(window.location.pathname);
                //path=(path===null)?window.location.pathname:path[1];
                //history.replaceState(stateObj, "", url);
                //$('#subtitle').text(data.subtitle);
            }
            if (
                request.collection === 'raffle' &&
                (
                    request.action === 'open' ||
                    request.action === 'close' ||
                    request.action === 'delete'
                )
            ){
                requestAndProcessPageJSONData(
                    {
                        'collection':'raffle',
                        'action':'list',
                        'creatorid':'me',
                        'subtitle': subtitle
                    }
                );
            } else if (
                request.collection === 'raffle' &&
                (
                    request.action === 'join'
                )
            ){
                requestAndProcessPageJSONData(
                    {
                        'collection':'raffle',
                        'action':'list',
                        'raffleid':request.raffleid,
                        'subtitle': subtitle
                    }
                );
            } else if (
                request.collection === 'raffle' &&
                (
                    request.action === 'leave'
                )
            ){
                requestAndProcessPageJSONData(
                    {
                        'collection':'raffle',
                        'action':'list',
                        'userid':'me',
                        'subtitle': subtitle
                    }
                );
            }
            $('#subtitle').text(subtitle);
            //$("#preAjaxContent").hide();
            //$("#postAjaxContent").show();
        } else if(xmlhttp.readyState === 4){
            spinner.stop();
            if(
                xmlhttp.status === 404 &&
                request.collection ==='raffle' &&
                (request.action === 'list' || request.action === 'check')
            ){
                data = {'data':{'columns':['']}};
            } else {
                window.alert(xmlhttp.responseText);
                try {
                    response = JSON.parse(xmlhttp.responseText);
                    data = {'data':{'columns':[],'rows':[[]]}};
                    for (var propertyName in response){
                        if (response.hasOwnProperty(propertyName)){
                            data.data.columns.push(
                                xmlhttp.status === 404?'':propertyName
                            );
                            data.data.rows[0].push(
                                response[propertyName]
                            );
                        }
                    }
                } catch (err){
                    data = {'data':{'columns':['error'],'rows':[[xmlhttp.status+': '+xmlhttp.responseText]]}};
                }
            }
            dumpTable(data,'dataTable','theMotherOfAllTables');
            fireDataTables('theMotherOfAllTables');
            //$("#preAjaxContent").hide();
            //$("#postAjaxContent").show();
        }
    };
    params = '?requestUUIDv4='+'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
        /[xy]/g,
        function(c) {
            var r = Math.random()*16|0,
                v = c === 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        }
    );
    for (var propertyName in request){
        if (request.hasOwnProperty(propertyName)) {
            params += '&'+propertyName+'='+request[propertyName];
        }
    }
    xmlhttp.open('GET', '../main.php'+params, true);
    xmlhttp.setRequestHeader('Content-type',
        'application/x-www-form-urlencoded');
    xmlhttp.send();
    opts = {
        lines: 13, // The number of lines to draw
        length: 20, // The length of each line
        width: 10, // The line thickness
        radius: 30, // The radius of the inner circle
        corners: 1, // Corner roundness (0..1)
        rotate: 0, // The rotation offset
        direction: 1, // 1: clockwise, -1: counterclockwise
        color: '#000', // #rgb or #rrggbb or array of colors
        speed: 1, // Rounds per second
        trail: 60, // Afterglow percentage
        shadow: false, // Whether to render a shadow
        hwaccel: false, // Whether to use hardware acceleration
        className: 'spinner', // The CSS class to assign to the spinner
        zIndex: 2e9, // The z-index (defaults to 2000000000)
        top: 'auto', // Top position relative to parent in px
        left: 'auto' // Left position relative to parent in px
    };
    target = document.getElementById('container');
    spinner = new Spinner(opts).spin(target);
}
$(document).ready(function(){
//call the AJAX request sender to get data to fill the view
    requestAndProcessPageJSONData(
        {
            'collection':'raffle',
            'action':'list',
            'userid':'me'
        }
    );
});

/**
 * Table handling functions
 */

 /**
 * Creates a table with id tableId using data object from JSON response
 * and places it into current document's containerId
 *
 * TODO: data is obscure, use meaningful names and clearly structured params
 * instead
 *
 * @param data
 * @param containerId
 * @param tableId
 */
function dumpTable(data,containerId,tableId){
    "use strict";
    var table, tbody, propertyName, row, th, index, td, outputNode;
    table = document.createElement('table');
    table.setAttribute('cellpadding','0');
    table.setAttribute('cellspacing','0');
    table.setAttribute('border','0');
    table.setAttribute('class',"table table-striped table-bordered");
    table.setAttribute('id',tableId);
    table.createTHead();
    row = document.createElement('tr');
    for (propertyName in data.data.columns){
        if (data.data.columns.hasOwnProperty(propertyName)) {
            th = document.createElement('th');
            $(th).text(data.data.columns[propertyName]);
            row.appendChild(th);
        }
    }
    table.tHead.appendChild(row);
    tbody = document.createElement('tbody');
    for (index in data.data.rows){
        if (data.data.rows.hasOwnProperty(index)) {
            row = document.createElement('tr');
            for (propertyName in data.data.columns){
                if (data.data.columns.hasOwnProperty(propertyName)){
                    td = document.createElement('td');
                    //noinspection JSUnfilteredForInLoop
                    if (typeof data.data.rows[index][propertyName] !== 'undefined') {
                        //noinspection JSUnfilteredForInLoop
                        if(data.data.columns[propertyName] === 'raffleid'){
                            //noinspection JSUnfilteredForInLoop
                            $(td).html(
                                "" +
                                    data.data.rows[index][propertyName] +
                                ""
                            );
                        } else //noinspection JSUnfilteredForInLoop
                        if (
                            //noinspection JSUnfilteredForInLoop
                            data.data.columns[propertyName] === 'creatorid' ||
                            data.data.columns[propertyName] === 'participantid' ||
                            data.data.columns[propertyName] === 'winnerid'
                        ){
                            //noinspection JSUnfilteredForInLoop
                            $(td).html(
                                "" +
                                    data.data.rows[index][propertyName] +
                                ""
                            );
                        } else //noinspection JSUnfilteredForInLoop
                            if(
                            data.data.columns[propertyName] === 'created' ||
                            data.data.columns[propertyName] === 'joined' ||
                            data.data.columns[propertyName] === 'raffled'
                        ) {
                            //noinspection JSUnfilteredForInLoop
                            var dateString = data.data.rows[index][propertyName],
                                dateParts = dateString.split(' '),
                                timeParts = dateParts[1].split(':'),
                                dateDateParts = dateParts[0].split('-'),
                                date = new Date(dateDateParts[0], parseInt(dateDateParts[1], 10) - 1, dateDateParts[2], timeParts[0], timeParts[1], timeParts[2]),
                                timeZoneOffsetInMinutes = date.getTimezoneOffset(),
                                timeZoneOffsetSign = (timeZoneOffsetInMinutes>0)?'-':'+',
                                timeZoneOffsetHours = Math.floor(Math.abs(timeZoneOffsetInMinutes)/60),
                                timeZoneOffsetMinutes = Math.abs(timeZoneOffsetInMinutes%60),
                                timeZoneString = 'GMT'+timeZoneOffsetSign+((timeZoneOffsetHours<10)?'0':'')+timeZoneOffsetHours.toString()+timeZoneOffsetMinutes.toString()+((timeZoneOffsetMinutes<10)?'0':''),
                                dateOffset = new Date(date.getTime()-timeZoneOffsetInMinutes*60*1000);

                            $(td).text(dateOffset.toLocaleString() + ' ' + timeZoneString);

                        } else {
                            //noinspection JSUnfilteredForInLoop
                            $(td).text(data.data.rows[index][propertyName]);
                        }
                    }
                    row.appendChild(td);
                }
            }
            tbody.appendChild(row);
        }
    }
    table.appendChild(tbody);
    outputNode = document.getElementById(containerId);
    while (outputNode.hasChildNodes()) {//overkill
        outputNode.removeChild(outputNode.lastChild);
    }
    outputNode.appendChild(table);
}
/**
 * Turns table in current document's tableId into a datatable.js table
 *
 * TODO: "records per page" text does not use translation interface
 *
 * @param tableId
 */
function fireDataTables(tableId) {
    "use strict";
    $('#'+tableId).dataTable({
    "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
    "sPaginationType": "full_numbers",
    "oLanguage": {
        "sLengthMenu": "_MENU_ records per page"
        }
    });
}

/*
 * I've obtained the following code from a blog post from datatables creator,
 * Allan Jardine, at sprymedia:
 *
 * http://datatables.net/blog/Twitter_Bootstrap_2
 */
/* Set the defaults for DataTables initialisation */
$.extend( true, $.fn.dataTable.defaults, {
    "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
    "oLanguage": {
        "sLengthMenu": "_MENU_ records per page"
    }
} );

/* Default class modification */

$.extend( $.fn.dataTableExt.oStdClasses, {
    "sWrapper": "dataTables_wrapper form-inline"
} );

/* API method to get paging information */
$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
{
    "use strict";
    return {
        "iStart":         oSettings._iDisplayStart,
        "iEnd":           oSettings.fnDisplayEnd(),
        "iLength":        oSettings._iDisplayLength,
        "iTotal":         oSettings.fnRecordsTotal(),
        "iFilteredTotal": oSettings.fnRecordsDisplay(),
        "iPage":          oSettings._iDisplayLength === -1 ?
            0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
        "iTotalPages":    oSettings._iDisplayLength === -1 ?
            0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
    };
};

/*
 * TableTools Bootstrap compatibility
 * Required TableTools 2.1+
 */
if ( $.fn.DataTable.TableTools ) {
    // Set the classes that TableTools uses to something suitable for Bootstrap
    $.extend( true, $.fn.DataTable.TableTools.classes, {
        "container": "DTTT btn-group",
        "buttons": {
            "normal": "btn",
            "disabled": "disabled"
        },
        "collection": {
            "container": "DTTT_dropdown dropdown-menu",
            "buttons": {
                "normal": "",
                "disabled": "disabled"
            }
        },
        "print": {
            "info": "DTTT_print_info modal"
        },
        "select": {
            "row": "active"
        }
    } );

    // Have the collection use a bootstrap compatible dropdown
    $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
        "collection": {
            "container": "ul",
            "button": "li",
            "liner": "a"
        }
    } );
}
<commit_msg>set jslint/jshint ActiveXObject global<commit_after>/*jshint bitwise: true */
/*jslint bitwise: true */
/*global $:false, Spinner:false, ActiveXObject:false*/

/**
 * gplusraffle - Google API PHP OAuth 2.0 and FusionTables client based raffle
 * management system
 *
 * Webapp Client Controller
 *
 * @package gplusraffle
 * @copyright Gael Abadin 2014
 * @license MIT Expat
 * @version v0.1.1-beta
 *
 */

/*
 * Processing dots animation
 */
/* (Replaced by spinner animation)
function processingDots(){
//dots animation shown while the server processes the request
    "use strict";
    var dots = document.getElementById('dots');
    if ($(dots).text().length < 3) {
        $(dots).text($(dots).text()+'.');
    } else {
        $(dots).text('.');
    }
}
*/

/**
 * Send a request to the web server
 */
function requestAndProcessPageJSONData(request){
    "use strict";
    var xmlhttp, //intervalID = window.setInterval(processingDots,1000),
        opts, target, spinner, data, params, response, subtitle;
    if (request.hasOwnProperty('subtitle')){
        subtitle = request.subtitle;
        delete request.subtitle; // this is bad design.
    }
    //$("#postAjaxContent").hide();
    //$("#preAjaxContent").show();
    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
            //window.clearInterval(intervalID);
            spinner.stop();
            if (xmlhttp.responseText) {
                //console.log(xmlhttp.responseText);
                data=JSON.parse(xmlhttp.responseText);
                    if (
                        typeof data === 'object'
                    ){
                        if (
                            data.hasOwnProperty('data') &&
                                typeof data.data === 'object' &&
                                data.data.hasOwnProperty('columns')
                        ){
                            //generate and dump table on #dataTable div
                            dumpTable(data,'dataTable','theMotherOfAllTables');
                            //initialize datatables features and styling
                            fireDataTables('theMotherOfAllTables');
                        }
                        if (data.hasOwnProperty('execTime')){
                            //set output text on some other fields
                            $('#execTime').text(data.execTime);
                        } else {
                            $('#execTime').text('');
                        }
                    }
                //set the url to reflect the parameters of the JSON acquired
                //path = /^([\w\W]*\/)\d+\/\d+\/\d+(\/[\w\W]*)$/.exec(window.location.pathname);
                //path=(path===null)?window.location.pathname:path[1];
                //history.replaceState(stateObj, "", url);
                //$('#subtitle').text(data.subtitle);
            }
            if (
                request.collection === 'raffle' &&
                (
                    request.action === 'open' ||
                    request.action === 'close' ||
                    request.action === 'delete'
                )
            ){
                requestAndProcessPageJSONData(
                    {
                        'collection':'raffle',
                        'action':'list',
                        'creatorid':'me',
                        'subtitle': subtitle
                    }
                );
            } else if (
                request.collection === 'raffle' &&
                (
                    request.action === 'join'
                )
            ){
                requestAndProcessPageJSONData(
                    {
                        'collection':'raffle',
                        'action':'list',
                        'raffleid':request.raffleid,
                        'subtitle': subtitle
                    }
                );
            } else if (
                request.collection === 'raffle' &&
                (
                    request.action === 'leave'
                )
            ){
                requestAndProcessPageJSONData(
                    {
                        'collection':'raffle',
                        'action':'list',
                        'userid':'me',
                        'subtitle': subtitle
                    }
                );
            }
            $('#subtitle').text(subtitle);
            //$("#preAjaxContent").hide();
            //$("#postAjaxContent").show();
        } else if(xmlhttp.readyState === 4){
            spinner.stop();
            if(
                xmlhttp.status === 404 &&
                request.collection ==='raffle' &&
                (request.action === 'list' || request.action === 'check')
            ){
                data = {'data':{'columns':['']}};
            } else {
                window.alert(xmlhttp.responseText);
                try {
                    response = JSON.parse(xmlhttp.responseText);
                    data = {'data':{'columns':[],'rows':[[]]}};
                    for (var propertyName in response){
                        if (response.hasOwnProperty(propertyName)){
                            data.data.columns.push(
                                xmlhttp.status === 404?'':propertyName
                            );
                            data.data.rows[0].push(
                                response[propertyName]
                            );
                        }
                    }
                } catch (err){
                    data = {'data':{'columns':['error'],'rows':[[xmlhttp.status+': '+xmlhttp.responseText]]}};
                }
            }
            dumpTable(data,'dataTable','theMotherOfAllTables');
            fireDataTables('theMotherOfAllTables');
            //$("#preAjaxContent").hide();
            //$("#postAjaxContent").show();
        }
    };
    params = '?requestUUIDv4='+'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
        /[xy]/g,
        function(c) {
            var r = Math.random()*16|0,
                v = c === 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        }
    );
    for (var propertyName in request){
        if (request.hasOwnProperty(propertyName)) {
            params += '&'+propertyName+'='+request[propertyName];
        }
    }
    xmlhttp.open('GET', '../main.php'+params, true);
    xmlhttp.setRequestHeader('Content-type',
        'application/x-www-form-urlencoded');
    xmlhttp.send();
    opts = {
        lines: 13, // The number of lines to draw
        length: 20, // The length of each line
        width: 10, // The line thickness
        radius: 30, // The radius of the inner circle
        corners: 1, // Corner roundness (0..1)
        rotate: 0, // The rotation offset
        direction: 1, // 1: clockwise, -1: counterclockwise
        color: '#000', // #rgb or #rrggbb or array of colors
        speed: 1, // Rounds per second
        trail: 60, // Afterglow percentage
        shadow: false, // Whether to render a shadow
        hwaccel: false, // Whether to use hardware acceleration
        className: 'spinner', // The CSS class to assign to the spinner
        zIndex: 2e9, // The z-index (defaults to 2000000000)
        top: 'auto', // Top position relative to parent in px
        left: 'auto' // Left position relative to parent in px
    };
    target = document.getElementById('container');
    spinner = new Spinner(opts).spin(target);
}
$(document).ready(function(){
//call the AJAX request sender to get data to fill the view
    requestAndProcessPageJSONData(
        {
            'collection':'raffle',
            'action':'list',
            'userid':'me'
        }
    );
});

/**
 * Table handling functions
 */

 /**
 * Creates a table with id tableId using data object from JSON response
 * and places it into current document's containerId
 *
 * TODO: data is obscure, use meaningful names and clearly structured params
 * instead
 *
 * @param data
 * @param containerId
 * @param tableId
 */
function dumpTable(data,containerId,tableId){
    "use strict";
    var table, tbody, propertyName, row, th, index, td, outputNode;
    table = document.createElement('table');
    table.setAttribute('cellpadding','0');
    table.setAttribute('cellspacing','0');
    table.setAttribute('border','0');
    table.setAttribute('class',"table table-striped table-bordered");
    table.setAttribute('id',tableId);
    table.createTHead();
    row = document.createElement('tr');
    for (propertyName in data.data.columns){
        if (data.data.columns.hasOwnProperty(propertyName)) {
            th = document.createElement('th');
            $(th).text(data.data.columns[propertyName]);
            row.appendChild(th);
        }
    }
    table.tHead.appendChild(row);
    tbody = document.createElement('tbody');
    for (index in data.data.rows){
        if (data.data.rows.hasOwnProperty(index)) {
            row = document.createElement('tr');
            for (propertyName in data.data.columns){
                if (data.data.columns.hasOwnProperty(propertyName)){
                    td = document.createElement('td');
                    //noinspection JSUnfilteredForInLoop
                    if (typeof data.data.rows[index][propertyName] !== 'undefined') {
                        //noinspection JSUnfilteredForInLoop
                        if(data.data.columns[propertyName] === 'raffleid'){
                            //noinspection JSUnfilteredForInLoop
                            $(td).html(
                                "" +
                                    data.data.rows[index][propertyName] +
                                ""
                            );
                        } else //noinspection JSUnfilteredForInLoop
                        if (
                            //noinspection JSUnfilteredForInLoop
                            data.data.columns[propertyName] === 'creatorid' ||
                            data.data.columns[propertyName] === 'participantid' ||
                            data.data.columns[propertyName] === 'winnerid'
                        ){
                            //noinspection JSUnfilteredForInLoop
                            $(td).html(
                                "" +
                                    data.data.rows[index][propertyName] +
                                ""
                            );
                        } else //noinspection JSUnfilteredForInLoop
                            if(
                            data.data.columns[propertyName] === 'created' ||
                            data.data.columns[propertyName] === 'joined' ||
                            data.data.columns[propertyName] === 'raffled'
                        ) {
                            //noinspection JSUnfilteredForInLoop
                            var dateString = data.data.rows[index][propertyName],
                                dateParts = dateString.split(' '),
                                timeParts = dateParts[1].split(':'),
                                dateDateParts = dateParts[0].split('-'),
                                date = new Date(dateDateParts[0], parseInt(dateDateParts[1], 10) - 1, dateDateParts[2], timeParts[0], timeParts[1], timeParts[2]),
                                timeZoneOffsetInMinutes = date.getTimezoneOffset(),
                                timeZoneOffsetSign = (timeZoneOffsetInMinutes>0)?'-':'+',
                                timeZoneOffsetHours = Math.floor(Math.abs(timeZoneOffsetInMinutes)/60),
                                timeZoneOffsetMinutes = Math.abs(timeZoneOffsetInMinutes%60),
                                timeZoneString = 'GMT'+timeZoneOffsetSign+((timeZoneOffsetHours<10)?'0':'')+timeZoneOffsetHours.toString()+timeZoneOffsetMinutes.toString()+((timeZoneOffsetMinutes<10)?'0':''),
                                dateOffset = new Date(date.getTime()-timeZoneOffsetInMinutes*60*1000);

                            $(td).text(dateOffset.toLocaleString() + ' ' + timeZoneString);

                        } else {
                            //noinspection JSUnfilteredForInLoop
                            $(td).text(data.data.rows[index][propertyName]);
                        }
                    }
                    row.appendChild(td);
                }
            }
            tbody.appendChild(row);
        }
    }
    table.appendChild(tbody);
    outputNode = document.getElementById(containerId);
    while (outputNode.hasChildNodes()) {//overkill
        outputNode.removeChild(outputNode.lastChild);
    }
    outputNode.appendChild(table);
}
/**
 * Turns table in current document's tableId into a datatable.js table
 *
 * TODO: "records per page" text does not use translation interface
 *
 * @param tableId
 */
function fireDataTables(tableId) {
    "use strict";
    $('#'+tableId).dataTable({
    "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
    "sPaginationType": "full_numbers",
    "oLanguage": {
        "sLengthMenu": "_MENU_ records per page"
        }
    });
}

/*
 * I've obtained the following code from a blog post from datatables creator,
 * Allan Jardine, at sprymedia:
 *
 * http://datatables.net/blog/Twitter_Bootstrap_2
 */
/* Set the defaults for DataTables initialisation */
$.extend( true, $.fn.dataTable.defaults, {
    "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
    "oLanguage": {
        "sLengthMenu": "_MENU_ records per page"
    }
} );

/* Default class modification */

$.extend( $.fn.dataTableExt.oStdClasses, {
    "sWrapper": "dataTables_wrapper form-inline"
} );

/* API method to get paging information */
$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
{
    "use strict";
    return {
        "iStart":         oSettings._iDisplayStart,
        "iEnd":           oSettings.fnDisplayEnd(),
        "iLength":        oSettings._iDisplayLength,
        "iTotal":         oSettings.fnRecordsTotal(),
        "iFilteredTotal": oSettings.fnRecordsDisplay(),
        "iPage":          oSettings._iDisplayLength === -1 ?
            0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
        "iTotalPages":    oSettings._iDisplayLength === -1 ?
            0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
    };
};

/*
 * TableTools Bootstrap compatibility
 * Required TableTools 2.1+
 */
if ( $.fn.DataTable.TableTools ) {
    // Set the classes that TableTools uses to something suitable for Bootstrap
    $.extend( true, $.fn.DataTable.TableTools.classes, {
        "container": "DTTT btn-group",
        "buttons": {
            "normal": "btn",
            "disabled": "disabled"
        },
        "collection": {
            "container": "DTTT_dropdown dropdown-menu",
            "buttons": {
                "normal": "",
                "disabled": "disabled"
            }
        },
        "print": {
            "info": "DTTT_print_info modal"
        },
        "select": {
            "row": "active"
        }
    } );

    // Have the collection use a bootstrap compatible dropdown
    $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
        "collection": {
            "container": "ul",
            "button": "li",
            "liner": "a"
        }
    } );
}
<|endoftext|>