<commit_before>'use strict';

// "Windowing desktop"
//
// Manages draggable iframes (drag from their edges, like real windows, but on the same page)

let maxZindex = 0;

function createDraggableIframe(pid) {
  const container = document.createElement('div');
  const iframe = document.createElement('iframe');

  const id = 'userland-process-' + pid;
  iframe.setAttribute('id', id);

  container.setAttribute('id', 'container-' + id);
  container.setAttribute('style', `
background: silver;
border-width: 5px;
border-radius: 10px;
padding: 8px;
border-style: groove;
cursor: move;
/* Tile windows TODO: automatic organization, non-overlapping mode */
position: absolute;
top: ${20 * pid}px;
left: ${20 * pid}px;
`);

  container.setAttribute('draggable', 'true');

  container.addEventListener('click', (event) => {
    maxZindex += 1;
    container.style.zIndex = maxZindex; // bring to top
  });

  container.addEventListener('dragstart', (event) => {
    const style = window.getComputedStyle(event.target, null);
    event.dataTransfer.dragEffect = 'move';
    event.dataTransfer.setData('text/plain', container.getAttribute('id') + ',' +
      (parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"),10) - event.clientY));
    iframe.style.visibility = 'hidden'; // temporarily hide to allow mouse events through
  });
  container.addEventListener('dragend', (event) => {
    console.log('dragend',event);
    iframe.style.visibility = '';
  });

  const titlebar = document.createElement('div');
  titlebar.setAttribute('id', 'titlebar-' + id);
  titlebar.setAttribute('style', `
width: 100%;
height: 20px;
background: #001caf;
color: white;
font-weight: bold;
`);
  titlebar.textContent = `New process ${pid}`;

  container.appendChild(titlebar);
  container.appendChild(iframe);

  return {iframe, container, titlebar};
}

document.body.addEventListener('dragover', (event) => {
  event.preventDefault();
  return false;
}, false);

document.body.addEventListener('drop', (event) => {
  const offset = event.dataTransfer.getData('text/plain').split(',');
  const dm = document.getElementById(offset[0]);
  dm.style.left = (event.clientX + parseInt(offset[1],10)) + 'px';
  dm.style.top = (event.clientY + parseInt(offset[2],10)) + 'px';
  event.preventDefault();
  return false;
}, false);

module.exports = {
  createDraggableIframe,
};
<commit_msg>Dragging windows also brings to top, not only clicking<commit_after>'use strict';

// "Windowing desktop"
//
// Manages draggable iframes (drag from their edges, like real windows, but on the same page)

let maxZindex = 0;

function createDraggableIframe(pid) {
  const container = document.createElement('div');
  const iframe = document.createElement('iframe');

  const id = 'userland-process-' + pid;
  iframe.setAttribute('id', id);

  container.setAttribute('id', 'container-' + id);
  container.setAttribute('style', `
background: silver;
border-width: 5px;
border-radius: 10px;
padding: 8px;
border-style: groove;
cursor: move;
/* Tile windows TODO: automatic organization, non-overlapping mode */
position: absolute;
top: ${20 * pid}px;
left: ${20 * pid}px;
`);

  container.setAttribute('draggable', 'true');

  function bringToTop() {
    maxZindex += 1;
    container.style.zIndex = maxZindex;
  }

  container.addEventListener('click', (event) => {
    bringToTop();
  });

  container.addEventListener('dragstart', (event) => {
    bringToTop();
    const style = window.getComputedStyle(event.target, null);
    event.dataTransfer.dragEffect = 'move';
    event.dataTransfer.setData('text/plain', container.getAttribute('id') + ',' +
      (parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"),10) - event.clientY));
    iframe.style.visibility = 'hidden'; // temporarily hide to allow mouse events through
  });
  container.addEventListener('dragend', (event) => {
    console.log('dragend',event);
    iframe.style.visibility = '';
  });

  const titlebar = document.createElement('div');
  titlebar.setAttribute('id', 'titlebar-' + id);
  titlebar.setAttribute('style', `
width: 100%;
height: 20px;
background: #001caf;
color: white;
font-weight: bold;
`);
  titlebar.textContent = `New process ${pid}`;

  container.appendChild(titlebar);
  container.appendChild(iframe);

  return {iframe, container, titlebar};
}

document.body.addEventListener('dragover', (event) => {
  event.preventDefault();
  return false;
}, false);

document.body.addEventListener('drop', (event) => {
  const offset = event.dataTransfer.getData('text/plain').split(',');
  const dm = document.getElementById(offset[0]);
  dm.style.left = (event.clientX + parseInt(offset[1],10)) + 'px';
  dm.style.top = (event.clientY + parseInt(offset[2],10)) + 'px';
  event.preventDefault();
  return false;
}, false);

module.exports = {
  createDraggableIframe,
};
<|endoftext|>


<commit_before>const worker = new Worker(new URL('./worker.js', import.meta.url));
import LS from './localStorage';

import seeds from './seeds';
import emitter from 'lib/emitter';
import crypto from 'crypto';
import encryption from 'lib/encryption';
import request from 'lib/request';
import Storage from 'lib/storage';
import { unlock, lock } from 'lib/wallet/security';

import CsWallet from '@coinspace/cs-wallet';
import EthereumWallet from '@coinspace/cs-ethereum-wallet';
import BinanceSmartChainWallet from '@coinspace/cs-binance-smart-chain-wallet';
import RippleWallet from '@coinspace/cs-ripple-wallet';
import StellarWallet from '@coinspace/cs-stellar-wallet';
import EOSWallet from '@coinspace/cs-eos-wallet';
import MoneroWallet from '@coinspace/cs-monero-wallet';

import { eddsa } from 'elliptic';

const ec = new eddsa('ed25519');
import touchId from 'lib/touch-id';
import ticker from 'lib/ticker-api';
import convert from 'lib/convert';
import { getCrypto, walletCoins } from 'lib/crypto';
import details from 'lib/wallet/details';
import settings from 'lib/wallet/settings';
import bchaddr from 'bchaddrjs';

const state = {
  wallet: null,
};

const Wallet = {
  bitcoin: CsWallet,
  bitcoincash: CsWallet,
  bitcoinsv: CsWallet,
  litecoin: CsWallet,
  ethereum: EthereumWallet,
  ripple: RippleWallet,
  stellar: StellarWallet,
  eos: EOSWallet,
  dogecoin: CsWallet,
  dash: CsWallet,
  monero: MoneroWallet,
  'binance-smart-chain': BinanceSmartChainWallet,
};

function createWallet(passphrase) {
  const data = { passphrase };
  return new Promise((resolve, reject) => {
    worker.onmessage = function(event) {
      seeds.set('private', event.data.seed);
      resolve({ mnemonic: event.data.mnemonic });
    };
    worker.onerror = function(event) {
      event.preventDefault();
      reject(new Error('Invalid passphrase'));
    };
    worker.postMessage(data);
  });
}

async function registerWallet(pin) {
  const pinKey = crypto.randomBytes(32).toString('hex');
  const walletSeed = seeds.get('private');
  const wallet = ec.keyFromSecret(walletSeed);
  const deviceSeed = crypto.randomBytes(32).toString('hex');
  const device = ec.keyFromSecret(deviceSeed);
  const deviceId = device.getPublic('hex');
  const pinHash = crypto.createHmac('sha256', Buffer.from(pinKey, 'hex')).update(pin).digest('hex');
  const detailsKey = crypto.createHmac('sha256', 'Coin Wallet').update(walletSeed).digest('hex');
  const { publicToken, privateToken } = await request({
    url: `${process.env.SITE_URL}api/v2/register`,
    method: 'post',
    data: {
      walletId: wallet.getPublic('hex'),
      deviceId,
      pinHash,
    },
    seed: 'private',
    id: false,
  });
  seeds.set('public', deviceSeed);
  LS.setEncryptedSeed('public', encryption.encrypt(deviceSeed, publicToken));
  LS.setEncryptedSeed('private', encryption.encrypt(walletSeed, privateToken));
  LS.setPinKey(pinKey);
  LS.setId(deviceId);
  LS.setDetailsKey(detailsKey);
  await Promise.all([details.init(), settings.init()]);
  emitter.emit('auth-success', pin);
  await initWallet(walletSeed);
}

async function loginWithPin(pin) {
  if (LS.isRegisteredLegacy()) {
    return migrateLegacyWallet(pin);
  }
  const pinHash = crypto.createHmac('sha256', Buffer.from(LS.getPinKey(), 'hex')).update(pin).digest('hex');
  const { publicToken } = await request({
    url: `${process.env.SITE_URL}api/v2/token/public/pin`,
    method: 'post',
    data: {
      pinHash,
    },
    id: true,
  });
  seeds.unlock('public', publicToken);
  await Promise.all([details.init(), settings.init()]);
  emitter.emit('auth-success');
  await initWallet();
}

async function loginWithTouchId(widget) {
  if (process.env.BUILD_TYPE === 'phonegap') {
    await touchId.phonegap();
    widget && widget.loading();
    const pin = LS.getPin();
    if (LS.isRegisteredLegacy()) {
      return migrateLegacyWallet(pin);
    }
    return loginWithPin(pin);
  } else {
    const { publicToken } = await touchId.publicToken(widget);
    seeds.unlock('public', publicToken);
    await Promise.all([details.init(), settings.init()]);
    emitter.emit('auth-success');
    await initWallet();
  }
}

export async function initWallet(seed) {
  const crypto = getCrypto();

  if (seed) {
    for (const key of Object.keys(Wallet)) {
      const wallet = new Wallet[key]({
        seed,
        networkName: key,
        ...await getExtraOptions({ network: key }),
      });
      wallet.lock();
      LS.setPublicKey(wallet, seeds.get('public'));
    }
  }

  const publicKey = LS.getPublicKey(crypto.network, seeds.get('public'));
  state.wallet = new Wallet[crypto.network]({
    publicKey,
    networkName: crypto.network,
    ...await getExtraOptions(crypto),
  });

  convert.setDecimals(state.wallet.decimals);

  await ticker.init([crypto]);

  try {
    await state.wallet.load();

    emitter.emit('wallet-ready');
  } catch (err) {
    emitter.emit('wallet-error', err);
  }
}

async function getExtraOptions(crypto) {
  const options = {
    useTestNetwork: process.env.COIN_NETWORK === 'regtest',
  };

  if (crypto.network === 'bitcoin') {
    options.apiNode = process.env.API_BTC_URL;
  } else if (crypto.network === 'bitcoincash') {
    options.apiNode = process.env.API_BCH_URL;
  } else if (crypto.network === 'bitcoinsv') {
    options.apiNode = process.env.API_BSV_URL;
  } else if (crypto.network === 'litecoin') {
    options.apiNode = process.env.API_LTC_URL;
  } else if (crypto.network === 'dogecoin') {
    options.apiNode = process.env.API_DOGE_URL;
  } else if (crypto.network === 'dash') {
    options.apiNode = process.env.API_DASH_URL;
  }

  if (crypto.network === 'ethereum') {
    options.name = crypto.name;
    options.minConf = 12;
    options.token = crypto._id !== 'ethereum' ? crypto : false;
    options.decimals = crypto.decimals !== undefined ? crypto.decimals : 18;
  } else if (crypto.network === 'binance-smart-chain') {
    options.name = crypto.name;
    options.minConf = 12;
    options.token = crypto._id !== 'binancecoin' ? crypto : false;
    options.decimals = crypto.decimals !== undefined ? crypto.decimals : 18;
    options.request = request;
    options.apiNode = process.env.API_BSC_URL;
  } else if (['bitcoin', 'bitcoincash', 'bitcoinsv', 'litecoin', 'dogecoin', 'dash'].includes(crypto.network)) {
    const addressType = details.get(crypto.network + '.addressType');
    if (addressType) {
      options.addressType = addressType;
    }
    options.minConf = 3;
    if (crypto.network === 'bitcoincash') {
      options.minConf = 0;
    }
    options.getDynamicFees = () => {
      return request({
        url: `${process.env.SITE_URL}api/v2/fees`,
        params: {
          crypto: crypto._id,
        },
        method: 'get',
        seed: 'public',
      }).catch(console.error);
    };
    options.getCsFee = () => {
      return request({
        url: `${process.env.SITE_URL}api/v1/csFee`,
        // TODO move to _id
        params: { network: crypto.network },
        id: true,
      }).catch(console.error);
    };
  } else if (crypto.network === 'eos') {
    options.accountName = details.get('eosAccountName') || '';
  } else if (crypto.network === 'monero') {
    const addressType = details.get(crypto.network + '.addressType');
    if (addressType) {
      options.addressType = addressType;
    }
    if (process.env.BUILD_TYPE === 'phonegap') {
      options.wasm = (new URL('@coinspace/monero-core-js/build/MoneroCoreJS.wasm', import.meta.url)).href;
    } else {
      options.wasm = require('@coinspace/monero-core-js/build/MoneroCoreJS.wasm');
    }
    options.storage = new Storage(process.env.SITE_URL, 'monero', LS.getDetailsKey());
    options.request = request;
    options.apiNode = process.env.API_XMR_URL;
    options.apiWeb = process.env.SITE_URL;
  }
  return options;
}

export async function updateWallet() {
  if (typeof state.wallet.update === 'function') {
    await state.wallet.update();
    emitter.emit('wallet-update');
  }
}

export async function addPublicKey(crypto) {
  try {
    await unlock();
    const wallet = new Wallet[crypto.network]({
      seed: seeds.get('private'),
      networkName: crypto.network,
      ...await getExtraOptions(crypto),
    });
    LS.setPublicKey(wallet, seeds.get('public'));
    lock();
  } catch (err) {
    lock();
    if (err.message !== 'cancelled') console.error(err);
    throw err;
  }
}

async function removeAccount() {
  await request({
    url: `${process.env.SITE_URL}api/v2/wallet`,
    method: 'delete',
    seed: 'private',
  });
  LS.reset();
}

function setUsername(username) {
  const userInfo = details.get('userInfo');
  const oldUsername = (userInfo.username || '').toLowerCase().replace(/[^a-z0-9-]/g, '');
  const newUsername = (username || '').toLowerCase().replace(/[^a-z0-9-]/g, '');
  if (newUsername === oldUsername) {
    return Promise.resolve(userInfo.username);
  }
  return request({
    url: `${process.env.SITE_URL}api/v2/username`,
    method: 'put',
    data: {
      username: newUsername,
    },
    seed: 'public',
  }).then((data) => {
    return data.username;
  });
}

export function getWallet() {
  return state.wallet;
}

export function getWalletCoin(wallet) {
  const networkName = wallet ? wallet.networkName : state.wallet.networkName;
  const coin = walletCoins.find((coin) => coin.network === networkName);
  return coin;
}

export function getDestinationInfo(to) {
  if (state.wallet.networkName === 'stellar') {
    return state.wallet.getDestinationInfo(to);
  } else {
    return Promise.resolve();
  }
}

export function setToAlias(data) {
  if (state.wallet.networkName !== 'bitcoincash') return;
  try {
    const legacy = bchaddr.toLegacyAddress(data.to);
    if (legacy !== data.to) {
      data.alias = data.to;
      data.to = legacy;
    }
  // eslint-disable-next-line
  } catch (e) {}
}

async function migrateLegacyWallet(pin) {
  await loginWithPinLegacy(pin);
  await registerWallet(pin);
  LS.deleteCredentialsLegacy();
}

// DEPRECATED
async function loginWithPinLegacy(pin) {
  const credentials = LS.getCredentials();
  const { id } = credentials;
  const encryptedSeed = credentials.seed;
  const token = await request({
    url: `${process.env.SITE_URL}api/v1/login`,
    method: 'post',
    data: { wallet_id: id, pin },
  });
  seeds.set('private', encryption.decrypt(encryptedSeed, token));
}

export default {
  createWallet,
  registerWallet,
  loginWithPin,
  loginWithTouchId,
  removeAccount,
  setUsername,
  getWallet,
  getWalletCoin,
  initWallet,
  updateWallet,
  addPublicKey,
  getDestinationInfo,
  setToAlias,
};
<commit_msg>feat(app): update eth wallet<commit_after>const worker = new Worker(new URL('./worker.js', import.meta.url));
import LS from './localStorage';

import seeds from './seeds';
import emitter from 'lib/emitter';
import crypto from 'crypto';
import encryption from 'lib/encryption';
import request from 'lib/request';
import Storage from 'lib/storage';
import { unlock, lock } from 'lib/wallet/security';

import CsWallet from '@coinspace/cs-wallet';
import EthereumWallet from '@coinspace/cs-ethereum-wallet';
import BinanceSmartChainWallet from '@coinspace/cs-binance-smart-chain-wallet';
import RippleWallet from '@coinspace/cs-ripple-wallet';
import StellarWallet from '@coinspace/cs-stellar-wallet';
import EOSWallet from '@coinspace/cs-eos-wallet';
import MoneroWallet from '@coinspace/cs-monero-wallet';

import { eddsa } from 'elliptic';

const ec = new eddsa('ed25519');
import touchId from 'lib/touch-id';
import ticker from 'lib/ticker-api';
import convert from 'lib/convert';
import { getCrypto, walletCoins } from 'lib/crypto';
import details from 'lib/wallet/details';
import settings from 'lib/wallet/settings';
import bchaddr from 'bchaddrjs';

const state = {
  wallet: null,
};

const Wallet = {
  bitcoin: CsWallet,
  bitcoincash: CsWallet,
  bitcoinsv: CsWallet,
  litecoin: CsWallet,
  ethereum: EthereumWallet,
  ripple: RippleWallet,
  stellar: StellarWallet,
  eos: EOSWallet,
  dogecoin: CsWallet,
  dash: CsWallet,
  monero: MoneroWallet,
  'binance-smart-chain': BinanceSmartChainWallet,
};

function createWallet(passphrase) {
  const data = { passphrase };
  return new Promise((resolve, reject) => {
    worker.onmessage = function(event) {
      seeds.set('private', event.data.seed);
      resolve({ mnemonic: event.data.mnemonic });
    };
    worker.onerror = function(event) {
      event.preventDefault();
      reject(new Error('Invalid passphrase'));
    };
    worker.postMessage(data);
  });
}

async function registerWallet(pin) {
  const pinKey = crypto.randomBytes(32).toString('hex');
  const walletSeed = seeds.get('private');
  const wallet = ec.keyFromSecret(walletSeed);
  const deviceSeed = crypto.randomBytes(32).toString('hex');
  const device = ec.keyFromSecret(deviceSeed);
  const deviceId = device.getPublic('hex');
  const pinHash = crypto.createHmac('sha256', Buffer.from(pinKey, 'hex')).update(pin).digest('hex');
  const detailsKey = crypto.createHmac('sha256', 'Coin Wallet').update(walletSeed).digest('hex');
  const { publicToken, privateToken } = await request({
    url: `${process.env.SITE_URL}api/v2/register`,
    method: 'post',
    data: {
      walletId: wallet.getPublic('hex'),
      deviceId,
      pinHash,
    },
    seed: 'private',
    id: false,
  });
  seeds.set('public', deviceSeed);
  LS.setEncryptedSeed('public', encryption.encrypt(deviceSeed, publicToken));
  LS.setEncryptedSeed('private', encryption.encrypt(walletSeed, privateToken));
  LS.setPinKey(pinKey);
  LS.setId(deviceId);
  LS.setDetailsKey(detailsKey);
  await Promise.all([details.init(), settings.init()]);
  emitter.emit('auth-success', pin);
  await initWallet(walletSeed);
}

async function loginWithPin(pin) {
  if (LS.isRegisteredLegacy()) {
    return migrateLegacyWallet(pin);
  }
  const pinHash = crypto.createHmac('sha256', Buffer.from(LS.getPinKey(), 'hex')).update(pin).digest('hex');
  const { publicToken } = await request({
    url: `${process.env.SITE_URL}api/v2/token/public/pin`,
    method: 'post',
    data: {
      pinHash,
    },
    id: true,
  });
  seeds.unlock('public', publicToken);
  await Promise.all([details.init(), settings.init()]);
  emitter.emit('auth-success');
  await initWallet();
}

async function loginWithTouchId(widget) {
  if (process.env.BUILD_TYPE === 'phonegap') {
    await touchId.phonegap();
    widget && widget.loading();
    const pin = LS.getPin();
    if (LS.isRegisteredLegacy()) {
      return migrateLegacyWallet(pin);
    }
    return loginWithPin(pin);
  } else {
    const { publicToken } = await touchId.publicToken(widget);
    seeds.unlock('public', publicToken);
    await Promise.all([details.init(), settings.init()]);
    emitter.emit('auth-success');
    await initWallet();
  }
}

export async function initWallet(seed) {
  const crypto = getCrypto();

  if (seed) {
    for (const key of Object.keys(Wallet)) {
      const wallet = new Wallet[key]({
        seed,
        networkName: key,
        ...await getExtraOptions({ network: key }),
      });
      wallet.lock();
      LS.setPublicKey(wallet, seeds.get('public'));
    }
  }

  const publicKey = LS.getPublicKey(crypto.network, seeds.get('public'));
  state.wallet = new Wallet[crypto.network]({
    publicKey,
    networkName: crypto.network,
    ...await getExtraOptions(crypto),
  });

  convert.setDecimals(state.wallet.decimals);

  await ticker.init([crypto]);

  try {
    await state.wallet.load();

    emitter.emit('wallet-ready');
  } catch (err) {
    emitter.emit('wallet-error', err);
  }
}

async function getExtraOptions(crypto) {
  const options = {
    useTestNetwork: process.env.COIN_NETWORK === 'regtest',
  };

  if (crypto.network === 'bitcoin') {
    options.apiNode = process.env.API_BTC_URL;
  } else if (crypto.network === 'bitcoincash') {
    options.apiNode = process.env.API_BCH_URL;
  } else if (crypto.network === 'bitcoinsv') {
    options.apiNode = process.env.API_BSV_URL;
  } else if (crypto.network === 'litecoin') {
    options.apiNode = process.env.API_LTC_URL;
  } else if (crypto.network === 'dogecoin') {
    options.apiNode = process.env.API_DOGE_URL;
  } else if (crypto.network === 'dash') {
    options.apiNode = process.env.API_DASH_URL;
  }

  if (crypto.network === 'ethereum') {
    options.name = crypto.name;
    options.minConf = 12;
    options.token = crypto._id !== 'ethereum' ? crypto : false;
    options.decimals = crypto.decimals !== undefined ? crypto.decimals : 18;
    options.request = request;
    options.apiNode = process.env.API_ETH_URL;
  } else if (crypto.network === 'binance-smart-chain') {
    options.name = crypto.name;
    options.minConf = 12;
    options.token = crypto._id !== 'binancecoin' ? crypto : false;
    options.decimals = crypto.decimals !== undefined ? crypto.decimals : 18;
    options.request = request;
    options.apiNode = process.env.API_BSC_URL;
  } else if (['bitcoin', 'bitcoincash', 'bitcoinsv', 'litecoin', 'dogecoin', 'dash'].includes(crypto.network)) {
    const addressType = details.get(crypto.network + '.addressType');
    if (addressType) {
      options.addressType = addressType;
    }
    options.minConf = 3;
    if (crypto.network === 'bitcoincash') {
      options.minConf = 0;
    }
    options.getDynamicFees = () => {
      return request({
        url: `${process.env.SITE_URL}api/v2/fees`,
        params: {
          crypto: crypto._id,
        },
        method: 'get',
        seed: 'public',
      }).catch(console.error);
    };
    options.getCsFee = () => {
      return request({
        url: `${process.env.SITE_URL}api/v1/csFee`,
        // TODO move to _id
        params: { network: crypto.network },
        id: true,
      }).catch(console.error);
    };
  } else if (crypto.network === 'eos') {
    options.accountName = details.get('eosAccountName') || '';
  } else if (crypto.network === 'monero') {
    const addressType = details.get(crypto.network + '.addressType');
    if (addressType) {
      options.addressType = addressType;
    }
    if (process.env.BUILD_TYPE === 'phonegap') {
      options.wasm = (new URL('@coinspace/monero-core-js/build/MoneroCoreJS.wasm', import.meta.url)).href;
    } else {
      options.wasm = require('@coinspace/monero-core-js/build/MoneroCoreJS.wasm');
    }
    options.storage = new Storage(process.env.SITE_URL, 'monero', LS.getDetailsKey());
    options.request = request;
    options.apiNode = process.env.API_XMR_URL;
    options.apiWeb = process.env.SITE_URL;
  }
  return options;
}

export async function updateWallet() {
  if (typeof state.wallet.update === 'function') {
    await state.wallet.update();
    emitter.emit('wallet-update');
  }
}

export async function addPublicKey(crypto) {
  try {
    await unlock();
    const wallet = new Wallet[crypto.network]({
      seed: seeds.get('private'),
      networkName: crypto.network,
      ...await getExtraOptions(crypto),
    });
    LS.setPublicKey(wallet, seeds.get('public'));
    lock();
  } catch (err) {
    lock();
    if (err.message !== 'cancelled') console.error(err);
    throw err;
  }
}

async function removeAccount() {
  await request({
    url: `${process.env.SITE_URL}api/v2/wallet`,
    method: 'delete',
    seed: 'private',
  });
  LS.reset();
}

function setUsername(username) {
  const userInfo = details.get('userInfo');
  const oldUsername = (userInfo.username || '').toLowerCase().replace(/[^a-z0-9-]/g, '');
  const newUsername = (username || '').toLowerCase().replace(/[^a-z0-9-]/g, '');
  if (newUsername === oldUsername) {
    return Promise.resolve(userInfo.username);
  }
  return request({
    url: `${process.env.SITE_URL}api/v2/username`,
    method: 'put',
    data: {
      username: newUsername,
    },
    seed: 'public',
  }).then((data) => {
    return data.username;
  });
}

export function getWallet() {
  return state.wallet;
}

export function getWalletCoin(wallet) {
  const networkName = wallet ? wallet.networkName : state.wallet.networkName;
  const coin = walletCoins.find((coin) => coin.network === networkName);
  return coin;
}

export function getDestinationInfo(to) {
  if (state.wallet.networkName === 'stellar') {
    return state.wallet.getDestinationInfo(to);
  } else {
    return Promise.resolve();
  }
}

export function setToAlias(data) {
  if (state.wallet.networkName !== 'bitcoincash') return;
  try {
    const legacy = bchaddr.toLegacyAddress(data.to);
    if (legacy !== data.to) {
      data.alias = data.to;
      data.to = legacy;
    }
  // eslint-disable-next-line
  } catch (e) {}
}

async function migrateLegacyWallet(pin) {
  await loginWithPinLegacy(pin);
  await registerWallet(pin);
  LS.deleteCredentialsLegacy();
}

// DEPRECATED
async function loginWithPinLegacy(pin) {
  const credentials = LS.getCredentials();
  const { id } = credentials;
  const encryptedSeed = credentials.seed;
  const token = await request({
    url: `${process.env.SITE_URL}api/v1/login`,
    method: 'post',
    data: { wallet_id: id, pin },
  });
  seeds.set('private', encryption.decrypt(encryptedSeed, token));
}

export default {
  createWallet,
  registerWallet,
  loginWithPin,
  loginWithTouchId,
  removeAccount,
  setUsername,
  getWallet,
  getWalletCoin,
  initWallet,
  updateWallet,
  addPublicKey,
  getDestinationInfo,
  setToAlias,
};
<|endoftext|>


<commit_before>angular.module('OpenMining', ["highcharts-ng"])
.controller('Process',
  function($scope, $http, $location) {
    $scope.loading = true;
    $scope.init = function(slug) {
      API_URL = "/process/" + slug + ".json?";
      for (var key in $location.search()){
        API_URL += key + "=" + $location.search()[key] + "&";
      };

      $http({method: 'POST', url: API_URL}).
        success(function(data, status, headers, config) {
          $scope.process = data.json;
          $scope.columns = data.columns;
          $scope.loading = false;
        });
    };
})

.controller('Chart',
  function($scope, $http, $location) {
    $scope.loading = true;
    $scope.init = function(slug) {
      API_URL = "/process/" + slug + ".json?";
      for (var key in $location.search()){
        API_URL += key + "=" + $location.search()[key] + "&";
      };

      $http({method: 'POST', url: API_URL}).
        success(function(data, status, headers, config) {
          $scope.process = data.json;
          $scope.columns = data.columns;
          $scope.loading = false;
        });

        $scope.chartConfig = {
          options: {
            chart: {
              type: 'line',
              zoomType: 'x'
            }
          },
          series: [
            {
              name: "Testando meta dados 1",
              data: [10002, 15987, 12987, 82222, 77622, 16236, 17833, 19787, 15223, 10123]
            },
            {
              name: "Testando meta dados 2",
              data: [11762, 212319, 231231, 52760, 212330, 10000, 123220]
            }
          ],
          title: {
            text: 'Hello'
          },
          credits: {
            enabled: false
          },
          xAxis: {currentMin: 0, currentMax: 10, minRange: 1},
          loading: false
        }

    };
});
<commit_msg>Add example to use categories on chart<commit_after>angular.module('OpenMining', ["highcharts-ng"])
.controller('Process',
  function($scope, $http, $location) {
    $scope.loading = true;
    $scope.init = function(slug) {
      API_URL = "/process/" + slug + ".json?";
      for (var key in $location.search()){
        API_URL += key + "=" + $location.search()[key] + "&";
      };

      $http({method: 'POST', url: API_URL}).
        success(function(data, status, headers, config) {
          $scope.process = data.json;
          $scope.columns = data.columns;
          $scope.loading = false;
        });
    };
})

.controller('Chart',
  function($scope, $http, $location) {
    $scope.loading = true;
    $scope.init = function(slug) {
      API_URL = "/process/" + slug + ".json?";
      for (var key in $location.search()){
        API_URL += key + "=" + $location.search()[key] + "&";
      };

      $http({method: 'POST', url: API_URL}).
        success(function(data, status, headers, config) {
          $scope.process = data.json;
          $scope.columns = data.columns;
          $scope.loading = false;
        });

        $scope.chartConfig = {
          options: {
            chart: {
              type: 'line',
              zoomType: 'x'
            }
          },
          series: [
            {
              name: "Testando meta dados 1",
              data: [10002, 15987, 12987, 82222, 77622, 16236, 17833, 19787, 15223, 10123]
            },
            {
              name: "Testando meta dados 2",
              data: [11762, 212319, 231231, 52760, 212330, 10000, 123220]
            }
          ],
          title: {
            text: 'Hello'
          },
          credits: {
            enabled: false
          },
          xAxis: {
            currentMin: 0,
            currentMax: 10,
            minRange: 1,
            categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
          },
          loading: false
        }

    };
});
<|endoftext|>


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

  function hasClass(el, className) {
    if (el.classList)
      return el.classList.contains(className)
    else
      return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))
  }

  function my_addClass(el, className) {
    if (el.classList)
      el.classList.add(className)
    else if (!hasClass(el, className)) el.className += " " + className
  }

  function my_removeClass(el, className) {
    if (el.classList)
      el.classList.remove(className)
    else if (hasClass(el, className)) {
      var reg = new RegExp('(\\s|^)' + className + '(\\s|$)')
      el.className=el.className.replace(reg, ' ')
    }
  }

  function scrollTo(element, to, duration) {
    var start = element.scrollTop,
        change = to - start,
        currentTime = 0,
        increment = 20;

    var animateScroll = function(){
        currentTime += increment;
        var val = Math.easeInOutQuad(currentTime, start, change, duration);
        element.scrollTop = val;
        if(currentTime < duration) {
            setTimeout(animateScroll, increment);
        }
    };
    animateScroll();
  }

  //t = current time
  //b = start value
  //c = change in value
  //d = duration
  Math.easeInOutQuad = function (t, b, c, d) {
    t /= d/2;
    if (t < 1) return c/2*t*t + b;
    t--;
    return -c/2 * (t*(t-2) - 1) + b;
  };

  function each(o, cb, s){
    var n;
    if (!o){
      return 0;
    }
    s = !s ? o : s;
    if (o instanceof Array){
      // Indexed arrays, needed for Safari
      for (n=0; n<o.length; n++) {
        if (cb.call(s, o[n], n, o) === false){
          return 0;
        }
      }
    } else {
      // Hashtables
      for (n in o){
        if (o.hasOwnProperty(n)) {
          if (cb.call(s, o[n], n, o) === false){
            return 0;
          }
        }
      }
    }
    return 1;
  };

  $(document).ready(function() {
    var
      scrollElements,
      inValidRange,
      setVisibility,
      setVisibilityAll,
      resetScroll;

    // scrollElements = $('[data-scroll-element]');
    scrollElements = document.querySelectorAll('[data-scroll-element]');

    inValidRange = function(offset, limit) {
      return offset >= 0 && offset < limit;
    };

    setVisibility = function(element, nextOffset, limit) {
      console.log("Set visibility");
      console.log("nextOffset", nextOffset);
      console.log("limit", limit);
      if(inValidRange(nextOffset, limit)) {
        // element.removeClass('disabled');
        my_removeClass(element, 'disabled');
      } else {
        // element.addClass('disabled');
        my_addClass(element, 'disabled');
      }
    };

    setVisibilityAll = function(elements, newOffset) {
      console.log("setVisibilityAll");
      var
        scrollElement,
        increment,
        nextOffset,
        limit;

      each(elements, function(el) {
        scrollElement = document.querySelector(el.dataset.scrollElement);
        increment  = parseInt(el.dataset.scrollIncrement);
        nextOffset = newOffset + increment;
        limit      = parseInt(scrollElement.dataset.scrollLimit);

        setVisibility(el, nextOffset, limit);
      });
    };

    resetScroll = function(element) {
      element.scrollTop = 0;
      element.dataset.scrollOffset = 0;
    };

    $('[data-clipboard-target]').each(function() {
      var
          clipboard,
          notification;

      clipboard = new Clipboard(this);

      var notify = function(clipboardNotification, notificationText) {
          notification = $($(clipboardNotification));
          notification.text(notificationText);
          notification.addClass('in').delay(1400).queue(function() {
              notification.removeClass('in');
              $(this).dequeue();
          })
      };

      var notifySuccess = function(e) {
          notify(e.trigger.dataset.clipboardNotification, "Copied!");
      };

      var notifyFailure = function(e) {
          //if the copy function failed the text should still be selected, so just ask the user to hit ctrl+c
          notify(e.trigger.dataset.clipboardNotification, "Press Ctrl+C to copy");
      };

      clipboard.on('success', notifySuccess);
      clipboard.on('error', notifyFailure);
    });

    each(scrollElements, function(el) {
      var
        $this,
        element,
        increment,
        limit,
        offset,
        nextOffset,
        newOffset;

      element = document.querySelector(el.dataset.scrollElement);
      increment = parseInt(el.dataset.scrollIncrement);
      limit     = parseInt(element.dataset.scrollLimit.valueOf());
      offset    = parseInt(element.dataset.scrollOffset.valueOf());

      // console.log("increment", increment);
      // console.log("limit", limit);
      // console.log("offset", offset);

      element.dataset.scrollLimit = limit;

      nextOffset = offset + increment;
      // console.log(nextOffset);
      setVisibility(el, nextOffset, limit);

      // Force IE to forget previous scroll top value
      resetScroll(element);

      el.addEventListener('click', function() {
        offset = parseInt(element.dataset.scrollOffset);

        newOffset = offset + increment;

        console.log("ELEMENT scroll top", element);
        if (inValidRange(newOffset, limit)) {
          // element.animate({
          //     scrollTop: document.getElementById(newOffset).offsetTop
          // }, 400);
          scrollTo(element, document.body, 400);
          element.dataset.scrollOffset = newOffset;

          setVisibilityAll(scrollElements, newOffset);
        }
      });

      // $this.on('click', function() {
      //   offset = element.dataset.scrollOffset;
      //
      //   newOffset = offset + increment;
      //
      //   console.log("newOffset", newOffset);
      //   if (inValidRange(newOffset, limit)) {
      //     element.animate({
      //         scrollTop: $('#' + newOffset).position().top
      //     }, 400);
      //     element.data('scroll-offset', newOffset);
      //
      //     setVisibilityAll(scrollElements, newOffset);
      //   }
      // });
    })
    // scrollElements.each();

    $('[data-open-panel]').each(function() {
      var
        $this,
        element;

      $this   = $(this);
      element = $($this.data('open-panel'));

      $this.on('click', function() {
        element.addClass('open');
      });
    });

    $('[data-close-panel]').each(function() {
      var
        $this,
        element;

      $this   = $(this);
      element = $($this.data('close-panel'));

      $this.on('click', function() {
        element
          .one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function() {
            $this.trigger('panel:closed');
          }).removeClass('open');
      });
    });

    $('[data-scroll-reset]').each(function() {
      var
        $this,
        element;

      $this   = $(this);
      element = $($this.data('scroll-reset'));

      $this.on('click', function() {
        $this.one('panel:closed', function() {
          resetScroll(element);
          setVisibilityAll(scrollElements, 0);
        });
      });
    });

    $('[data-moment]').each(function() {
      var $this;

      $this = $(this);

      var time = moment(parseInt($this.text()));
      $this.text(time.fromNow());
    });
  });

  var setContainerHeight = function(containerEl) {
    // TODO: Refactor this to make simpler
    var
      bodyEl,
      bodyHeight,
      bodyHeightWithoutTitle,
      titleEl,
      panelEl,
      referralsEl,
      referralsTitleEl,
      panelHeight,
      css,
      stylesheet;

    bodyEl           = $('.squatch-body');
    titleEl          = bodyEl.find('.squatch-title');
    panelEl          = $('#squatch-panel');
    referralsEl      = $('.squatch-referrals');
    referralsTitleEl = $('.squatch-referrals-title');

    bodyHeight = bodyEl.outerHeight();
    bodyHeightWithoutTitle = bodyHeight - titleEl.outerHeight(true) - titleEl.position().top;
    panelHeight = panelEl.outerHeight();

    if (referralsEl.is(':visible')) {
      panelHeight -= referralsEl.outerHeight();
    }

    if (referralsTitleEl.is(':visible')) {
      panelHeight -= referralsTitleEl.outerHeight();
    }

    containerEl.css('height', bodyHeight + panelHeight);

    stylesheet = document.createElement('style');
    stylesheet.type = 'text/css';

    css = '#squatch-panel.open {' +
      '-webkit-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
      '-ms-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
      '-o-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
      'transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
      '}' +
      'html.lt-ie9 #squatch-panel.open {' +
      'top: -' + bodyHeightWithoutTitle + 'px;' +
      '}';

    if (stylesheet.styleSheet){
      // IE
      stylesheet.styleSheet.cssText = css;
    } else {
      // W3C Standard
      stylesheet.appendChild(document.createTextNode(css));
    }

    document.querySelector('head').appendChild(stylesheet);
  };

  var containerEl = $('.squatch-container-popup');
  if (containerEl.length) {
    var setContainerHeightForPopup = setContainerHeight.bind(undefined, containerEl);
    var windowEl = $(window);

    // Workaround for popup height being incorrectly set during iframe resizing.
    // This is due to the popup being displayed inconsistently - with responsive styles activated, sometimes the mobile view will be displayed, even on a desktop monitor with more than 500 pixels width. The solution may be to set the iframe width to the full browser width, rather than the width of the widget theme.
    // There is another hack in _popup.less as well
    // TODO: Find a solution for this and enable responsive styles again.
    windowEl.on('load', function (i) {
      var setContainerHeightIfWideEnough = function () {
        var width = windowEl.width();

        if (width === 500) {
          setContainerHeightForPopup();
        } else {
          setTimeout(function() {
            setContainerHeightIfWideEnough();
          }, 50);
        }
      };

      setContainerHeightIfWideEnough();
    });

    // The content has a different height in mobile
    // TODO: Find a a solution for responsive in popups and re-enable this
    // var mql = window.matchMedia('(max-width: 500px)');
    // mql.addListener(setContainerHeightForPopup);
  }
})();
<commit_msg>new scroll top<commit_after>(function() {
  'use strict';

  function hasClass(el, className) {
    if (el.classList)
      return el.classList.contains(className)
    else
      return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))
  }

  function my_addClass(el, className) {
    if (el.classList)
      el.classList.add(className)
    else if (!hasClass(el, className)) el.className += " " + className
  }

  function my_removeClass(el, className) {
    if (el.classList)
      el.classList.remove(className)
    else if (hasClass(el, className)) {
      var reg = new RegExp('(\\s|^)' + className + '(\\s|$)')
      el.className=el.className.replace(reg, ' ')
    }
  }

  function scrollTo(element, to, duration) {
    var start = element.scrollTop,
        change = to - start,
        currentTime = 0,
        increment = 20;

    console.log("Move element ", element);
    console.log("to position ", to);

    var animateScroll = function(){
        currentTime += increment;
        var val = Math.easeInOutQuad(currentTime, start, change, duration);
        element.scrollTop = val;
        if(currentTime < duration) {
            setTimeout(animateScroll, increment);
        }
    };
    animateScroll();
  }

  //t = current time
  //b = start value
  //c = change in value
  //d = duration
  Math.easeInOutQuad = function (t, b, c, d) {
    t /= d/2;
    if (t < 1) return c/2*t*t + b;
    t--;
    return -c/2 * (t*(t-2) - 1) + b;
  };

  function each(o, cb, s){
    var n;
    if (!o){
      return 0;
    }
    s = !s ? o : s;
    if (o instanceof Array){
      // Indexed arrays, needed for Safari
      for (n=0; n<o.length; n++) {
        if (cb.call(s, o[n], n, o) === false){
          return 0;
        }
      }
    } else {
      // Hashtables
      for (n in o){
        if (o.hasOwnProperty(n)) {
          if (cb.call(s, o[n], n, o) === false){
            return 0;
          }
        }
      }
    }
    return 1;
  };

  $(document).ready(function() {
    var
      scrollElements,
      inValidRange,
      setVisibility,
      setVisibilityAll,
      resetScroll;

    // scrollElements = $('[data-scroll-element]');
    scrollElements = document.querySelectorAll('[data-scroll-element]');

    inValidRange = function(offset, limit) {
      return offset >= 0 && offset < limit;
    };

    setVisibility = function(element, nextOffset, limit) {
      console.log("Set visibility");
      console.log("nextOffset", nextOffset);
      console.log("limit", limit);
      if(inValidRange(nextOffset, limit)) {
        // element.removeClass('disabled');
        my_removeClass(element, 'disabled');
      } else {
        // element.addClass('disabled');
        my_addClass(element, 'disabled');
      }
    };

    setVisibilityAll = function(elements, newOffset) {
      console.log("setVisibilityAll");
      var
        scrollElement,
        increment,
        nextOffset,
        limit;

      each(elements, function(el) {
        scrollElement = document.querySelector(el.dataset.scrollElement);
        increment  = parseInt(el.dataset.scrollIncrement);
        nextOffset = newOffset + increment;
        limit      = parseInt(scrollElement.dataset.scrollLimit);

        setVisibility(el, nextOffset, limit);
      });
    };

    resetScroll = function(element) {
      element.scrollTop = 0;
      element.dataset.scrollOffset = 0;
    };

    $('[data-clipboard-target]').each(function() {
      var
          clipboard,
          notification;

      clipboard = new Clipboard(this);

      var notify = function(clipboardNotification, notificationText) {
          notification = $($(clipboardNotification));
          notification.text(notificationText);
          notification.addClass('in').delay(1400).queue(function() {
              notification.removeClass('in');
              $(this).dequeue();
          })
      };

      var notifySuccess = function(e) {
          notify(e.trigger.dataset.clipboardNotification, "Copied!");
      };

      var notifyFailure = function(e) {
          //if the copy function failed the text should still be selected, so just ask the user to hit ctrl+c
          notify(e.trigger.dataset.clipboardNotification, "Press Ctrl+C to copy");
      };

      clipboard.on('success', notifySuccess);
      clipboard.on('error', notifyFailure);
    });

    each(scrollElements, function(el) {
      var
        $this,
        element,
        increment,
        limit,
        offset,
        nextOffset,
        newOffset;

      element = document.querySelector(el.dataset.scrollElement);
      increment = parseInt(el.dataset.scrollIncrement);
      limit     = parseInt(element.dataset.scrollLimit.valueOf());
      offset    = parseInt(element.dataset.scrollOffset.valueOf());

      // console.log("increment", increment);
      // console.log("limit", limit);
      // console.log("offset", offset);

      element.dataset.scrollLimit = limit;

      nextOffset = offset + increment;
      // console.log(nextOffset);
      setVisibility(el, nextOffset, limit);

      // Force IE to forget previous scroll top value
      resetScroll(element);

      el.addEventListener('click', function() {
        offset = parseInt(element.dataset.scrollOffset);

        newOffset = offset + increment;

        console.log("ELEMENT scroll top", element);
        if (inValidRange(newOffset, limit)) {
          // element.animate({
          //     scrollTop: document.getElementById(newOffset).offsetTop
          // }, 400);
          scrollTo(element, 0, 400);
          element.dataset.scrollOffset = newOffset;

          setVisibilityAll(scrollElements, newOffset);
        }
      });

      // $this.on('click', function() {
      //   offset = element.dataset.scrollOffset;
      //
      //   newOffset = offset + increment;
      //
      //   console.log("newOffset", newOffset);
      //   if (inValidRange(newOffset, limit)) {
      //     element.animate({
      //         scrollTop: $('#' + newOffset).position().top
      //     }, 400);
      //     element.data('scroll-offset', newOffset);
      //
      //     setVisibilityAll(scrollElements, newOffset);
      //   }
      // });
    })
    // scrollElements.each();

    $('[data-open-panel]').each(function() {
      var
        $this,
        element;

      $this   = $(this);
      element = $($this.data('open-panel'));

      $this.on('click', function() {
        element.addClass('open');
      });
    });

    $('[data-close-panel]').each(function() {
      var
        $this,
        element;

      $this   = $(this);
      element = $($this.data('close-panel'));

      $this.on('click', function() {
        element
          .one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function() {
            $this.trigger('panel:closed');
          }).removeClass('open');
      });
    });

    $('[data-scroll-reset]').each(function() {
      var
        $this,
        element;

      $this   = $(this);
      element = $($this.data('scroll-reset'));

      $this.on('click', function() {
        $this.one('panel:closed', function() {
          resetScroll(element);
          setVisibilityAll(scrollElements, 0);
        });
      });
    });

    $('[data-moment]').each(function() {
      var $this;

      $this = $(this);

      var time = moment(parseInt($this.text()));
      $this.text(time.fromNow());
    });
  });

  var setContainerHeight = function(containerEl) {
    // TODO: Refactor this to make simpler
    var
      bodyEl,
      bodyHeight,
      bodyHeightWithoutTitle,
      titleEl,
      panelEl,
      referralsEl,
      referralsTitleEl,
      panelHeight,
      css,
      stylesheet;

    bodyEl           = $('.squatch-body');
    titleEl          = bodyEl.find('.squatch-title');
    panelEl          = $('#squatch-panel');
    referralsEl      = $('.squatch-referrals');
    referralsTitleEl = $('.squatch-referrals-title');

    bodyHeight = bodyEl.outerHeight();
    bodyHeightWithoutTitle = bodyHeight - titleEl.outerHeight(true) - titleEl.position().top;
    panelHeight = panelEl.outerHeight();

    if (referralsEl.is(':visible')) {
      panelHeight -= referralsEl.outerHeight();
    }

    if (referralsTitleEl.is(':visible')) {
      panelHeight -= referralsTitleEl.outerHeight();
    }

    containerEl.css('height', bodyHeight + panelHeight);

    stylesheet = document.createElement('style');
    stylesheet.type = 'text/css';

    css = '#squatch-panel.open {' +
      '-webkit-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
      '-ms-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
      '-o-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
      'transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
      '}' +
      'html.lt-ie9 #squatch-panel.open {' +
      'top: -' + bodyHeightWithoutTitle + 'px;' +
      '}';

    if (stylesheet.styleSheet){
      // IE
      stylesheet.styleSheet.cssText = css;
    } else {
      // W3C Standard
      stylesheet.appendChild(document.createTextNode(css));
    }

    document.querySelector('head').appendChild(stylesheet);
  };

  var containerEl = $('.squatch-container-popup');
  if (containerEl.length) {
    var setContainerHeightForPopup = setContainerHeight.bind(undefined, containerEl);
    var windowEl = $(window);

    // Workaround for popup height being incorrectly set during iframe resizing.
    // This is due to the popup being displayed inconsistently - with responsive styles activated, sometimes the mobile view will be displayed, even on a desktop monitor with more than 500 pixels width. The solution may be to set the iframe width to the full browser width, rather than the width of the widget theme.
    // There is another hack in _popup.less as well
    // TODO: Find a solution for this and enable responsive styles again.
    windowEl.on('load', function (i) {
      var setContainerHeightIfWideEnough = function () {
        var width = windowEl.width();

        if (width === 500) {
          setContainerHeightForPopup();
        } else {
          setTimeout(function() {
            setContainerHeightIfWideEnough();
          }, 50);
        }
      };

      setContainerHeightIfWideEnough();
    });

    // The content has a different height in mobile
    // TODO: Find a a solution for responsive in popups and re-enable this
    // var mql = window.matchMedia('(max-width: 500px)');
    // mql.addListener(setContainerHeightForPopup);
  }
})();
<|endoftext|>


<commit_before>var RealTeam = Ember.Application.create({
  socket: io.connect(window.location.hostname),
  issueSort: ['subject']
});
<commit_msg>ember: default sort issues by priority<commit_after>var RealTeam = Ember.Application.create({
  socket: io.connect(window.location.hostname),
  issueSort: ['priority.id']
});
<|endoftext|>


<commit_before>import DS from 'ember-data';
import Ember from 'ember';

let Statement = DS.Model.extend({
    steps: DS.hasMany('step', {async: true}),

    //Data types
    identityData: DS.attr('boolean'),
    locationData: DS.attr('boolean'),
    userBehaviourData: DS.attr('boolean'),
    computerNetworkData: DS.attr('boolean'),
    financialData: DS.attr('boolean'),
    otherData: DS.attr('boolean'),
    noData: DS.attr('boolean'),
    otherDataInfo: DS.attr(),

    //Data Sources
    userDataSource: DS.attr('boolean'),
    publicDataSource: DS.attr('boolean'),
    thirdPartyDataSource: DS.attr('boolean'),
    otherDataSource: DS.attr('boolean'),
    otherDataSourceInfo: DS.attr(),

    //why
    extraReasons: Ember.A(),

    //Sharing
    sharingParties: Ember.A(),

});

Statement.reopenClass({
  FIXTURES: [{
    id: 1,
    businessName: 'Spacely Sprockets'
  }]
});

export default Statement;
<commit_msg>gave the booleans some default values<commit_after>import DS from 'ember-data';
import Ember from 'ember';

let Statement = DS.Model.extend({
    steps: DS.hasMany('step', {async: true}),

    //Data types
    otherDataInfo: DS.attr(),
    identityData: DS.attr('boolean', {default: false}),
    locationData: DS.attr('boolean', {default: false}),
    userBehaviourData: DS.attr('boolean', {default: false}),
    computerNetworkData: DS.attr('boolean', {default: false}),
    financialData: DS.attr('boolean', {default: false}),
    otherData: DS.attr('boolean', {default: false}),
    noData: DS.attr('boolean', {default: false}),

    //Data Sources
    userDataSource: DS.attr('boolean', {default: false}),
    publicDataSource: DS.attr('boolean', {default: false}),
    thirdPartyDataSource: DS.attr('boolean', {default: false}),
    otherDataSource: DS.attr('boolean'),
    otherDataSourceInfo: DS.attr(),

    //why
    extraReasons: Ember.A(),

    //Sharing
    sharingParties: Ember.A(),

});

Statement.reopenClass({
  FIXTURES: [{
    id: 1,
    businessName: 'Spacely Sprockets'
  }]
});

export default Statement;
<|endoftext|>


<commit_before>jQuery(function ($) {

	var prog_hidden = true,
		results_hidden = true, //added
		loc = window.location,
		$prog_container = $(".progress"),
		$prog = $(".progress-bar"),
		$results_container = $(".results"), //added
		$email = $("#email"),
		$pass = $("#password"),
		$submit = $("#submit"),
		$auth_form = $("#auth-form"),
		$auth_fields = $auth_form.find(":input"),
		$alert = $(".alert"),
		$sync_form = $("#sync-form"),
		$confim_form = $("#confirm-form"),
		$no_confirm_bttn = $confim_form.find("[type=cancel]"),
		$delete = $("#delete"),
		$select_all = $("#select-all"),
		select_bool = false,
		$image_menu = $("#image-menu"),
		$save = $("#save"),
		$input = $("#input"),
		rewrite_index = null,
		rewrite_total = null,
		feedback = null,
		num_messages = null,
		update_progress = null,
		hide_progress = null,
		update_results = null, //added
		img_id = null,
		hide_results = null, //added
		selected_imgs = [],
		ws = new WebSocket("ws://" + loc.host + "/ws");

	//added
	hide_results = function () {

		$results_container.fadeOut();
		results_hidden = true;
	};

	//displays images in the browser as they are found in the users mailbox
	update_results = function (msg_id, img_id, enc_img) {

		if (results_hidden) {

			$results_container.show();
			results_hidden = false;
		}

		//decode image from base64 to small image to display in img tag
		var img = new Image();
		img.src = 'data:image/jpeg;base64,' + enc_img;

		//create thumbnail for image to be displayed in
		//create a unique img_id for the purpose of selecting each image
		$results_container.append('
' +
								  '<input class="img-checkbox" id="' + img_id +
								  '" name="' + msg_id + '" type="checkbox">' +
								  '' +
								  '' +
								  '' +
								  '
');
	};

	hide_progress = function () {
		$prog_container.fadeOut();
		prog_hidden = true;
	};

	update_progress = function (cur, max) {

		if (prog_hidden) {
			$prog_container.fadeIn();
			prog_hidden = false;
		}

		if (!cur && !max) {

			$prog_container.addClass("progress-striped").addClass("active");
			$prog.attr("aria-valuenow", 1)
			.attr("aria-valuemax", 1)
			.css("width", "100%");

		} else {

			$prog_container.removeClass("progress-striped").removeClass("active");
			$prog.attr("aria-valuenow", cur)
			.attr("aria-valuemax", max)
			.css("width", ((cur / max) * 100) + "%");
		}
	};

	feedback = function (msg, additional_message) {

		$alert.removeClass("alert-info").removeClass("alert-warning");
		$alert.show();

		if (msg.ok) {

			$alert.addClass("alert-info");

		} else {

			$alert.addClass("alert-warning");

		}

		if (additional_message) {

			$alert.html("
" + msg.msg + "

" + additional_message + "
");

		} else {

			$alert.text(msg.msg);

		}
	};

	previewImage = function (image_body) {

		$("#imagePreview").attr("src", image_body);
		$("#imageModal").modal('show', function(){

			$(this).find('.modal-body').css({

				width:'auto', //probably not needed
				height:'auto', //probably not needed
				'max-height':'100%'
			});
		});
	};

	//TODO - select all doesn't select images in the correct format
	$select_all.click(function(){

		//this.addClass("disabled");

		//select all inputs if not selected
		if(select_bool === false){

			//$("input.img-checkbox").prop("checked", true);

			$("input.img-checkbox").each(function(){
				//set property of each checkbox to checked
				$(this).prop('checked', true);

				img = new Array(2);
				img[0] = $(this).attr("name");
				img[1] = $(this).attr("id");

				//push selected images to selected images array
				selected_imgs.push(img);
			});

			select_bool = true;

			//change name of button to deselect all
			$("#select-all").text("Deselect All");

		}

		//deselect all inputs if selected
		else {

			$("input.img-checkbox").each(function(){
				//set property of each checkbox to checked
				$(this).prop("checked", false);
			});

			select_bool = false;

			//pop all selected images in selected images array
			selected_imgs = [];

			//change name of button to select all
			$("#select-all").text("Select All");
		}
		//change delete button state
		num_checked = count_checked();
		changeBtnState(num_checked, "delete");
		changeBtnState(num_checked, "save");
	});

	//on click sends selected images to server to retreive full sized images
	$save.click(function(){

		var params = {};

		//send all selected images to backend
		params = JSON.stringify({
			"type": "save",
			"image": selected_imgs
		});

		ws.send(params);

	});

	//sends currently selected images to the backend for removal
	$delete.click(function () {

		var params = JSON.stringify({
			"type" : "delete",
			"image" : selected_imgs
		});

		ws.send(params);

	});

	$auth_form.submit(function () {

		var params = JSON.stringify({
			"email": $email.val(),
			"pass": $pass.val(),
			"type": "connect",
			"limit": 0,
			"simultaneous": 10,
			"rewrite": 1
		});

		$auth_fields.attr("disabled", "disabled");
		ws.send(params);

		return false;
	});

	$sync_form.submit(function () {

		var params = JSON.stringify({
			"type": "sync"
		});

		$(this).find("[type=submit]").attr("disabled", "disabled");
		ws.send(params);

		return false;
	});

	$confim_form.submit(function () {

		var params = JSON.stringify({
			"type": "confirm",
		});

		$(this).find("button").attr("disabled", "disabled");
		ws.send(params);

		return false;
	});

	$no_confirm_bttn.click(function () {

		feedback({msg: "Thank you for your participation in this study."});
		$confim_form.fadeOut();
		return false;
	});

	var count_checked = function() {
		return $( "input:checked" ).length;
	};

	String.prototype.capitalizeFirstLetter = function(){

		return this.charAt(0).toUpperCase() + this.slice(1);
	};

	var changeBtnState = function(value, msg){

		msg = msg.toLowerCase();

		var $type = $( "#" + msg);

		msg = msg.capitalizeFirstLetter();

		if(value === 0){

			$type.addClass("disabled");
			$type.text(msg + " Image");
		}
		else if(value === 1){

			$type.removeClass("disabled");
			$type.text(msg + " Image");
		}
		else if(value > 1){

			$type.removeClass("disabled");
			$type.text(msg + " Images");
		}
		else{

			return; //an error has occured
		}
	};

	remove_image = function(gmail_id, image_id){

		var $image_thumbnail = $('#' + image_id);

		if($image_thumbnail.attr('id') === image_id && $image_thumbnail.attr('name') === gmail_id){

			//delete image thumbnail
			$image_thumbnail.closest('div').remove();
		}
		else{

		}
	};

	function save_file(encoded_images, image_names)
	{
		try {

			//create JSZip object
			var zip = new JSZip();

			//add images and their names to zip file
			for (var i = 0; i < encoded_images.length; i++)
			{
				zip.file(image_names[i], encoded_images[i], {base64: true});
			}

			var content = null;

			var content = zip.generate({type:"blob"});

			//display os save dialoge using FileSaver.js
			saveAs(content, "gmail_images.zip");

		} catch(e) {
			console.log(e)
		}

	};

$(document).on( "click", "input.img-checkbox", function() {

		var img_id = [ $(this).attr("name"), $(this).attr("id") ];
		var is_checked = $(this).prop('checked');
		var num_checked = count_checked();
		var select_bool = false;

		changeBtnState(num_checked, "delete");
		changeBtnState(num_checked, "save");

		//checkbox is clicked, save filename in an array
		if(is_checked){

		selected_imgs.push(img_id);
		}
		//checkbox is unclicked, remove filename from the array
		else {

		var index = selected_imgs.indexOf(img_id);
		selected_imgs.splice(index, 1);
		}
		});

ws.onmessage = function (evt) {
	var msg = JSON.parse(evt.data);

	switch (msg['type']) {

		case "connect":
			feedback(msg);
			if (!msg.ok) {
				$auth_fields.removeAttr("disabled");
			} else {
				$auth_form.fadeOut();
			}
			break;

		case "count":
			feedback(msg);
			num_messages = msg.num;
			break;

		case "image":
			$image_menu.fadeIn();
			update_results(msg.msg_id, msg.img_id, msg.enc_img);
			break;

		case "save":
			save_file(msg.images, msg.image_names);
			break;

		case "downloading":
			feedback(msg);
			update_progress(msg.num, num_messages);
			break;

		case "download-complete":
			feedback(msg, "Please check all attachments you'd like removed from your GMail account");
			hide_progress();
			//$sync_form.fadeIn();
			break;

		case "image-removed":
			remove_image(msg.gmail_id, msg.image_id)
		break;

		case "file-checking":
			feedback(msg);
			update_progress();
			//$sync_form.fadeOut();
			break;

		case "file-checked":
			rewrite_total = msg.num;
			hide_progress();
			$alert.hide();
			$confim_form
				.fadeIn()
				.find("p")
				.text("Are you sure you want to remove " + rewrite_total + " images from your email account?  This action is irreversable.");
			break;

		case "removing":
			$confim_form.fadeOut();
			feedback(msg);
			update_progress(++rewrite_index, rewrite_total);
			break;

		case "removed":
			feedback(msg);
			break;

		case "finished":
			feedback(msg);
			hide_progress();
			break;
	}
};

});
<commit_msg>fixed image selection bug<commit_after>jQuery(function ($) {

	var prog_hidden = true,
		results_hidden = true,
		loc = window.location,
		$prog_container = $(".progress"),
		$prog = $(".progress-bar"),
		$results_container = $(".results"),
		$email = $("#email"),
		$pass = $("#password"),
		$submit = $("#submit"),
		$auth_form = $("#auth-form"),
		$auth_fields = $auth_form.find(":input"),
		$alert = $(".alert"),
		$sync_form = $("#sync-form"),
		$confim_form = $("#confirm-form"),
		$no_confirm_bttn = $confim_form.find("[type=cancel]"),
		$delete = $("#delete"),
		$select_all = $("#select-all"),
		select_bool = false,
		$image_menu = $("#image-menu"),
		$save = $("#save"),
		$input = $("#input"),
		rewrite_index = null,
		rewrite_total = null,
		feedback = null,
		num_messages = null,
		update_progress = null,
		hide_progress = null,
		update_results = null,
		img_id = null,
		hide_results = null,
		selected_imgs = [],
		ws = new WebSocket("ws://" + loc.host + "/ws");

	hide_results = function () {

		$results_container.fadeOut();
		results_hidden = true;
	};

	//displays images in the browser as they are found in the users mailbox
	update_results = function (msg_id, img_id, enc_img) {

		if (results_hidden) {

			$results_container.show();
			results_hidden = false;
		}

		//decode image from base64 to small image to display in img tag
		var img = new Image();
		img.src = 'data:image/jpeg;base64,' + enc_img;

		//create thumbnail for image to be displayed in
		//create a unique img_id for the purpose of selecting each image
		$results_container.append('
' +
								  '<input class="img-checkbox" id="' + img_id +
								  '" name="' + msg_id + '" type="checkbox">' +
								  '' +
								  '' +
								  '' +
								  '
');
	};

	hide_progress = function () {
		$prog_container.fadeOut();
		prog_hidden = true;
	};

	update_progress = function (cur, max) {

		if (prog_hidden) {
			$prog_container.fadeIn();
			prog_hidden = false;
		}

		if (!cur && !max) {

			$prog_container.addClass("progress-striped").addClass("active");
			$prog.attr("aria-valuenow", 1)
			.attr("aria-valuemax", 1)
			.css("width", "100%");

		} else {

			$prog_container.removeClass("progress-striped").removeClass("active");
			$prog.attr("aria-valuenow", cur)
			.attr("aria-valuemax", max)
			.css("width", ((cur / max) * 100) + "%");
		}
	};

	feedback = function (msg, additional_message) {

		$alert.removeClass("alert-info").removeClass("alert-warning");
		$alert.show();

		if (msg.ok) {

			$alert.addClass("alert-info");

		} else {

			$alert.addClass("alert-warning");

		}

		if (additional_message) {

			$alert.html("
" + msg.msg + "

" + additional_message + "
");

		} else {

			$alert.text(msg.msg);

		}
	};

	previewImage = function (image_body) {

		$("#imagePreview").attr("src", image_body);
		$("#imageModal").modal('show', function(){

			$(this).find('.modal-body').css({

				width:'auto', //probably not needed
				height:'auto', //probably not needed
				'max-height':'100%'
			});
		});
	};

	//TODO - select all doesn't select images in the correct format
	$select_all.click(function(){

		//this.addClass("disabled");

		//select all inputs if not selected
		if(select_bool === false){

			//clear all selected images first
			selected_imgs = []

			//push all images to selected_imgs array
			$("input.img-checkbox").each(function(){
				//set property of each checkbox to checked
				$(this).prop('checked', true);

				var img_info = [$(this).attr("name"), $(this).attr("id")];

				//push selected images to selected images array
				selected_imgs.push(img_info);
			});

			select_bool = true;

			//change name of button to deselect all
			$("#select-all").text("Deselect All");

		}

		//deselect all inputs if selected
		else {

			$("input.img-checkbox").each(function(){
				//set property of each checkbox to checked
				$(this).prop("checked", false);
			});

			select_bool = false;

			//pop all selected images in selected images array
			selected_imgs = [];

			//change name of button to select all
			$("#select-all").text("Select All");
		}
		//change delete button state
		num_checked = count_checked();
		changeBtnState(num_checked, "delete");
		changeBtnState(num_checked, "save");
	});

	//on click sends selected images to server to retreive full sized images
	$save.click(function(){

		var params = {};

		//send all selected images to backend
		params = JSON.stringify({
			"type": "save",
			"image": selected_imgs
		});

		ws.send(params);

	});

	//sends currently selected images to the backend for removal
	$delete.click(function () {

		var params = JSON.stringify({
			"type" : "delete",
			"image" : selected_imgs
		});

		ws.send(params);

	});

	$auth_form.submit(function () {

		var params = JSON.stringify({
			"email": $email.val(),
			"pass": $pass.val(),
			"type": "connect",
			"limit": 0,
			"simultaneous": 10,
			"rewrite": 1
		});

		$auth_fields.attr("disabled", "disabled");
		ws.send(params);

		return false;
	});

	$sync_form.submit(function () {

		var params = JSON.stringify({
			"type": "sync"
		});

		$(this).find("[type=submit]").attr("disabled", "disabled");
		ws.send(params);

		return false;
	});

	$confim_form.submit(function () {

		var params = JSON.stringify({
			"type": "confirm",
		});

		$(this).find("button").attr("disabled", "disabled");
		ws.send(params);

		return false;
	});

	$no_confirm_bttn.click(function () {

		feedback({msg: "Thank you for your participation in this study."});
		$confim_form.fadeOut();
		return false;
	});

	var count_checked = function() {
		return $( "input:checked" ).length;
	};

	String.prototype.capitalizeFirstLetter = function(){

		return this.charAt(0).toUpperCase() + this.slice(1);
	};

	var changeBtnState = function(value, msg){

		msg = msg.toLowerCase();

		var $type = $( "#" + msg);

		msg = msg.capitalizeFirstLetter();

		if(value === 0){

			$type.addClass("disabled");
			$type.text(msg + " Image");
		}
		else if(value === 1){

			$type.removeClass("disabled");
			$type.text(msg + " Image");
		}
		else if(value > 1){

			$type.removeClass("disabled");
			$type.text(msg + " Images");
		}
		else{

			return; //an error has occured
		}
	};

	remove_image = function(gmail_id, image_id){

		var $image_thumbnail = $('#' + image_id);

		if($image_thumbnail.attr('id') === image_id && $image_thumbnail.attr('name') === gmail_id){

			//delete image thumbnail
			$image_thumbnail.closest('div').remove();
		}
		else{

		}
	};

	function save_file(encoded_images, image_names)
	{
		try {

			//create JSZip object
			var zip = new JSZip();

			//add images and their names to zip file
			for (var i = 0; i < encoded_images.length; i++)
			{
				zip.file(image_names[i], encoded_images[i], {base64: true});
			}

			var content = null;

			var content = zip.generate({type:"blob"});

			//display os save dialoge using FileSaver.js
			saveAs(content, "gmail_images.zip");

		} catch(e) {
			console.log(e)
		}

	};

$(document).on( "click", "input.img-checkbox", function() {

		var img_info = [ $(this).attr("name"), $(this).attr("id") ];
		var is_checked = $(this).prop('checked');
		var num_checked = count_checked();
		var select_bool = false;

		changeBtnState(num_checked, "delete");
		changeBtnState(num_checked, "save");

		//checkbox is clicked, save filename in an array
		if(is_checked){

			selected_imgs.push(img_info);
		}

		//checkbox is unclicked, remove filename from the array
		else {

			var index = -1;
			for (i=0; i<selected_imgs.length; i++){
				if (selected_imgs[i][1].localeCompare(img_info[1]) === 0){
					index = i
				}
			}
			selected_imgs.splice(index, 1);
		}
});

ws.onmessage = function (evt) {
	var msg = JSON.parse(evt.data);

	switch (msg['type']) {

		case "connect":
			feedback(msg);
			if (!msg.ok) {
				$auth_fields.removeAttr("disabled");
			} else {
				$auth_form.fadeOut();
			}
			break;

		case "count":
			feedback(msg);
			num_messages = msg.num;
			break;

		case "image":
			$image_menu.fadeIn();
			update_results(msg.msg_id, msg.img_id, msg.enc_img);
			break;

		case "save":
			save_file(msg.images, msg.image_names);
			break;

		case "downloading":
			feedback(msg);
			update_progress(msg.num, num_messages);
			break;

		case "download-complete":
			feedback(msg, "Please check all attachments you'd like removed from your GMail account");
			hide_progress();
			//$sync_form.fadeIn();
			break;

		case "image-removed":
			remove_image(msg.gmail_id, msg.image_id)
		break;

		case "file-checking":
			feedback(msg);
			update_progress();
			//$sync_form.fadeOut();
			break;

		case "file-checked":
			rewrite_total = msg.num;
			hide_progress();
			$alert.hide();
			$confim_form
				.fadeIn()
				.find("p")
				.text("Are you sure you want to remove " + rewrite_total + " images from your email account?  This action is irreversable.");
			break;

		case "removing":
			$confim_form.fadeOut();
			feedback(msg);
			update_progress(++rewrite_index, rewrite_total);
			break;

		case "removed":
			feedback(msg);
			break;

		case "finished":
			feedback(msg);
			hide_progress();
			break;
	}
};

});
<|endoftext|>


<commit_before>(function (window, Cryptoloji, $, _, theaterJS, undefined) {
  'use strict'

  Cryptoloji.states.encrypt = {
    enter: function () {
      var theater = theaterJS()

      if (!_.isEmpty(Cryptoloji.current.output)) {
        $('.main_share').addClass('main_share-visible')
      }

      if(Cryptoloji.stateman.previous.name === 'welcome'){
        $('#encryptHeader').css({y:-300})
        setTimeout(function(){
              $('#encryptHeader').transition({y:0, duration:1000, delay:250, easing:'easeInOutExpo'})
        },0)
      } else if(Cryptoloji.mq.matches) {
        $('.encryption_help_button').show()
        TweenLite.to($('.encryption_help_button'), 1.25, {opacity: 1, ease:Elastic.easeInOut})
      }

      // Cryptoloji.stateman.emit('header:show')
      Cryptoloji.stateman.emit('footer:show')
      Cryptoloji.stateman.emit('header:hide')

      // transition
      if (Cryptoloji.stateman.previous.name !== 'share' &&
          Cryptoloji.stateman.previous.name !== 'captcha') {
        Cryptoloji.UI.encryptionEnteringTransition('encryption')
      }

      Cryptoloji.UI.CharCounter('encrypt', '#encryption_input_count')
        .setMaxSize(Cryptoloji.settings.inputMaxSize)
        .attachTo('#encryption_input')

      // if we should serve a smaller version
      if (!Cryptoloji.mq.matches) {
        animateInputPlaceholder(theater)

        Cryptoloji.UI.Keyslider('encrypt', '#encryption_keyslider')
          .fill(keysliderEmojiList)

        Cryptoloji.stateman.on('keyslider:key-chosen', function (key) {
          if ($('#encryption_input').val().length === 0) {
            var newplaceholder = ['You\'ve picked a key. ', 500, '\nWrite your message here to see it in cipher.', 400]
            animateInputPlaceholder(theater, newplaceholder)
          }

          // check if the key is already being selected
          // this avoid multiple call from slider and modal
          if (Cryptoloji.current.key !== key) {
            Cryptoloji.UI.selectKey(key)

            // select corresponding emoji in keymodal
            Cryptoloji.UI.KeyModal().select(key)

            Cryptoloji.UI.encryptText()
          }
        })

        Cryptoloji.stateman.on('keymodal:key-chosen', function (key) {
          // check if the key is already being selected
          // this avoid multiple call from slider and modal
          if (Cryptoloji.current.key !== key) {
            Cryptoloji.UI.selectKey(key)

            Cryptoloji.UI.Keyslider('encrypt')
              .resetSelection()
              .addKey(key).select(key).scrollToSelectedKey()

            Cryptoloji.UI.encryptText()
          }
        })
      } else {
        Cryptoloji.stateman.on('keypanel:key-chosen', function (key) {

          Cryptoloji.UI.selectKey(key)
          $('#encryption_selected_key').html(Cryptoloji.UI.toTwemoji(key))
          // coachmark error
          if (_.isEmpty($('#encryption_input').val())) {
            $('body').addClass('main_content_top_input-first')
            setTimeout(function () {
              $('body').removeClass('main_content_top_input-first')
              $('#encryption_input').focus()
            }, 800)
            Cryptoloji.UI.KeyPanel('encrypt').tooltipAnimation(key)
          } else {
            Cryptoloji.UI.encryptText()
          }
        })
      }

      $('.encryption').addClass('section-show')

      // encrypt text on input
      $('#encryption_input').bind('input propertychange', _.debounce(function () {
        Cryptoloji.UI.encryptText()
        if (_.isEmpty($('#encryption_input').val())) {
          emptyOutput()
        }
      }, 350))

      // show share button at proper time
      Cryptoloji.stateman.on('encrypt:show-share', function () {
        var text = $('#encryption_input').val()
        // if want to show the share button only if key modal is closed
        // if (!$('body').hasClass('main_key_modal-open')) {}
        if (!_.isEmpty(text)) {
          $('.main_share').addClass('main_share-visible')
        }
      })
      Cryptoloji.stateman.on('encrypt:hide-share', function () {
        $('.main_share').removeClass('main_share-visible')
      })

      Cryptoloji.stateman.on('encrypt:animate-input-placeholder', function () {
        animateInputPlaceholder(theater)
      })
      // show/hide bottom placeholder text
      Cryptoloji.stateman.on('encrypt:hide-output-placeholder', function () {
        $('.main_content_bottom_input').removeClass('placeholdit')
      })

      // empty input field
      $('#encryption_input_cleaner').on('click', function () {
        emptyInput()
        emptyOutput()
        Cryptoloji.UI.CharCounter('encrypt').resetCount()
      })

      // show input related UI elements
      $('#encryption_input').on('focus', function () {
        $('#encryption_input_cleaner').hide()
        $('#encryption_input_count').show()
      })
      $('#encryption_input').on('blur', function () {
        var text = $('#encryption_input').val()
        if (!_.isEmpty(text)) {
          $('#encryption_input_cleaner').show()
        }
      })
    },
    leave: function () {
      // Cryptoloji.stateman.emit('header:hide')
      Cryptoloji.stateman.emit('footer:hide')
      Cryptoloji.UI.KeyModal().close()
      $('.encryption').removeClass('section-show')
      Cryptoloji.stateman.off('encrypt')
      Cryptoloji.stateman.off('keyslider')
      Cryptoloji.stateman.off('keypanel')
      Cryptoloji.stateman.off('keymodal')
      TweenLite.to($('.encryption_help_button'), 1.25, {opacity: 0, ease:Elastic.easeInOut, onComplete: function () {
        $('.encryption_help_button').hide()
      }})
      $('.section_more').removeClass('section-show')
      // reset main share
      $('.main_share').removeClass('main_share-visible')
    }
  }

  function animateInputPlaceholder (theater, text) {
    // store current placeholder
    var inputElem = $('#encryption_input')
    var encryptionInputPlaceholder = text ? text : inputElem.attr('placeholder')

    // typify placeholder (if it'is not playing yet)
    if (theater.status !== 'playing') {
      theater
        .addActor('inputPlaceholder', {speed: 1.3, accuracy: 1}, function (displayValue) {
          inputElem.attr('placeholder', displayValue)
        })
        .on('type:start', function () {
          $('body').addClass('main_content_top_input-first')
          // remove current placeholder for a cleaner start
          inputElem.attr('placeholder', '')
        })
        .addScene('inputPlaceholder:', encryptionInputPlaceholder)
        .addScene(function (done) {
          setTimeout(function () {
            $('body').removeClass('main_content_top_input-first')
            done()
          }, 400)
        })
    }
  }

  function emptyInput () {
    $('#encryption_input').val('')
    $('#encryption_input_cleaner').hide()
    $('#encryption_input_count').hide()
  }

  function emptyOutput () {
    $('#encryption_output > .emojis_output').html('')
    $('#encryption_output > .bluebox_output').html('')
    $('#encryption_output').addClass('placeholdit')
    $('.share_message_item').html('')
    $('.main_share').removeClass('main_share-visible')
  }

})(window, window.Cryptoloji, window.jQuery, window._, window.theaterJS);
<commit_msg>minor fix<commit_after>(function (window, Cryptoloji, $, _, theaterJS, undefined) {
  'use strict'

  Cryptoloji.states.encrypt = {
    enter: function () {
      var theater = theaterJS()

      if (!_.isEmpty(Cryptoloji.current.output)) {
        $('.main_share').addClass('main_share-visible')
      }

      if (Cryptoloji.stateman.previous.name === 'welcome'){
        $('#encryptHeader').css({y:-300})
        setTimeout(function(){
              $('#encryptHeader').transition({y:0, duration:1000, delay:250, easing:'easeInOutExpo'})
        },0)
      } else if (Cryptoloji.mq.matches) {
        $('.encryption_help_button').show()
        TweenLite.to($('.encryption_help_button'), 1.25, {opacity: 1, ease:Elastic.easeInOut})
      }

      // Cryptoloji.stateman.emit('header:show')
      Cryptoloji.stateman.emit('footer:show')
      Cryptoloji.stateman.emit('header:hide')

      // transition
      if (Cryptoloji.stateman.previous.name !== 'share' &&
          Cryptoloji.stateman.previous.name !== 'captcha') {
        Cryptoloji.UI.encryptionEnteringTransition('encryption')
      }

      Cryptoloji.UI.CharCounter('encrypt', '#encryption_input_count')
        .setMaxSize(Cryptoloji.settings.inputMaxSize)
        .attachTo('#encryption_input')

      // if we should serve a smaller version
      if (!Cryptoloji.mq.matches) {
        animateInputPlaceholder(theater)

        Cryptoloji.UI.Keyslider('encrypt', '#encryption_keyslider')
          .fill(keysliderEmojiList)

        Cryptoloji.stateman.on('keyslider:key-chosen', function (key) {
          if ($('#encryption_input').val().length === 0) {
            var newplaceholder = ['You\'ve picked a key. ', 500, '\nWrite your message here to see it in cipher.', 400]
            animateInputPlaceholder(theater, newplaceholder)
          }

          // check if the key is already being selected
          // this avoid multiple call from slider and modal
          if (Cryptoloji.current.key !== key) {
            Cryptoloji.UI.selectKey(key)

            // select corresponding emoji in keymodal
            Cryptoloji.UI.KeyModal().select(key)

            Cryptoloji.UI.encryptText()
          }
        })

        Cryptoloji.stateman.on('keymodal:key-chosen', function (key) {
          // check if the key is already being selected
          // this avoid multiple call from slider and modal
          if (Cryptoloji.current.key !== key) {
            Cryptoloji.UI.selectKey(key)

            Cryptoloji.UI.Keyslider('encrypt')
              .resetSelection()
              .addKey(key).select(key).scrollToSelectedKey()

            Cryptoloji.UI.encryptText()
          }
        })
      } else {
        Cryptoloji.stateman.on('keypanel:key-chosen', function (key) {

          Cryptoloji.UI.selectKey(key)
          $('#encryption_selected_key').html(Cryptoloji.UI.toTwemoji(key))
          // coachmark error
          if (_.isEmpty($('#encryption_input').val())) {
            $('body').addClass('main_content_top_input-first')
            setTimeout(function () {
              $('body').removeClass('main_content_top_input-first')
              $('#encryption_input').focus()
            }, 800)
            Cryptoloji.UI.KeyPanel('encrypt').tooltipAnimation(key)
          } else {
            Cryptoloji.UI.encryptText()
          }
        })
      }

      $('.encryption').addClass('section-show')

      // encrypt text on input
      $('#encryption_input').bind('input propertychange', _.debounce(function () {
        Cryptoloji.UI.encryptText()
        if (_.isEmpty($('#encryption_input').val())) {
          emptyOutput()
        }
      }, 350))

      // show share button at proper time
      Cryptoloji.stateman.on('encrypt:show-share', function () {
        var text = $('#encryption_input').val()
        // if want to show the share button only if key modal is closed
        // if (!$('body').hasClass('main_key_modal-open')) {}
        if (!_.isEmpty(text)) {
          $('.main_share').addClass('main_share-visible')
        }
      })
      Cryptoloji.stateman.on('encrypt:hide-share', function () {
        $('.main_share').removeClass('main_share-visible')
      })

      Cryptoloji.stateman.on('encrypt:animate-input-placeholder', function () {
        animateInputPlaceholder(theater)
      })
      // show/hide bottom placeholder text
      Cryptoloji.stateman.on('encrypt:hide-output-placeholder', function () {
        $('.main_content_bottom_input').removeClass('placeholdit')
      })

      // empty input field
      $('#encryption_input_cleaner').on('click', function () {
        emptyInput()
        emptyOutput()
        Cryptoloji.UI.CharCounter('encrypt').resetCount()
      })

      // show input related UI elements
      $('#encryption_input').on('focus', function () {
        $('#encryption_input_cleaner').hide()
        $('#encryption_input_count').show()
      })
      $('#encryption_input').on('blur', function () {
        var text = $('#encryption_input').val()
        if (!_.isEmpty(text)) {
          $('#encryption_input_cleaner').show()
        }
      })
    },
    leave: function () {
      // Cryptoloji.stateman.emit('header:hide')
      Cryptoloji.stateman.emit('footer:hide')
      Cryptoloji.UI.KeyModal().close()
      $('.encryption').removeClass('section-show')
      Cryptoloji.stateman.off('encrypt')
      Cryptoloji.stateman.off('keyslider')
      Cryptoloji.stateman.off('keypanel')
      Cryptoloji.stateman.off('keymodal')
      TweenLite.to($('.encryption_help_button'), 1.25, {opacity: 0, ease:Elastic.easeInOut, onComplete: function () {
        $('.encryption_help_button').hide()
      }})
      $('.section_more').removeClass('section-show')
      // reset main share
      $('.main_share').removeClass('main_share-visible')
    }
  }

  function animateInputPlaceholder (theater, text) {
    // store current placeholder
    var inputElem = $('#encryption_input')
    var encryptionInputPlaceholder = text ? text : inputElem.attr('placeholder')

    // typify placeholder (if it'is not playing yet)
    if (theater.status !== 'playing') {
      theater
        .addActor('inputPlaceholder', {speed: 1.3, accuracy: 1}, function (displayValue) {
          inputElem.attr('placeholder', displayValue)
        })
        .on('type:start', function () {
          $('body').addClass('main_content_top_input-first')
          // remove current placeholder for a cleaner start
          inputElem.attr('placeholder', '')
        })
        .addScene('inputPlaceholder:', encryptionInputPlaceholder)
        .addScene(function (done) {
          setTimeout(function () {
            $('body').removeClass('main_content_top_input-first')
            done()
          }, 400)
        })
    }
  }

  function emptyInput () {
    $('#encryption_input').val('')
    $('#encryption_input_cleaner').hide()
    $('#encryption_input_count').hide()
  }

  function emptyOutput () {
    $('#encryption_output > .emojis_output').html('')
    $('#encryption_output > .bluebox_output').html('')
    $('#encryption_output').addClass('placeholdit')
    $('.share_message_item').html('')
    $('.main_share').removeClass('main_share-visible')
  }

})(window, window.Cryptoloji, window.jQuery, window._, window.theaterJS);
<|endoftext|>


<commit_before>"use strict";

var file = require("../util/file");

function makeFilename(args) {

    var collection = args.collection,
        id = args.id,
        root = args.config.filedb.path,
        path = root + collection,
        filename = path;

    if (id) {
        filename += id;
    }

    return filename;

}

exports.readOne = function (args, callback) {
    var filename = makeFilename(args);
    file.readJSONFile(filename, function (err, file) {
        callback(err, file);
    });
};

exports.readList = function (args, callback) {
    var path = makeFilename(args);
    file.forceReadJSONDirectory(path, function (err, files) {
        callback(err, files);
    });
};

exports.create = function (args, callback) {

    var uuid = require("node-uuid"),
        uri = args.uri,
        id = uuid.v4(),
        data = args.data,
        filename;

    data._id = id;
    data.uri = uri + "/" + id;
    args.id = "/" + id; //TODO: fix this - other modules that are using substring get the leading slash

    filename = makeFilename(args);
    file.forceWriteJSONFile(filename, data, function (err, content) {
        callback(err, data);
    });
};

exports.update = function (args, callback) {
    var filename = makeFilename(args);
    file.forceWriteJSONFile(filename, args.data, function (err, content) {
        callback(err, args.data);
    });
};

exports.remove = function (args, callback) {
    var filename = makeFilename(args);
    file.deleteJSONFile(filename, function (err) {
        callback(err);
    });
};
<commit_msg>fixed id path issue on filedb<commit_after>"use strict";

var file = require("../util/file");

function makeFilename(args) {

    var collection = args.collection,
        id = args.id,
        root = args.config.filedb.path,
        path = root + collection,
        filename = path;

    if (id) {
        filename += id;
    }

    return filename;

}

exports.readOne = function (args, callback) {
    var filename = makeFilename(args);
    file.readJSONFile(filename, function (err, file) {
        callback(err, file);
    });
};

exports.readList = function (args, callback) {
    var path = makeFilename(args);
    file.forceReadJSONDirectory(path, function (err, files) {
        callback(err, files);
    });
};

exports.create = function (args, callback) {

    var uuid = require("node-uuid"),
        uri = args.uri,
        id = uuid.v4(),
        data = args.data,
        filename;

    data._id = id;
    data.uri = uri + "/" + id;
    args.id = id;

    filename = makeFilename(args);
    file.forceWriteJSONFile(filename, data, function (err, content) {
        callback(err, data);
    });
};

exports.update = function (args, callback) {
    var filename = makeFilename(args);
    file.forceWriteJSONFile(filename, args.data, function (err, content) {
        callback(err, args.data);
    });
};

exports.remove = function (args, callback) {
    var filename = makeFilename(args);
    file.deleteJSONFile(filename, function (err) {
        callback(err);
    });
};
<|endoftext|>


<commit_before>import mm723Image from '../../images/MM723_CNL_combo@2x.jpg';
import medtronic600PumpImage from '../../images/bayer_contour_next_link_24.jpg';

const devices = {
  carelink: {
    instructions: ['Import from CareLink', '(We will not store your credentials)'],
    isFetching: false,
    key: 'carelink',
    name: 'Medtronic',
    // for the device selection list
    selectName: 'Medtronic (from CareLink)',
    source: {type: 'carelink'},
    enabled: {mac: true, win: true}
  },
  medtronic: {
    instructions: 'Connect your Bayer Contour Next Link to your computer',
    image: {
      'src': mm723Image,
      'height': 128,
      'width': 200,
      'alt': 'Bayer Contour Next Link'
    },
    key: 'medtronic',
    name: 'Medtronic - 523, 723 or 530G',
    selectName: 'Medtronic direct from Bayer Contour Next Link',
    source: {type: 'device', driverId: 'Medtronic'},
    enabled: {mac: true, win: true}
  },
  medtronic600: {
    instructions: 'Pair your Bayer Contour Next Link 2.4 with your Medtronic pump and connect to your computer',
    image: {
      'src': medtronic600PumpImage,
      'height': 52,
      'width': 143,
      'alt': 'Bayer Contour Next Link 2.4'
    },
    key: 'medtronic600',
    name: 'Medtronic - 630G, 640G or 670G',
    selectName: 'Medtronic direct from Bayer Contour Next Link 2.4',
    showDriverLink: {mac: false, win: false},
    source: {type: 'device', driverId: 'Medtronic600'},
    enabled: {mac: true, win: true}
  },
  omnipod: {
    instructions: 'Plug in PDM with mini-USB and choose .ibf file from PDM',
    key: 'omnipod',
    name: 'Insulet OmniPod',
    source: {type: 'block', driverId: 'InsuletOmniPod', extension: '.ibf'},
    enabled: {mac: true, win: true}
  },
  dexcom: {
    instructions: 'Plug in receiver with micro-USB',
    key: 'dexcom',
    name: 'Dexcom',
    source: {type: 'device', driverId: 'Dexcom'},
    enabled: {mac: true, win: true}
  },
  precisionxtra: {
    instructions: 'Plug in meter with cable',
    key: 'precisionxtra',
    name: 'Abbott Precision Xtra',
    source: {type: 'device', driverId: 'AbbottPrecisionXtra'},
    enabled: {mac: false, win: true}
  },
  tandem: {
    instructions: 'Plug in pump with micro-USB',
    key: 'tandem',
    name: 'Tandem',
    source: {type: 'device', driverId: 'Tandem'},
    enabled: {mac: true, win: true}
  },
  abbottfreestylelite: {
    instructions: 'Plug in meter with cable',
    key: 'abbottfreestylelite',
    name: 'Abbott FreeStyle Lite & Freedom Lite',
    source: {type: 'device', driverId: 'AbbottFreeStyleLite'},
    enabled: {mac: false, win: true}
  },
  abbottfreestylelibre: {
    instructions: '(Unsupported) Plug in meter with micro-USB cable',
    key: 'abbottfreestylelibre',
    name: 'Abbott FreeStyle Libre (Beta)',
    showDriverLink: {linux: false, mac: false, win: false},
    source: {type: 'device', driverId: 'AbbottFreeStyleLibre'},
    enabled: {linux: true, mac: true, win: true}
  },
  bayercontournext: {
    instructions: 'Plug meter into USB port',
    key: 'bayercontournext',
    name: 'Bayer Contour Next',
    source: {type: 'device', driverId: 'BayerContourNext'},
    enabled: {mac: true, win: true}
  },
  animas: {
    instructions: 'Suspend and align back of pump with IR dongle front',
    key: 'animas',
    name: 'Animas',
    source: {type: 'device', driverId: 'Animas'},
    enabled: {mac: true, win: true}
  },
  onetouchverioiq: {
    instructions: 'Plug in meter with mini-USB',
    name: 'OneTouch VerioIQ',
    key: 'onetouchverioiq',
    source: {type: 'device', driverId: 'OneTouchVerioIQ'},
    enabled: {mac: true, win: true}
  },
  onetouchultramini: {
    instructions: 'Plug in meter with cable',
    name: 'OneTouch UltraMini',
    key: 'onetouchultramini',
    showDriverLink: {mac: true, win: true},
    source: {type: 'device', driverId: 'OneTouchUltraMini'},
    enabled: {mac: true, win: true}
  },
  onetouchultra2: {
    instructions: 'Plug in meter with cable',
    name: 'OneTouch Ultra 2',
    key: 'onetouchultra2',
    showDriverLink: {mac: true, win: true},
    source: {type: 'device', driverId: 'OneTouchUltra2'},
    enabled: {mac: true, win: true}
  }
};

export default devices;
<commit_msg>Apply driver copy changes as per https://trello.com/c/BF1URAvH<commit_after>import mm723Image from '../../images/MM723_CNL_combo@2x.jpg';
import medtronic600PumpImage from '../../images/bayer_contour_next_link_24.jpg';

const devices = {
  carelink: {
    instructions: ['Import from CareLink', '(We will not store your credentials)'],
    isFetching: false,
    key: 'carelink',
    name: 'Medtronic',
    // for the device selection list
    selectName: 'Medtronic (CareLink import)',
    source: {type: 'carelink'},
    enabled: {mac: true, win: true}
  },
  medtronic: {
    instructions: 'Connect your Bayer Contour Next Link to your computer',
    image: {
      'src': mm723Image,
      'height': 128,
      'width': 200,
      'alt': 'Bayer Contour Next Link'
    },
    key: 'medtronic',
    name: 'Medtronic 523, 723 or 530G',
    selectName: 'Medtronic 523, 723, 530G (Bayer Contour Next Link)',
    source: {type: 'device', driverId: 'Medtronic'},
    enabled: {mac: true, win: true}
  },
  medtronic600: {
    instructions: 'Pair your Bayer Contour Next Link 2.4 with your Medtronic pump and connect to your computer',
    image: {
      'src': medtronic600PumpImage,
      'height': 52,
      'width': 143,
      'alt': 'Bayer Contour Next Link 2.4'
    },
    key: 'medtronic600',
    name: 'Medtronic 630G, 640G or 670G',
    selectName: 'Medtronic 630G, 640G, 670G (Bayer Contour Next Link 2.4)',
    showDriverLink: {mac: false, win: false},
    source: {type: 'device', driverId: 'Medtronic600'},
    enabled: {mac: true, win: true}
  },
  omnipod: {
    instructions: 'Plug in PDM with mini-USB and choose .ibf file from PDM',
    key: 'omnipod',
    name: 'Insulet OmniPod',
    source: {type: 'block', driverId: 'InsuletOmniPod', extension: '.ibf'},
    enabled: {mac: true, win: true}
  },
  dexcom: {
    instructions: 'Plug in receiver with micro-USB',
    key: 'dexcom',
    name: 'Dexcom',
    source: {type: 'device', driverId: 'Dexcom'},
    enabled: {mac: true, win: true}
  },
  precisionxtra: {
    instructions: 'Plug in meter with cable',
    key: 'precisionxtra',
    name: 'Abbott Precision Xtra',
    source: {type: 'device', driverId: 'AbbottPrecisionXtra'},
    enabled: {mac: false, win: true}
  },
  tandem: {
    instructions: 'Plug in pump with micro-USB',
    key: 'tandem',
    name: 'Tandem',
    source: {type: 'device', driverId: 'Tandem'},
    enabled: {mac: true, win: true}
  },
  abbottfreestylelite: {
    instructions: 'Plug in meter with cable',
    key: 'abbottfreestylelite',
    name: 'Abbott FreeStyle Lite & Freedom Lite',
    source: {type: 'device', driverId: 'AbbottFreeStyleLite'},
    enabled: {mac: false, win: true}
  },
  abbottfreestylelibre: {
    instructions: '(Unsupported) Plug in meter with micro-USB cable',
    key: 'abbottfreestylelibre',
    name: 'Abbott FreeStyle Libre (Beta)',
    showDriverLink: {linux: false, mac: false, win: false},
    source: {type: 'device', driverId: 'AbbottFreeStyleLibre'},
    enabled: {linux: true, mac: true, win: true}
  },
  bayercontournext: {
    instructions: 'Plug meter into USB port',
    key: 'bayercontournext',
    name: 'Bayer Contour Next',
    source: {type: 'device', driverId: 'BayerContourNext'},
    enabled: {mac: true, win: true}
  },
  animas: {
    instructions: 'Suspend and align back of pump with IR dongle front',
    key: 'animas',
    name: 'Animas',
    source: {type: 'device', driverId: 'Animas'},
    enabled: {mac: true, win: true}
  },
  onetouchverioiq: {
    instructions: 'Plug in meter with mini-USB',
    name: 'OneTouch VerioIQ',
    key: 'onetouchverioiq',
    source: {type: 'device', driverId: 'OneTouchVerioIQ'},
    enabled: {mac: true, win: true}
  },
  onetouchultramini: {
    instructions: 'Plug in meter with cable',
    name: 'OneTouch UltraMini',
    key: 'onetouchultramini',
    showDriverLink: {mac: true, win: true},
    source: {type: 'device', driverId: 'OneTouchUltraMini'},
    enabled: {mac: true, win: true}
  },
  onetouchultra2: {
    instructions: 'Plug in meter with cable',
    name: 'OneTouch Ultra 2',
    key: 'onetouchultra2',
    showDriverLink: {mac: true, win: true},
    source: {type: 'device', driverId: 'OneTouchUltra2'},
    enabled: {mac: true, win: true}
  }
};

export default devices;
<|endoftext|>