<commit_before>const elecApp = require('@electron');
const { autoUpdater } = require('electron-updater');
const { Menu, app, BrowserWindow, crashReporter, dialog } = require('electron');
require('electron-debug')({ enabled: true });
const log = require('electron-log');
const { machineIdSync } = require('node-machine-id');
const os = require('os');

log.transports.file.level = 'info';
global.MACHINE_ID_ORIGINAL = machineIdSync({ original: true });
global.MACHINE_ID = machineIdSync({ original: false });
global.MACHINE_NAME = os.hostname();

if (process.env.CRASHREPORT_URL) {
  crashReporter.start({
    productName: 'App',
    companyName: 'cool.app',
    submitURL: process.env.CRASHREPORT_URL,
    uploadToServer: true,
  });
}

log.transports.file.level = 'info';
log.info('Starting');

const path = require('path');
const url = require('url');

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
const template = [
  {
    label: 'Programm',
    submenu: [
      { label: 'About', selector: 'orderFrontStandardAboutPanel:' },
      { type: 'separator' },
      {
        label: 'Beenden',
        accelerator: 'Command+Q',
        click() {
          app.quit();
        },
      },
    ],
  },
  {
    label: 'Bearbeiten',
    submenu: [
      { label: 'Rückgängig', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: 'Wiederholen', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { type: 'separator' },
      { label: 'Ausschneiden', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: 'Kopieren', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: 'Einfügen', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      { label: 'Alles Einfügen', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' },
    ],
  },
];

function createWindow() {
  log.info('Starting');
  if (template.length) {
    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
  }

  if (process.env.NODE_ENV === 'production') {
    log.info('Starting updater..');

    autoUpdater
      .checkForUpdates()
      .then(() => {
        log.info('Promise fulfilled');
      })
      .catch((reason) => {
        log.info(`Handle rejected promise (${reason.stack || reason}) here.`);
      });
  }
  log.info('Creating browser window');
  // Create the browser window.
  // mainWindow = new BrowserWindow({ width: 800, height: 600, frame: true, titleBarStyle: 'hidden' });
  mainWindow = new BrowserWindow({
    width: 1000,
    height: 750,
    minWidth: 600,
    minHeight: 450,
    center: true,
    // frame: false,
    // titleBarStyle: 'hidden',
  });

  log.info('Call app script');
  if (elecApp && elecApp.default) {
    try {
      elecApp.default(mainWindow);
    } catch (err) {
      dialog.showMessageBox({
        type: 'error',
        title: 'Error',
        message: JSON.stringify(err, null, 2),
      });
    }
  }

  log.info('Loading url');
  // and load the index.html of the app.
  mainWindow.loadURL(
    url.format({
      pathname: path.join(__dirname, 'index.html'),
      protocol: 'file:',
      slashes: true,
    }),
  );

  /* // Open the DevTools.
  if (process.env.NODE_ENV === 'development') {
    mainWindow.webContents.openDevTools();
  }*/

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

autoUpdater.on('checking-for-update', () => {
  log.info('Checking for update...');
});
autoUpdater.on('update-available', (ev, info) => {
  log.info('Update available.', ev, info);
  dialog.showMessageBox({
    type: 'info',
    title: 'Updater',
    message:
      'Ein Update wurde gefunden und wird jetzt heruntergeladen/installiert. Das Programm wird sich anschließend automatisch erneut öffnen.',
  });
});
autoUpdater.on('update-not-available', (ev, info) => {
  log.info('Update not available.', ev, info);
});
autoUpdater.on('error', (ev, err) => {
  log.info('Error in auto-updater.', ev, err);
});
autoUpdater.on('download-progress', (ev, progressObj) => {
  log.info('Download progress...', progressObj);
});
autoUpdater.on('update-downloaded', (ev, info) => {
  log.info('Update downloaded. Will quit and install.');
  autoUpdater.quitAndInstall();
});
<commit_msg>open log file from elec<commit_after>const elecApp = require('@electron');
const { autoUpdater } = require('electron-updater');
const { Menu, app, BrowserWindow, crashReporter, dialog, shell } = require('electron');
require('electron-debug')({ enabled: true });
const log = require('electron-log');
const { machineIdSync } = require('node-machine-id');
const os = require('os');

log.transports.file.level = 'info';
global.MACHINE_ID_ORIGINAL = machineIdSync({ original: true });
global.MACHINE_ID = machineIdSync({ original: false });
global.MACHINE_NAME = os.hostname();

if (process.env.CRASHREPORT_URL) {
  crashReporter.start({
    productName: 'App',
    companyName: 'cool.app',
    submitURL: process.env.CRASHREPORT_URL,
    uploadToServer: true,
  });
}

log.transports.file.level = 'info';
log.info('Starting');

const path = require('path');
const url = require('url');

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
const name = app.getName();
const template = [
  {
    label: name,
    submenu: [
      { label: `Über ${name}`, selector: 'orderFrontStandardAboutPanel:' },
      { type: 'separator' },
      {
        label: 'Beenden',
        accelerator: 'Command+Q',
        click() {
          app.quit();
        },
      },
    ],
  },
  {
    label: 'Bearbeiten',
    submenu: [
      { label: 'Rückgängig', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: 'Wiederholen', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { type: 'separator' },
      { label: 'Ausschneiden', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: 'Kopieren', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: 'Einfügen', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      { label: 'Alles Einfügen', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' },
    ],
  },
  {
    label: 'Hilfe',
    submenu: [
      {
        label: 'Log-Datei',
        click() {
          shell.openItem(log.transports.file.file);
        },
      },
    ],
  },
];

function createWindow() {
  log.info('Starting');
  if (template.length) {
    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
  }

  if (process.env.NODE_ENV === 'production') {
    log.info('Starting updater..');

    autoUpdater
      .checkForUpdates()
      .then(() => {
        log.info('Promise fulfilled');
      })
      .catch((reason) => {
        log.info(`Handle rejected promise (${reason.stack || reason}) here.`);
      });
  }
  log.info('Creating browser window');
  // Create the browser window.
  // mainWindow = new BrowserWindow({ width: 800, height: 600, frame: true, titleBarStyle: 'hidden' });
  mainWindow = new BrowserWindow({
    width: 1000,
    height: 750,
    minWidth: 600,
    minHeight: 450,
    center: true,
    // frame: false,
    // titleBarStyle: 'hidden',
  });

  log.info('Call app script');
  if (elecApp && elecApp.default) {
    try {
      elecApp.default(mainWindow);
    } catch (err) {
      dialog.showMessageBox({
        type: 'error',
        title: 'Error',
        message: JSON.stringify(err, null, 2),
      });
    }
  }

  log.info('Loading url');
  // and load the index.html of the app.
  mainWindow.loadURL(
    url.format({
      pathname: path.join(__dirname, 'index.html'),
      protocol: 'file:',
      slashes: true,
    }),
  );

  /* // Open the DevTools.
  if (process.env.NODE_ENV === 'development') {
    mainWindow.webContents.openDevTools();
  }*/

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

autoUpdater.on('checking-for-update', () => {
  log.info('Checking for update...');
});
autoUpdater.on('update-available', (ev, info) => {
  log.info('Update available.', ev, info);
  dialog.showMessageBox({
    type: 'info',
    title: 'Updater',
    message:
      'Ein Update wurde gefunden und wird jetzt heruntergeladen/installiert. Das Programm wird sich anschließend automatisch erneut öffnen.',
  });
});
autoUpdater.on('update-not-available', (ev, info) => {
  log.info('Update not available.', ev, info);
});
autoUpdater.on('error', (ev, err) => {
  log.info('Error in auto-updater.', ev, err);
});
autoUpdater.on('download-progress', (ev, progressObj) => {
  log.info('Download progress...', progressObj);
});
autoUpdater.on('update-downloaded', (ev, info) => {
  log.info('Update downloaded. Will quit and install.');
  autoUpdater.quitAndInstall();
});
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');

const projectName = require(path.join(process.cwd(), 'package.json')).name;
const s3Bucket = process.env.ASSETS_S3_BUCKET;

module.exports = () => {
  const queryMap = new Map();
  const assetsBase = s3Bucket ? `${s3Bucket}/${projectName}/assets` : path.resolve('build/assets');

  return (req, res, next) => {
    if (req.body && req.body.id && !req.body.query) {
      try {
        let queryText = queryMap.get(req.body.id);
        if (!queryText) {
          queryText = fs.readFileSync(`${assetsBase}/${req.body.id}.query`, 'utf8');
          queryMap.set(req.body.id, queryText);
        }
        req.body.query = queryText;
      } catch (e) {
        console.error(e);
        throw new Error(e);
      }
    }
    return next();
  };
};
<commit_msg>async readfile<commit_after>const fs = require('fs');
const path = require('path');
const { promisify } = require('util');

const projectName = require(path.join(process.cwd(), 'package.json')).name;
const readFile = promisify(fs.readFile);
const s3Bucket = process.env.ASSETS_S3_BUCKET;

module.exports = () => {
  const queryMap = new Map();
  const assetsBase = s3Bucket ? `${s3Bucket}/${projectName}/assets` : path.resolve('build/assets');

  return async (req, res, next) => {
    if (req.body && req.body.id && !req.body.query) {
      try {
        let queryText = queryMap.get(req.body.id);
        if (!queryText) {
          queryText = await readFile(`${assetsBase}/${req.body.id}.query.txt`, 'utf8');
          queryMap.set(req.body.id, queryText);
        }
        req.body.query = queryText;
      } catch (e) {
        console.error(e);
        throw new Error(e);
      }
    }
    return next();
  };
};
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var levels = require('../levels');
var times = require('../times');

function init() {

  var bwp = {
    name: 'bwp'
    , label: 'Bolus Wizard Preview'
    , pluginType: 'pill-minor'
  };

  function checkMissingInfo (sbx) {
    var errors = [];
    if (!sbx.data.profile || !sbx.data.profile.hasData()) {
      errors.push('Missing need a treatment profile');
    } else if (profileFieldsMissing(sbx)) {
      errors.push('Missing sens, target_high, or target_low treatment profile fields');
    }

    if (!sbx.properties.iob) {
      errors.push('Missing IOB property');
    }

    if (!isSGVOk(sbx)) {
      errors.push('Data isn\'t current');
    }

    return errors;
  }

  bwp.setProperties = function setProperties(sbx) {
    sbx.offerProperty('bwp', function setBWP ( ) {
      return bwp.calc(sbx);
    });
  };

  bwp.checkNotifications = function checkNotifications (sbx) {

    var prop = sbx.properties.bwp;
    if (prop === undefined) { return; }

    var settings = prepareSettings(sbx);

    if (bwp.highSnoozedByIOB(prop, settings, sbx)) {
      sbx.notifications.requestSnooze({
        level: levels.URGENT
        , title: 'Snoozing high alarm since there is enough IOB'
        , message: [sbx.propertyLine('bwp'), sbx.propertyLine('iob')].join('\n')
        , lengthMills: settings.snoozeLength
        , debug: prop
      });
    } else if (prop.scaledSGV > sbx.data.profile.getHighBGTarget(sbx.time) && prop.bolusEstimate > settings.warnBWP) {
      var level = prop.bolusEstimate > settings.urgentBWP ? levels.URGENT : levels.WARN;
      var levelLabel = levels.toDisplay(level);
      var sound = level === levels.URGENT ? 'updown' : 'bike';

      sbx.notifications.requestNotify({
        level: level
        , title: levelLabel + ', Check BG, time to bolus?'
        , message: sbx.buildDefaultMessage()
        , eventName: 'bwp'
        , pushoverSound: sound
        , plugin: bwp
        , debug: prop
      });
    }
  };

  bwp.highSnoozedByIOB = function highSnoozedByIOB(prop, settings, sbx) {
    var ar2EventType = sbx.properties.ar2 && sbx.properties.ar2.eventType;
    var high = ar2EventType === 'high' || prop.scaledSGV >= sbx.scaleMgdl(sbx.settings.thresholds.bgTargetTop);

    return high && prop.bolusEstimate < settings.snoozeBWP;
  };

  bwp.updateVisualisation = function updateVisualisation (sbx) {

    var prop = sbx.properties.bwp;

    var info = [];
    pushInfo(prop, info, sbx);

    var value;
    if (prop && prop.bolusEstimateDisplay >= 0) {
      value = prop.bolusEstimateDisplay + 'U';
    } else if (prop && prop.bolusEstimateDisplay < 0) {
      value = '< 0U';
    }

    sbx.pluginBase.updatePillText(bwp, {
      value: value
      , label: 'BWP'
      , info: info
    });
  };

  bwp.calc = function calc (sbx) {

    var results = {
      effect: 0
      , outcome: 0
      , bolusEstimate: 0.0
    };

    var scaled = sbx.lastScaledSGV();

    results.scaledSGV = scaled;

    var errors = checkMissingInfo(sbx);

    if (errors && errors.length > 0) {
      results.errors = errors;
      return results;
    }

    var profile = sbx.data.profile;
    var iob = results.iob = sbx.properties.iob.iob;

    results.effect = iob * profile.getSensitivity(sbx.time);
    results.outcome = scaled - results.effect;
    var delta = 0;

    var recentCarbs = _.findLast(sbx.data.treatments, function eachTreatment (treatment) {
      return treatment.mills <= sbx.time &&
        sbx.time - treatment.mills < times.mins(60).msecs &&
        treatment.carbs > 0;
    });

    results.recentCarbs = recentCarbs;

    var target_high = profile.getHighBGTarget(sbx.time);
    var sens = profile.getSensitivity(sbx.time);

    if (results.outcome > target_high) {
      delta = results.outcome - target_high;
      results.bolusEstimate = delta / sens;
      results.aimTarget = target_high;
      results.aimTargetString = 'above high';
    }

    var target_low = profile.getLowBGTarget(sbx.time);

    results.belowLowTarget = false;
    if (scaled < target_low) {
      results.belowLowTarget = true;
    }

    if (results.outcome < target_low) {
      delta = Math.abs(results.outcome - target_low);
      results.bolusEstimate = delta / sens * -1;
      results.aimTarget = target_low;
      results.aimTargetString = 'below low';
    }

    if (results.bolusEstimate !== 0 && sbx.data.profile.getBasal(sbx.time)) {
      // Basal profile exists, calculate % change
      var basal = sbx.data.profile.getBasal(sbx.time);

      var thirtyMinAdjustment = Math.round((basal/2 + results.bolusEstimate) / (basal / 2) * 100);
      var oneHourAdjustment = Math.round((basal + results.bolusEstimate) / basal * 100);

      results.tempBasalAdjustment = {
        'thirtymin': thirtyMinAdjustment
        ,'onehour': oneHourAdjustment};
    }

    results.bolusEstimateDisplay = sbx.roundInsulinForDisplayFormat(results.bolusEstimate);
    results.outcomeDisplay = sbx.roundBGToDisplayFormat(results.outcome);
    results.displayIOB = sbx.roundInsulinForDisplayFormat(results.iob);
    results.effectDisplay = sbx.roundBGToDisplayFormat(results.effect);
    results.displayLine = 'BWP: ' + results.bolusEstimateDisplay + 'U';

    return results;
  };

  function prepareSettings (sbx) {
    return {
      snoozeBWP: Number(sbx.extendedSettings.snooze) || 0.10
    , warnBWP: Number(sbx.extendedSettings.warn) || 0.50
    , urgentBWP: Number(sbx.extendedSettings.urgent) || 1.00
    , snoozeLength: (sbx.extendedSettings.snoozeMins && Number(sbx.extendedSettings.snoozeMins) * 60 * 1000) || times.mins(10).msecs
    };
  }

  return bwp;

}

function isSGVOk (sbx) {
  var lastSGVEntry = sbx.lastSGVEntry();
  return lastSGVEntry && lastSGVEntry.mgdl >= 39 && sbx.isCurrent(lastSGVEntry);
}

function profileFieldsMissing (sbx) {
  return !sbx.data.profile.getSensitivity(sbx.time)
    || !sbx.data.profile.getHighBGTarget(sbx.time)
    || !sbx.data.profile.getLowBGTarget(sbx.time);
}

function pushInfo(prop, info, sbx) {
  if (prop && prop.errors) {
    info.push({label: 'Notice', value: 'required info missing'});
    _.each(prop.errors, function pushError (error) {
      info.push({label: '  • ', value: error});
    });
  } else if (prop) {
    info.push({label: 'Insulin on Board', value: prop.displayIOB + 'U'});
    info.push({label: 'Current target', value: 'Low: '+sbx.data.profile.getLowBGTarget(sbx.time) + ' High: ' + sbx.data.profile.getHighBGTarget(sbx.time)});
    info.push({label: 'Sensitivity', value: '-' + sbx.data.profile.getSensitivity(sbx.time) + ' ' + sbx.settings.units + '/U'});
    info.push({label: 'Expected effect', value: prop.displayIOB + ' x -' + sbx.data.profile.getSensitivity(sbx.time) + ' = -' + prop.effectDisplay + ' ' + sbx.settings.units});
    info.push({label: 'Expected outcome', value: sbx.lastScaledSGV() + '-' + prop.effectDisplay + ' = ' + prop.outcomeDisplay + ' ' + sbx.settings.units});
    if (prop.bolusEstimateDisplay < 0) {
      info.unshift({label: '---------', value: ''});
      var carbEquivalent = Math.ceil(Math.abs(sbx.data.profile.getCarbRatio() * prop.bolusEstimateDisplay));
      info.unshift({label: 'Carb Equivalent', value: prop.bolusEstimateDisplay + 'U * ' + sbx.data.profile.getCarbRatio() + ' = ' + carbEquivalent + 'g'});
      info.unshift({label: 'Current Carb Ratio', value: '1U / ' + sbx.data.profile.getCarbRatio() + ' g'});

      if (prop.recentCarbs) {
        info.unshift({
          label: 'Recent carbs'
          , value: prop.recentCarbs.carbs + 'g @ ' + moment(prop.recentCarbs.mills).format('LT')});
      }

      if (!prop.belowLowTarget) {
        info.unshift({
          label: '-BWP'
          , value: 'Excess insulin equivalent ' + prop.bolusEstimateDisplay + 'U more than needed to reach low target, not accounting for carbs'});
      }

      if (prop.belowLowTarget) {
        if (prop.iob > 0) {
          info.unshift({
            label: '-BWP'
            , value: 'Excess insulin equivalent ' + prop.bolusEstimateDisplay + 'U more than needed to reach low target, MAKE SURE IOB IS COVERED BY CARBS'});
        } else {
          info.unshift({
            label: '-BWP'
            , value: prop.bolusEstimateDisplay + 'U reduction needed in active insulin to reach low target, too much basal?'});
        }
      }
    }
  } else {
    info.push({label: 'Notice', value: 'required info missing'});
  }

  pushTempBasalAdjustments(prop, info, sbx);
}

function pushTempBasalAdjustments(prop, info, sbx) {
  if (prop && prop.tempBasalAdjustment) {
    var carbsOrBolusMessage = 'basal adjustment our of range, give carbs?';
    var sign = '';
    if (prop.tempBasalAdjustment.thirtymin > 100) {
      carbsOrBolusMessage = 'basal adjustment our of range, give bolus?';
      sign = '+';
    }

    info.push({label: '---------', value: ''});
    if (prop.aimTarget) {
      info.push({label: 'Projected BG ' + prop.aimTargetString +' target', value: 'aiming at ' + prop.aimTarget + ' ' + sbx.settings.units});
    }

    if (prop.bolusEstimate > 0) {
      info.push({label: 'Bolus ' + prop.bolusEstimateDisplay + ' units', value: 'or adjust basal'});
      info.push({label: 'Check BG using glucometer before correcting!', value: ''});
      info.push({label: '---------', value: ''});
    } else {
      info.push({label: 'Basal reduction to account ' + prop.bolusEstimateDisplay + ' units:', value: ''});
    }

    info.push({label: 'Current basal', value: sbx.data.profile.getBasal(sbx.time)});

    if (prop.tempBasalAdjustment.thirtymin >= 0 && prop.tempBasalAdjustment.thirtymin <= 200) {
      info.push({label: '30m temp basal', value: '' + prop.tempBasalAdjustment.thirtymin + '% (' + sign + (prop.tempBasalAdjustment.thirtymin - 100) + '%)'});
    } else {
      info.push({label: '30m temp basal', value: carbsOrBolusMessage});
    }
    if (prop.tempBasalAdjustment.onehour >= 0 && prop.tempBasalAdjustment.onehour <= 200) {
      info.push({label: '1h temp basal', value: '' + prop.tempBasalAdjustment.onehour + '% (' + sign + (prop.tempBasalAdjustment.onehour - 100) + '%)'});
    } else {
      info.push({label: '1h temp basal', value: carbsOrBolusMessage});
    }
  }
}

module.exports = init;<commit_msg>Fixing a typo<commit_after>'use strict';

var _ = require('lodash');
var levels = require('../levels');
var times = require('../times');

function init() {

  var bwp = {
    name: 'bwp'
    , label: 'Bolus Wizard Preview'
    , pluginType: 'pill-minor'
  };

  function checkMissingInfo (sbx) {
    var errors = [];
    if (!sbx.data.profile || !sbx.data.profile.hasData()) {
      errors.push('Missing need a treatment profile');
    } else if (profileFieldsMissing(sbx)) {
      errors.push('Missing sens, target_high, or target_low treatment profile fields');
    }

    if (!sbx.properties.iob) {
      errors.push('Missing IOB property');
    }

    if (!isSGVOk(sbx)) {
      errors.push('Data isn\'t current');
    }

    return errors;
  }

  bwp.setProperties = function setProperties(sbx) {
    sbx.offerProperty('bwp', function setBWP ( ) {
      return bwp.calc(sbx);
    });
  };

  bwp.checkNotifications = function checkNotifications (sbx) {

    var prop = sbx.properties.bwp;
    if (prop === undefined) { return; }

    var settings = prepareSettings(sbx);

    if (bwp.highSnoozedByIOB(prop, settings, sbx)) {
      sbx.notifications.requestSnooze({
        level: levels.URGENT
        , title: 'Snoozing high alarm since there is enough IOB'
        , message: [sbx.propertyLine('bwp'), sbx.propertyLine('iob')].join('\n')
        , lengthMills: settings.snoozeLength
        , debug: prop
      });
    } else if (prop.scaledSGV > sbx.data.profile.getHighBGTarget(sbx.time) && prop.bolusEstimate > settings.warnBWP) {
      var level = prop.bolusEstimate > settings.urgentBWP ? levels.URGENT : levels.WARN;
      var levelLabel = levels.toDisplay(level);
      var sound = level === levels.URGENT ? 'updown' : 'bike';

      sbx.notifications.requestNotify({
        level: level
        , title: levelLabel + ', Check BG, time to bolus?'
        , message: sbx.buildDefaultMessage()
        , eventName: 'bwp'
        , pushoverSound: sound
        , plugin: bwp
        , debug: prop
      });
    }
  };

  bwp.highSnoozedByIOB = function highSnoozedByIOB(prop, settings, sbx) {
    var ar2EventType = sbx.properties.ar2 && sbx.properties.ar2.eventType;
    var high = ar2EventType === 'high' || prop.scaledSGV >= sbx.scaleMgdl(sbx.settings.thresholds.bgTargetTop);

    return high && prop.bolusEstimate < settings.snoozeBWP;
  };

  bwp.updateVisualisation = function updateVisualisation (sbx) {

    var prop = sbx.properties.bwp;

    var info = [];
    pushInfo(prop, info, sbx);

    var value;
    if (prop && prop.bolusEstimateDisplay >= 0) {
      value = prop.bolusEstimateDisplay + 'U';
    } else if (prop && prop.bolusEstimateDisplay < 0) {
      value = '< 0U';
    }

    sbx.pluginBase.updatePillText(bwp, {
      value: value
      , label: 'BWP'
      , info: info
    });
  };

  bwp.calc = function calc (sbx) {

    var results = {
      effect: 0
      , outcome: 0
      , bolusEstimate: 0.0
    };

    var scaled = sbx.lastScaledSGV();

    results.scaledSGV = scaled;

    var errors = checkMissingInfo(sbx);

    if (errors && errors.length > 0) {
      results.errors = errors;
      return results;
    }

    var profile = sbx.data.profile;
    var iob = results.iob = sbx.properties.iob.iob;

    results.effect = iob * profile.getSensitivity(sbx.time);
    results.outcome = scaled - results.effect;
    var delta = 0;

    var recentCarbs = _.findLast(sbx.data.treatments, function eachTreatment (treatment) {
      return treatment.mills <= sbx.time &&
        sbx.time - treatment.mills < times.mins(60).msecs &&
        treatment.carbs > 0;
    });

    results.recentCarbs = recentCarbs;

    var target_high = profile.getHighBGTarget(sbx.time);
    var sens = profile.getSensitivity(sbx.time);

    if (results.outcome > target_high) {
      delta = results.outcome - target_high;
      results.bolusEstimate = delta / sens;
      results.aimTarget = target_high;
      results.aimTargetString = 'above high';
    }

    var target_low = profile.getLowBGTarget(sbx.time);

    results.belowLowTarget = false;
    if (scaled < target_low) {
      results.belowLowTarget = true;
    }

    if (results.outcome < target_low) {
      delta = Math.abs(results.outcome - target_low);
      results.bolusEstimate = delta / sens * -1;
      results.aimTarget = target_low;
      results.aimTargetString = 'below low';
    }

    if (results.bolusEstimate !== 0 && sbx.data.profile.getBasal(sbx.time)) {
      // Basal profile exists, calculate % change
      var basal = sbx.data.profile.getBasal(sbx.time);

      var thirtyMinAdjustment = Math.round((basal/2 + results.bolusEstimate) / (basal / 2) * 100);
      var oneHourAdjustment = Math.round((basal + results.bolusEstimate) / basal * 100);

      results.tempBasalAdjustment = {
        'thirtymin': thirtyMinAdjustment
        ,'onehour': oneHourAdjustment};
    }

    results.bolusEstimateDisplay = sbx.roundInsulinForDisplayFormat(results.bolusEstimate);
    results.outcomeDisplay = sbx.roundBGToDisplayFormat(results.outcome);
    results.displayIOB = sbx.roundInsulinForDisplayFormat(results.iob);
    results.effectDisplay = sbx.roundBGToDisplayFormat(results.effect);
    results.displayLine = 'BWP: ' + results.bolusEstimateDisplay + 'U';

    return results;
  };

  function prepareSettings (sbx) {
    return {
      snoozeBWP: Number(sbx.extendedSettings.snooze) || 0.10
    , warnBWP: Number(sbx.extendedSettings.warn) || 0.50
    , urgentBWP: Number(sbx.extendedSettings.urgent) || 1.00
    , snoozeLength: (sbx.extendedSettings.snoozeMins && Number(sbx.extendedSettings.snoozeMins) * 60 * 1000) || times.mins(10).msecs
    };
  }

  return bwp;

}

function isSGVOk (sbx) {
  var lastSGVEntry = sbx.lastSGVEntry();
  return lastSGVEntry && lastSGVEntry.mgdl >= 39 && sbx.isCurrent(lastSGVEntry);
}

function profileFieldsMissing (sbx) {
  return !sbx.data.profile.getSensitivity(sbx.time)
    || !sbx.data.profile.getHighBGTarget(sbx.time)
    || !sbx.data.profile.getLowBGTarget(sbx.time);
}

function pushInfo(prop, info, sbx) {
  if (prop && prop.errors) {
    info.push({label: 'Notice', value: 'required info missing'});
    _.each(prop.errors, function pushError (error) {
      info.push({label: '  • ', value: error});
    });
  } else if (prop) {
    info.push({label: 'Insulin on Board', value: prop.displayIOB + 'U'});
    info.push({label: 'Current target', value: 'Low: '+sbx.data.profile.getLowBGTarget(sbx.time) + ' High: ' + sbx.data.profile.getHighBGTarget(sbx.time)});
    info.push({label: 'Sensitivity', value: '-' + sbx.data.profile.getSensitivity(sbx.time) + ' ' + sbx.settings.units + '/U'});
    info.push({label: 'Expected effect', value: prop.displayIOB + ' x -' + sbx.data.profile.getSensitivity(sbx.time) + ' = -' + prop.effectDisplay + ' ' + sbx.settings.units});
    info.push({label: 'Expected outcome', value: sbx.lastScaledSGV() + '-' + prop.effectDisplay + ' = ' + prop.outcomeDisplay + ' ' + sbx.settings.units});
    if (prop.bolusEstimateDisplay < 0) {
      info.unshift({label: '---------', value: ''});
      var carbEquivalent = Math.ceil(Math.abs(sbx.data.profile.getCarbRatio() * prop.bolusEstimateDisplay));
      info.unshift({label: 'Carb Equivalent', value: prop.bolusEstimateDisplay + 'U * ' + sbx.data.profile.getCarbRatio() + ' = ' + carbEquivalent + 'g'});
      info.unshift({label: 'Current Carb Ratio', value: '1U / ' + sbx.data.profile.getCarbRatio() + ' g'});

      if (prop.recentCarbs) {
        info.unshift({
          label: 'Recent carbs'
          , value: prop.recentCarbs.carbs + 'g @ ' + moment(prop.recentCarbs.mills).format('LT')});
      }

      if (!prop.belowLowTarget) {
        info.unshift({
          label: '-BWP'
          , value: 'Excess insulin equivalent ' + prop.bolusEstimateDisplay + 'U more than needed to reach low target, not accounting for carbs'});
      }

      if (prop.belowLowTarget) {
        if (prop.iob > 0) {
          info.unshift({
            label: '-BWP'
            , value: 'Excess insulin equivalent ' + prop.bolusEstimateDisplay + 'U more than needed to reach low target, MAKE SURE IOB IS COVERED BY CARBS'});
        } else {
          info.unshift({
            label: '-BWP'
            , value: prop.bolusEstimateDisplay + 'U reduction needed in active insulin to reach low target, too much basal?'});
        }
      }
    }
  } else {
    info.push({label: 'Notice', value: 'required info missing'});
  }

  pushTempBasalAdjustments(prop, info, sbx);
}

function pushTempBasalAdjustments(prop, info, sbx) {
  if (prop && prop.tempBasalAdjustment) {
    var carbsOrBolusMessage = 'basal adjustment out of range, give carbs?';
    var sign = '';
    if (prop.tempBasalAdjustment.thirtymin > 100) {
      carbsOrBolusMessage = 'basal adjustment out of range, give bolus?';
      sign = '+';
    }

    info.push({label: '---------', value: ''});
    if (prop.aimTarget) {
      info.push({label: 'Projected BG ' + prop.aimTargetString +' target', value: 'aiming at ' + prop.aimTarget + ' ' + sbx.settings.units});
    }

    if (prop.bolusEstimate > 0) {
      info.push({label: 'Bolus ' + prop.bolusEstimateDisplay + ' units', value: 'or adjust basal'});
      info.push({label: 'Check BG using glucometer before correcting!', value: ''});
      info.push({label: '---------', value: ''});
    } else {
      info.push({label: 'Basal reduction to account ' + prop.bolusEstimateDisplay + ' units:', value: ''});
    }

    info.push({label: 'Current basal', value: sbx.data.profile.getBasal(sbx.time)});

    if (prop.tempBasalAdjustment.thirtymin >= 0 && prop.tempBasalAdjustment.thirtymin <= 200) {
      info.push({label: '30m temp basal', value: '' + prop.tempBasalAdjustment.thirtymin + '% (' + sign + (prop.tempBasalAdjustment.thirtymin - 100) + '%)'});
    } else {
      info.push({label: '30m temp basal', value: carbsOrBolusMessage});
    }
    if (prop.tempBasalAdjustment.onehour >= 0 && prop.tempBasalAdjustment.onehour <= 200) {
      info.push({label: '1h temp basal', value: '' + prop.tempBasalAdjustment.onehour + '% (' + sign + (prop.tempBasalAdjustment.onehour - 100) + '%)'});
    } else {
      info.push({label: '1h temp basal', value: carbsOrBolusMessage});
    }
  }
}

module.exports = init;<|endoftext|>


<commit_before>var tfs     = require('tfs'),
    vscode  = require('vscode');

/**
 * @todo Add a description
 *
 * @module  TFS Get
 * @version 0.5.0
 *
 * @param {Array} itemspec File(s) and folder(s) to get latest version of.
 */
var get = function(itemspec) {
  vscode.window.setStatusBarMessage('TFS: Getting latest version...');

  var response = tfs('get', itemspec);

  if (response.isError) {
    console.error(response.error);

    var error = response.error.split('\n');
    vscode.window.showErrorMessage('TFS: ' + error[0]);
    return;
  }

  vscode.window.setStatusBarMessage('TFS: Get Latest Version successful.');
}

module.exports = get;
<commit_msg>Dev: async get command<commit_after>var tfs     = require('tfs'),
    vscode  = require('vscode');

/**
 * Get latest version of files for the entire workspace
 *
 * @module  TFS Get
 * @version 0.5.0
 *
 * @param {Array} itemspec File(s) and folder(s) to get latest version of.
 */
var get = function(itemspec) {
  vscode.window.setStatusBarMessage('TFS: Getting latest version...');

  var callback = function(responseError, response) {
    if (responseError) {
      vscode.window.showErrorMessage('TFS: ' + responseError.error);
      return;
    }

    vscode.window.setStatusBarMessage('TFS: Get Latest Version successful.');

    if (!response.hasUpdated) {
      vscode.window.showInformationMessage('TFS: ' + response.message);
      return;
    }

    vscode.window.showInformationMessage('TFS: Workspace files updated to the latest version.');
  }

  tfs('get', itemspec, {
    recursive: true
  }, callback);
}

module.exports = get;
<|endoftext|>


<commit_before>/**
 Copyright 2014 Gordon Williams (gw@pur3.co.uk)

 This Source Code is subject to the terms of the Mozilla Public
 License, v2.0. If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.

 ------------------------------------------------------------------
  Automatically minify code before it is sent to Espruino
 ------------------------------------------------------------------
**/
"use strict";
(function(){

  var minifyUrl = "https://closure-compiler.appspot.com/compile";
  var minifyCache = [];

  function init() {
    Espruino.Core.Config.addSection("Minification", {
      sortOrder:600,
      description: "Minification takes your JavaScript code and makes it smaller by removing comments and whitespace. "+
                   "It can make your code execute faster and will save memory, but it will also make it harder to debug.\n"+
                   "Esprima is a minifier built in to the Web IDE, so it can be used without an internet connection. "+
                   "The Closure Compiler is an online service offered by Google. It produces more efficient code, but you need an internet connection to use it."
    });

    Espruino.Core.Config.add("MINIFICATION_LEVEL", {
      section : "Minification",
      name : "Minification",
      description : "Automatically minify code from the Editor window?",
      type : { "":"No Minification",
               "TERSER":"Terser (uglify-es)",
               "ESPRIMA":"Esprima (offline)",
               "WHITESPACE_ONLY":"Closure (online) - Whitespace Only",
               "SIMPLE_OPTIMIZATIONS":"Closure (online) - Simple Optimizations",
               "ADVANCED_OPTIMIZATIONS":"Closure (online) - Advanced Optimizations (not recommended)"},
      defaultValue : ""
    });
    Espruino.Core.Config.add("MODULE_MINIFICATION_LEVEL", {
      section : "Minification",
      name : "Module Minification",
      description : "Automatically minify modules? Only modules with a .js extension will be minified - if a file with a .min.js extension exists then it will be used instead.",
      type : { "":"No Minification",
               "TERSER":"Terser (uglify-es)",
               "ESPRIMA":"Esprima (offline)",
               "WHITESPACE_ONLY":"Closure (online) - Whitespace Only",
               "SIMPLE_OPTIMIZATIONS":"Closure (online) - Simple Optimizations",
               "ADVANCED_OPTIMIZATIONS":"Closure (online) - Advanced Optimizations (not recommended)"},
      defaultValue : "ESPRIMA"
    });

    Espruino.Core.Config.add("ROLLUP",{
      section : "Rollup",
      name : "Use Rollup",
      description : "Uses rollup.js along with rollup-plugin-espruino-modules for bundling",
      type : "boolean",
      defaultValue : false
    });
    Espruino.Core.Config.add("MODULE_MERGE",{
      section : "Rollup",
      name : "Unwrap modules using rollup.js",
      description : "Uses rollup.js wihout the Modules.addCache",
      type : "boolean",
      defaultValue : true
    });
    Espruino.Core.Config.add("MINIFICATION_Mangle",{
      section : "Minification",
      name : "Esprima: Mangle",
      description : "Shorten variable names",
      type : "boolean",
      defaultValue : true
    });

    // When code is sent to Espruino, search it for modules and add extra code required to load them
    Espruino.addProcessor("transformForEspruino", function(code, callback) {
      minify(code, callback, Espruino.Config.MINIFICATION_LEVEL, false, "");
    });
   // When code is sent to Espruino, search it for modules and add extra code required to load them
    Espruino.addProcessor("transformModuleForEspruino", function(module, callback) {
      minify(module.code, function(code) {
        module.code = code;
        callback(module);
      }, Espruino.Config.MODULE_MINIFICATION_LEVEL, true, " in "+module.name);
    });
  }

  // Use the 'offline' Esprima compile
  function minifyCodeEsprima(code,callback,description) {
    if ((typeof esprima == "undefined") ||
        (typeof esmangle == "undefined") ||
        (typeof escodegen == "undefined")) {
      console.warn("esprima/esmangle/escodegen not defined - not minifying")
      return callback(code);
    }

    var code, syntax, option, str, before, after;
    var options = {};
    options["mangle"] = Espruino.Config.MINIFICATION_Mangle;
    option = {format: {
      renumber: true,
      hexadecimal: true,
      escapeless: true,
      indent: {style: ''},
      quotes: 'auto',
      compact: true,
      semicolons: false,
      parentheses: false
    }};
    str = '';
    try {
        before = code.length;
        syntax = esprima.parse(code, { raw: true, loc: true });
        syntax = obfuscate(syntax,options);
        code = escodegen.generate(syntax, option);
        after = code.length;
        if (before > after) {
          Espruino.Core.Notifications.info('No errors'+description+'. Minified ' + before + ' bytes to ' + after + ' bytes.');
        } else {
          Espruino.Core.Notifications.info('Can not minify further'+description+', code is already optimized.');
        }
        callback(code);
    } catch (e) {
      Espruino.Core.Notifications.error(e.toString()+description);
      console.error(e.stack);
      callback(code);
    } finally { }
  }
  function obfuscate(syntax,options) {
    // hack for random changes between version we have included for Web IDE and node.js version
    if (typeof esmangle.require == "undefined")
      esmangle.require = esmangle.pass.require;
    syntax = esmangle.optimize(syntax, null,{
        destructive: true,
        directive: true,
        preserveCompletionValue: false,
        legacy: false,
        topLevelContext: false,
        inStrictCode: false
    });
    if (options.mangle) syntax = esmangle.mangle(syntax);
    return syntax;
  }

  // Use the 'online' Closure compiler
  function minifyCodeGoogle(code, callback, minificationLevel, description){
    for (var i in minifyCache) {
      var item = minifyCache[i];
      if (item.code==code && item.level==minificationLevel) {
        console.log("Found code in minification cache - using that"+description);
        // move to front of cache
        minifyCache.splice(i,1); // remove old
        minifyCache.push(item); // add at front
        // callback
        callback(item.minified);
        return;
      }
    }
    closureCompilerGoogle(code,  minificationLevel, 'compiled_code', function(minified) {
      if (minified.trim()!="") {
        Espruino.Core.Notifications.info('No errors'+description+'. Minifying ' + code.length + ' bytes to ' + minified.length + ' bytes');
        if (minifyCache.length>100)
          minifyCache = minifyCache.slice(-100);
        minifyCache.push({ level : minificationLevel, code : code, minified : minified });
        callback(minified);
      } else {
        Espruino.Core.Notifications.warning("Errors while minifying"+description+" - sending unminified code.");
        callback(code);
        // get errors...
        closureCompilerGoogle(code,  minificationLevel, 'errors',function(errors) {
          errors.split("\n").forEach(function (err) {
            if (err.trim()!="")
              Espruino.Core.Notifications.error(err.trim()+description);
          });
        });
      }
    });
  }
  function closureCompilerGoogle(code, minificationLevel, output_info, callback){
    if(minificationLevel !== ""){
      var minifyObj = $.param({
        compilation_level: minificationLevel,
        output_format: "text",
        output_info: output_info,
        js_code: code,
        language : "ECMASCRIPT6", // so no need to mess with binary numbers now. \o/
        language_out : "ECMASCRIPT5" // ES6 output uses some now features now that Espruino doesn't like
      });
      $.post(minifyUrl, minifyObj, function(minifiedCode) {
        code = minifiedCode;
      },"text")
      .error(function() {
        Espruino.Core.Notifications.error("HTTP error while minifying");
      })
      .complete(function() {
        // ensure we call the callback even if minification failes
        callback(code);
      });
    }
  }

  function minifyCodeTerser(code, callback, description){
    rollupTools.minifyCodeTerser(code)
      .then(generated => {
        var minified = generated.code;

        // FIXME: needs warnings?
        Espruino.Core.Notifications.info('Terser no errors'+description+'. Minifying ' + code.length + ' bytes to ' + minified.length + ' bytes');
        callback(minified);
      })
      .catch(err => {
        Espruino.Core.Notifications.warning("Terser errors"+description+" - sending unminified code.");
        Espruino.Core.Notifications.error(String(err).trim());
        callback(code);
      });
  }

  function minify(code, callback, level, isModule, description) {
    if (Espruino.Config.ROLLUP) {
        // already minified by the ROLLUP pipeline
        return callback(code);
    }
    (function() {
      Espruino.Core.Status.setStatus("Minifying"+(isModule?description.substr(2):""));
      var _callback = callback;
      callback = function(code) {
        Espruino.Core.Status.setStatus("Minification complete");
        _callback(code);
      };
    })();

    var minifyCode = code;
    var minifyCallback = callback;
    if (isModule) {
      /* if we're a module, we wrap this in a function so that unused constants
      and functions can be removed */
      var header = "(function(){";
      var footer = "})();";
      minifyCode = header+code+footer;
      minifyCallback = function (minified){
        callback(minified.substr(header.length, minified.length-(header.length+footer.length+1)));
      }
    }

    switch(level){
      case "WHITESPACE_ONLY":
      case "SIMPLE_OPTIMIZATIONS":
      case "ADVANCED_OPTIMIZATIONS": minifyCodeGoogle(code, callback, level, description); break;
      case "ESPRIMA": minifyCodeEsprima(code, callback, description); break;
      case "TERSER": minifyCodeTerser(code, callback, description); break;
      default: callback(code); break;
    }
  }

  Espruino.Plugins.Minify = {
    init : init,
  };
}());
<commit_msg>Move some options from a specific rollup settings page into Minification<commit_after>/**
 Copyright 2014 Gordon Williams (gw@pur3.co.uk)

 This Source Code is subject to the terms of the Mozilla Public
 License, v2.0. If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.

 ------------------------------------------------------------------
  Automatically minify code before it is sent to Espruino
 ------------------------------------------------------------------
**/
"use strict";
(function(){

  var minifyUrl = "https://closure-compiler.appspot.com/compile";
  var minifyCache = [];

  function init() {
    Espruino.Core.Config.addSection("Minification", {
      sortOrder:600,
      description: "Minification takes your JavaScript code and makes it smaller by removing comments and whitespace. "+
                   "It can make your code execute faster and will save memory, but it will also make it harder to debug.\n"+
                   "Esprima is a minifier built in to the Web IDE, so it can be used without an internet connection. "+
                   "The Closure Compiler is an online service offered by Google. It produces more efficient code, but you need an internet connection to use it."
    });

    Espruino.Core.Config.add("MINIFICATION_LEVEL", {
      section : "Minification",
      name : "Minification",
      description : "Automatically minify code from the Editor window?",
      type : { "":"No Minification",
               "TERSER":"Terser (uglify-es)",
               "ESPRIMA":"Esprima (offline)",
               "WHITESPACE_ONLY":"Closure (online) - Whitespace Only",
               "SIMPLE_OPTIMIZATIONS":"Closure (online) - Simple Optimizations",
               "ADVANCED_OPTIMIZATIONS":"Closure (online) - Advanced Optimizations (not recommended)"},
      defaultValue : ""
    });
    Espruino.Core.Config.add("MODULE_MINIFICATION_LEVEL", {
      section : "Minification",
      name : "Module Minification",
      description : "Automatically minify modules? Only modules with a .js extension will be minified - if a file with a .min.js extension exists then it will be used instead.",
      type : { "":"No Minification",
               "TERSER":"Terser (uglify-es)",
               "ESPRIMA":"Esprima (offline)",
               "WHITESPACE_ONLY":"Closure (online) - Whitespace Only",
               "SIMPLE_OPTIMIZATIONS":"Closure (online) - Simple Optimizations",
               "ADVANCED_OPTIMIZATIONS":"Closure (online) - Advanced Optimizations (not recommended)"},
      defaultValue : "ESPRIMA"
    });

    Espruino.Core.Config.add("ROLLUP",{
      section : "Minification",
      name : "Rollup: Enable Rollup",
      description : "Use rollup.js along with rollup-plugin-espruino-modules for bundling",
      type : "boolean",
      defaultValue : false
    });
    Espruino.Core.Config.add("MODULE_MERGE",{
      section : "Minification",
      name : "Rollup: Unwrap modules using rollup.js",
      description : "Uses rollup.js to merge modules and remove unused code",
      type : "boolean",
      defaultValue : true
    });
    Espruino.Core.Config.add("MINIFICATION_Mangle",{
      section : "Minification",
      name : "Esprima: Mangle",
      description : "Shorten variable names",
      type : "boolean",
      defaultValue : true
    });

    // When code is sent to Espruino, search it for modules and add extra code required to load them
    Espruino.addProcessor("transformForEspruino", function(code, callback) {
      minify(code, callback, Espruino.Config.MINIFICATION_LEVEL, false, "");
    });
   // When code is sent to Espruino, search it for modules and add extra code required to load them
    Espruino.addProcessor("transformModuleForEspruino", function(module, callback) {
      minify(module.code, function(code) {
        module.code = code;
        callback(module);
      }, Espruino.Config.MODULE_MINIFICATION_LEVEL, true, " in "+module.name);
    });
  }

  // Use the 'offline' Esprima compile
  function minifyCodeEsprima(code,callback,description) {
    if ((typeof esprima == "undefined") ||
        (typeof esmangle == "undefined") ||
        (typeof escodegen == "undefined")) {
      console.warn("esprima/esmangle/escodegen not defined - not minifying")
      return callback(code);
    }

    var code, syntax, option, str, before, after;
    var options = {};
    options["mangle"] = Espruino.Config.MINIFICATION_Mangle;
    option = {format: {
      renumber: true,
      hexadecimal: true,
      escapeless: true,
      indent: {style: ''},
      quotes: 'auto',
      compact: true,
      semicolons: false,
      parentheses: false
    }};
    str = '';
    try {
        before = code.length;
        syntax = esprima.parse(code, { raw: true, loc: true });
        syntax = obfuscate(syntax,options);
        code = escodegen.generate(syntax, option);
        after = code.length;
        if (before > after) {
          Espruino.Core.Notifications.info('No errors'+description+'. Minified ' + before + ' bytes to ' + after + ' bytes.');
        } else {
          Espruino.Core.Notifications.info('Can not minify further'+description+', code is already optimized.');
        }
        callback(code);
    } catch (e) {
      Espruino.Core.Notifications.error(e.toString()+description);
      console.error(e.stack);
      callback(code);
    } finally { }
  }
  function obfuscate(syntax,options) {
    // hack for random changes between version we have included for Web IDE and node.js version
    if (typeof esmangle.require == "undefined")
      esmangle.require = esmangle.pass.require;
    syntax = esmangle.optimize(syntax, null,{
        destructive: true,
        directive: true,
        preserveCompletionValue: false,
        legacy: false,
        topLevelContext: false,
        inStrictCode: false
    });
    if (options.mangle) syntax = esmangle.mangle(syntax);
    return syntax;
  }

  // Use the 'online' Closure compiler
  function minifyCodeGoogle(code, callback, minificationLevel, description){
    for (var i in minifyCache) {
      var item = minifyCache[i];
      if (item.code==code && item.level==minificationLevel) {
        console.log("Found code in minification cache - using that"+description);
        // move to front of cache
        minifyCache.splice(i,1); // remove old
        minifyCache.push(item); // add at front
        // callback
        callback(item.minified);
        return;
      }
    }
    closureCompilerGoogle(code,  minificationLevel, 'compiled_code', function(minified) {
      if (minified.trim()!="") {
        Espruino.Core.Notifications.info('No errors'+description+'. Minifying ' + code.length + ' bytes to ' + minified.length + ' bytes');
        if (minifyCache.length>100)
          minifyCache = minifyCache.slice(-100);
        minifyCache.push({ level : minificationLevel, code : code, minified : minified });
        callback(minified);
      } else {
        Espruino.Core.Notifications.warning("Errors while minifying"+description+" - sending unminified code.");
        callback(code);
        // get errors...
        closureCompilerGoogle(code,  minificationLevel, 'errors',function(errors) {
          errors.split("\n").forEach(function (err) {
            if (err.trim()!="")
              Espruino.Core.Notifications.error(err.trim()+description);
          });
        });
      }
    });
  }
  function closureCompilerGoogle(code, minificationLevel, output_info, callback){
    if(minificationLevel !== ""){
      var minifyObj = $.param({
        compilation_level: minificationLevel,
        output_format: "text",
        output_info: output_info,
        js_code: code,
        language : "ECMASCRIPT6", // so no need to mess with binary numbers now. \o/
        language_out : "ECMASCRIPT5" // ES6 output uses some now features now that Espruino doesn't like
      });
      $.post(minifyUrl, minifyObj, function(minifiedCode) {
        code = minifiedCode;
      },"text")
      .error(function() {
        Espruino.Core.Notifications.error("HTTP error while minifying");
      })
      .complete(function() {
        // ensure we call the callback even if minification failes
        callback(code);
      });
    }
  }

  function minifyCodeTerser(code, callback, description){
    rollupTools.minifyCodeTerser(code)
      .then(generated => {
        var minified = generated.code;

        // FIXME: needs warnings?
        Espruino.Core.Notifications.info('Terser no errors'+description+'. Minifying ' + code.length + ' bytes to ' + minified.length + ' bytes');
        callback(minified);
      })
      .catch(err => {
        Espruino.Core.Notifications.warning("Terser errors"+description+" - sending unminified code.");
        Espruino.Core.Notifications.error(String(err).trim());
        callback(code);
      });
  }

  function minify(code, callback, level, isModule, description) {
    if (Espruino.Config.ROLLUP) {
        // already minified by the ROLLUP pipeline
        return callback(code);
    }
    (function() {
      Espruino.Core.Status.setStatus("Minifying"+(isModule?description.substr(2):""));
      var _callback = callback;
      callback = function(code) {
        Espruino.Core.Status.setStatus("Minification complete");
        _callback(code);
      };
    })();

    var minifyCode = code;
    var minifyCallback = callback;
    if (isModule) {
      /* if we're a module, we wrap this in a function so that unused constants
      and functions can be removed */
      var header = "(function(){";
      var footer = "})();";
      minifyCode = header+code+footer;
      minifyCallback = function (minified){
        callback(minified.substr(header.length, minified.length-(header.length+footer.length+1)));
      }
    }

    switch(level){
      case "WHITESPACE_ONLY":
      case "SIMPLE_OPTIMIZATIONS":
      case "ADVANCED_OPTIMIZATIONS": minifyCodeGoogle(code, callback, level, description); break;
      case "ESPRIMA": minifyCodeEsprima(code, callback, description); break;
      case "TERSER": minifyCodeTerser(code, callback, description); break;
      default: callback(code); break;
    }
  }

  Espruino.Plugins.Minify = {
    init : init,
  };
}());
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var defaultConfigFile = path.resolve(__dirname, '../etc/licode_default.js');
var nuveConfig = require(defaultConfigFile).nuve;
var dbURL = process.env.DB_URL || nuveConfig.dataBaseURL;
var mongojs = require('mongojs');
var db = mongojs.connect(dbURL, ['services']);
var nuveConfigFile = path.resolve(__dirname, '../local/etc/nuve.json');

function prepareService (serviceName, next) {
  db.services.findOne({name: serviceName}, function cb (err, service) {
    if (err || !service) {
      service = {name: serviceName, key: crypto.randomBytes(32).toString('base64'), rooms: []};
      db.services.save(service, function cb (err, saved) {
        if (err) {
          console.log('mongodb: error in adding', serviceName);
          return db.close();
        }
        next(saved);
      });
    } else {
      next(service);
    }
  });
}

prepareService('superService', function (service) {
  db.close();
  var superServiceId = service._id+'';
  var superServiceKey = service.key;
  console.log('superServiceId:', superServiceId);
  console.log('superServiceKey:', superServiceKey);
  try {
    fs.statSync(nuveConfigFile);
    nuveConfig = require(nuveConfigFile);
  } catch (e) {}
  nuveConfig.dataBaseURL = dbURL;
  nuveConfig.superserviceID = superServiceId;
  fs.writeFile(nuveConfigFile, JSON.stringify(nuveConfig, null, '  '), 'utf8', function (err) {
    if (err) return console.log('Error in saving nuve.json:', err);
    console.log(nuveConfigFile, 'configured.');
  });
});<commit_msg>Fixes initdb.js: regard local/etc/nuve.json<commit_after>#!/usr/bin/env node
'use strict';

var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var defaultConfigFile = path.resolve(__dirname, '../etc/licode_default.js');
var nuveConfigFile = path.resolve(__dirname, '../local/etc/nuve.json');
var nuveConfig = require(defaultConfigFile).nuve;
try {
  nuveConfig = require(nuveConfigFile);
} catch (e) {
  console.log(e);
}
var dbURL = process.env.DB_URL || nuveConfig.dataBaseURL;
var mongojs = require('mongojs');
var db = mongojs.connect(dbURL, ['services']);

function prepareService (serviceName, next) {
  db.services.findOne({name: serviceName}, function cb (err, service) {
    if (err || !service) {
      service = {name: serviceName, key: crypto.randomBytes(32).toString('base64'), rooms: []};
      db.services.save(service, function cb (err, saved) {
        if (err) {
          console.log('mongodb: error in adding', serviceName);
          return db.close();
        }
        next(saved);
      });
    } else {
      next(service);
    }
  });
}

prepareService('superService', function (service) {
  db.close();
  var superServiceId = service._id+'';
  var superServiceKey = service.key;
  console.log('superServiceId:', superServiceId);
  console.log('superServiceKey:', superServiceKey);
  nuveConfig.dataBaseURL = dbURL;
  nuveConfig.superserviceID = superServiceId;
  fs.writeFile(nuveConfigFile, JSON.stringify(nuveConfig, null, '  '), 'utf8', function (err) {
    if (err) return console.log('Error in saving nuve.json:', err);
    console.log(nuveConfigFile, 'configured.');
  });
});<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const graphiteUtil = require('../../support/tsdbUtil');

module.exports = {
  open(context, options) {
    this.storageManager = context.storageManager;
    this.alias = {};
    this.options = options;
  },
  async processMessage(message) {
    switch (message.type) {
      // Collect alias so we can use it
      case 'browsertime.alias': {
        this.alias[message.url] = message.data;
        break;
      }

      case 'browsertime.config': {
        if (message.data.screenshot) {
          this.useScreenshots = message.data.screenshot;
          this.screenshotType = message.data.screenshotType;
        }
        break;
      }

      case 'browsertime.run': {
        // Only use the first one for now
        if (message.iteration === 1 && this.options.copyLatestFilesToBase) {
          console.log(message.data.android);
          const options = this.options;
          const baseDir = this.storageManager.getBaseDir();
          // Hack to get out of the date dir
          const newPath = path.resolve(baseDir, '..');

          // This is a hack to get the same name as in Grafana, meaning we can
          // generate the path to the URL there
          const name = graphiteUtil.getURLAndGroup(
            options,
            message.group,
            message.url,
            this.options.graphite.includeQueryParams,
            this.alias
          );
          const connectivity = graphiteUtil.getConnectivity(options);

          if (this.useScreenshots) {
            const imageFullPath = path.join(baseDir, message.data.screenshot);
            await this.storageManager.copyFileToDir(
              imageFullPath,
              newPath +
                '/' +
                name +
                '.' +
                this.options.browser +
                '.' +
                connectivity +
                '.' +
                this.screenshotType
            );
          }
          if (this.options.browsertime && this.options.browsertime.video) {
            const videoFullPath = path.join(baseDir, message.data.video);

            await this.storageManager.copyFileToDir(
              videoFullPath,
              newPath +
                '/' +
                name +
                '.' +
                this.options.browser +
                '.' +
                connectivity +
                '.mp4'
            );
          }

          // Also store a JSON with data that we can use later
          const json = {
            url: message.url,
            alias: this.alias[message.url],
            timestamp: message.data.timestamp
          };
          if (message.data.android) {
            json.android = {};
            json.android.model = message.data.android.model;
            json.android.androidVersion = message.data.android.androidVersion;
          }
          const data = JSON.stringify(json, null, 0);
          return this.storageManager.writeDataToDir(
            data,
            name + '.' + this.options.browser + '.' + connectivity + '.json',
            newPath
          );
        }
      }
    }
  }
};
<commit_msg>Remove test log message<commit_after>'use strict';

const path = require('path');
const graphiteUtil = require('../../support/tsdbUtil');

module.exports = {
  open(context, options) {
    this.storageManager = context.storageManager;
    this.alias = {};
    this.options = options;
  },
  async processMessage(message) {
    switch (message.type) {
      // Collect alias so we can use it
      case 'browsertime.alias': {
        this.alias[message.url] = message.data;
        break;
      }

      case 'browsertime.config': {
        if (message.data.screenshot) {
          this.useScreenshots = message.data.screenshot;
          this.screenshotType = message.data.screenshotType;
        }
        break;
      }

      case 'browsertime.run': {
        // Only use the first one for now
        if (message.iteration === 1 && this.options.copyLatestFilesToBase) {
          const options = this.options;
          const baseDir = this.storageManager.getBaseDir();
          // Hack to get out of the date dir
          const newPath = path.resolve(baseDir, '..');

          // This is a hack to get the same name as in Grafana, meaning we can
          // generate the path to the URL there
          const name = graphiteUtil.getURLAndGroup(
            options,
            message.group,
            message.url,
            this.options.graphite.includeQueryParams,
            this.alias
          );
          const connectivity = graphiteUtil.getConnectivity(options);

          if (this.useScreenshots) {
            const imageFullPath = path.join(baseDir, message.data.screenshot);
            await this.storageManager.copyFileToDir(
              imageFullPath,
              newPath +
                '/' +
                name +
                '.' +
                this.options.browser +
                '.' +
                connectivity +
                '.' +
                this.screenshotType
            );
          }
          if (this.options.browsertime && this.options.browsertime.video) {
            const videoFullPath = path.join(baseDir, message.data.video);

            await this.storageManager.copyFileToDir(
              videoFullPath,
              newPath +
                '/' +
                name +
                '.' +
                this.options.browser +
                '.' +
                connectivity +
                '.mp4'
            );
          }

          // Also store a JSON with data that we can use later
          const json = {
            url: message.url,
            alias: this.alias[message.url],
            timestamp: message.data.timestamp
          };
          if (message.data.android) {
            json.android = {};
            json.android.model = message.data.android.model;
            json.android.androidVersion = message.data.android.androidVersion;
          }
          const data = JSON.stringify(json, null, 0);
          return this.storageManager.writeDataToDir(
            data,
            name + '.' + this.options.browser + '.' + connectivity + '.json',
            newPath
          );
        }
      }
    }
  }
};
<|endoftext|>


<commit_before>(function(){
	window.opener && window.opener.location.replace('scam.html');
})();<commit_msg>Fix window opener path issue<commit_after>(function(){
	window.opener && window.opener.location.replace('../scam.html');
})();<|endoftext|>


<commit_before>#!/usr/bin/env node

var _ = require('lodash');
var fs = require('fs');
var path = require("path");
var xml2js = require('xml2js');
var commandExists = require('command-exists');
var spawn = require('child_process').spawn;
var parser = new xml2js.Parser();

module.exports = function (context) {

    if (context.opts.platforms.indexOf('ios') === -1) {
        return;
    }

    var Q = context.requireCordovaModule('q');
    var podfileContents = [];
    var rootPath = context.opts.projectRoot;
    var configXmlPath = path.join(rootPath, 'config.xml');
    var configParser = getConfigParser(context, configXmlPath);
    var appName = configParser.name();
    var iosMinVersion = configParser.getPreference('pods_ios_min_version', 'ios') || configParser.getPreference('pods_ios_min_version') || '7.0';
    var useFrameworks = configParser.getPreference('pods_use_frameworks', 'ios') || configParser.getPreference('pods_use_frameworks') || 'false';
    var podConfigPath = path.join(rootPath, 'platforms', 'ios', '.pods.json');
    var pod, podId;
    var podified = fs.existsSync(podConfigPath);
    var currentPods = podified ? JSON.parse(fs.readFileSync(podConfigPath)) : {};
    var workspaceDir = path.join(rootPath, 'platforms', 'ios', '' + appName + '.xcworkspace');
    var sharedDataDir = path.join(workspaceDir, 'xcshareddata');
    var pluginDir = context.opts.plugin.pluginInfo.dir;
    var schemesSrcDir = path.join(pluginDir, 'schemes');
    var schemesTargetDir = path.join(sharedDataDir, 'xcschemes');
    var bundlePathsToFix = [];
    var newPods = {
        pods: {}
    };

    console.log('Searching for new pods');

    return Q.all(parsePluginXmls())
        .then(parseConfigXml)
        .then(createFiles)
        .then(installPods)
        .then(fixBundlePaths)
        .then(updateBuild);

    function parseConfigXml() {

        parser.parseString(fs.readFileSync('config.xml'), function (err, data) {

            if (data.widget.platform) {
                console.log('Checking config.xml for pods.');
                data.widget.platform.forEach(function (platform) {
                    if (platform.$.name === 'ios') {
                        (platform.pod || []).forEach(function (pod) {
                            newPods.pods[pod.$.id] = pod.$;
                            console.log('config.xml requires pod: %s', pod.$.id);
                        });
                    }
                });
            }
        });
    }

    function parsePluginXmls() {

        var promises = [];
        context.opts.cordova.plugins.forEach(function (id) {

            var deferred = Q.defer();

            parser.parseString(fs.readFileSync('plugins/' + id + '/plugin.xml'), function (err, data) {

                if (err) {
                    deferred.reject(err);
                } else {
                    if (data.plugin.platform) {
                        console.log('Checking %s for pods.', id);
                        data.plugin.platform.forEach(function (platform) {

                            if (platform.$.name === 'ios') {
                                if (platform.$.name === 'ios') {
                                    var podsConfig = (platform['pods-config'] || [])[0];
                                    if(podsConfig) {
                                        iosMinVersion = maxVer(iosMinVersion, podsConfig.$['ios-min-version']);
                                        useFrameworks = podsConfig.$['use-frameworks'] === 'true' ? 'true' : useFrameworks;
                                    }
                                    (platform.pod || []).forEach(function (pod) {
                                        newPods.pods[pod.$.id] = pod.$;
                                        console.log('%s requires pod: %s', id, pod.$.id);
                                    });
                                }
                            }
                        });
                    }

                    deferred.resolve();
                }
            });

            promises.push(deferred.promise);
        });
        return promises;
    }

    function createFiles() {

        newPods.iosMinVersion = iosMinVersion;
        newPods.useFrameworks = useFrameworks === 'true';

        if (!podified || !_.isEqual(newPods, currentPods)) {

            podfileContents.push("platform :ios, '" + iosMinVersion + "'");
            if (useFrameworks === 'true') {
                podfileContents.push("use_frameworks!");
            }
            podfileContents.push("target '" + appName + "' do");

            for (podId in newPods.pods) {
                pod = newPods.pods[podId];
                var entry = "\tpod '" + pod.id + "'";
                if(pod['fix-bundle-path']) {
                    bundlePathsToFix.push(pod['fix-bundle-path']);
                }
                if (pod.version) {
                    entry += ", '" + pod.version + "'";
                } else if (pod.git) {
                    entry += ", :git => '" + pod.git + "'";
                    if (pod.tag) {
                        entry += ", :tag => '" + pod.tag + "'";
                    } else if (pod.branch) {
                        entry += ", :branch => '" + pod.branch + "'";
                    } else if (pod.commit) {
                        entry += ", :commit => '" + pod.commit + "'";
                    }

                } else if (pod.path) {
                    entry += ", :path => '" + pod.path + "'";
                } else if (pod.subspecs) {
                    var specs = pod.subspec.split(',').map(function (spec) {
                        return "'" + spec.trim() + "'";
                    });
                    entry += ", :subspecs => [" + specs.join() + "]";
                } else if (pod.configuration) {
                    entry += ", :configuration => '" + pod.configuration + "'";
                } else if (pod.configurations) {
                    var configs = pod.configurations.split(',').map(function (config) {
                        return "'" + config.trim() + "'";
                    });
                    entry += ", :subspecs => [" + configs.join() + "]";
                }
                podfileContents.push(entry);
            }
            podfileContents.push('end');
            fs.writeFileSync('platforms/ios/Podfile', podfileContents.join('\n'));

            var debugXcContents = fs.readFileSync('platforms/ios/cordova/build-debug.xcconfig', 'utf8');
            var includeRegex = new RegExp('#include "Pods/Target Support Files/Pods-' + appName + '/Pods-' + appName + '\\.\\w+\\.xcconfig"');
            if (!includeRegex.test(debugXcContents)) {
                fs.writeFileSync('platforms/ios/cordova/build-debug.xcconfig', debugXcContents + '\n' + '#include "Pods/Target Support Files/Pods-' + appName + '/Pods-' + appName + '.debug.xcconfig"');
            }
            var releaseXcContents = fs.readFileSync('platforms/ios/cordova/build-release.xcconfig', 'utf8');
            if (!includeRegex.test(releaseXcContents)) {
                fs.writeFileSync('platforms/ios/cordova/build-release.xcconfig', releaseXcContents + '\n' + '#include "Pods/Target Support Files/Pods-' + appName + '/Pods-' + appName + '.release.xcconfig"');
            }

            var buildConfigContext = fs.readFileSync('platforms/ios/cordova/build.xcconfig', 'utf8');
            var bridgedHeaderRegex;
            if (useFrameworks) {
                bridgedHeaderRegex = /SWIFT_OBJC_BRIDGING_HEADER/g;
                fs.writeFileSync('platforms/ios/cordova/build.xcconfig', buildConfigContext.replace(bridgedHeaderRegex, '//SWIFT_OBJC_BRIDGING_HEADER'));
            } else {
                bridgedHeaderRegex = /\/\/SWIFT_OBJC_BRIDGING_HEADER/g;
                fs.writeFileSync('platforms/ios/cordova/build.xcconfig', buildConfigContext.replace(bridgedHeaderRegex, 'SWIFT_OBJC_BRIDGING_HEADER'));

            }

            fs.writeFileSync(podConfigPath, JSON.stringify(newPods, null, '\t'));
        } else {
            console.log('No new pods detects');
        }
    }

    function installPods() {

        var deferred = Q.defer();
        commandExists('pod', function (err, exists) {

            if (exists) {

                if (!podified || !_.isEqual(newPods, currentPods)) {
                    console.log("Installing pods");
                    console.log("Sit back and relax this could take a while.");
                    var podInstall = spawn('pod', ['install'], {
                        cwd: 'platforms/ios'
                    });
                    podInstall.stdout.on('data', function(data) {
                        console.log(data.toString('utf8'));
                    });
                    podInstall.stderr.on('data', function(data) {
                        console.error(data.toString('utf8'));
                    });
                    podInstall.on('close', function(exitCode) {
                        deferred.resolve(exitCode === 0);
                    });
                } else {
                    deferred.resolve(false);
                }

            } else {
                console.log("\nAh man!. It doesn't look like you have CocoaPods installed.\n\nYou have two choices.\n\n1. Install Cocoapods:\n$ sudo gem install cocoapods\n2. Manually install the dependencies.");
                deferred.resolve(false);
            }
        });

        return deferred.promise;
    }

    function fixBundlePaths(shouldRun) {

        if(bundlePathsToFix.length) {
            var podsResourcesSh = 'platforms/ios/Pods/Target Support Files/Pods-' + appName + '/Pods-' + appName + '-resources.sh';
            var content = fs.readFileSync(podsResourcesSh, 'utf8');

            bundlePathsToFix.forEach(function(path) {
                var fixedPath = appName + '.app/' + path.split('/').slice(1).join('/');
                var regex = new RegExp('(install_resource.*)' + path, 'gi');
                console.log(content)
                content = content.replace(regex, "$1" + fixedPath);
                console.log(content)

            });
            fs.writeFileSync(podsResourcesSh, content);
        }

        return shouldRun;
    }

    function updateBuild(shouldRun) {

        if(shouldRun) {
            console.log('Updating ios build to use workspace.');
            var buildContent = fs.readFileSync('platforms/ios/cordova/lib/build.js', 'utf8');
            var targetRegex = new RegExp("'-target',\\s*projectName\\s*,", 'g');
            var targetFix = "'-scheme', projectName,";
            var projectRegex = new RegExp("'-project'\\s*,\\s*projectName\\s*\\+\\s*'\\.xcodeproj'\\s*,", 'g');
            var projectFix = "'-workspace', projectName + '.xcworkspace',";
            var xcodeprojRegex = /\.xcodeproj/g;
            var xcodeprojFix = '.xcworkspace';
            var destinationSimulatorOrg = "'-destination', 'platform=iOS Simulator'";
            var destinationSimulatorNew = "'-destination generic/platform=iOS'";
            var destinationRegex = /\-destination\.*$/g;
            var destinationFix = "'-destination generic/platform=iOS',";
            var fixedBuildContent = buildContent
                .replace(targetRegex, targetFix)
                .replace(projectRegex, projectFix)
                .replace(xcodeprojRegex, xcodeprojFix)
                .replace(destinationRegex, destinationFix);
                // .replace(destinationSimulatorOrg, destinationSimulatorNew);

            fs.writeFileSync('platforms/ios/cordova/lib/build.js', fixedBuildContent);

            if (!podified) {
                console.log('Adding schemes');
                fs.mkdirSync(sharedDataDir);
                fs.mkdirSync(schemesTargetDir);
                copyTpl(schemesSrcDir + '/CordovaLib.xcscheme', schemesTargetDir + '/CordovaLib.xcscheme', {
                    appName: appName
                });
                copyTpl(schemesSrcDir + '/App.xcscheme', schemesTargetDir + '/' + appName + '.xcscheme', {
                    appName: appName,
                    appId: '1D6058900D05DD3D006BFB54'
                });
            }
        }
    }

    function templify(str, data) {

        return str.replace(/{[^{}]+}/g, function (key) {
            var k = key.replace(/[{}]+/g, "");
            return data.hasOwnProperty(k) ? data[k] : "";
        });
    }

    function copyTpl(src, dest, data) {
        fs.writeFileSync(dest, templify(fs.readFileSync(src, 'utf8'), data));
    }

    function getConfigParser(context, config) {
        var semver = context.requireCordovaModule('semver');
        var ConfigParser;

        if (semver.lt(context.opts.cordova.version, '5.4.0')) {
            ConfigParser = context.requireCordovaModule('cordova-lib/src/ConfigParser/ConfigParser');
        } else {
            ConfigParser = context.requireCordovaModule('cordova-common/src/ConfigParser/ConfigParser');
        }

        return new ConfigParser(config);
    }

    function maxVer(v1, v2) {

        if(!v2) {
            return v1;
        }

        var v1Parts = v1.split('.');
        var v2Parts = v2.split('.');

        if(+v1Parts[0] > +v2Parts[0]) {
            return v1;
        } else if(+v1Parts[0] < +v2Parts[0]) {
            return v2;
        } else if(+v1Parts[1] > +v2Parts[1]) {
            return v1;
        } else {
            return v2;
        }
    }
};

<commit_msg>origin/master - changed regex for destination<commit_after>#!/usr/bin/env node

var _ = require('lodash');
var fs = require('fs');
var path = require("path");
var xml2js = require('xml2js');
var commandExists = require('command-exists');
var spawn = require('child_process').spawn;
var parser = new xml2js.Parser();

module.exports = function (context) {

    if (context.opts.platforms.indexOf('ios') === -1) {
        return;
    }

    var Q = context.requireCordovaModule('q');
    var podfileContents = [];
    var rootPath = context.opts.projectRoot;
    var configXmlPath = path.join(rootPath, 'config.xml');
    var configParser = getConfigParser(context, configXmlPath);
    var appName = configParser.name();
    var iosMinVersion = configParser.getPreference('pods_ios_min_version', 'ios') || configParser.getPreference('pods_ios_min_version') || '7.0';
    var useFrameworks = configParser.getPreference('pods_use_frameworks', 'ios') || configParser.getPreference('pods_use_frameworks') || 'false';
    var podConfigPath = path.join(rootPath, 'platforms', 'ios', '.pods.json');
    var pod, podId;
    var podified = fs.existsSync(podConfigPath);
    var currentPods = podified ? JSON.parse(fs.readFileSync(podConfigPath)) : {};
    var workspaceDir = path.join(rootPath, 'platforms', 'ios', '' + appName + '.xcworkspace');
    var sharedDataDir = path.join(workspaceDir, 'xcshareddata');
    var pluginDir = context.opts.plugin.pluginInfo.dir;
    var schemesSrcDir = path.join(pluginDir, 'schemes');
    var schemesTargetDir = path.join(sharedDataDir, 'xcschemes');
    var bundlePathsToFix = [];
    var newPods = {
        pods: {}
    };

    console.log('Searching for new pods');

    return Q.all(parsePluginXmls())
        .then(parseConfigXml)
        .then(createFiles)
        .then(installPods)
        .then(fixBundlePaths)
        .then(updateBuild);

    function parseConfigXml() {

        parser.parseString(fs.readFileSync('config.xml'), function (err, data) {

            if (data.widget.platform) {
                console.log('Checking config.xml for pods.');
                data.widget.platform.forEach(function (platform) {
                    if (platform.$.name === 'ios') {
                        (platform.pod || []).forEach(function (pod) {
                            newPods.pods[pod.$.id] = pod.$;
                            console.log('config.xml requires pod: %s', pod.$.id);
                        });
                    }
                });
            }
        });
    }

    function parsePluginXmls() {

        var promises = [];
        context.opts.cordova.plugins.forEach(function (id) {

            var deferred = Q.defer();

            parser.parseString(fs.readFileSync('plugins/' + id + '/plugin.xml'), function (err, data) {

                if (err) {
                    deferred.reject(err);
                } else {
                    if (data.plugin.platform) {
                        console.log('Checking %s for pods.', id);
                        data.plugin.platform.forEach(function (platform) {

                            if (platform.$.name === 'ios') {
                                if (platform.$.name === 'ios') {
                                    var podsConfig = (platform['pods-config'] || [])[0];
                                    if(podsConfig) {
                                        iosMinVersion = maxVer(iosMinVersion, podsConfig.$['ios-min-version']);
                                        useFrameworks = podsConfig.$['use-frameworks'] === 'true' ? 'true' : useFrameworks;
                                    }
                                    (platform.pod || []).forEach(function (pod) {
                                        newPods.pods[pod.$.id] = pod.$;
                                        console.log('%s requires pod: %s', id, pod.$.id);
                                    });
                                }
                            }
                        });
                    }

                    deferred.resolve();
                }
            });

            promises.push(deferred.promise);
        });
        return promises;
    }

    function createFiles() {

        newPods.iosMinVersion = iosMinVersion;
        newPods.useFrameworks = useFrameworks === 'true';

        if (!podified || !_.isEqual(newPods, currentPods)) {

            podfileContents.push("platform :ios, '" + iosMinVersion + "'");
            if (useFrameworks === 'true') {
                podfileContents.push("use_frameworks!");
            }
            podfileContents.push("target '" + appName + "' do");

            for (podId in newPods.pods) {
                pod = newPods.pods[podId];
                var entry = "\tpod '" + pod.id + "'";
                if(pod['fix-bundle-path']) {
                    bundlePathsToFix.push(pod['fix-bundle-path']);
                }
                if (pod.version) {
                    entry += ", '" + pod.version + "'";
                } else if (pod.git) {
                    entry += ", :git => '" + pod.git + "'";
                    if (pod.tag) {
                        entry += ", :tag => '" + pod.tag + "'";
                    } else if (pod.branch) {
                        entry += ", :branch => '" + pod.branch + "'";
                    } else if (pod.commit) {
                        entry += ", :commit => '" + pod.commit + "'";
                    }

                } else if (pod.path) {
                    entry += ", :path => '" + pod.path + "'";
                } else if (pod.subspecs) {
                    var specs = pod.subspec.split(',').map(function (spec) {
                        return "'" + spec.trim() + "'";
                    });
                    entry += ", :subspecs => [" + specs.join() + "]";
                } else if (pod.configuration) {
                    entry += ", :configuration => '" + pod.configuration + "'";
                } else if (pod.configurations) {
                    var configs = pod.configurations.split(',').map(function (config) {
                        return "'" + config.trim() + "'";
                    });
                    entry += ", :subspecs => [" + configs.join() + "]";
                }
                podfileContents.push(entry);
            }
            podfileContents.push('end');
            fs.writeFileSync('platforms/ios/Podfile', podfileContents.join('\n'));

            var debugXcContents = fs.readFileSync('platforms/ios/cordova/build-debug.xcconfig', 'utf8');
            var includeRegex = new RegExp('#include "Pods/Target Support Files/Pods-' + appName + '/Pods-' + appName + '\\.\\w+\\.xcconfig"');
            if (!includeRegex.test(debugXcContents)) {
                fs.writeFileSync('platforms/ios/cordova/build-debug.xcconfig', debugXcContents + '\n' + '#include "Pods/Target Support Files/Pods-' + appName + '/Pods-' + appName + '.debug.xcconfig"');
            }
            var releaseXcContents = fs.readFileSync('platforms/ios/cordova/build-release.xcconfig', 'utf8');
            if (!includeRegex.test(releaseXcContents)) {
                fs.writeFileSync('platforms/ios/cordova/build-release.xcconfig', releaseXcContents + '\n' + '#include "Pods/Target Support Files/Pods-' + appName + '/Pods-' + appName + '.release.xcconfig"');
            }

            var buildConfigContext = fs.readFileSync('platforms/ios/cordova/build.xcconfig', 'utf8');
            var bridgedHeaderRegex;
            if (useFrameworks) {
                bridgedHeaderRegex = /SWIFT_OBJC_BRIDGING_HEADER/g;
                fs.writeFileSync('platforms/ios/cordova/build.xcconfig', buildConfigContext.replace(bridgedHeaderRegex, '//SWIFT_OBJC_BRIDGING_HEADER'));
            } else {
                bridgedHeaderRegex = /\/\/SWIFT_OBJC_BRIDGING_HEADER/g;
                fs.writeFileSync('platforms/ios/cordova/build.xcconfig', buildConfigContext.replace(bridgedHeaderRegex, 'SWIFT_OBJC_BRIDGING_HEADER'));

            }

            fs.writeFileSync(podConfigPath, JSON.stringify(newPods, null, '\t'));
        } else {
            console.log('No new pods detects');
        }
    }

    function installPods() {

        var deferred = Q.defer();
        commandExists('pod', function (err, exists) {

            if (exists) {

                if (!podified || !_.isEqual(newPods, currentPods)) {
                    console.log("Installing pods");
                    console.log("Sit back and relax this could take a while.");
                    var podInstall = spawn('pod', ['install'], {
                        cwd: 'platforms/ios'
                    });
                    podInstall.stdout.on('data', function(data) {
                        console.log(data.toString('utf8'));
                    });
                    podInstall.stderr.on('data', function(data) {
                        console.error(data.toString('utf8'));
                    });
                    podInstall.on('close', function(exitCode) {
                        deferred.resolve(exitCode === 0);
                    });
                } else {
                    deferred.resolve(false);
                }

            } else {
                console.log("\nAh man!. It doesn't look like you have CocoaPods installed.\n\nYou have two choices.\n\n1. Install Cocoapods:\n$ sudo gem install cocoapods\n2. Manually install the dependencies.");
                deferred.resolve(false);
            }
        });

        return deferred.promise;
    }

    function fixBundlePaths(shouldRun) {

        if(bundlePathsToFix.length) {
            var podsResourcesSh = 'platforms/ios/Pods/Target Support Files/Pods-' + appName + '/Pods-' + appName + '-resources.sh';
            var content = fs.readFileSync(podsResourcesSh, 'utf8');

            bundlePathsToFix.forEach(function(path) {
                var fixedPath = appName + '.app/' + path.split('/').slice(1).join('/');
                var regex = new RegExp('(install_resource.*)' + path, 'gi');
                console.log(content)
                content = content.replace(regex, "$1" + fixedPath);
                console.log(content)

            });
            fs.writeFileSync(podsResourcesSh, content);
        }

        return shouldRun;
    }

    function updateBuild(shouldRun) {

        if(shouldRun) {
            console.log('Updating ios build to use workspace.');
            var buildContent = fs.readFileSync('platforms/ios/cordova/lib/build.js', 'utf8');
            var targetRegex = new RegExp("'-target',\\s*projectName\\s*,", 'g');
            var targetFix = "'-scheme', projectName,";
            var projectRegex = new RegExp("'-project'\\s*,\\s*projectName\\s*\\+\\s*'\\.xcodeproj'\\s*,", 'g');
            var projectFix = "'-workspace', projectName + '.xcworkspace',";
            var xcodeprojRegex = /\.xcodeproj/g;
            var xcodeprojFix = '.xcworkspace';
            var destinationSimulatorOrg = "'-destination', 'platform=iOS Simulator'";
            var destinationSimulatorNew = "'-destination generic/platform=iOS'";
            var destinationRegex = /\-destination.*$/g;
            var destinationFix = "'-destination generic/platform=iOS',";
            var fixedBuildContent = buildContent
                .replace(targetRegex, targetFix)
                .replace(projectRegex, projectFix)
                .replace(xcodeprojRegex, xcodeprojFix)
                .replace(destinationRegex, destinationFix);
                // .replace(destinationSimulatorOrg, destinationSimulatorNew);

            fs.writeFileSync('platforms/ios/cordova/lib/build.js', fixedBuildContent);

            if (!podified) {
                console.log('Adding schemes');
                fs.mkdirSync(sharedDataDir);
                fs.mkdirSync(schemesTargetDir);
                copyTpl(schemesSrcDir + '/CordovaLib.xcscheme', schemesTargetDir + '/CordovaLib.xcscheme', {
                    appName: appName
                });
                copyTpl(schemesSrcDir + '/App.xcscheme', schemesTargetDir + '/' + appName + '.xcscheme', {
                    appName: appName,
                    appId: '1D6058900D05DD3D006BFB54'
                });
            }
        }
    }

    function templify(str, data) {

        return str.replace(/{[^{}]+}/g, function (key) {
            var k = key.replace(/[{}]+/g, "");
            return data.hasOwnProperty(k) ? data[k] : "";
        });
    }

    function copyTpl(src, dest, data) {
        fs.writeFileSync(dest, templify(fs.readFileSync(src, 'utf8'), data));
    }

    function getConfigParser(context, config) {
        var semver = context.requireCordovaModule('semver');
        var ConfigParser;

        if (semver.lt(context.opts.cordova.version, '5.4.0')) {
            ConfigParser = context.requireCordovaModule('cordova-lib/src/ConfigParser/ConfigParser');
        } else {
            ConfigParser = context.requireCordovaModule('cordova-common/src/ConfigParser/ConfigParser');
        }

        return new ConfigParser(config);
    }

    function maxVer(v1, v2) {

        if(!v2) {
            return v1;
        }

        var v1Parts = v1.split('.');
        var v2Parts = v2.split('.');

        if(+v1Parts[0] > +v2Parts[0]) {
            return v1;
        } else if(+v1Parts[0] < +v2Parts[0]) {
            return v2;
        } else if(+v1Parts[1] > +v2Parts[1]) {
            return v1;
        } else {
            return v2;
        }
    }
};

<|endoftext|>