<commit_before>/*
 * Price object handles all the functions we need to display prices
 *
 * We create Price proposal that we need to send to server to get price,
 * longcode and all other information that we need to get the price for
 * current contract
 *
 *
 * Usage:
 *
 * `socket.send(Price.createProposal())` to send price proposal to sever
 * `Price.display()` to display the price details returned from server
 */
var Price = (function() {
    'use strict';

    var typeDisplayIdMapping = {},
        form_id = 0;

    var createProposal = function(typeOfContract) {
        var proposal = {
                proposal: 1,
                subscribe: 1
            },
            underlying = document.getElementById('underlying'),
            submarket = document.getElementById('submarket'),
            contractType = typeOfContract,
            amountType = document.getElementById('amount_type'),
            currency = document.getElementById('currency'),
            payout = document.getElementById('amount'),
            startTime = StartDates.node(),
            expiryType = document.getElementById('expiry_type'),
            duration = document.getElementById('duration_amount'),
            durationUnit = document.getElementById('duration_units'),
            endDate = document.getElementById('expiry_date'),
            endTime = document.getElementById('expiry_time'),
            barrier = document.getElementById('barrier'),
            highBarrier = document.getElementById('barrier_high'),
            lowBarrier = document.getElementById('barrier_low'),
            prediction = document.getElementById('prediction'),
            amountPerPoint = document.getElementById('amount_per_point'),
            stopType = document.querySelector('input[name="stop_type"]:checked'),
            stopLoss = document.getElementById('stop_loss'),
            stopProfit = document.getElementById('stop_profit');

        if (payout && isVisible(payout) && payout.value) {
            proposal['amount'] = parseFloat(payout.value);
        }

        if (amountType && isVisible(amountType) && amountType.value) {
            proposal['basis'] = amountType.value;
        }

        if (contractType) {
            proposal['contract_type'] = typeOfContract;
        }

        if (currency && currency.value) {
            proposal['currency'] = currency.value;
        }

        if (underlying && underlying.value) {
            proposal['symbol'] = underlying.value;
        }

        if (startTime && isVisible(startTime) && startTime.value !== 'now') {
            proposal['date_start'] = startTime.value;
        }

        if (expiryType && isVisible(expiryType) && expiryType.value === 'duration') {
            proposal['duration'] = parseInt(duration.value);
            proposal['duration_unit'] = durationUnit.value;
        } else if (expiryType && isVisible(expiryType) && expiryType.value === 'endtime') {
            var endDate2 = endDate.value;
            var endTime2 = Durations.getTime();
            if (!endTime2) {
                var trading_times = Durations.trading_times();
                if (trading_times.hasOwnProperty(endDate2) && typeof trading_times[endDate2][underlying.value] === 'object' && trading_times[endDate2][underlying.value].length && trading_times[endDate2][underlying.value][0] !== '--') {
                    if( trading_times[endDate2][underlying.value].length>1)
                        endTime2 = trading_times[endDate2][underlying.value][1];
                    else
                         endTime2=trading_times[endDate2][underlying.value];
                }
            }

            proposal['date_expiry'] = moment.utc(endDate2 + " " + endTime2).unix();
            // For stopping tick trade behaviour
            proposal['duration_unit'] = "m";
        }

        if (barrier && isVisible(barrier) && barrier.value) {
            proposal['barrier'] = barrier.value;
        }

        if (highBarrier && isVisible(highBarrier) && highBarrier.value) {
            proposal['barrier'] = highBarrier.value;
        }

        if (lowBarrier && isVisible(lowBarrier) && lowBarrier.value) {
            proposal['barrier2'] = lowBarrier.value;
        }

        if (prediction && isVisible(prediction)) {
            proposal['barrier'] = parseInt(prediction.value);
        }

        if (amountPerPoint && isVisible(amountPerPoint)) {
            proposal['amount_per_point'] = parseFloat(amountPerPoint.value);
        }

        if (stopType && isVisible(stopType)) {
            proposal['stop_type'] = stopType.value;
        }

        if (stopLoss && isVisible(stopLoss)) {
            proposal['stop_loss'] = parseFloat(stopLoss.value);
        }

        if (stopProfit && isVisible(stopProfit)) {
            proposal['stop_profit'] = parseFloat(stopProfit.value);
        }

        if (contractType) {
            proposal['contract_type'] = typeOfContract;
        }

        proposal['passthrough'] = {
            form_id: form_id
        };

        return proposal;
    };

    var display = function(details, contractType) {
        var proposal = details['proposal'];
        var id = proposal ? proposal['id'] : '';
        var params = details['echo_req'];

        var type = params['contract_type'];
        if (id && !type) {
            type = typeDisplayIdMapping[id];
        }

        var is_spread = false;
        if (proposal && proposal['spread']) {
            is_spread = true;
        }

        if (params && id && Object.getOwnPropertyNames(params).length > 0) {
            typeDisplayIdMapping[id] = type;
        }

        var position = contractTypeDisplayMapping(type);

        if (!position) {
            return;
        }

        var container = document.getElementById('price_container_' + position);
        if (!$(container).is(":visible")) {
            $(container).fadeIn(200);
        }

        var h4 = container.getElementsByClassName('contract_heading')[0],
            amount = container.getElementsByClassName('contract_amount')[0],
            purchase = container.getElementsByClassName('purchase_button')[0],
            description = container.getElementsByClassName('contract_description')[0],
            comment = container.getElementsByClassName('price_comment')[0],
            error = container.getElementsByClassName('contract_error')[0],
            amount_wrapper = container.getElementsByClassName('amount_wrapper')[0],
            price_wrapper = container.getElementsByClassName('price_wrapper')[0],
            currency = document.getElementById('currency');

        var display = type ? (contractType ? contractType[type] : '') : '';
        if (display) {
            h4.setAttribute('class', 'contract_heading ' + type);
            if (is_spread) {
                if (position === "top") {
                    h4.textContent = Content.localize().textSpreadTypeLong;
                } else {
                    h4.textContent = Content.localize().textSpreadTypeShort;
                }
            } else {
                h4.textContent = display;
            }
        }

        if (proposal && proposal['display_value']) {
            if (is_spread) {
                amount.textContent = proposal['display_value'];
            } else {
                amount.textContent = currency.value + ' ' + proposal['display_value'];
            }
        }

        if (proposal && proposal['longcode']) {
            proposal['longcode'] = proposal['longcode'].replace(/[\d\,]+\.\d\d/, function(x) {
                return '' + x + '';
            });
            description.innerHTML = '
' + proposal['longcode'] + '
';
        }

        if (details['error']) {
            purchase.hide();
            comment.hide();
            amount_wrapper.hide();
            description.innerHTML = "";
            price_wrapper.classList.add('small');
            error.show();
            error.textContent = details['error'].message;
        } else {
            purchase.show();
            comment.show();
            amount_wrapper.show();
            price_wrapper.classList.remove('small');
            error.hide();
            if (is_spread) {
                displayCommentSpreads(comment, currency.value, proposal['spread']);
            } else {
                displayCommentPrice(comment, currency.value, proposal['ask_price'], proposal['payout']);
            }
            var oldprice = purchase.getAttribute('data-display_value');
            if (oldprice) {
                displayPriceMovement(amount, oldprice, proposal['display_value']);
            }
            purchase.setAttribute('data-purchase-id', id);
            purchase.setAttribute('data-ask-price', proposal['ask_price']);
            purchase.setAttribute('data-display_value', proposal['display_value']);
            purchase.setAttribute('data-symbol', id);
            for (var key in params) {
                if (key && key !== 'proposal') {
                    purchase.setAttribute('data-' + key, params[key]);
                }
            }
        }
    };

    var clearMapping = function() {
        typeDisplayIdMapping = {};
    };

    var clearFormId = function() {
        form_id = 0;
    };

    return {
        proposal: createProposal,
        display: display,
        clearMapping: clearMapping,
        idDisplayMapping: function() {
            return typeDisplayIdMapping;
        },
        getFormId: function() {
            return form_id;
        },
        incrFormId: function() {
            form_id++;
        },
        clearFormId: clearFormId
    };

})();
<commit_msg>spreads label fix<commit_after>/*
 * Price object handles all the functions we need to display prices
 *
 * We create Price proposal that we need to send to server to get price,
 * longcode and all other information that we need to get the price for
 * current contract
 *
 *
 * Usage:
 *
 * `socket.send(Price.createProposal())` to send price proposal to sever
 * `Price.display()` to display the price details returned from server
 */
var Price = (function() {
    'use strict';

    var typeDisplayIdMapping = {},
        form_id = 0;

    var createProposal = function(typeOfContract) {
        var proposal = {
                proposal: 1,
                subscribe: 1
            },
            underlying = document.getElementById('underlying'),
            submarket = document.getElementById('submarket'),
            contractType = typeOfContract,
            amountType = document.getElementById('amount_type'),
            currency = document.getElementById('currency'),
            payout = document.getElementById('amount'),
            startTime = StartDates.node(),
            expiryType = document.getElementById('expiry_type'),
            duration = document.getElementById('duration_amount'),
            durationUnit = document.getElementById('duration_units'),
            endDate = document.getElementById('expiry_date'),
            endTime = document.getElementById('expiry_time'),
            barrier = document.getElementById('barrier'),
            highBarrier = document.getElementById('barrier_high'),
            lowBarrier = document.getElementById('barrier_low'),
            prediction = document.getElementById('prediction'),
            amountPerPoint = document.getElementById('amount_per_point'),
            stopType = document.querySelector('input[name="stop_type"]:checked'),
            stopLoss = document.getElementById('stop_loss'),
            stopProfit = document.getElementById('stop_profit');

        if (payout && isVisible(payout) && payout.value) {
            proposal['amount'] = parseFloat(payout.value);
        }

        if (amountType && isVisible(amountType) && amountType.value) {
            proposal['basis'] = amountType.value;
        }

        if (contractType) {
            proposal['contract_type'] = typeOfContract;
        }

        if (currency && currency.value) {
            proposal['currency'] = currency.value;
        }

        if (underlying && underlying.value) {
            proposal['symbol'] = underlying.value;
        }

        if (startTime && isVisible(startTime) && startTime.value !== 'now') {
            proposal['date_start'] = startTime.value;
        }

        if (expiryType && isVisible(expiryType) && expiryType.value === 'duration') {
            proposal['duration'] = parseInt(duration.value);
            proposal['duration_unit'] = durationUnit.value;
        } else if (expiryType && isVisible(expiryType) && expiryType.value === 'endtime') {
            var endDate2 = endDate.value;
            var endTime2 = Durations.getTime();
            if (!endTime2) {
                var trading_times = Durations.trading_times();
                if (trading_times.hasOwnProperty(endDate2) && typeof trading_times[endDate2][underlying.value] === 'object' && trading_times[endDate2][underlying.value].length && trading_times[endDate2][underlying.value][0] !== '--') {
                    if( trading_times[endDate2][underlying.value].length>1)
                        endTime2 = trading_times[endDate2][underlying.value][1];
                    else
                         endTime2=trading_times[endDate2][underlying.value];
                }
            }

            proposal['date_expiry'] = moment.utc(endDate2 + " " + endTime2).unix();
            // For stopping tick trade behaviour
            proposal['duration_unit'] = "m";
        }

        if (barrier && isVisible(barrier) && barrier.value) {
            proposal['barrier'] = barrier.value;
        }

        if (highBarrier && isVisible(highBarrier) && highBarrier.value) {
            proposal['barrier'] = highBarrier.value;
        }

        if (lowBarrier && isVisible(lowBarrier) && lowBarrier.value) {
            proposal['barrier2'] = lowBarrier.value;
        }

        if (prediction && isVisible(prediction)) {
            proposal['barrier'] = parseInt(prediction.value);
        }

        if (amountPerPoint && isVisible(amountPerPoint)) {
            proposal['amount_per_point'] = parseFloat(amountPerPoint.value);
        }

        if (stopType && isVisible(stopType)) {
            proposal['stop_type'] = stopType.value;
        }

        if (stopLoss && isVisible(stopLoss)) {
            proposal['stop_loss'] = parseFloat(stopLoss.value);
        }

        if (stopProfit && isVisible(stopProfit)) {
            proposal['stop_profit'] = parseFloat(stopProfit.value);
        }

        if (contractType) {
            proposal['contract_type'] = typeOfContract;
        }

        proposal['passthrough'] = {
            form_id: form_id
        };

        return proposal;
    };

    var display = function(details, contractType) {
        var proposal = details['proposal'];
        var id = proposal ? proposal['id'] : '';
        var params = details['echo_req'];

        var type = params['contract_type'];
        if (id && !type) {
            type = typeDisplayIdMapping[id];
        }

        var is_spread = false;
        if (params.contract_type && (params.contract_type === 'SPREADU' || params.contract_type === 'SPREADD')) {
            is_spread = true;
        }

        if (params && id && Object.getOwnPropertyNames(params).length > 0) {
            typeDisplayIdMapping[id] = type;
        }

        var position = contractTypeDisplayMapping(type);

        if (!position) {
            return;
        }

        var container = document.getElementById('price_container_' + position);
        if (!$(container).is(":visible")) {
            $(container).fadeIn(200);
        }

        var h4 = container.getElementsByClassName('contract_heading')[0],
            amount = container.getElementsByClassName('contract_amount')[0],
            purchase = container.getElementsByClassName('purchase_button')[0],
            description = container.getElementsByClassName('contract_description')[0],
            comment = container.getElementsByClassName('price_comment')[0],
            error = container.getElementsByClassName('contract_error')[0],
            amount_wrapper = container.getElementsByClassName('amount_wrapper')[0],
            price_wrapper = container.getElementsByClassName('price_wrapper')[0],
            currency = document.getElementById('currency');

        var display = type ? (contractType ? contractType[type] : '') : '';
        if (display) {
            h4.setAttribute('class', 'contract_heading ' + type);
            if (is_spread) {
                if (position === "top") {
                    h4.textContent = Content.localize().textSpreadTypeLong;
                } else {
                    h4.textContent = Content.localize().textSpreadTypeShort;
                }
            } else {
                h4.textContent = display;
            }
        }

        if (proposal && proposal['display_value']) {
            if (is_spread) {
                amount.textContent = proposal['display_value'];
            } else {
                amount.textContent = currency.value + ' ' + proposal['display_value'];
            }
        }

        if (proposal && proposal['longcode']) {
            proposal['longcode'] = proposal['longcode'].replace(/[\d\,]+\.\d\d/, function(x) {
                return '' + x + '';
            });
            description.innerHTML = '
' + proposal['longcode'] + '
';
        }

        if (details['error']) {
            purchase.hide();
            comment.hide();
            amount_wrapper.hide();
            description.innerHTML = "";
            price_wrapper.classList.add('small');
            error.show();
            error.textContent = details['error'].message;
        } else {
            purchase.show();
            comment.show();
            amount_wrapper.show();
            price_wrapper.classList.remove('small');
            error.hide();
            if (is_spread) {
                displayCommentSpreads(comment, currency.value, proposal['spread']);
            } else {
                displayCommentPrice(comment, currency.value, proposal['ask_price'], proposal['payout']);
            }
            var oldprice = purchase.getAttribute('data-display_value');
            if (oldprice) {
                displayPriceMovement(amount, oldprice, proposal['display_value']);
            }
            purchase.setAttribute('data-purchase-id', id);
            purchase.setAttribute('data-ask-price', proposal['ask_price']);
            purchase.setAttribute('data-display_value', proposal['display_value']);
            purchase.setAttribute('data-symbol', id);
            for (var key in params) {
                if (key && key !== 'proposal') {
                    purchase.setAttribute('data-' + key, params[key]);
                }
            }
        }
    };

    var clearMapping = function() {
        typeDisplayIdMapping = {};
    };

    var clearFormId = function() {
        form_id = 0;
    };

    return {
        proposal: createProposal,
        display: display,
        clearMapping: clearMapping,
        idDisplayMapping: function() {
            return typeDisplayIdMapping;
        },
        getFormId: function() {
            return form_id;
        },
        incrFormId: function() {
            form_id++;
        },
        clearFormId: clearFormId
    };

})();
<|endoftext|>


<commit_before>var amqp = require('amqplib/callback_api');
const queueName = 'ad-location-queue';
import top500 from './top500';

function handleError(err) {
  if (err) {
    console.error(err);
    process.exit();
  }
}

amqp.connect('amqp://localhost', (err, conn) => {
  handleError(err);
  conn.createChannel((connErr, ch) => {
    handleError(connErr);
    ch.assertQueue(queueName, {
      durable: true
    });
    top500.forEach(site => {
      ch.sendToQueue(queueName, Buffer(site), {
        persistent: true
      });
      console.log(` [x] Sent ${site}`);
    });
    setTimeout(() => {
      conn.close();
      process.exit(0);
    }, 10000);
  });
});
<commit_msg>Change to top 1M for pushSites<commit_after>var amqp = require('amqplib/callback_api');
let fs = require('fs');
const queueName = 'ad-location-queue';

let top1MRaw = fs.readFileSync('./data/top-1m.csv', 'utf-8');
let top1MLines = top1MRaw.split('\n');
let top1M = top1MLines.map(line => line.split(',')[1]);
top1M.splice(-1);

function handleError(err) {
  if (err) {
    console.error(err);
    process.exit();
  }
}

amqp.connect('amqp://localhost', (err, conn) => {
  handleError(err);
  conn.createChannel((connErr, ch) => {
    handleError(connErr);
    ch.assertQueue(queueName, {
      durable: true
    });
    top1M.forEach(site => {
      ch.sendToQueue(queueName, Buffer(site), {
        persistent: true
      });
      console.log(` [x] Sent ${site}`);
    });
    setTimeout(() => {
      conn.close();
      process.exit(0);
    }, 10000);
  });
});
<|endoftext|>


<commit_before>/*
 * Price object handles all the functions we need to display prices
 *
 * We create Price proposal that we need to send to server to get price,
 * longcode and all other information that we need to get the price for
 * current contract
 *
 *
 * Usage:
 *
 * `socket.send(Price.createProposal())` to send price proposal to sever
 * `Price.display()` to display the price details returned from server
 */
var Price = (function () {
    'use strict';

    var typeDisplayIdMapping = {},
        bufferedIds = {},
        bufferRequests = {};

    var createProposal = function (typeOfContract) {
        var proposal = {proposal: 1}, underlying = document.getElementById('underlying'),
            submarket = document.getElementById('submarket'),
            contractType = typeOfContract,
            amountType = document.getElementById('amount_type'),
            currency = document.getElementById('currency'),
            payout = document.getElementById('amount'),
            startTime = document.getElementById('date_start'),
            expiryType = document.getElementById('expiry_type'),
            duration = document.getElementById('duration_amount'),
            durationUnit = document.getElementById('duration_units'),
            endDate = document.getElementById('expiry_date'),
            endTime = document.getElementById('expiry_time'),
            barrier = document.getElementById('barrier'),
            highBarrier = document.getElementById('barrier_high'),
            lowBarrier = document.getElementById('barrier_low'),
            prediction = document.getElementById('prediction'),
            amountPerPoint = document.getElementById('amount_per_point'),
            stopType = document.querySelector('input[name="stop_type"]:checked'),
            stopLoss = document.getElementById('stop_loss'),
            stopProfit = document.getElementById('stop_profit');

        if (payout && isVisible(payout) && payout.value) {
            proposal['amount_val'] = parseFloat(payout.value);
        }

        if (amountType && isVisible(amountType) && amountType.value) {
            proposal['basis'] = amountType.value;
        }

        if (contractType) {
            proposal['contract_type'] = typeOfContract;
        }

        if (currency && currency.value) {
            proposal['currency'] = currency.value;
        }

        if (underlying && underlying.value) {
            proposal['symbol'] = underlying.value;
        }

        if (startTime && isVisible(startTime) && startTime.value !== 'now') {
            proposal['date_start'] = startTime.value;
        }

        if (expiryType && expiryType.value === 'duration') {
            proposal['duration'] = parseInt(duration.value);
            proposal['duration_unit'] = durationUnit.value;
        } else if (expiryType && expiryType.value === 'endtime') {
            proposal['date_expiry'] = moment.utc(endDate.value + " " + endTime.value).unix();
        }

        if (barrier && isVisible(barrier) && barrier.value) {
            proposal['barrier'] = parseFloat(barrier.value);
        }

        if (highBarrier && isVisible(highBarrier) && highBarrier.value) {
            proposal['barrier'] = parseFloat(highBarrier.value);
        }

        if (lowBarrier && isVisible(lowBarrier) && lowBarrier.value) {
            proposal['barrier2'] = parseFloat(lowBarrier.value);
        }

        if(prediction && isVisible(prediction)){
            proposal['barrier'] = parseInt(prediction.value);
        }

        if (amountPerPoint && isVisible(amountPerPoint)) {
            proposal['amount_per_point'] = parseFloat(amountPerPoint.value);
        }

        if (stopType && isVisible(stopType)) {
            proposal['stop_type'] = stopType.value;
        }

        if (stopLoss && isVisible(stopLoss)) {
            proposal['stop_loss'] = parseFloat(stopLoss.value);
        }

        if (stopProfit && isVisible(stopProfit)) {
            proposal['stop_profit'] = parseFloat(stopProfit.value);
        }

        return proposal;
    };

    var display = function (details, contractType) {
        var proposal = details['proposal'];
        var params = details['echo_req'],
            id = proposal['id'],
            type = params['contract_type'] || typeDisplayIdMapping[id];

        if (params && Object.getOwnPropertyNames(params).length > 0) {
            typeDisplayIdMapping[id] = type;

            if (!bufferedIds.hasOwnProperty(id)) {
                bufferedIds[id] = moment().utc().unix();
            }

            if (!bufferRequests.hasOwnProperty(id)) {
                bufferRequests[id] = params;
            }
        }

        var position = contractTypeDisplayMapping(type);
        var container = document.getElementById('price_container_'+position);

        var h4 = container.getElementsByClassName('contract_heading')[0],
            amount = container.getElementsByClassName('contract_amount')[0],
            purchase = container.getElementsByClassName('purchase_button')[0],
            description = container.getElementsByClassName('contract_description')[0],
            comment = container.getElementsByClassName('price_comment')[0],
            error = container.getElementsByClassName('contract_error')[0];

        var display = type ? (contractType ? contractType[type] : '') : '';
        if (display) {
            h4.setAttribute('class', 'contract_heading ' + display.toLowerCase().replace(/ /g, '_'));
            h4.textContent = display;
        }

        if (proposal['ask_price']) {
            amount.textContent = document.getElementById('currency').value + ' ' + proposal['ask_price'];
        }

        if (proposal['longcode']) {
            proposal['longcode'] = proposal['longcode'].replace(/\d+\.\d\d/,function(x){return ''+x+'';});
            description.innerHTML = proposal['longcode'];
        }

        if (details['error']){
            purchase.hide();
            comment.hide();
            error.show();
            error.textContent = details['error'].message;
        }
        else{
            purchase.show();
            comment.show();
            error.hide();
            displayCommentPrice(comment, document.getElementById('currency').value, proposal['ask_price'], proposal['payout']);
            var oldprice = purchase.getAttribute('data-ask-price');
            if (oldprice) {
                displayPriceMovement(amount, oldprice, proposal['ask_price']);
            }
            purchase.setAttribute('data-purchase-id', id);
            purchase.setAttribute('data-ask-price', proposal['ask_price']);
            purchase.setAttribute('data-symbol', id);
            for(var key in bufferRequests[id]){
                if(key && key !== 'proposal'){
                    purchase.setAttribute('data-'+key, bufferRequests[id][key]);
                }
            }
        }
    };

    var clearMapping = function () {
        typeDisplayIdMapping = {};
    };

    return {
        proposal: createProposal,
        display: display,
        clearMapping: clearMapping,
        idDisplayMapping: function () { return typeDisplayIdMapping; },
        bufferedIds: function () { return bufferedIds; }
    };

})();
<commit_msg>change amount_val to amount<commit_after>/*
 * Price object handles all the functions we need to display prices
 *
 * We create Price proposal that we need to send to server to get price,
 * longcode and all other information that we need to get the price for
 * current contract
 *
 *
 * Usage:
 *
 * `socket.send(Price.createProposal())` to send price proposal to sever
 * `Price.display()` to display the price details returned from server
 */
var Price = (function () {
    'use strict';

    var typeDisplayIdMapping = {},
        bufferedIds = {},
        bufferRequests = {};

    var createProposal = function (typeOfContract) {
        var proposal = {proposal: 1}, underlying = document.getElementById('underlying'),
            submarket = document.getElementById('submarket'),
            contractType = typeOfContract,
            amountType = document.getElementById('amount_type'),
            currency = document.getElementById('currency'),
            payout = document.getElementById('amount'),
            startTime = document.getElementById('date_start'),
            expiryType = document.getElementById('expiry_type'),
            duration = document.getElementById('duration_amount'),
            durationUnit = document.getElementById('duration_units'),
            endDate = document.getElementById('expiry_date'),
            endTime = document.getElementById('expiry_time'),
            barrier = document.getElementById('barrier'),
            highBarrier = document.getElementById('barrier_high'),
            lowBarrier = document.getElementById('barrier_low'),
            prediction = document.getElementById('prediction'),
            amountPerPoint = document.getElementById('amount_per_point'),
            stopType = document.querySelector('input[name="stop_type"]:checked'),
            stopLoss = document.getElementById('stop_loss'),
            stopProfit = document.getElementById('stop_profit');

        if (payout && isVisible(payout) && payout.value) {
            proposal['amount'] = parseFloat(payout.value);
        }

        if (amountType && isVisible(amountType) && amountType.value) {
            proposal['basis'] = amountType.value;
        }

        if (contractType) {
            proposal['contract_type'] = typeOfContract;
        }

        if (currency && currency.value) {
            proposal['currency'] = currency.value;
        }

        if (underlying && underlying.value) {
            proposal['symbol'] = underlying.value;
        }

        if (startTime && isVisible(startTime) && startTime.value !== 'now') {
            proposal['date_start'] = startTime.value;
        }

        if (expiryType && expiryType.value === 'duration') {
            proposal['duration'] = parseInt(duration.value);
            proposal['duration_unit'] = durationUnit.value;
        } else if (expiryType && expiryType.value === 'endtime') {
            proposal['date_expiry'] = moment.utc(endDate.value + " " + endTime.value).unix();
        }

        if (barrier && isVisible(barrier) && barrier.value) {
            proposal['barrier'] = parseFloat(barrier.value);
        }

        if (highBarrier && isVisible(highBarrier) && highBarrier.value) {
            proposal['barrier'] = parseFloat(highBarrier.value);
        }

        if (lowBarrier && isVisible(lowBarrier) && lowBarrier.value) {
            proposal['barrier2'] = parseFloat(lowBarrier.value);
        }

        if(prediction && isVisible(prediction)){
            proposal['barrier'] = parseInt(prediction.value);
        }

        if (amountPerPoint && isVisible(amountPerPoint)) {
            proposal['amount_per_point'] = parseFloat(amountPerPoint.value);
        }

        if (stopType && isVisible(stopType)) {
            proposal['stop_type'] = stopType.value;
        }

        if (stopLoss && isVisible(stopLoss)) {
            proposal['stop_loss'] = parseFloat(stopLoss.value);
        }

        if (stopProfit && isVisible(stopProfit)) {
            proposal['stop_profit'] = parseFloat(stopProfit.value);
        }

        return proposal;
    };

    var display = function (details, contractType) {
        var proposal = details['proposal'];
        var params = details['echo_req'],
            id = proposal['id'],
            type = params['contract_type'] || typeDisplayIdMapping[id];

        if (params && Object.getOwnPropertyNames(params).length > 0) {
            typeDisplayIdMapping[id] = type;

            if (!bufferedIds.hasOwnProperty(id)) {
                bufferedIds[id] = moment().utc().unix();
            }

            if (!bufferRequests.hasOwnProperty(id)) {
                bufferRequests[id] = params;
            }
        }

        var position = contractTypeDisplayMapping(type);
        var container = document.getElementById('price_container_'+position);

        var h4 = container.getElementsByClassName('contract_heading')[0],
            amount = container.getElementsByClassName('contract_amount')[0],
            purchase = container.getElementsByClassName('purchase_button')[0],
            description = container.getElementsByClassName('contract_description')[0],
            comment = container.getElementsByClassName('price_comment')[0],
            error = container.getElementsByClassName('contract_error')[0];

        var display = type ? (contractType ? contractType[type] : '') : '';
        if (display) {
            h4.setAttribute('class', 'contract_heading ' + display.toLowerCase().replace(/ /g, '_'));
            h4.textContent = display;
        }

        if (proposal['ask_price']) {
            amount.textContent = document.getElementById('currency').value + ' ' + proposal['ask_price'];
        }

        if (proposal['longcode']) {
            proposal['longcode'] = proposal['longcode'].replace(/\d+\.\d\d/,function(x){return ''+x+'';});
            description.innerHTML = proposal['longcode'];
        }

        if (details['error']){
            purchase.hide();
            comment.hide();
            error.show();
            error.textContent = details['error'].message;
        }
        else{
            purchase.show();
            comment.show();
            error.hide();
            displayCommentPrice(comment, document.getElementById('currency').value, proposal['ask_price'], proposal['payout']);
            var oldprice = purchase.getAttribute('data-ask-price');
            if (oldprice) {
                displayPriceMovement(amount, oldprice, proposal['ask_price']);
            }
            purchase.setAttribute('data-purchase-id', id);
            purchase.setAttribute('data-ask-price', proposal['ask_price']);
            purchase.setAttribute('data-symbol', id);
            for(var key in bufferRequests[id]){
                if(key && key !== 'proposal'){
                    purchase.setAttribute('data-'+key, bufferRequests[id][key]);
                }
            }
        }
    };

    var clearMapping = function () {
        typeDisplayIdMapping = {};
    };

    return {
        proposal: createProposal,
        display: display,
        clearMapping: clearMapping,
        idDisplayMapping: function () { return typeDisplayIdMapping; },
        bufferedIds: function () { return bufferedIds; }
    };

})();
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

// Various helper functions

import _  from 'lodash';
import sundial from 'sundial';

import { MGDL_UNITS, MMOLL_UNITS, MGDL_PER_MMOLL } from './constants';
import { utils as vizUtils } from '@tidepool/viz';

const { DEFAULT_BG_BOUNDS } = vizUtils.constants;

const utils = {};

/**
 * Convenience function for capitalizing a string
 *
 * @param  {String} str
 * @return {String}
 */
utils.capitalize = (str) => {
  return str.charAt(0).toUpperCase() + str.slice(1)
}

// Returns the value in a nested object,
// where `props` is the sequence of properties to follow.
// Returns `undefined` if the key is not present,
// or the `notFound` value if supplied
utils.getIn = (obj, props, notFound) => {
  var start = {
    child: obj,
    isNotFound: false
  };

  var result = _.reduce(props, (state, prop) => {
    if (state.isNotFound) {
      return state;
    }

    var child = state.child;
    if (!_.has(child, prop)) {
      return {
        child: notFound,
        isNotFound: true
      };
    }

    return {
      child: child[prop],
      isNotFound: false
    };
  }, start);

  return result.child;
};

utils.isChrome = () => {
  var userAgent = navigator.userAgent.toLowerCase();
  return (userAgent.indexOf('chrome') > -1 && userAgent.indexOf('edge') === -1);
};

utils.isMobile = () => {
  var userAgent = navigator.userAgent.toLowerCase();
  return (userAgent.indexOf('mobi') > -1);
};

utils.validateEmail = email => {
  var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return re.test(email);
};

// Shallow difference of two objects
// Returns all attributes and their values in `destination`
// that have different values from `source`
utils.objectDifference = (destination, source) => {
  var result = {};

  _.forEach(source, (sourceValue, key) => {
    var destinationValue = destination[key];
    if (!_.isEqual(sourceValue, destinationValue)) {
      result[key] = destinationValue;
    }
  });

  return result;
};

/**
 * Utility function to get whether page has changed or not
 *
 * @param  {Object} oldProps
 * @param  {[type]} newProps
 *
 * @return {Boolean}
 */
utils.isOnSamePage = (oldProps, newProps) => {
  return oldProps.location === newProps.location;
}

/**
 * Utility function to strip trailing slashes from a string
 *
 * @param  {str} string
 *
 * @return {String}
 */
utils.stripTrailingSlash = (str) => {
  return str.replace(/\/$/, '');
}

utils.buildExceptionDetails = () =>{
  return {
    href: window.location.href,
    stack: console.trace()
  };
};

utils.stringifyErrorData = data => {
  if(_.isEmpty(data)){
    return '';
  }

  if (_.isPlainObject(data)) {
    return JSON.stringify(data);
  }
  else {
    return data.toString();
  }
};

utils.getInviteEmail = function(location) {
  if (location && location.query) {

    let { inviteEmail } = location.query;

    if (!_.isEmpty(inviteEmail)) {
      // all standard query string parsers transform + to a space
      // so we reverse and swap spaces for +
      // in order to allow e-mails with mutators (e.g., +skip) to pass waitlist
      inviteEmail = inviteEmail.replace(/\s/, '+');

      if (utils.validateEmail(inviteEmail)) {
        return inviteEmail;
      }
    }
  }
  return null;
}

utils.getDonationAccountCodeFromEmail = function(email) {
  let matches = email.match(/\+(.*)@/) || [];
  return matches[1] || null;
}

utils.hasVerifiedEmail = function(user) {
  return (user.emailVerified);
}

utils.getSignupKey = function(location) {
  if (location && location.query) {
    let { signupKey } = location.query;

    if(!_.isEmpty(signupKey)){
      return signupKey;
    }
  }
  return false;
}

utils.getSignupEmail = function (location) {
  if (location && location.query) {
    let { signupEmail } = location.query;
    if (!_.isEmpty(signupEmail)) {
      // all standard query string parsers transform + to a space
      // so we reverse and swap spaces for +
      // in order to allow e-mails with mutators (e.g., +skip) to pass waitlist
      signupEmail = signupEmail.replace(/\s/, '+');

      if (utils.validateEmail(signupEmail)) {
        return signupEmail;
      }
    }
  }
  return null;
};

utils.getInviteKey = function(location) {
  if (location && location.query) {
    let { inviteKey } = location.query;

    if(!_.isEmpty(inviteKey)){
      return inviteKey;
    }
  }
  return '';
}

utils.getRoles = function(location) {
  if (location && location.query) {
    let { roles } = location.query;

    if(!_.isEmpty(roles)){
      let rolesFiltered = _.reject(_.map(roles.split(','), _.trim), _.isEmpty);

      if(!_.isEmpty(rolesFiltered)){
        return rolesFiltered;
      }
    }
  }
  return [];
}

utils.getCarelink = function(location) {
  if (location && location.query) {
    let { carelink } = location.query;

    if (!_.isUndefined(carelink)) {
      return carelink;
    }
  }
  return null;
}

utils.getDexcom = function(location) {
  if (location && location.query) {
    let { dexcom } = location.query;

    if (!_.isUndefined(dexcom)) {
      return dexcom;
    }
  }
  return null;
}

utils.getMedtronic = function(location) {
  if (location && location.query) {
    let { medtronic } = location.query;

    if (!_.isUndefined(medtronic)) {
      return medtronic;
    }
  }
  return null;
}

/**
 * Translate a BG value to the desired target unit
 *
 * @param {Number} a bg value
 * @param {String} one of [mg/dL, mmol/L] the units to convert to
 *
 * @return {Number} the converted value
 */
utils.translateBg = (value, targetUnits) => {
  if (targetUnits === MGDL_UNITS) {
    return parseInt(Math.round(value * MGDL_PER_MMOLL), 10);
  }
  return parseFloat((value / MGDL_PER_MMOLL).toFixed(1));
}

/**
 * Round a target BG value as appropriate
 * mg/dL - to the nearest 5
 * mmol/L - to the nearest .1
 *
 * @param {Number} a bg value
 * @param {String} one of [mg/dL, mmol/L] the units to convert to
 *
 * @return {Number} the converted value
 */
utils.roundBgTarget = (value, units) => {
  const nearest = units === MGDL_UNITS ? 5 : 0.1;
  const precision = units === MGDL_UNITS ? 0 : 1;
  return parseFloat((nearest * Math.round(value / nearest)).toFixed(precision));
}

utils.getTimePrefsForDataProcessing = (latestUpload, queryParams) => {
  var timePrefsForTideline;
  var browserTimezone = new Intl.DateTimeFormat().resolvedOptions().timeZone;

  try {
    sundial.checkTimezoneName(browserTimezone);
  } catch (err) {
    browserTimezone = false;
  }

  function setNewTimePrefs(timezoneName) {
    try {
      sundial.checkTimezoneName(timezoneName);
      timePrefsForTideline = {
        timezoneAware: true,
        timezoneName: timezoneName
      };
    } catch(err) {
      if (browserTimezone) {
        console.log('Not a valid timezone! Defaulting to browser timezone display:', browserTimezone);
        timePrefsForTideline = {
          timezoneAware: true,
          timezoneName: browserTimezone
        };
      }
      else {
        console.log('Not a valid timezone! Defaulting to timezone-naive display.');
        timePrefsForTideline = {};
      }
    }
  }

  // a timezone in the queryParams always overrides any other timePrefs
  if (!_.isEmpty(queryParams.timezone)) {
    setNewTimePrefs(queryParams.timezone);
    console.log('Displaying in timezone from query params:', queryParams.timezone);
  }
  else if (!_.isEmpty(latestUpload) && !_.isEmpty(latestUpload.timezone)) {
    setNewTimePrefs(latestUpload.timezone);
    console.log('Defaulting to display in timezone of most recent upload at', latestUpload.normalTime, latestUpload.timezone);
  }
  else if (browserTimezone) {
    setNewTimePrefs(browserTimezone);
    console.log('Falling back to browser timezone:', browserTimezone);
  }
  else {
    console.log('Falling back to timezone-naive display.');
  }
  return timePrefsForTideline;
};

utils.getBGPrefsForDataProcessing = (patientSettings, queryParams = {}) => {
  var bgUnits = _.get(patientSettings, 'units.bg', MGDL_UNITS);

  const low = _.get(patientSettings, 'bgTarget.low', DEFAULT_BG_BOUNDS[bgUnits].targetLowerBound);
  const high = _.get(patientSettings, 'bgTarget.high', DEFAULT_BG_BOUNDS[bgUnits].targetUpperBound);

  var bgClasses = {
    low: { boundary: utils.roundBgTarget(low, bgUnits) },
    target: { boundary: utils.roundBgTarget(high, bgUnits) },
  };

  // Allow overriding stored BG Unit preferences via query param
  const bgUnitsFormatted = bgUnits.replace('/', '').toLowerCase();
  if (!_.isEmpty(queryParams.units) && queryParams.units !== bgUnitsFormatted && _.includes([ 'mgdl', 'mmoll' ], queryParams.units)) {
    bgUnits = queryParams.units === 'mmoll' ? MMOLL_UNITS : MGDL_UNITS;
    bgClasses.low.boundary = utils.roundBgTarget(utils.translateBg(patientSettings.bgTarget.low, bgUnits), bgUnits);
    bgClasses.target.boundary = utils.roundBgTarget(utils.translateBg(patientSettings.bgTarget.high, bgUnits), bgUnits);
    console.log(`Displaying BG in ${bgUnits} from query params`);
  }

  return {
    bgUnits,
    bgClasses,
  };
}

// from http://bgrins.github.io/devtools-snippets/#console-save
// MIT license
(function(console) {

  console.save = function(data, filename){

    if(!data) {
      console.error('Console.save: No data');
      return;
    }

    if(!filename) filename = 'blip-output.json';

    if(typeof data === 'object'){
      data = JSON.stringify(data, undefined, 4);
    }

    var blob = new Blob([data], {type: 'text/json'});
    var e = document.createEvent('MouseEvents');
    var a = document.createElement('a');

    a.download = filename;
    a.href = window.URL.createObjectURL(blob);
    a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':');
    e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    a.dispatchEvent(e);
  };
})(console);

utils.getLatestGithubRelease = (releases) => {
  const latestRelease = _.filter(releases, {prerelease: false})[0];
  let latestTag = latestRelease.tag_name;
  const urlBase = `https://github.com/tidepool-org/uploader/releases/download/${latestTag}`;
  latestTag = latestTag.substr(1);
  const latestWinRelease = `${urlBase}/tidepool-uploader-setup-${latestTag}.exe`;
  const latestMacRelease = `${urlBase}/tidepool-uploader-${latestTag}.dmg`;
  return {
    latestWinRelease: latestWinRelease,
    latestMacRelease: latestMacRelease,
  };
}

export default utils;
<commit_msg>Allow using query param to fall back to deviceTime<commit_after>/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

// Various helper functions

import _  from 'lodash';
import sundial from 'sundial';

import { MGDL_UNITS, MMOLL_UNITS, MGDL_PER_MMOLL } from './constants';
import { utils as vizUtils } from '@tidepool/viz';

const { DEFAULT_BG_BOUNDS } = vizUtils.constants;

const utils = {};

/**
 * Convenience function for capitalizing a string
 *
 * @param  {String} str
 * @return {String}
 */
utils.capitalize = (str) => {
  return str.charAt(0).toUpperCase() + str.slice(1)
}

// Returns the value in a nested object,
// where `props` is the sequence of properties to follow.
// Returns `undefined` if the key is not present,
// or the `notFound` value if supplied
utils.getIn = (obj, props, notFound) => {
  var start = {
    child: obj,
    isNotFound: false
  };

  var result = _.reduce(props, (state, prop) => {
    if (state.isNotFound) {
      return state;
    }

    var child = state.child;
    if (!_.has(child, prop)) {
      return {
        child: notFound,
        isNotFound: true
      };
    }

    return {
      child: child[prop],
      isNotFound: false
    };
  }, start);

  return result.child;
};

utils.isChrome = () => {
  var userAgent = navigator.userAgent.toLowerCase();
  return (userAgent.indexOf('chrome') > -1 && userAgent.indexOf('edge') === -1);
};

utils.isMobile = () => {
  var userAgent = navigator.userAgent.toLowerCase();
  return (userAgent.indexOf('mobi') > -1);
};

utils.validateEmail = email => {
  var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return re.test(email);
};

// Shallow difference of two objects
// Returns all attributes and their values in `destination`
// that have different values from `source`
utils.objectDifference = (destination, source) => {
  var result = {};

  _.forEach(source, (sourceValue, key) => {
    var destinationValue = destination[key];
    if (!_.isEqual(sourceValue, destinationValue)) {
      result[key] = destinationValue;
    }
  });

  return result;
};

/**
 * Utility function to get whether page has changed or not
 *
 * @param  {Object} oldProps
 * @param  {[type]} newProps
 *
 * @return {Boolean}
 */
utils.isOnSamePage = (oldProps, newProps) => {
  return oldProps.location === newProps.location;
}

/**
 * Utility function to strip trailing slashes from a string
 *
 * @param  {str} string
 *
 * @return {String}
 */
utils.stripTrailingSlash = (str) => {
  return str.replace(/\/$/, '');
}

utils.buildExceptionDetails = () =>{
  return {
    href: window.location.href,
    stack: console.trace()
  };
};

utils.stringifyErrorData = data => {
  if(_.isEmpty(data)){
    return '';
  }

  if (_.isPlainObject(data)) {
    return JSON.stringify(data);
  }
  else {
    return data.toString();
  }
};

utils.getInviteEmail = function(location) {
  if (location && location.query) {

    let { inviteEmail } = location.query;

    if (!_.isEmpty(inviteEmail)) {
      // all standard query string parsers transform + to a space
      // so we reverse and swap spaces for +
      // in order to allow e-mails with mutators (e.g., +skip) to pass waitlist
      inviteEmail = inviteEmail.replace(/\s/, '+');

      if (utils.validateEmail(inviteEmail)) {
        return inviteEmail;
      }
    }
  }
  return null;
}

utils.getDonationAccountCodeFromEmail = function(email) {
  let matches = email.match(/\+(.*)@/) || [];
  return matches[1] || null;
}

utils.hasVerifiedEmail = function(user) {
  return (user.emailVerified);
}

utils.getSignupKey = function(location) {
  if (location && location.query) {
    let { signupKey } = location.query;

    if(!_.isEmpty(signupKey)){
      return signupKey;
    }
  }
  return false;
}

utils.getSignupEmail = function (location) {
  if (location && location.query) {
    let { signupEmail } = location.query;
    if (!_.isEmpty(signupEmail)) {
      // all standard query string parsers transform + to a space
      // so we reverse and swap spaces for +
      // in order to allow e-mails with mutators (e.g., +skip) to pass waitlist
      signupEmail = signupEmail.replace(/\s/, '+');

      if (utils.validateEmail(signupEmail)) {
        return signupEmail;
      }
    }
  }
  return null;
};

utils.getInviteKey = function(location) {
  if (location && location.query) {
    let { inviteKey } = location.query;

    if(!_.isEmpty(inviteKey)){
      return inviteKey;
    }
  }
  return '';
}

utils.getRoles = function(location) {
  if (location && location.query) {
    let { roles } = location.query;

    if(!_.isEmpty(roles)){
      let rolesFiltered = _.reject(_.map(roles.split(','), _.trim), _.isEmpty);

      if(!_.isEmpty(rolesFiltered)){
        return rolesFiltered;
      }
    }
  }
  return [];
}

utils.getCarelink = function(location) {
  if (location && location.query) {
    let { carelink } = location.query;

    if (!_.isUndefined(carelink)) {
      return carelink;
    }
  }
  return null;
}

utils.getDexcom = function(location) {
  if (location && location.query) {
    let { dexcom } = location.query;

    if (!_.isUndefined(dexcom)) {
      return dexcom;
    }
  }
  return null;
}

utils.getMedtronic = function(location) {
  if (location && location.query) {
    let { medtronic } = location.query;

    if (!_.isUndefined(medtronic)) {
      return medtronic;
    }
  }
  return null;
}

/**
 * Translate a BG value to the desired target unit
 *
 * @param {Number} a bg value
 * @param {String} one of [mg/dL, mmol/L] the units to convert to
 *
 * @return {Number} the converted value
 */
utils.translateBg = (value, targetUnits) => {
  if (targetUnits === MGDL_UNITS) {
    return parseInt(Math.round(value * MGDL_PER_MMOLL), 10);
  }
  return parseFloat((value / MGDL_PER_MMOLL).toFixed(1));
}

/**
 * Round a target BG value as appropriate
 * mg/dL - to the nearest 5
 * mmol/L - to the nearest .1
 *
 * @param {Number} a bg value
 * @param {String} one of [mg/dL, mmol/L] the units to convert to
 *
 * @return {Number} the converted value
 */
utils.roundBgTarget = (value, units) => {
  const nearest = units === MGDL_UNITS ? 5 : 0.1;
  const precision = units === MGDL_UNITS ? 0 : 1;
  return parseFloat((nearest * Math.round(value / nearest)).toFixed(precision));
}

utils.getTimePrefsForDataProcessing = (latestUpload, queryParams) => {
  var timePrefsForTideline;
  var browserTimezone = new Intl.DateTimeFormat().resolvedOptions().timeZone;

  try {
    sundial.checkTimezoneName(browserTimezone);
  } catch (err) {
    browserTimezone = false;
  }

  function setNewTimePrefs(timezoneName, fallbackToBrowserTimeZone = true) {
    try {
      sundial.checkTimezoneName(timezoneName);
      timePrefsForTideline = {
        timezoneAware: true,
        timezoneName: timezoneName
      };
    } catch(err) {
      if (fallbackToBrowserTimeZone && browserTimezone) {
        console.log('Not a valid timezone! Defaulting to browser timezone display:', browserTimezone);
        timePrefsForTideline = {
          timezoneAware: true,
          timezoneName: browserTimezone
        };
      }
      else {
        console.log('Not a valid timezone! Defaulting to timezone-naive display.');
        timePrefsForTideline = {
          timezoneAware: false,
        };
      }
    }
  }

  // a timezone in the queryParams always overrides any other timePrefs
  if (!_.isEmpty(queryParams.timezone)) {
    setNewTimePrefs(queryParams.timezone, false);
    console.log('Displaying in timezone from query params:', queryParams.timezone);
  }
  else if (!_.isEmpty(latestUpload) && !_.isEmpty(latestUpload.timezone)) {
    setNewTimePrefs(latestUpload.timezone);
    console.log('Defaulting to display in timezone of most recent upload at', latestUpload.normalTime, latestUpload.timezone);
  }
  else if (browserTimezone) {
    setNewTimePrefs(browserTimezone);
    console.log('Falling back to browser timezone:', browserTimezone);
  }
  else {
    console.log('Falling back to timezone-naive display.');
  }
  return timePrefsForTideline;
};

utils.getBGPrefsForDataProcessing = (patientSettings, queryParams = {}) => {
  var bgUnits = _.get(patientSettings, 'units.bg', MGDL_UNITS);

  const low = _.get(patientSettings, 'bgTarget.low', DEFAULT_BG_BOUNDS[bgUnits].targetLowerBound);
  const high = _.get(patientSettings, 'bgTarget.high', DEFAULT_BG_BOUNDS[bgUnits].targetUpperBound);

  var bgClasses = {
    low: { boundary: utils.roundBgTarget(low, bgUnits) },
    target: { boundary: utils.roundBgTarget(high, bgUnits) },
  };

  // Allow overriding stored BG Unit preferences via query param
  const bgUnitsFormatted = bgUnits.replace('/', '').toLowerCase();
  if (!_.isEmpty(queryParams.units) && queryParams.units !== bgUnitsFormatted && _.includes([ 'mgdl', 'mmoll' ], queryParams.units)) {
    bgUnits = queryParams.units === 'mmoll' ? MMOLL_UNITS : MGDL_UNITS;
    bgClasses.low.boundary = utils.roundBgTarget(utils.translateBg(patientSettings.bgTarget.low, bgUnits), bgUnits);
    bgClasses.target.boundary = utils.roundBgTarget(utils.translateBg(patientSettings.bgTarget.high, bgUnits), bgUnits);
    console.log(`Displaying BG in ${bgUnits} from query params`);
  }

  return {
    bgUnits,
    bgClasses,
  };
}

// from http://bgrins.github.io/devtools-snippets/#console-save
// MIT license
(function(console) {

  console.save = function(data, filename){

    if(!data) {
      console.error('Console.save: No data');
      return;
    }

    if(!filename) filename = 'blip-output.json';

    if(typeof data === 'object'){
      data = JSON.stringify(data, undefined, 4);
    }

    var blob = new Blob([data], {type: 'text/json'});
    var e = document.createEvent('MouseEvents');
    var a = document.createElement('a');

    a.download = filename;
    a.href = window.URL.createObjectURL(blob);
    a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':');
    e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    a.dispatchEvent(e);
  };
})(console);

utils.getLatestGithubRelease = (releases) => {
  const latestRelease = _.filter(releases, {prerelease: false})[0];
  let latestTag = latestRelease.tag_name;
  const urlBase = `https://github.com/tidepool-org/uploader/releases/download/${latestTag}`;
  latestTag = latestTag.substr(1);
  const latestWinRelease = `${urlBase}/tidepool-uploader-setup-${latestTag}.exe`;
  const latestMacRelease = `${urlBase}/tidepool-uploader-${latestTag}.dmg`;
  return {
    latestWinRelease: latestWinRelease,
    latestMacRelease: latestMacRelease,
  };
}

export default utils;
<|endoftext|>


<commit_before>(function(){
  'use strict';

  angular.module('ui.grid').directive('uiGridViewport', ['$log', 'gridUtil',
    function($log, gridUtil) {
      return {
        replace: true,
        scope: {},
        templateUrl: 'ui-grid/uiGridViewport',
        require: ['^uiGrid', '^uiGridRenderContainer'],
        link: function($scope, $elm, $attrs, controllers) {
          $log.debug('viewport post-link');

          var uiGridCtrl = controllers[0];
          var containerCtrl = controllers[1];

          $scope.containerCtrl = containerCtrl;

          var rowContainer = containerCtrl.rowContainer;
          var colContainer = containerCtrl.colContainer;

          var grid = uiGridCtrl.grid;

          $scope.grid = uiGridCtrl.grid;

          // Put the containers in scope so we can get rows and columns from them
          $scope.rowContainer = containerCtrl.rowContainer;
          $scope.colContainer = containerCtrl.colContainer;

          // Register this viewport with its container
          containerCtrl.viewport = $elm;

          $elm.on('scroll', function (evt) {
            var newScrollTop = $elm[0].scrollTop;
            // var newScrollLeft = $elm[0].scrollLeft;
            var newScrollLeft = gridUtil.normalizeScrollLeft($elm);

            // Handle RTL here

            if (newScrollLeft !== colContainer.prevScrollLeft) {
              var xDiff = newScrollLeft - colContainer.prevScrollLeft;

              var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
              var horizScrollPercentage = newScrollLeft / horizScrollLength;

              colContainer.adjustScrollHorizontal(newScrollLeft, horizScrollPercentage);
            }

            if (newScrollTop !== rowContainer.prevScrollTop) {
              var yDiff = newScrollTop - rowContainer.prevScrollTop;

              // uiGridCtrl.fireScrollingEvent({ y: { pixels: diff } });
              var vertScrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
              // var vertScrollPercentage = (uiGridCtrl.prevScrollTop + yDiff) / vertScrollLength;
              var vertScrollPercentage = newScrollTop / vertScrollLength;

              if (vertScrollPercentage > 1) { vertScrollPercentage = 1; }
              if (vertScrollPercentage < 0) { vertScrollPercentage = 0; }

              rowContainer.adjustScrollVertical(newScrollTop, vertScrollPercentage);
            }
          });
        }
      };
    }
  ]);

})();<commit_msg>Fix #1591 cellNav not scrolling header<commit_after>(function(){
  'use strict';

  angular.module('ui.grid').directive('uiGridViewport', ['$log', 'gridUtil',
    function($log, gridUtil) {
      return {
        replace: true,
        scope: {},
        templateUrl: 'ui-grid/uiGridViewport',
        require: ['^uiGrid', '^uiGridRenderContainer'],
        link: function($scope, $elm, $attrs, controllers) {
          $log.debug('viewport post-link');

          var uiGridCtrl = controllers[0];
          var containerCtrl = controllers[1];

          $scope.containerCtrl = containerCtrl;

          var rowContainer = containerCtrl.rowContainer;
          var colContainer = containerCtrl.colContainer;

          var grid = uiGridCtrl.grid;

          $scope.grid = uiGridCtrl.grid;

          // Put the containers in scope so we can get rows and columns from them
          $scope.rowContainer = containerCtrl.rowContainer;
          $scope.colContainer = containerCtrl.colContainer;

          // Register this viewport with its container
          containerCtrl.viewport = $elm;

          $elm.on('scroll', function (evt) {
            var newScrollTop = $elm[0].scrollTop;
            // var newScrollLeft = $elm[0].scrollLeft;
            var newScrollLeft = gridUtil.normalizeScrollLeft($elm);
            var horizScrollPercentage = -1;
            var vertScrollPercentage = -1;

            // Handle RTL here

            if (newScrollLeft !== colContainer.prevScrollLeft) {
              var xDiff = newScrollLeft - colContainer.prevScrollLeft;

              var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
              horizScrollPercentage = newScrollLeft / horizScrollLength;

              colContainer.adjustScrollHorizontal(newScrollLeft, horizScrollPercentage);
            }

            if (newScrollTop !== rowContainer.prevScrollTop) {
              var yDiff = newScrollTop - rowContainer.prevScrollTop;

              // uiGridCtrl.fireScrollingEvent({ y: { pixels: diff } });
              var vertScrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
              // var vertScrollPercentage = (uiGridCtrl.prevScrollTop + yDiff) / vertScrollLength;
              vertScrollPercentage = newScrollTop / vertScrollLength;

              if (vertScrollPercentage > 1) { vertScrollPercentage = 1; }
              if (vertScrollPercentage < 0) { vertScrollPercentage = 0; }

              rowContainer.adjustScrollVertical(newScrollTop, vertScrollPercentage);
            }

            if ( !$scope.grid.isScrollingVertically && !$scope.grid.isScrollingHorizontally ){
              // viewport scroll that didn't come from fireScrollEvent, so fire a scroll to keep
              // the header in sync
              var args = {};
              if ( horizScrollPercentage > -1 ){
                args.x = { percentage: horizScrollPercentage };
              }

              if ( vertScrollPercentage > -1 ){
                args.y = { percentage: vertScrollPercentage };
              }
              uiGridCtrl.fireScrollingEvent(args);
            }
          });
        }
      };
    }
  ]);

})();<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'

import {
  VISIBLITY_DIRECT, VISIBLITY_PRIVATE, VISIBLITY_UNLISTED, VISIBLITY_PUBLIC,
} from 'src/constants'
import TootPanel from './TootPanel'
import {AcctPropType, AccountPropType, StatusPropType} from 'src/propTypes'
import {TimelineActionPropTypes} from 'src/controllers/TimelineActions'
import {DropdownMenuButton, IconFont, UserIconWithHost, SafeContent, UserDisplayName, UserAcct} from '../parts'

export default class TimelineStatus extends React.Component {
  static propTypes = {
    subject: AcctPropType,
    account: AccountPropType.isRequired,
    status: StatusPropType.isRequired,
    reblog: StatusPropType,
    reblogAccount: AccountPropType,
    modifier: PropTypes.string,
    tokens: TootPanel.propTypes.tokens,
    onLockStatus: PropTypes.func,
    ...TimelineActionPropTypes,
  }

  /**
   * @constructor
   */
  constructor(...args) {
    super(...args)

    const {status, reblog} = this.props
    const mainStatus = reblog || status

    this.state = {
      isShowMediaCover: mainStatus.sensitive,
      isContentOpen: mainStatus.hasSpoilerText ? false : true,
      isShowReplyPanel: false,
      isAnimatedReplyPanel: true,
      isShowFavouritePanel: false,
      isAnimatedFavouritePanel: true,
      isShowReblogPanel: false,
      isAnimatedReblogPanel: true,
    }
  }

  /**
   * @override
   */
  componentWillUnmount() {
    if(this.unlockTimelineHandler) {
      this.unlockTimelineHandler()
      delete this.unlockTimelineHandler
    }
  }
  /**
   * @override
   */
  render() {
    const {status, reblog, account, reblogAccount, modifier} = this.props
    require('assert')(!reblog || (reblog && reblogAccount))
    const {isContentOpen, isShowReplyPanel} = this.state
    const mainStatus = reblog || status
    const mainAccount = reblogAccount || account
    const statusBodyClass = ['status-body']
    const onClickAvatar = this.onClickAvatar.bind(this, account)

    if(mainStatus.spoilerText.length) {
      statusBodyClass.push(
        'has-spoilerText',
        isContentOpen ? 'is-contentOpen' : 'is-contentClose'
      )
    }

    return (
      <article className={`status ${modifier ? `status--${modifier}` : ''}`}>

        {reblog && (

<IconFont iconName="reblog" />

              {account.display_name}さんにブーストされました

        )}

              <UserIconWithHost account={mainAccount} onClick={onClickAvatar} />

              <VisibilityIcon visibility={status.visibility} />

                <UserDisplayName account={account} onClick={onClickAvatar} />
                <UserAcct account={account} onClick={onClickAvatar} />

              {mainStatus.createdAt.fromNow()}

              {this.renderSpoilerText()}
              {isContentOpen && (

                  <SafeContent parsedContent={mainStatus.parsedContent} {...this.props} />

              )}

            {this.renderMedia()}

              <button
                className={`status-actionReply ${isShowReplyPanel ? 'is-active' : ''}`}
                onClick={::this.onClickToggleReply}>
                <IconFont iconName="reply" />
              </button>

              {status.canReblog()
                ? this.renderReblogButton()
                : <VisibilityIcon visibility={status.visibility} className="is-inactive" />
              }

              {this.renderFavButton()}

              <button className="status-actionMenu" style={{display: 'none'}}>
                <DropdownMenuButton onRenderMenu={::this.onRenderStatusMenu}>
                  <IconFont iconName="dot-3" />
                </DropdownMenuButton>
              </button>

        {isShowReplyPanel && this.renderReplyPanel()}
        {this.state.isShowReblogPanel && this.renderReblogPanel()}
        {this.state.isShowFavouritePanel && this.renderFavPanel()}

    )
  }

  renderSpoilerText() {
    const {status} = this.props
    const {isContentOpen} = this.state
    const mainStatus = status.reblog || status

    if(!mainStatus.hasSpoilerText)
      return null

    return (

        {mainStatus.spoilerText}
         this.setState({isContentOpen: !isContentOpen})}>
          {isContentOpen ? '閉じる' : 'もっと見る...'}

    )
  }

  renderMedia() {
    const {status, reblog} = this.props
    const {isShowMediaCover} = this.state
    const mainStatus = reblog || status
    const mediaList = mainStatus.media_attachments
    if(!mediaList.length)
      return null

    const className = [
      'status-mediaList',
      `status-mediaList${mediaList.length}`,
    ]
    if(mainStatus.sensitive) {
      className.push('is-sensitive')
    }

    return (

        {mediaList.map((media) => (
          <a key={media.id}
            className="status-media"
            style={{backgroundImage: `url(${media.preview_url})`}}
            target="_blank"
            href={media.url}
            onClick={this.onClickMedia.bind(this, media)}
            />
        ))}

        {isShowMediaCover && (

              不適切なコンテンツ

              クリックして表示

        )}
        {!isShowMediaCover && (
          <button className="status-buttonShowMediaListCover" onClick={::this.onClickMediaCover}>
            <IconFont iconName="eye-off" />
          </button>
        )}

    )
  }

  renderReblogButton() {
    const {status, tokens} = this.props
    const on = tokens.find((token) => status.isRebloggedAt(token.acct)) ? true : false

    const onClickHandler =
      tokens.length === 1
        ? this.props.onReblogStatus.bind(this, tokens[0], status, !on)
        : ::this.onClickToggleReblogPanel

    return (
      <button className="status-actionReblog" onClick={onClickHandler}>
        <IconFont iconName="reblog" className={on ? 'is-active' : ''} />
      </button>
    )
  }

  renderFavButton() {
    const {status, tokens} = this.props
    const on = tokens.find((token) => status.isFavouritedAt(token.acct)) ? true : false

    const onClickHandler =
      tokens.length === 1
        ? this.props.onFavouriteStatus.bind(this, tokens[0], status, !on)
        : ::this.onClickToggleFavouritePanel

    return (
      <button className="status-actionFavorite" onClick={onClickHandler}>
        <IconFont iconName="star-filled" className={on ? 'is-active' : ''} />
      </button>
    )
  }

  renderReplyPanel() {
    const {account, tokens, subject} = this.props
    const {isAnimatedReplyPanel} = this.state

    // デフォルトの返信元。 親Timelineの主題か、Statusと同じホストの最初のアカウントから選ぶ
    let sendFrom = subject
      ? [subject]
      : tokens.filter((t) => t.host === account.instance).map((t) => t.acct)

    return (
      <div className={`status-replyPanel ${isAnimatedReplyPanel ? 'off' : ''}`}>

          <TootPanel {...this.props}
            onSend={::this.onSendReply}
            initialSendFrom={sendFrom}
            initialContent={`@${account.acct} `}
            />

    )
  }

  renderReblogPanel() {
    const {tokens, status} = this.props
    const {isAnimatedReblogPanel} = this.state

    return (
      <div className={`status-reblogPanel ${isAnimatedReblogPanel ? 'off' : ''}`}>

            {tokens.map((token) => {
              const {account} = token
              const disabled = status.getIdByHost(token.host) ? false : true
              const on = status.isRebloggedAt(token.acct) ? true : false

              return (
                <li className={`${disabled ? 'is-disabled' : ''} ${on ? 'on' : ''}`}
                  key={token.acct}
                  onClick={(e) => !disabled && this.props.onReblogStatus(token, status, !on)}
                >
                  <IconFont iconName="reblog" className={on ? 'is-active' : ''} />
                  <UserIconWithHost account={account} size="mini" />
                  {account.acct}

              )
            })}

    )
  }

  renderFavPanel() {
    const {tokens, status} = this.props
    const {isAnimatedFavouritePanel} = this.state

    return (
      <div className={`status-favPanel ${isAnimatedFavouritePanel ? 'off' : ''}`}>

            {tokens.map((token) => {
              const {account} = token
              const disabled = status.getIdByHost(token.host) ? false : true
              const on = status.isFavouritedAt(token.acct) ? true : false

              return (
                <li className={`${disabled ? 'is-disabled' : ''} ${on ? 'on' : ''}`}
                  key={token.acct}
                  onClick={(e) => !disabled && this.props.onFavouriteStatus(token, status, !on)}
                >
                  <IconFont iconName="star-filled" className={on ? 'is-active' : ''} />
                  <UserIconWithHost account={account} size="mini" />
                  {account.acct}

              )
            })}

    )
  }

  // callbacks
  onClickAvatar(account, e) {
    e.preventDefault()

    this.props.onAvatarClicked(account)
  }

  onRenderStatusMenu(entry) {
    return (

hogehoge

    )
  }

  onClickMediaCover() {
    this.setState({isShowMediaCover: !this.state.isShowMediaCover})
  }

  onClickToggleReply(e) {
    e.preventDefault()
    this.togglePanel('ReplyPanel')
  }

  onClickToggleReblogPanel(e) {
    e.preventDefault()
    this.togglePanel('ReblogPanel')
  }

  onClickToggleFavouritePanel(e) {
    e.preventDefault()
    this.togglePanel('FavouritePanel')
  }

  togglePanel(panel) {
    const isShowKey = `isShow${panel}`

    if(this.state[isShowKey]) {
      // hide panel
      this.showHidePanel(false, panel)
      if(this.unlockTimelineHandler) {
        this.unlockTimelineHandler()
        delete this.unlockTimelineHandler
      }
    } else {
      // show panel
      if(!this.unlockTimelineHandler) {
        this.unlockTimelineHandler = this.props.onLockStatus && this.props.onLockStatus()
      }
      this.hideAllPanel()
        .then(() => this.showHidePanel(true, panel))
    }
  }

  hideAllPanel() {
    return Promise.all([
      this.showHidePanel(false, 'ReplyPanel'),
      this.showHidePanel(false, 'ReblogPanel'),
      this.showHidePanel(false, 'FavouritePanel'),
    ])
  }

  showHidePanel(show, panel) {
    const isShowKey = `isShow${panel}`

    if(this.state[isShowKey] === show)
      return Promise.resolve()

    return new Promise((resolve) => {
      if(show) {
        this.setState(
          {[`isShow${panel}`]: true, [`isAnimated${panel}`]: true},
          () => this.setState({[`isAnimated${panel}`]: false}, () => resolve())
        )
      } else {
        this.setState(
          {[`isShow${panel}`]: true, [`isAnimated${panel}`]: true},
          () => setTimeout(() => this.setState({[`isShow${panel}`]: false}, () => resolve()), 100)
        )
      }
    })
  }

  onClickMedia(media, e) {
    e.preventDefault()

    this.props.onClickMedia(media)
  }

  /**
   * TootPanel用のonSendをoverrideする。
   * Send完了時にTootPanelを閉じたい
   * @return {Promise}
   */
  onSendReply(...args) {
    return this.props.onSendReply(this.props.status, ...args)
      .then(() => {
        this.showHideReplyPanel(false)
      })
  }
}

function VisibilityIcon({visibility, className}) {
  let iconName
  switch(visibility) {
  case VISIBLITY_DIRECT:
    iconName = 'mail'
    break
  case VISIBLITY_PRIVATE:
    iconName = 'lock'
    break
  case VISIBLITY_UNLISTED:
    iconName = 'lock-open'
    break
  case VISIBLITY_PUBLIC:
    iconName = 'globe'
    break
  }

  return <IconFont className={className} iconName={iconName} />
}
<commit_msg>Replyの問題を修正<commit_after>import React from 'react'
import PropTypes from 'prop-types'

import {
  VISIBLITY_DIRECT, VISIBLITY_PRIVATE, VISIBLITY_UNLISTED, VISIBLITY_PUBLIC,
} from 'src/constants'
import TootPanel from './TootPanel'
import {AcctPropType, AccountPropType, StatusPropType} from 'src/propTypes'
import {TimelineActionPropTypes} from 'src/controllers/TimelineActions'
import {DropdownMenuButton, IconFont, UserIconWithHost, SafeContent, UserDisplayName, UserAcct} from '../parts'

export default class TimelineStatus extends React.Component {
  static propTypes = {
    subject: AcctPropType,
    account: AccountPropType.isRequired,
    status: StatusPropType.isRequired,
    reblog: StatusPropType,
    reblogAccount: AccountPropType,
    modifier: PropTypes.string,
    tokens: TootPanel.propTypes.tokens,
    onLockStatus: PropTypes.func,
    ...TimelineActionPropTypes,
  }

  /**
   * @constructor
   */
  constructor(...args) {
    super(...args)

    const {status, reblog} = this.props
    const mainStatus = reblog || status

    this.state = {
      isShowMediaCover: mainStatus.sensitive,
      isContentOpen: mainStatus.hasSpoilerText ? false : true,
      isShowReplyPanel: false,
      isAnimatedReplyPanel: true,
      isShowFavouritePanel: false,
      isAnimatedFavouritePanel: true,
      isShowReblogPanel: false,
      isAnimatedReblogPanel: true,
    }
  }

  /**
   * @override
   */
  componentWillUnmount() {
    if(this.unlockTimelineHandler) {
      this.unlockTimelineHandler()
      delete this.unlockTimelineHandler
    }
  }
  /**
   * @override
   */
  render() {
    const {status, reblog, account, reblogAccount, modifier} = this.props
    require('assert')(!reblog || (reblog && reblogAccount))
    const {isContentOpen, isShowReplyPanel} = this.state
    const mainStatus = reblog || status
    const mainAccount = reblogAccount || account
    const statusBodyClass = ['status-body']
    const onClickAvatar = this.onClickAvatar.bind(this, account)

    if(mainStatus.spoilerText.length) {
      statusBodyClass.push(
        'has-spoilerText',
        isContentOpen ? 'is-contentOpen' : 'is-contentClose'
      )
    }

    return (
      <article className={`status ${modifier ? `status--${modifier}` : ''}`}>

        {reblog && (

<IconFont iconName="reblog" />

              {account.display_name}さんにブーストされました

        )}

              <UserIconWithHost account={mainAccount} onClick={onClickAvatar} />

              <VisibilityIcon visibility={status.visibility} />

                <UserDisplayName account={account} onClick={onClickAvatar} />
                <UserAcct account={account} onClick={onClickAvatar} />

              {mainStatus.createdAt.fromNow()}

              {this.renderSpoilerText()}
              {isContentOpen && (

                  <SafeContent parsedContent={mainStatus.parsedContent} {...this.props} />

              )}

            {this.renderMedia()}

              <button
                className={`status-actionReply ${isShowReplyPanel ? 'is-active' : ''}`}
                onClick={::this.onClickToggleReply}>
                <IconFont iconName="reply" />
              </button>

              {status.canReblog()
                ? this.renderReblogButton()
                : <VisibilityIcon visibility={status.visibility} className="is-inactive" />
              }

              {this.renderFavButton()}

              <button className="status-actionMenu" style={{display: 'none'}}>
                <DropdownMenuButton onRenderMenu={::this.onRenderStatusMenu}>
                  <IconFont iconName="dot-3" />
                </DropdownMenuButton>
              </button>

        {isShowReplyPanel && this.renderReplyPanel()}
        {this.state.isShowReblogPanel && this.renderReblogPanel()}
        {this.state.isShowFavouritePanel && this.renderFavPanel()}

    )
  }

  renderSpoilerText() {
    const {status} = this.props
    const {isContentOpen} = this.state
    const mainStatus = status.reblog || status

    if(!mainStatus.hasSpoilerText)
      return null

    return (

        {mainStatus.spoilerText}
         this.setState({isContentOpen: !isContentOpen})}>
          {isContentOpen ? '閉じる' : 'もっと見る...'}

    )
  }

  renderMedia() {
    const {status, reblog} = this.props
    const {isShowMediaCover} = this.state
    const mainStatus = reblog || status
    const mediaList = mainStatus.media_attachments
    if(!mediaList.length)
      return null

    const className = [
      'status-mediaList',
      `status-mediaList${mediaList.length}`,
    ]
    if(mainStatus.sensitive) {
      className.push('is-sensitive')
    }

    return (

        {mediaList.map((media) => (
          <a key={media.id}
            className="status-media"
            style={{backgroundImage: `url(${media.preview_url})`}}
            target="_blank"
            href={media.url}
            onClick={this.onClickMedia.bind(this, media)}
            />
        ))}

        {isShowMediaCover && (

              不適切なコンテンツ

              クリックして表示

        )}
        {!isShowMediaCover && (
          <button className="status-buttonShowMediaListCover" onClick={::this.onClickMediaCover}>
            <IconFont iconName="eye-off" />
          </button>
        )}

    )
  }

  renderReblogButton() {
    const {status, tokens} = this.props
    const on = tokens.find((token) => status.isRebloggedAt(token.acct)) ? true : false

    const onClickHandler =
      tokens.length === 1
        ? this.props.onReblogStatus.bind(this, tokens[0], status, !on)
        : ::this.onClickToggleReblogPanel

    return (
      <button className="status-actionReblog" onClick={onClickHandler}>
        <IconFont iconName="reblog" className={on ? 'is-active' : ''} />
      </button>
    )
  }

  renderFavButton() {
    const {status, tokens} = this.props
    const on = tokens.find((token) => status.isFavouritedAt(token.acct)) ? true : false

    const onClickHandler =
      tokens.length === 1
        ? this.props.onFavouriteStatus.bind(this, tokens[0], status, !on)
        : ::this.onClickToggleFavouritePanel

    return (
      <button className="status-actionFavorite" onClick={onClickHandler}>
        <IconFont iconName="star-filled" className={on ? 'is-active' : ''} />
      </button>
    )
  }

  renderReplyPanel() {
    const {account, tokens, subject} = this.props
    const {isAnimatedReplyPanel} = this.state

    // デフォルトの返信元。 親Timelineの主題か、Statusと同じホストの最初のアカウントから選ぶ
    let sendFrom = subject
      ? [subject]
      : tokens.filter((t) => t.host === account.instance).map((t) => t.acct)

    return (
      <div className={`status-replyPanel ${isAnimatedReplyPanel ? 'off' : ''}`}>

          <TootPanel {...this.props}
            onSend={::this.onSendReply}
            initialSendFrom={sendFrom}
            initialContent={`@${account.acct} `}
            />

    )
  }

  renderReblogPanel() {
    const {tokens, status} = this.props
    const {isAnimatedReblogPanel} = this.state

    return (
      <div className={`status-reblogPanel ${isAnimatedReblogPanel ? 'off' : ''}`}>

            {tokens.map((token) => {
              const {account} = token
              const disabled = status.getIdByHost(token.host) ? false : true
              const on = status.isRebloggedAt(token.acct) ? true : false

              return (
                <li className={`${disabled ? 'is-disabled' : ''} ${on ? 'on' : ''}`}
                  key={token.acct}
                  onClick={(e) => !disabled && this.props.onReblogStatus(token, status, !on)}
                >
                  <IconFont iconName="reblog" className={on ? 'is-active' : ''} />
                  <UserIconWithHost account={account} size="mini" />
                  {account.acct}

              )
            })}

    )
  }

  renderFavPanel() {
    const {tokens, status} = this.props
    const {isAnimatedFavouritePanel} = this.state

    return (
      <div className={`status-favPanel ${isAnimatedFavouritePanel ? 'off' : ''}`}>

            {tokens.map((token) => {
              const {account} = token
              const disabled = status.getIdByHost(token.host) ? false : true
              const on = status.isFavouritedAt(token.acct) ? true : false

              return (
                <li className={`${disabled ? 'is-disabled' : ''} ${on ? 'on' : ''}`}
                  key={token.acct}
                  onClick={(e) => !disabled && this.props.onFavouriteStatus(token, status, !on)}
                >
                  <IconFont iconName="star-filled" className={on ? 'is-active' : ''} />
                  <UserIconWithHost account={account} size="mini" />
                  {account.acct}

              )
            })}

    )
  }

  // callbacks
  onClickAvatar(account, e) {
    e.preventDefault()

    this.props.onAvatarClicked(account)
  }

  onRenderStatusMenu(entry) {
    return (

hogehoge

    )
  }

  onClickMediaCover() {
    this.setState({isShowMediaCover: !this.state.isShowMediaCover})
  }

  onClickToggleReply(e) {
    e.preventDefault()
    this.togglePanel('ReplyPanel')
  }

  onClickToggleReblogPanel(e) {
    e.preventDefault()
    this.togglePanel('ReblogPanel')
  }

  onClickToggleFavouritePanel(e) {
    e.preventDefault()
    this.togglePanel('FavouritePanel')
  }

  togglePanel(panel) {
    const isShowKey = `isShow${panel}`

    if(this.state[isShowKey]) {
      // hide panel
      this.showHidePanel(false, panel)
      if(this.unlockTimelineHandler) {
        this.unlockTimelineHandler()
        delete this.unlockTimelineHandler
      }
    } else {
      // show panel
      if(!this.unlockTimelineHandler) {
        this.unlockTimelineHandler = this.props.onLockStatus && this.props.onLockStatus()
      }
      this.hideAllPanel()
        .then(() => this.showHidePanel(true, panel))
    }
  }

  hideAllPanel() {
    return Promise.all([
      this.showHidePanel(false, 'ReplyPanel'),
      this.showHidePanel(false, 'ReblogPanel'),
      this.showHidePanel(false, 'FavouritePanel'),
    ])
  }

  showHidePanel(show, panel) {
    const isShowKey = `isShow${panel}`

    if(this.state[isShowKey] === show)
      return Promise.resolve()

    return new Promise((resolve) => {
      if(show) {
        this.setState(
          {[`isShow${panel}`]: true, [`isAnimated${panel}`]: true},
          () => this.setState({[`isAnimated${panel}`]: false}, () => resolve())
        )
      } else {
        this.setState(
          {[`isShow${panel}`]: true, [`isAnimated${panel}`]: true},
          () => setTimeout(() => this.setState({[`isShow${panel}`]: false}, () => resolve()), 100)
        )
      }
    })
  }

  onClickMedia(media, e) {
    e.preventDefault()

    this.props.onClickMedia(media)
  }

  /**
   * TootPanel用のonSendをoverrideする。
   * Send完了時にTootPanelを閉じたい
   * @return {Promise}
   */
  onSendReply(...args) {
    return this.props.onSendReply(this.props.status, ...args)
      .then(() => {
        this.showHidePanel(false, 'ReplyPanel')
      })
  }
}

function VisibilityIcon({visibility, className}) {
  let iconName
  switch(visibility) {
  case VISIBLITY_DIRECT:
    iconName = 'mail'
    break
  case VISIBLITY_PRIVATE:
    iconName = 'lock'
    break
  case VISIBLITY_UNLISTED:
    iconName = 'lock-open'
    break
  case VISIBLITY_PUBLIC:
    iconName = 'globe'
    break
  }

  return <IconFont className={className} iconName={iconName} />
}
<|endoftext|>


<commit_before>"use strict"
var userToken = process.env.AGENDOR_TOKEN;
var agendorUrl = "https://api.agendor.com.br/v1/";
var request = require('request');

module.exports.nextTask = function nextTask(sendTextMessage, sender, res) {
  request({
    url: agendorUrl + "tasks",
    headers: {"Authorization": "Token " + userToken},
    qs: {page:1, per_page:1},
    method: 'GET'
  }, function(error, response, body) {
    if (error) {
      console.log('Error sending messages: ', error)
    } else if (response.body.error) {
      console.log('Error: ', response.body.error)
    }
    if (!error && response.statusCode == 200) {
      var text = formatTask(body[0]);
      console.log("Text");
      console.log(text);
      console.log("End Text");
      sendTextMessage(text, sender);
      res.sendStatus(200);
    }
  });
};

function formatTask(task) {
  var entity;
  var entityDesc;
  if (task.deal) {
    entityDesc = "o negócio";
    entity = task.deal.name;
  } else if (task.organization) {
    entityDesc = "a empresa";
    entity = task.organization.legalName;
  } else if (task.person) {
    entityDesc = "a pessoa";
    entity = task.person.name;
  }

  var text = task.text;
  var dueDate = task.dueDate;

  var textMessage = "Você possuí uma tarefa para " + entityDesc + ": " + entity + " ";
  if (dueDate) {
    textMessage += "às " + dueDate;
  }
  if (text) {
    textMessage += "\n Descrição:\n" + text;
  }
  console.log("Text Message");
  console.log(task);
  console.log("End Text Message");
  return textMessage;
}
<commit_msg>Fix some issues<commit_after>"use strict"
var userToken = process.env.AGENDOR_TOKEN;
var agendorUrl = "https://api.agendor.com.br/v1/";
var request = require('request');

module.exports.nextTask = function nextTask(sendTextMessage, sender, res) {
  request({
    url: agendorUrl + "tasks",
    headers: {"Authorization": "Token " + userToken},
    qs: {page:1, per_page:1},
    method: 'GET'
  }, function(error, response, body) {
    if (error) {
      console.log('Error sending messages: ', error)
    } else if (response.body.error) {
      console.log('Error: ', response.body.error)
    }
    console.log("statusCode");
    console.log(response.statusCode);
    console.log("end statusCode");
    if (!error && response.statusCode == 200) {
      var text = formatTask(body[0]);
      console.log("Text");
      console.log(text);
      console.log("End Text");
      sendTextMessage(text, sender);
      res.sendStatus(200);
    }
  });
};

function formatTask(task) {
  var entity;
  var entityDesc;
  if (task.deal) {
    entityDesc = "o negócio";
    entity = task.deal.name;
  } else if (task.organization) {
    entityDesc = "a empresa";
    entity = task.organization.legalName;
  } else if (task.person) {
    entityDesc = "a pessoa";
    entity = task.person.name;
  }

  var text = task.text;
  var dueDate = task.dueDate;

  var textMessage = "Você possuí uma tarefa para " + entityDesc + ": " + entity + " ";
  if (dueDate) {
    textMessage += "às " + dueDate;
  }
  if (text) {
    textMessage += "\n Descrição:\n" + text;
  }
  console.log("Text Message");
  console.log(task);
  console.log("End Text Message");
  return textMessage;
}
<|endoftext|>


<commit_before>var cloudIDList = [];

function newCloudID(){
	var newID = "cloud" + cloudIDList.length;
	cloudIDList.push(newID);
	return newID;
}

Cloud.prototype.id = ""; //String
Cloud.prototype.xCoord = 0; //Double
Cloud.prototype.yCoord = 0; //Double
Cloud.prototype.text = 'ins'; //String
Cloud.prototype.boardSize = 100; //Double

function Cloud(x, y, boardID, text){
	this.id = newCloudID();
	this.xCoord = x || 0;
	this.yCoord = y || 0;
	this.text = text || 'null';
	this.boardSize = board.size;
	console.log('new cloud: ' + this.id + " at (" + this.xCoord + ", " + this.yCoord + "):");
	if(printed){
		document.getElementById(boardID + '-clouds').innerHTML += this.toHTML();
		board.clouds.push(this);
	}
}

/*function checkNewPosition(initial, increment, limit){
	var
	if((initial + increment) > limit){

	}
}*/

Cloud.prototype.update = function(roadSize, newBoardSize){
	var exists = true;
	var oldBoardSize = this.boardSize;
	if(printed){
		var xNew = (this.xCoord / oldBoardSize) * newBoardSize;
		var yNew = (this.yCoord / oldBoardSize) * newBoardSize;
		this.xCoord = xNew + (Math.random() - 0.5) * (roadSize / 4);
		this.yCoord = yNew + (Math.random() - 0.5) * (roadSize / 4);
		/*var magnitude = roadSize * 2;
		var xRand = Math.random() * magnitude - (magnitude / 2);
		var yRand = Math.random() * magnitude - (magnitude / 2);
		var xLo = this.xCoord > (boardSize * 0.1);
		var xHi = this.xCoord < ((boardSize * 0.9) - roadSize);
		var yLo = this.yCoord > (boardSize * 0.1);
		var yHi = this.yCoord < ((boardSize * 0.9) - roadSize);
		if(xHi && yHi){
			this.xCoord += xRand;
			this.yCoord += yRand;
		}
		else if(xLo && yLo){
			this.xCoord -= xRand;
			this.yCoord -= yRand;
		}*/
		if(document.getElementById(this.id)){
			document.getElementById(this.id).style.marginLeft = this.xCoord + 'px';
			document.getElementById(this.id).style.marginTop = this.yCoord + 'px';
		}
		else{
			exists = false;
			console.log('cloud.update() ' + this.id + " DNE")
		}
	}
	this.boardSize = newBoardSize;
	return exists;
}

Cloud.prototype.toHTML = function(){
	var html = '';
	html += '
';
	html += this.text + '
';
	return html;
}

Cloud.prototype.toString = function(){
	return this.id + " at {" + this.xCoord + ", " + this.yCoord + "}";
}<commit_msg>Added cloud.deviance variabl<commit_after>var cloudIDList = [];

function newCloudID(){
	var newID = "cloud" + cloudIDList.length;
	cloudIDList.push(newID);
	return newID;
}

Cloud.prototype.id = ""; //String
Cloud.prototype.xCoord = 0; //Double
Cloud.prototype.yCoord = 0; //Double
Cloud.prototype.text = 'ins'; //String
Cloud.prototype.boardSize = 100; //Double
Cloud.prototype.deviance = 0; //Double

function Cloud(x, y, boardID, text){
	this.id = newCloudID();
	this.xCoord = x || 0;
	this.yCoord = y || 0;
	this.text = text || 'null';
	this.boardSize = board.size;
	this.deviance = 0;
	console.log('new cloud: ' + this.id + " at (" + this.xCoord + ", " + this.yCoord + "):");
	if(printed){
		document.getElementById(boardID + '-clouds').innerHTML += this.toHTML();
		board.clouds.push(this);
	}
}

/*function checkNewPosition(initial, increment, limit){
	var
	if((initial + increment) > limit){

	}
}*/

Cloud.prototype.update = function(roadSize, newBoardSize){
	var exists = true;
	var oldBoardSize = this.boardSize;
	if(printed){
		var xNew = (this.xCoord / oldBoardSize) * newBoardSize;
		var yNew = (this.yCoord / oldBoardSize) * newBoardSize;
		var xRand = (Math.random() - 0.5) * (roadSize / 2);
		var yRand = (Math.random() - 0.5) * (roadSize / 2);
		this.deviance += (xRand + yRand);
		if(Math.abs(this.deviance) > 0){
			xRand = 0;
			yRand = 0;
		}
		this.xCoord = xNew + xRand;
		this.yCoord = yNew + yRand;
		/*var magnitude = roadSize * 2;
		var xRand = Math.random() * magnitude - (magnitude / 2);
		var yRand = Math.random() * magnitude - (magnitude / 2);
		var xLo = this.xCoord > (boardSize * 0.1);
		var xHi = this.xCoord < ((boardSize * 0.9) - roadSize);
		var yLo = this.yCoord > (boardSize * 0.1);
		var yHi = this.yCoord < ((boardSize * 0.9) - roadSize);
		if(xHi && yHi){
			this.xCoord += xRand;
			this.yCoord += yRand;
		}
		else if(xLo && yLo){
			this.xCoord -= xRand;
			this.yCoord -= yRand;
		}*/
		if(document.getElementById(this.id)){
			document.getElementById(this.id).style.marginLeft = this.xCoord + 'px';
			document.getElementById(this.id).style.marginTop = this.yCoord + 'px';
		}
		else{
			exists = false;
			console.log('cloud.update() ' + this.id + " DNE")
		}
	}
	this.boardSize = newBoardSize;
	return exists;
}

Cloud.prototype.toHTML = function(){
	var html = '';
	html += '
';
	html += this.text + '
';
	return html;
}

Cloud.prototype.toString = function(){
	return this.id + " at {" + this.xCoord + ", " + this.yCoord + "}";
}<|endoftext|>


<commit_before>import Ember from 'ember';

const { inject } = Ember;

export default Ember.Route.extend({
  notify: inject.service('notify'),

  titleToken: Ember.computed.readOnly('controller.model.description'),

  beforeModel () {
    return this.session.fetch('github-oauth2').catch(function() {
      // Swallow error for now
    });
  },

  deactivate () {
    var gist = this.controller.get('model');
    if (gist.get('isNew')) {
      this.store.unloadRecord(gist);
    }
  },

  actions: {
    saveGist (gist) {
      var newGist = gist.get('isNew');
      if (!newGist && gist.get('ownerLogin') !== this.get('session.currentUser.login')) {
        this.send('fork', gist);
        return;
      }
      gist.save().then(() => {
        this.get('notify').info(`Saved to Gist ${gist.get('id')} on Github`);
        if(newGist) {
          this.transitionTo('gist.edit', gist).then(function() {
            this.send('setSaved');
          });
        } else {
          this.send('setSaved');
        }
      });
    },

    setSaved () {
      this.get('controller').set('unsaved', false);
    },

    fork (gist) {
      gist.fork().then((response) => {
        this.get('store').find('gist', response.id).then((newGist) => {
          gist.get('files').toArray().forEach((file) => {
            file.set('gist', newGist);
          });
          return newGist.save().then(() => {
            this.transitionTo('gist.edit', newGist);
          });
        });
      }).catch(this.catchForkError.bind(this));
    },

    copy () {
      this.transitionTo('gist.new', {
        queryParams: {
          copyCurrentTwiddle: true
        }
      });
    },

    signInViaGithub () {
      this.session.open('github-oauth2').catch(function(error) {
        alert('Could not sign you in: ' + error.message);
        throw error;
      });
    },

    signOut () {
      this.session.close();
    },

    showTwiddles: function() {
      this.transitionTo('twiddles');
    }
  },

  catchForkError(error) {
    if (error && error.errors) {
      let firstError = error.errors[0];
      if (firstError.code === "unprocessable" && firstError.field === "forks") {
        this.get('notify').info("You already own this gist.");
        return;
      }
    }
    throw error;
  }
});
<commit_msg>Use arrow function to preserve this.<commit_after>import Ember from 'ember';

const { inject } = Ember;

export default Ember.Route.extend({
  notify: inject.service('notify'),

  titleToken: Ember.computed.readOnly('controller.model.description'),

  beforeModel () {
    return this.session.fetch('github-oauth2').catch(function() {
      // Swallow error for now
    });
  },

  deactivate () {
    var gist = this.controller.get('model');
    if (gist.get('isNew')) {
      this.store.unloadRecord(gist);
    }
  },

  actions: {
    saveGist (gist) {
      var newGist = gist.get('isNew');
      if (!newGist && gist.get('ownerLogin') !== this.get('session.currentUser.login')) {
        this.send('fork', gist);
        return;
      }
      gist.save().then(() => {
        this.get('notify').info(`Saved to Gist ${gist.get('id')} on Github`);
        if(newGist) {
          this.transitionTo('gist.edit', gist).then(() => {
            this.send('setSaved');
          });
        } else {
          this.send('setSaved');
        }
      });
    },

    setSaved () {
      this.get('controller').set('unsaved', false);
    },

    fork (gist) {
      gist.fork().then((response) => {
        this.get('store').find('gist', response.id).then((newGist) => {
          gist.get('files').toArray().forEach((file) => {
            file.set('gist', newGist);
          });
          return newGist.save().then(() => {
            this.transitionTo('gist.edit', newGist);
          });
        });
      }).catch(this.catchForkError.bind(this));
    },

    copy () {
      this.transitionTo('gist.new', {
        queryParams: {
          copyCurrentTwiddle: true
        }
      });
    },

    signInViaGithub () {
      this.session.open('github-oauth2').catch(function(error) {
        alert('Could not sign you in: ' + error.message);
        throw error;
      });
    },

    signOut () {
      this.session.close();
    },

    showTwiddles: function() {
      this.transitionTo('twiddles');
    }
  },

  catchForkError(error) {
    if (error && error.errors) {
      let firstError = error.errors[0];
      if (firstError.code === "unprocessable" && firstError.field === "forks") {
        this.get('notify').info("You already own this gist.");
        return;
      }
    }
    throw error;
  }
});
<|endoftext|>