<commit_before>angular.module('os.administrative.setting',
  [
    'os.administrative.setting.list',
    'os.administrative.setting.util'
  ])

  .config(function($stateProvider) {
    $stateProvider
      .state('settings', {
        url: '/settings',
        controller: function($scope, $translate, settings, areTranslationsLoaded) {
          $scope.ctx = {
            dbModules: {},
            dbModuleNames: [],
            filteredModules: {},
            filteredModuleNames: [],
            search: ''
          };

          var dbModules = {}, dbModuleNames = [];
          angular.forEach(settings,
            function(setting) {
              var module = dbModules[setting.module];
              if (!module) {
                module = {name: setting.module, settings: []};
                dbModules[setting.module] = module;
                dbModuleNames.push(setting.module);
              }

              module.settings.push(setting);

              var pnKey = 'settings.' + setting.module + '.' + setting.name;
              setting.$$osPropName = $translate.instant(pnKey);
              setting.$$osPropDesc = $translate.instant(pnKey + '_desc');
            }
          );

          $scope.ctx.dbModules     = $scope.ctx.filteredModules     = dbModules;
          $scope.ctx.dbModuleNames = $scope.ctx.filteredModuleNames = dbModuleNames;
        },
        template: '

',
        resolve: {
          settings: function(isAdmin, Setting) {
            return Setting.query();
          },

          areTranslationsLoaded: function($translate) {
            return $translate('common.none').then(
              function() {
                return true;
              }
            );
          }
        },
        parent: 'admin-view',
        abstract: true
      })
      .state('settings-list', {
        url: '/settings-list?moduleName',
        templateUrl: 'modules/administrative/settings/list.html',
        controller: 'SettingsListCtrl',
        parent: 'settings'
      });
  });
<commit_msg>OPSMN-5499: It was not possible to open the settings view in another tab because loading of translations failed in the view resolver. The $translate service is not available in the route/view dependency resolvers.<commit_after>angular.module('os.administrative.setting',
  [
    'os.administrative.setting.list',
    'os.administrative.setting.util'
  ])

  .config(function($stateProvider) {
    $stateProvider
      .state('settings', {
        url: '/settings',
        controller: function($scope, $translate, settings) {
          $scope.ctx = {
            dbModules: {},
            dbModuleNames: [],
            filteredModules: {},
            filteredModuleNames: [],
            search: ''
          };

          var dbModules = {}, dbModuleNames = [];
          angular.forEach(settings,
            function(setting) {
              var module = dbModules[setting.module];
              if (!module) {
                module = {name: setting.module, settings: []};
                dbModules[setting.module] = module;
                dbModuleNames.push(setting.module);
              }

              module.settings.push(setting);
            }
          );

          $translate('common.none').then(
            function() {
              angular.forEach(settings,
                function(setting) {
                  var pnKey = 'settings.' + setting.module + '.' + setting.name;
                  setting.$$osPropName = $translate.instant(pnKey);
                  setting.$$osPropDesc = $translate.instant(pnKey + '_desc');
                }
              );
            }
          );

          $scope.ctx.dbModules     = $scope.ctx.filteredModules     = dbModules;
          $scope.ctx.dbModuleNames = $scope.ctx.filteredModuleNames = dbModuleNames;
        },
        template: '

',
        resolve: {
          settings: function(Setting) {
            return Setting.query();
          }
        },
        parent: 'admin-view',
        abstract: true
      })
      .state('settings-list', {
        url: '/settings-list?moduleName',
        templateUrl: 'modules/administrative/settings/list.html',
        controller: 'SettingsListCtrl',
        parent: 'settings'
      });
  });
<|endoftext|>


<commit_before>/*
 *  Majiang.View.Analyzer
 */
"use strict";

const $ = require('jquery');
const Majiang = require('../../majiang');
Majiang.View = {
    pai:     require('./pai'),
    Shoupai: require('./shoupai'),
};

let _status;
let _dapai;

module.exports = class Analyzer extends Majiang.Player {

constructor(id, root) {
    super(id);
    this._root = root;
    if (! _status) _status = $('.status .row', root);
    if (! _dapai)  _dapai  = $('.dapai .row', root);
    $('.status', root).empty();
    $('.dapai',  root).empty();
}

id(id) { this._id = id }

next(data) {
    $('.status', this._root).empty();
    $('.dapai',  this._root).empty();
    super.action(data);
}

action(data) {
    if (data.qipai || data.hule || data.pingju) {
        $('.status', this._root).empty();
    }
    if (data.qipai || data.zimo || data.gangzimo || data.fulou
        || data.hule || data.pingju)
    {
        $('.dapai',   this._root).empty();
    }
    super.action(data, ()=>{});
}

dapai(dapai) {
    super.dapai(dapai);
    if (dapai.l == this._model.menfeng) {
        this.redraw_status(this.get_status());
        this.update_dapai(dapai.p.substr(0,2));
    }
}

gang(gang) {
    if (gang.l == this._model.menfeng) {
        this.update_dapai(gang.m);
    }
    super.gang(gang);
}

action_zimo(zimo, option) {

    this.redraw_status(this.get_status());

    let info  = [];
    let gang  = this.select_gang(info);
    let dapai = this.select_dapai(info);
    if (gang) {
        for (let i of info) {
            if (i.m == gang) {
                i.selected = true;
            }
        }
    }
    else if (dapai) {
        let p = dapai.substr(0,2);
        for (let i of info) {
            if (i.p == p && ! i.m) {
                i.selected = true;
            }
        }
    }
    this.redraw_dapai(info);
}

action_dapai(dapai) {
    let info = [];
    let fulou = this.select_fulou(dapai, info);
    if (fulou) {
        for (let i of info) {
            if (i.m == fulou) {
                i.selected = true;
            }
        }
    }
    this.redraw_status(info);
}

action_fulou(fulou) {

    this.redraw_status(this.get_status());

    let info  = [];
    let dapai = this.select_dapai(info);
    let p = dapai.substr(0,2);
    for (let i of info) {
        if (i.p == p && ! i.m) {
            i.selected = true;
        }
    }
    this.redraw_dapai(info);
}

get_status() {

    let info = [];
    let n_xiangting = Majiang.Util.xiangting(this._shoupai);
    let paishu = this._suanpai.paishu_all();
    let ev = this.eval_shoupai(this._shoupai, paishu);
    let n_tingpai;
    if (n_xiangting > 2) {
        if (this._shoupai._zimo)
                ev = null;
        else    n_tingpai = Majiang.Util.tingpai(this._shoupai)
                                .map(p=>this._suanpai._paishu[p[0]][p[1]])
                                .reduce((x,y)=> x + y);
    }
    info.push({
        m: '', n_xiangting: n_xiangting,
        ev: ev, n_tingpai: n_tingpai,
        shoupai: this._shoupai.toString()
    });
    return info;
}

redraw_status(info) {

    $('.status', this._root).empty();
    for (let i of info.sort((a,b) => a.selected ? -1
                                   : b.selected ?  1
                                   : b.ev - a.ev))
    {
        let row = _status.clone();
        row.attr('data-status', i.m);
        $('.xiangting', row).text(
                      i.n_xiangting == -1 ? '和了形'
                    : i.n_xiangting ==  0 ? '聴牌'
                    :                       `${i.n_xiangting}向聴`);
        if (i.ev != null) {
            if (i.n_tingpai == null) {
                let ev = Math.floor(i.ev * 100);
                ev = ev < 100 ? ('00' + ev).substr(-3) : '' + ev;
                ev = ev.replace(/(\d{2})$/, '.$1');
                $('.eval', row).text(ev);
            }
            else {
                let ev = i.n_tingpai
                       + (i.ev > i.n_tingpai ? `(+${i.ev - i.n_tingpai})` : '')
                       + '枚';
                $('.eval', row).text(ev);
            }
        }
        new Majiang.View.Shoupai($('.shoupai', row),
                        Majiang.Shoupai.fromString(i.shoupai)).redraw(true);
        let m = i.m.replace(/0/,'5');
        $('.action', row).text(
              m.match(/^[mpsz](\d)\1\1\1/) ? 'カン'
            : m.match(/^[mpsz](\d)\1\1/)   ? 'ポン'
            : m.match(/^[mps]/)            ? 'チー'
            :                                ''
        );
        $('.status', this._root).append(row);
    }
}

redraw_dapai(info) {

    $('.dapai', this._root).empty();
    for (let i of info.sort((a,b) => a.selected ? -1
                                   : b.selected ?  1
                                   : b.ev - a.ev))
    {
        let row = _dapai.clone();
        row.attr('data-dapai', i.m || i.p);
        $('.p', row).append(Majiang.View.pai(i.p));
        if (i.m) $('.p', row).append($('<span>').text('カン'));
        $('.xiangting', row).text(
                    i.n_xiangting == 0 ? '聴牌' : `${i.n_xiangting}向聴`);
        if (i.n_xiangting < 3) {
            let ev = Math.floor(i.ev * 100);
            ev = ev < 100 ? ('00' + ev).substr(-3) : '' + ev;
            ev = ev.replace(/(\d{2})$/, '.$1');
            $('.eval', row).text(ev);
        }
        else {
            let ev = i.n_tingpai
                   + (i.ev > i.n_tingpai ? `(+${i.ev - i.n_tingpai})` : '')
                   + '枚';
            $('.eval', row).text(ev);
        }
        for (let p of i.tingpai) {
            $('.tingpai', row).append(Majiang.View.pai(p));
        }
        if (i.n_xiangting < 3) {
            $('.tingpai', row).append($('<span>').text(`(${i.n_tingpai}枚)`));
        }
        $('.dapai', this._root).append(row);
    }
}

update_dapai(dapai) {
    $(`.dapai tr[data-dapai="${dapai}"]`).addClass('selected');
}

}
<commit_msg>#56 戻る場合でも手牌を必ず表示するようにした<commit_after>/*
 *  Majiang.View.Analyzer
 */
"use strict";

const $ = require('jquery');
const Majiang = require('../../majiang');
Majiang.View = {
    pai:     require('./pai'),
    Shoupai: require('./shoupai'),
};

let _status;
let _dapai;

module.exports = class Analyzer extends Majiang.Player {

constructor(id, root) {
    super(id);
    this._root = root;
    if (! _status) _status = $('.status .row', root);
    if (! _dapai)  _dapai  = $('.dapai .row', root);
    $('.status', root).empty();
    $('.dapai',  root).empty();
}

id(id) { this._id = id }

next(data) {
    $('.status', this._root).empty();
    $('.dapai',  this._root).empty();
    super.action(data);
}

action(data) {
    if (data.qipai || data.hule || data.pingju) {
        $('.status', this._root).empty();
    }
    if (data.qipai || data.zimo || data.gangzimo || data.fulou
        || data.hule || data.pingju)
    {
        $('.dapai',   this._root).empty();
    }
    super.action(data, ()=>{});
}

zimo(zimo, option) {
    super.zimo(zimo, option);
    if (! this._callback) return;
    if (zimo.l != this._model.menfeng) {
        this.redraw_status(this.get_status());
    }
}

dapai(dapai) {
    super.dapai(dapai);
    if (! this._callback) return;
    if (dapai.l == this._model.menfeng) {
        this.redraw_status(this.get_status());
        this.update_dapai(dapai.p.substr(0,2));
    }
}

gang(gang) {
    super.gang(gang);
    if (! this._callback) return;
    if (gang.l == this._model.menfeng) {
        this.update_dapai(gang.m);
    }
}

action_zimo(zimo, option) {

    this.redraw_status(this.get_status());

    let info  = [];
    let gang  = this.select_gang(info);
    let dapai = this.select_dapai(info);
    if (gang) {
        for (let i of info) {
            if (i.m == gang) {
                i.selected = true;
            }
        }
    }
    else if (dapai) {
        let p = dapai.substr(0,2);
        for (let i of info) {
            if (i.p == p && ! i.m) {
                i.selected = true;
            }
        }
    }
    this.redraw_dapai(info);
}

action_dapai(dapai) {
    let info = [];
    let fulou = this.select_fulou(dapai, info);
    if (fulou) {
        for (let i of info) {
            if (i.m == fulou) {
                i.selected = true;
            }
        }
    }
    this.redraw_status(info);
}

action_fulou(fulou) {

    this.redraw_status(this.get_status());

    let info  = [];
    let dapai = this.select_dapai(info);
    let p = dapai.substr(0,2);
    for (let i of info) {
        if (i.p == p && ! i.m) {
            i.selected = true;
        }
    }
    this.redraw_dapai(info);
}

get_status() {

    let info = [];
    let n_xiangting = Majiang.Util.xiangting(this._shoupai);
    let paishu = this._suanpai.paishu_all();
    let ev = this.eval_shoupai(this._shoupai, paishu);
    let n_tingpai;
    if (n_xiangting > 2) {
        if (this._shoupai._zimo)
                ev = null;
        else    n_tingpai = Majiang.Util.tingpai(this._shoupai)
                                .map(p=>this._suanpai._paishu[p[0]][p[1]])
                                .reduce((x,y)=> x + y);
    }
    info.push({
        m: '', n_xiangting: n_xiangting,
        ev: ev, n_tingpai: n_tingpai,
        shoupai: this._shoupai.toString()
    });
    return info;
}

redraw_status(info) {

    $('.status', this._root).empty();
    for (let i of info.sort((a,b) => a.selected ? -1
                                   : b.selected ?  1
                                   : b.ev - a.ev))
    {
        let row = _status.clone();
        row.attr('data-status', i.m);
        $('.xiangting', row).text(
                      i.n_xiangting == -1 ? '和了形'
                    : i.n_xiangting ==  0 ? '聴牌'
                    :                       `${i.n_xiangting}向聴`);
        if (i.ev != null) {
            if (i.n_tingpai == null) {
                let ev = Math.floor(i.ev * 100);
                ev = ev < 100 ? ('00' + ev).substr(-3) : '' + ev;
                ev = ev.replace(/(\d{2})$/, '.$1');
                $('.eval', row).text(ev);
            }
            else {
                let ev = i.n_tingpai
                       + (i.ev > i.n_tingpai ? `(+${i.ev - i.n_tingpai})` : '')
                       + '枚';
                $('.eval', row).text(ev);
            }
        }
        new Majiang.View.Shoupai($('.shoupai', row),
                        Majiang.Shoupai.fromString(i.shoupai)).redraw(true);
        let m = i.m.replace(/0/,'5');
        $('.action', row).text(
              m.match(/^[mpsz](\d)\1\1\1/) ? 'カン'
            : m.match(/^[mpsz](\d)\1\1/)   ? 'ポン'
            : m.match(/^[mps]/)            ? 'チー'
            :                                ''
        );
        $('.status', this._root).append(row);
    }
}

redraw_dapai(info) {

    $('.dapai', this._root).empty();
    for (let i of info.sort((a,b) => a.selected ? -1
                                   : b.selected ?  1
                                   : b.ev - a.ev))
    {
        let row = _dapai.clone();
        row.attr('data-dapai', i.m || i.p);
        $('.p', row).append(Majiang.View.pai(i.p));
        if (i.m) $('.p', row).append($('<span>').text('カン'));
        $('.xiangting', row).text(
                    i.n_xiangting == 0 ? '聴牌' : `${i.n_xiangting}向聴`);
        if (i.n_xiangting < 3) {
            let ev = Math.floor(i.ev * 100);
            ev = ev < 100 ? ('00' + ev).substr(-3) : '' + ev;
            ev = ev.replace(/(\d{2})$/, '.$1');
            $('.eval', row).text(ev);
        }
        else {
            let ev = i.n_tingpai
                   + (i.ev > i.n_tingpai ? `(+${i.ev - i.n_tingpai})` : '')
                   + '枚';
            $('.eval', row).text(ev);
        }
        for (let p of i.tingpai) {
            $('.tingpai', row).append(Majiang.View.pai(p));
        }
        if (i.n_xiangting < 3) {
            $('.tingpai', row).append($('<span>').text(`(${i.n_tingpai}枚)`));
        }
        $('.dapai', this._root).append(row);
    }
}

update_dapai(dapai) {
    $(`.dapai tr[data-dapai="${dapai}"]`).addClass('selected');
}

}
<|endoftext|>


<commit_before>import { Container } from 'aurelia-framework';

import { EventAggregator } from 'aurelia-event-aggregator';

import States from 'services/states';

import {
  dispersePiles,
  recoverPiles,
  trashPiles
} from 'components/fragments/fragments-actions';

import {
  MODE_MAD, MODE_MEAN, MODE_STD
} from 'components/fragments/fragments-defaults';

import COLORS from 'configs/colors';

const store = Container.instance.get(States).store;
const event = Container.instance.get(EventAggregator);

export const INSPECT = {
  name: 'Inspect',
  color: COLORS.WHITE,
  background: COLORS.BLACK,
  shortCut: 'I',
  trigger (pile) {
    event.publish('decompose.fgm.inspectPile', { pile });
  },
  stackedPileOnly: true
};

export const DISPERSE = {
  name: 'Disperse',
  color: COLORS.WHITE,
  background: COLORS.BLACK,
  shortCut: 'D',
  trigger (pile) {
    store.dispatch(dispersePiles([pile.id]));
  },
  stackedPileOnly: true
};

export const MAD = {
  name: 'Mean Avg. Dev.',
  color: COLORS.WHITE,
  background: 0x666666,
  row: 0,
  shortCut: 'F',
  trigger (pile) {
    event.publish('decompose.fgm.coverDispMode', { mode: MODE_MAD, pile });
  },
  triggerEvent: 'hover',
  stackedPileOnly: true
};

export const MEAN = {
  name: 'Mean',
  color: COLORS.WHITE,
  background: 0x666666,
  shortCut: 'M',
  trigger (pile) {
    event.publish('decompose.fgm.coverDispMode', { mode: MODE_MEAN, pile });
  },
  triggerEvent: 'hover',
  stackedPileOnly: true
};

export const RECOVER = {
  name: 'Recover',
  color: COLORS.WHITE,
  background: COLORS.BLACK,
  shortCut: 'R',
  trigger (pile) {
    store.dispatch(recoverPiles([pile.id]));
  },
  trashedOnly: true,
  closeOnClick: true,
  unsetHighlightOnClick: true
};

export const TRASH = {
  name: 'Trash',
  color: COLORS.WHITE,
  background: COLORS.BLACK,
  shortCut: 'R',
  trigger (pile) {
    store.dispatch(trashPiles([pile.id]));
  },
  closeOnClick: true,
  unsetHighlightOnClick: true
};

export const STD = {
  name: 'Standard Dev.',
  color: COLORS.WHITE,
  background: 0x666666,
  shortCut: 'V',
  trigger (pile) {
    event.publish('decompose.fgm.coverDispMode', { mode: MODE_STD, pile });
  },
  triggerEvent: 'hover',
  stackedPileOnly: true
};

export default [
  INSPECT,
  DISPERSE,
  TRASH,
  RECOVER,
  MEAN,
  MAD,
  STD
];
<commit_msg>Use assigned piled for debouncing<commit_after>import { Container } from 'aurelia-framework';

import { EventAggregator } from 'aurelia-event-aggregator';

import States from 'services/states';

import {
  dispersePiles,
  recoverPiles,
  trashPiles
} from 'components/fragments/fragments-actions';

import {
  MODE_MAD, MODE_MEAN, MODE_STD
} from 'components/fragments/fragments-defaults';

import COLORS from 'configs/colors';

const store = Container.instance.get(States).store;
const event = Container.instance.get(EventAggregator);

export const INSPECT = {
  name: 'Inspect',
  color: COLORS.WHITE,
  background: COLORS.BLACK,
  shortCut: 'I',
  trigger (pile) {
    event.publish(
      'decompose.fgm.inspectPile', { pile: this.pile }
    );
  },
  stackedPileOnly: true
};

export const DISPERSE = {
  name: 'Disperse',
  color: COLORS.WHITE,
  background: COLORS.BLACK,
  shortCut: 'D',
  trigger (pile) {
    store.dispatch(dispersePiles([this.pile.id]));
  },
  stackedPileOnly: true
};

export const MAD = {
  name: 'Mean Avg. Dev.',
  color: COLORS.WHITE,
  background: 0x666666,
  row: 0,
  shortCut: 'F',
  trigger (pile) {
    event.publish(
      'decompose.fgm.coverDispMode', { mode: MODE_MAD, pile: this.pile }
    );
  },
  triggerEvent: 'hover',
  stackedPileOnly: true
};

export const MEAN = {
  name: 'Mean',
  color: COLORS.WHITE,
  background: 0x666666,
  shortCut: 'M',
  trigger (pile) {
    event.publish(
      'decompose.fgm.coverDispMode', { mode: MODE_MEAN, pile: this.pile }
    );
  },
  triggerEvent: 'hover',
  stackedPileOnly: true
};

export const RECOVER = {
  name: 'Recover',
  color: COLORS.WHITE,
  background: COLORS.BLACK,
  shortCut: 'R',
  trigger (pile) {
    store.dispatch(recoverPiles([this.pile.id]));
  },
  trashedOnly: true,
  closeOnClick: true,
  unsetHighlightOnClick: true
};

export const TRASH = {
  name: 'Trash',
  color: COLORS.WHITE,
  background: COLORS.BLACK,
  shortCut: 'R',
  trigger (pile) {
    store.dispatch(trashPiles([this.pile.id]));
  },
  closeOnClick: true,
  unsetHighlightOnClick: true
};

export const STD = {
  name: 'Standard Dev.',
  color: COLORS.WHITE,
  background: 0x666666,
  shortCut: 'V',
  trigger (pile) {
    event.publish(
      'decompose.fgm.coverDispMode', { mode: MODE_STD, pile: this.pile }
    );
  },
  triggerEvent: 'hover',
  stackedPileOnly: true
};

export default [
  INSPECT,
  DISPERSE,
  TRASH,
  RECOVER,
  MEAN,
  MAD,
  STD
];
<|endoftext|>


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

var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');
var hyperquest = require('hyperquest');
var concat = require('concat-stream');
var rsa = require('rsa-stream');
var level = require('level');
var HOME = process.env.HOME || process.env.USERPROFILE;

var minimist = require('minimist');
var argv = minimist(process.argv.slice(2), {
    alias: {
        e: 'encoding',
        d: 'decrypt',
        a: 'add',
        l: [ 'ls', 'list' ],
        r: [ 'rm', 'remove' ],
        q: 'quiet',
        h: 'help'
    },
    'default': {
        encoding: 'base64'
    }
});

var db;

if (argv.help) {
    return fs.createReadStream(__dirname + '/usage.txt')
        .pipe(process.stdout)
    ;
}

if (argv.add) {
    var user = argv.add;
    if (user === true) {
        console.error('usage: cipherhub --add USER < id_rsa.pub');
        return process.exit(22);
    }
    db = getDb();

    return process.stdin.pipe(concat(function (body) {
        db.put(user, body.toString('utf8'), function (err) {
            if (err) {
                console.error(err);
                process.exit(11);
            }
            else console.log(
                'added key for', user,
                '(' + body.length + ' bytes)'
            );
        });
    }));
}
if (argv.list) {
    db = getDb();
    return db.createReadStream().on('data', function (row) {
        console.log(row.key, row.value.trim());
    });
}
if (argv.remove) {
    var user = argv.remove;
    if (user === true) {
        console.error('usage: cipherhub --rm USER');
        return process.exit(23);
    }
    db = getDb();

    return db.del(user, function (err) {
        if (err) {
            console.error(err);
            process.exit(12);
        }
        else console.log('removed key for ' + user);
    });
}

//assume the user is decrypting when there is no args,
//but they are piping something in.
if(!argv.decrypt && (argv._.length === 0 && !process.stdin.isTTY))
  argv.decrypt = true

if (argv.decrypt) {
    var keyfile = argv.decrypt;
    if (keyfile === true) {
        keyfile = path.join(
            process.env.HOME || process.env.USERPROFILE,
            '.ssh', 'id_rsa'
        );
    }
    return fs.readFile(keyfile, function (err, privkey) {
        if (err) {
            console.error(err);
            process.exit(1);
        }
        process.stdin
            .pipe(rsa.decrypt(privkey, { encoding: argv.encoding }))
            .on('error', onError)
            .pipe(process.stdout)
        ;

        function onError (err) {
            console.error('cipherhub: you tried to decrypt something')
            console.error('           that was not a message for you!')
            throw err
        }
    });
}

if (argv._.length === 0) {
    fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout);
    return;
}

var user = argv._[0];
db = getDb();
keyOf(user, function (err, keys, fromGithub) {
    if (err) {
        console.error(err);
        return process.exit(10);
    }
    if (!keys || keys.length === 0) {
        console.error(
            'No RSA keys available for the requested user.\n'
            + 'Add a key manually by doing:\n\n'
            + '  cipherhub --add ' + user + ' < rsa.pub'
            + '\n'
        );
        return process.exit(20);
    }
    if (keys.length > 1) {
        console.error(
            'Multiple keys available for the user: ' + user + ':\n\n'
            + keys.map(function (key) {
                return '  ' + key;
            }).join('\n') + '\n\n'
            + 'Add a key manually by doing:\n\n'
            + ' cipherhub --add ' + user + ' <<< KEYDATA\n'
            + '\n'
        );
        return process.exit(21);
    }

    if (fromGithub && argv.save !== false) {
        db.put(user, keys[0], function (err) {
            if (err) {
                console.error('Error saving key for user', user + ':');
                console.error(err);
            }
            else if (!argv.quiet) {
                console.error('# saved new key for user ', user);
                encrypt();
            }
            else encrypt();
        });
    }
    else encrypt();

    function encrypt () {
        var enc = rsa.encrypt(keys[0], { encoding: argv.encoding });
        process.stdin.pipe(enc).pipe(process.stdout);
        enc.on('end', function () { process.stdout.write('\n') });
    }
});

function keyOf (user, cb) {
    db.get(user, function (err, row) {
        if (err && err.name === 'NotFoundError') {
            if (argv.github === false) {
                cb(null, undefined);
            }
            else githubKeys(user, function (err, keys) {
                cb(err, keys, true);
            })
        }
        else if (err) cb(err)
        else cb(null, [row])
    });
}

function githubKeys (user, cb) {
    var u = 'https://github.com/' + user + '.keys';
    var hq = hyperquest(u);
    hq.on('error', function (err) {
        cb(err);
        cb = function () {};
    });
    hq.pipe(concat(function (body) {
        var keys = body.toString().split(/\r?\n/)
            .map(function (key) { return key.trim() })
            .filter(function (key) {
                return /^ssh-rsa\b/.test(key);
            })
        ;
        cb(null, keys);
    }));
}

function getDb () {
    mkdirp.sync(path.join(HOME, '.config', 'cipherhub'));
    return level(path.join(HOME, '.config', 'cipherhub', 'keys.db'));
}
<commit_msg>Adds keyname option<commit_after>#!/usr/bin/env node

var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');
var hyperquest = require('hyperquest');
var concat = require('concat-stream');
var rsa = require('rsa-stream');
var level = require('level');
var HOME = process.env.HOME || process.env.USERPROFILE;

var minimist = require('minimist');
var argv = minimist(process.argv.slice(2), {
    alias: {
        e: 'encoding',
        d: 'decrypt',
        a: 'add',
        l: [ 'ls', 'list' ],
        r: [ 'rm', 'remove' ],
        q: 'quiet',
        h: 'help'
        k: 'keyname'
    },
    'default': {
        encoding: 'base64'
    }
});

var db;

if (argv.help) {
    return fs.createReadStream(__dirname + '/usage.txt')
        .pipe(process.stdout)
    ;
}

if (argv.add) {
    var user = argv.add;
    if (user === true) {
        console.error('usage: cipherhub --add USER < id_rsa.pub');
        return process.exit(22);
    }
    db = getDb();

    return process.stdin.pipe(concat(function (body) {
        db.put(user, body.toString('utf8'), function (err) {
            if (err) {
                console.error(err);
                process.exit(11);
            }
            else console.log(
                'added key for', user,
                '(' + body.length + ' bytes)'
            );
        });
    }));
}
if (argv.list) {
    db = getDb();
    return db.createReadStream().on('data', function (row) {
        console.log(row.key, row.value.trim());
    });
}
if (argv.remove) {
    var user = argv.remove;
    if (user === true) {
        console.error('usage: cipherhub --rm USER');
        return process.exit(23);
    }
    db = getDb();

    return db.del(user, function (err) {
        if (err) {
            console.error(err);
            process.exit(12);
        }
        else console.log('removed key for ' + user);
    });
}

//assume the user is decrypting when there is no args,
//but they are piping something in.
if(!argv.decrypt && (argv._.length === 0 && !process.stdin.isTTY))
  argv.decrypt = true

if (argv.decrypt) {
    var keyfile = argv.decrypt;
    if (keyfile === true) {
      var keyname = 'id_rsa';
      if (argv.keyname)
        keyname = argv.keyname;
      keyfile = path.join(
          process.env.HOME || process.env.USERPROFILE,
          '.ssh', keyname
      );
    }
    return fs.readFile(keyfile, function (err, privkey) {
        if (err) {
            console.error(err);
            process.exit(1);
        }
        process.stdin
            .pipe(rsa.decrypt(privkey, { encoding: argv.encoding }))
            .on('error', onError)
            .pipe(process.stdout)
        ;

        function onError (err) {
            console.error('cipherhub: you tried to decrypt something')
            console.error('           that was not a message for you!')
            throw err
        }
    });
}

if (argv._.length === 0) {
    fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout);
    return;
}

var user = argv._[0];
db = getDb();
keyOf(user, function (err, keys, fromGithub) {
    if (err) {
        console.error(err);
        return process.exit(10);
    }
    if (!keys || keys.length === 0) {
        console.error(
            'No RSA keys available for the requested user.\n'
            + 'Add a key manually by doing:\n\n'
            + '  cipherhub --add ' + user + ' < rsa.pub'
            + '\n'
        );
        return process.exit(20);
    }
    if (keys.length > 1) {
        console.error(
            'Multiple keys available for the user: ' + user + ':\n\n'
            + keys.map(function (key) {
                return '  ' + key;
            }).join('\n') + '\n\n'
            + 'Add a key manually by doing:\n\n'
            + ' cipherhub --add ' + user + ' <<< KEYDATA\n'
            + '\n'
        );
        return process.exit(21);
    }

    if (fromGithub && argv.save !== false) {
        db.put(user, keys[0], function (err) {
            if (err) {
                console.error('Error saving key for user', user + ':');
                console.error(err);
            }
            else if (!argv.quiet) {
                console.error('# saved new key for user ', user);
                encrypt();
            }
            else encrypt();
        });
    }
    else encrypt();

    function encrypt () {
        var enc = rsa.encrypt(keys[0], { encoding: argv.encoding });
        process.stdin.pipe(enc).pipe(process.stdout);
        enc.on('end', function () { process.stdout.write('\n') });
    }
});

function keyOf (user, cb) {
    db.get(user, function (err, row) {
        if (err && err.name === 'NotFoundError') {
            if (argv.github === false) {
                cb(null, undefined);
            }
            else githubKeys(user, function (err, keys) {
                cb(err, keys, true);
            })
        }
        else if (err) cb(err)
        else cb(null, [row])
    });
}

function githubKeys (user, cb) {
    var u = 'https://github.com/' + user + '.keys';
    var hq = hyperquest(u);
    hq.on('error', function (err) {
        cb(err);
        cb = function () {};
    });
    hq.pipe(concat(function (body) {
        var keys = body.toString().split(/\r?\n/)
            .map(function (key) { return key.trim() })
            .filter(function (key) {
                return /^ssh-rsa\b/.test(key);
            })
        ;
        cb(null, keys);
    }));
}

function getDb () {
    mkdirp.sync(path.join(HOME, '.config', 'cipherhub'));
    return level(path.join(HOME, '.config', 'cipherhub', 'keys.db'));
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Table from './Table';
import Item from './Item/Item';
import NewItem from './Item/NewItem';
import classnames from 'classnames';
import { connect } from 'react-redux';

class Budgets extends Component {
	constructor() {
		super();
	}

	render(){

		return (

 Center (temp title)

					<NewItem />

 Features (temp title)

						<Item summary="This is a summary"/>

		);
	}
}

export default connect()(Budgets);<commit_msg>Clean up and add items as default state<commit_after>import React, { Component } from 'react';
import Table from './Table';
import Item from './Item';
import NewItem from './Item/NewItem';

class Budgets extends Component {
	constructor() {
		super();

    this.state = {
      items: [
        {
          summary: "Klevu discovery & calls",
          phase: "dev/Klevu",
          feature: "Klevu",
          budgetHours: {
            column: "Discovery",
            value: 6,
          },
          descriptions: {
            workplan: [
              "Time for communication with Klevu.",
            ],
            budget: [],
            assumptions: [
              "Accounts for one onboarding call."
            ],
            exclusions: [],
          },
          tags: "klevu",
        },
        {
          summary: "Install Klevu extension",
          phase: "dev/Klevu",
          feature: "Klevu",
          budgetHours: {
            column: 'Dev',
            value: 4,
          },
          descriptions: {
            workplan: [
              "Install Klevu extension using composer.",
            ],
            assumptions: [
              "Install extension once using code provided by Klevu."
            ],
          },
          tags: "klevu",
        },
        {
          summary: "Configure Klevu flyout",
          phase: "dev/Klevu",
          feature: "Klevu",
          budgetHours: {
            column: 'Dev',
            value: 4,
          },
          descriptions: {
            workplan: [
              "Use Klevu control panel to choose between autocomplete and faceted.",
            ],
            assumptions: [
              "Use one of out of box options provided by Klevu (autocomplete or faceted) without customization.",
            ],
          },
          tags: "klevu",
        },
      ],
    };
  }

  render() {
    return (

Center (temp title)

          <NewItem />

 Features (temp title)

            {this.state.items.map(item => (
              <Item summary={item.summary} />
            ))}

    );
  }
}

export default Budgets;
<|endoftext|>


<commit_before>App.module('Models', function( Models, App, Backbone, Marionette, $, _ ) {

  'use strict';

  var Mix = Models.Mix = Backbone.Model.extend({

    url: 'mix.json',

    defaults: {
      // mix name
      name      : 'Mix',
      // master gain (0 - 1)
      gain      : 1,
      // playback position (in seconds)
      position  : 0,
      // minimum allowed playback position
      minTime   : 0,
      // maximum allowed playback position
      maxTime   : Infinity,
      // internal value for playback scheduling
      startTime : 0,
      // are we currently playing?
      playing   : false,
      // internal value for VU meters
      dBFSLeft   : -48,
      // internal value for VU meters
      dBFSRight  : -48,
      // internally calculated song duration
      duration  : Infinity
    },

    initialize: function() {
      this.nodes = {};
      this.createNodes();
      this.setGain();
      this.updatePosition();
      App.vent.on('solo', this.soloMute.bind(this));
      App.vent.on('unsolo', this.soloMute.bind(this));
      App.vent.on('anim-tick', this.updatePosition.bind(this));
      this.on('change:gain', this.setGain, this);
    },

    // create audio nodes
    createNodes: function() {
      this.fftSize = 2048;
      this.timeDataL = new Uint8Array(this.fftSize);
      this.timeDataR = new Uint8Array(this.fftSize);
      this.nodes.gain = App.ac.createGain();
      this.nodes.splitter = App.ac.createChannelSplitter(2);
      this.nodes.analyserL = App.ac.createAnalyser();
      this.nodes.analyserR = App.ac.createAnalyser();
      this.nodes.gain.connect(this.nodes.splitter);
      this.nodes.splitter.connect(this.nodes.analyserL, 0, 0);
      this.nodes.splitter.connect(this.nodes.analyserR, 1, 0);
      this.nodes.gain.connect(App.ac.destination);
      this.nodes.analyserL.smoothingTimeConstant = 1;
      this.nodes.analyserR.smoothingTimeConstant = 1;
      return this;
    },

    // set gain
    setGain: function() {
      this.nodes.gain.gain.value = this.get('gain');
      return this;
    },

    // begin playback of all tracks
    // optionally accepts a playback position in seconds
    play: function( pos ) {
      var now = App.ac.currentTime,
        time = this.get('position'),
        max = this.get('tracks').maxLength();
      if ( !App.ready ) {
        throw new Error('Cannot play before App.ready');
      }
      if ( typeof pos === 'number' ) {
        this.set('position', time = Math.max(pos, this.get('minTime')));
      }
      this.set({startTime: now - time, playing: true, duration: max});
      this.get('tracks').play(time);
      return this;
    },

    // pause all tracks
    pause: function() {
      this.get('tracks').pause();
      this.set('playing', false);
      App.vent.trigger('mix-pause');
      return this;
    },

    // get the exact, up-to-date playback position
    exactTime: function(){
      var now = App.ac.currentTime,
        playing = this.get('playing'),
        start = this.get('startTime'),
        position = this.get('position'),
        delta = now - start;
      return playing ? delta : position;
    },

    // periodically update the position attribute (for UI)
    updatePosition: function(){
      var position = this.exactTime(),
        playing = this.get('playing');
      if ( position > Math.min(this.get('maxTime'), this.get('duration')) ) {
        this.play(0).pause();
      } else {
        this.set('position', position, {silent: true});
      }
      return this;
    },

    // selectively apply/remove mutes depending on which tracks
    // are soloed and unsoloed
    soloMute: function() {
      var unsoloed, soloed, _muted;
      if ( this.get('tracks') ) {
        unsoloed = this.get('tracks').where({soloed: false});
        soloed = this.get('tracks').where({soloed: true});
        _muted = this.get('tracks').where({_muted: true});
        // apply _mute to non-soloed tracks
        if ( soloed.length ){
          unsoloed.forEach(function( track ){
            track._mute();
          });
        }
        // remove _mute when nothing is soloed
        if ( !soloed.length ) {
          _muted.forEach(function( track ) {
            track._unmute();
          });
        }
      }
      return this;
    },

    // get dBFS values
    levels: function( e ) {
      var playing = this.get('playing'),
        len = this.timeDataL.length,
        right = new Array(len),
        left = new Array(len),
        i = 0;
      this.nodes.analyserL.getByteTimeDomainData(this.timeDataL);
      this.nodes.analyserR.getByteTimeDomainData(this.timeDataR);
      for ( ; i < len; ++i ) {
        left[i] = ( this.timeDataL[i] * 2 / 255 ) - 1;
        right[i] = ( this.timeDataR[i] * 2 / 255 ) - 1;
      }
      left = App.util.dBFS(left);
      right = App.util.dBFS(right);
      this.set({
        dBFSLeft: playing ? left : this.get('dBFSLeft') - 0.8,
        dBFSRight: playing ? right : this.get('dBFSRight') - 0.8
      });
      return this;
    },

    // override default parsing to create `tracks` collection
    parse: function( data ) {
      data.tracks = new App.Collections.Tracks(data.tracks);
      data.position = data.position || data.minTime || 0;
      App.tracks = data.tracks.length;
      return _.extend({}, data);
    },

    toJSON: function() {
      var out = _.extend({}, this.attributes),
        tracks = _.map(this.get('tracks').models, function( track ) {
          return track.toJSON();
        });
      out.tracks = tracks;
      delete out.dBFSLeft;
      delete out.dBFSRight;
      delete out.startTime;
      delete out.binURI;
      return out;
    },

    persist: _.debounce(function() {
      var self = this,
        data = App.mix.toJSON(),
        binURI = this.get('binURI');
      delete data.position;
      delete data.playing;
      delete data.duration;
      delete data.binURI;
      data = JSON.stringify(data);
      $.ajax({
        type: binURI ? 'PUT' : 'POST',
        url: binURI || 'http://api.myjson.com/bins',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        data: data,
        success: function( response ) {
          self.set('binURI', response.uri, {silent: true});
          location.hash = response.uri.split('/').pop();
        }
      });
    }, 500)

  });

});
<commit_msg>lol @ fucking up my `this` context<commit_after>App.module('Models', function( Models, App, Backbone, Marionette, $, _ ) {

  'use strict';

  var Mix = Models.Mix = Backbone.Model.extend({

    url: 'mix.json',

    defaults: {
      // mix name
      name      : 'Mix',
      // master gain (0 - 1)
      gain      : 1,
      // playback position (in seconds)
      position  : 0,
      // minimum allowed playback position
      minTime   : 0,
      // maximum allowed playback position
      maxTime   : Infinity,
      // internal value for playback scheduling
      startTime : 0,
      // are we currently playing?
      playing   : false,
      // internal value for VU meters
      dBFSLeft   : -48,
      // internal value for VU meters
      dBFSRight  : -48,
      // internally calculated song duration
      duration  : Infinity
    },

    initialize: function() {
      this.nodes = {};
      this.createNodes();
      this.setGain();
      this.updatePosition();
      App.vent.on('solo', this.soloMute.bind(this));
      App.vent.on('unsolo', this.soloMute.bind(this));
      App.vent.on('anim-tick', this.updatePosition.bind(this));
      this.on('change:gain', this.setGain, this);
    },

    // create audio nodes
    createNodes: function() {
      this.fftSize = 2048;
      this.timeDataL = new Uint8Array(this.fftSize);
      this.timeDataR = new Uint8Array(this.fftSize);
      this.nodes.gain = App.ac.createGain();
      this.nodes.splitter = App.ac.createChannelSplitter(2);
      this.nodes.analyserL = App.ac.createAnalyser();
      this.nodes.analyserR = App.ac.createAnalyser();
      this.nodes.gain.connect(this.nodes.splitter);
      this.nodes.splitter.connect(this.nodes.analyserL, 0, 0);
      this.nodes.splitter.connect(this.nodes.analyserR, 1, 0);
      this.nodes.gain.connect(App.ac.destination);
      this.nodes.analyserL.smoothingTimeConstant = 1;
      this.nodes.analyserR.smoothingTimeConstant = 1;
      return this;
    },

    // set gain
    setGain: function() {
      this.nodes.gain.gain.value = this.get('gain');
      return this;
    },

    // begin playback of all tracks
    // optionally accepts a playback position in seconds
    play: function( pos ) {
      var now = App.ac.currentTime,
        time = this.get('position'),
        max = this.get('tracks').maxLength();
      if ( !App.ready ) {
        throw new Error('Cannot play before App.ready');
      }
      if ( typeof pos === 'number' ) {
        this.set('position', time = Math.max(pos, this.get('minTime')));
      }
      this.set({startTime: now - time, playing: true, duration: max});
      this.get('tracks').play(time);
      return this;
    },

    // pause all tracks
    pause: function() {
      this.get('tracks').pause();
      this.set('playing', false);
      App.vent.trigger('mix-pause');
      return this;
    },

    // get the exact, up-to-date playback position
    exactTime: function(){
      var now = App.ac.currentTime,
        playing = this.get('playing'),
        start = this.get('startTime'),
        position = this.get('position'),
        delta = now - start;
      return playing ? delta : position;
    },

    // periodically update the position attribute (for UI)
    updatePosition: function(){
      var position = this.exactTime(),
        playing = this.get('playing');
      if ( position > Math.min(this.get('maxTime'), this.get('duration')) ) {
        this.play(0).pause();
      } else {
        this.set('position', position, {silent: true});
      }
      return this;
    },

    // selectively apply/remove mutes depending on which tracks
    // are soloed and unsoloed
    soloMute: function() {
      var unsoloed, soloed, _muted;
      if ( this.get('tracks') ) {
        unsoloed = this.get('tracks').where({soloed: false});
        soloed = this.get('tracks').where({soloed: true});
        _muted = this.get('tracks').where({_muted: true});
        // apply _mute to non-soloed tracks
        if ( soloed.length ){
          unsoloed.forEach(function( track ){
            track._mute();
          });
        }
        // remove _mute when nothing is soloed
        if ( !soloed.length ) {
          _muted.forEach(function( track ) {
            track._unmute();
          });
        }
      }
      return this;
    },

    // get dBFS values
    levels: function( e ) {
      var playing = this.get('playing'),
        len = this.timeDataL.length,
        right = new Array(len),
        left = new Array(len),
        i = 0;
      this.nodes.analyserL.getByteTimeDomainData(this.timeDataL);
      this.nodes.analyserR.getByteTimeDomainData(this.timeDataR);
      for ( ; i < len; ++i ) {
        left[i] = ( this.timeDataL[i] * 2 / 255 ) - 1;
        right[i] = ( this.timeDataR[i] * 2 / 255 ) - 1;
      }
      left = App.util.dBFS(left);
      right = App.util.dBFS(right);
      this.set({
        dBFSLeft: playing ? left : this.get('dBFSLeft') - 0.8,
        dBFSRight: playing ? right : this.get('dBFSRight') - 0.8
      });
      return this;
    },

    // override default parsing to create `tracks` collection
    parse: function( data ) {
      data.tracks = new App.Collections.Tracks(data.tracks);
      data.position = data.position || data.minTime || 0;
      App.tracks = data.tracks.length;
      return _.extend({}, data);
    },

    toJSON: function() {
      var out = _.extend({}, this.attributes),
        tracks = _.map(this.get('tracks').models, function( track ) {
          return track.toJSON();
        });
      out.tracks = tracks;
      delete out.dBFSLeft;
      delete out.dBFSRight;
      delete out.startTime;
      delete out.binURI;
      return out;
    },

    persist: _.debounce(function() {
      var self = App.mix,
        data = self.toJSON(),
        binURI = self.get('binURI');
      delete data.position;
      delete data.playing;
      delete data.duration;
      delete data.binURI;
      data = JSON.stringify(data);
      $.ajax({
        type: binURI ? 'PUT' : 'POST',
        url: binURI || 'http://api.myjson.com/bins',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        data: data,
        success: function( response ) {
          self.set('binURI', response.uri, {silent: true});
          location.hash = response.uri.split('/').pop();
        }
      });
    }, 500)

  });

});
<|endoftext|>


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

var FeedParser = require('feedparser'); // to parse feeds
// var Feed = require('feed'); // to write feeds (but not necessary to require here because we should get a Feed object from app.js -- which seems wrong)
var async = require('async');
var request = require('request'); // TODO let's abstract this so that we can switch it out (e.g., to fs.readFile )

exports.feedmerger = function (feedsArray, feedObject, mergedCallback) {
  // TODO some error handling; checking the arguments etc.

  var getFeed = function (feed, callback) {
    var req = request(feed);
    var feedparser = new FeedParser();
    req.on('error', function (error) {
      console.error(error);
    });
    req.on('response', function (res) {
      var stream = this;
      if (res.statusCode != 200) {
        return this.emit('error', new Error('Bad status code'));
      }
      //    stream.pipe(process.stdout); //works
      stream.pipe(feedparser);
    });
    feedparser.on('error', function (error) {
      console.error(error);
    });
    feedparser.on('readable', function () {
      // This is where the action is!
      var stream = this;
      //    var meta = this.meta; // **NOTE** the "meta" is always available in the context of the feedparser instance
      var item;
      while (item = stream.read()) {
        var itemTitle = item['rss:title']['#']; // how to make it "or use item['atom:title']['#']" ??
        var itemLink = item.link;
        var itemDescription = item.description;
        var itemDate = item.date;
        var itemAuthor = item.author;
//        console.error(typeof itemAuthor);
        feedObject.addItem({
          title: itemTitle,
          link: itemLink,
          description: itemDescription,
          date: itemDate,
          author: itemAuthor
        });
      }
    });
    feedparser.on('finish', function () {
      callback();
    });
  };

//  console.log(feedsArray);
  async.each(feedsArray, getFeed, function (err) {
    if (err) {
      throw err;
    }
    feedObject.items.sort(function (a, b) { //sort by date for creating pages later
      return b.date - a.date;
    });
//   console.log("feedmerger completed!");
//     console.log(feedObject.render('atom-1.0'));
   return mergedCallback(null,feedObject);
  });
};

//    exports.feedmerger = new feedmerger();<commit_msg>rewrite feedmerger to use fs; fix some but not all issues around reading author properties<commit_after>/* eslint-env node */

var FeedParser = require('feedparser'); // to parse feeds
// var Feed = require('feed'); // to write feeds (but not necessary to require here because we should get a Feed object from app.js -- which seems wrong)
var async = require('async');
// var request = require('request'); // TODO let's abstract this so that we can switch it out (e.g., to fs.readFile )
var fs = require('fs');

exports.feedmerger = function(feedsJson, feedObject, mergedCallback) {
  'use strict';
  // TODO some error handling; checking the arguments etc.

  var getFeed = function(feed, callback) {
    var feedparser = new FeedParser();
    var req = fs.createReadStream(feed); // request(feed);
    req.on('error', function(error) {
        console.error(error);
    });
    req.on('readable', function() {
      var stream = this;
      stream.pipe(feedparser);
    });
    // req.on('response', function(res) {
    //   var stream = this;
    //   if (res.statusCode !== 200) {
    //     return this.emit('error', new Error('Bad status code'));
    //   }
    //   //    stream.pipe(process.stdout); //works
    //   stream.pipe(feedparser);
    // });
    feedparser.on('error', function(error) {
      console.error(feed + ' as a parsing error' + error);
    });
    feedparser.on('readable', function() {
      // This is where the action is!
      var stream = this;
      //    var meta = this.meta; // **NOTE** the "meta" is always available in the context of the feedparser instance
      var item;
      while ( (item = stream.read())) {
        var itemTitle = item.title;
        var itemLink = item.link;
        var itemDescription = item.description;
        var itemDate = item.date;
        var itemAuthor = [{ name: item.author.toString(), email: '', link: ''}];//TODO handle multiple authors??? npm/feed supports that
        feedObject.addItem({
          title: itemTitle,
          link: itemLink,
          description: itemDescription,
          date: itemDate,
          author: itemAuthor
        });
      }
    });
    feedparser.on('finish', function() {
      callback();
    });
  };

  //  console.log(feedsJson);
  async.each(feedsJson, getFeed, function(err) {
    if (err) {
      throw err;
    }
    feedObject.items.sort(function(a, b) { //sort by date for creating pages later
      return b.date - a.date;
    });
    //   console.log("feedmerger completed!");
    //     console.log(feedObject.render('atom-1.0'));
    return mergedCallback(null, feedObject);
  });
};

//    exports.feedmerger = new feedmerger();
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';

import SecretListItemFolderSecret from 'components/secrets/SecretListItem/Secret';
import SecretListBreadcrumb from 'components/secrets/SecretListBreadcrumb';

const propTypes = {
  folder: PropTypes.any,
};

function SecretListFolderInfo({ folder }) {
  return (

      {
        !folder.has('root') &&

              <SecretListBreadcrumb folders={folder.get('breadcrumb')} withTitle={false} />

      }
      {
        folder.get('secrets').map(secret => (
          <SecretListItemFolderSecret
            key={secret.id}
            secret={secret}
          />
        )).toArray()
      }

  );
}

SecretListFolderInfo.propTypes = propTypes;

export default SecretListFolderInfo;
<commit_msg>Order secret behind folder breadcrumb in filtered views<commit_after>import React, { PropTypes } from 'react';

import SecretListItemFolderSecret from 'components/secrets/SecretListItem/Secret';
import SecretListBreadcrumb from 'components/secrets/SecretListBreadcrumb';

const propTypes = {
  folder: PropTypes.any,
};

function SecretListFolderInfo({ folder }) {
  return (

      {
        !folder.has('root') &&

              <SecretListBreadcrumb folders={folder.get('breadcrumb')} withTitle={false} />

      }
      {
        folder.get('secrets').sortBy(secret => secret.get('title').toLowerCase()).map(secret => (
          <SecretListItemFolderSecret
            key={secret.id}
            secret={secret}
          />
        )).toArray()
      }

  );
}

SecretListFolderInfo.propTypes = propTypes;

export default SecretListFolderInfo;
<|endoftext|>


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

var Liftoff = require('liftoff');
var argv = require('minimist')(process.argv.slice(2));
var logger = require('../lib/log.js');
var v8flags = require('v8flags');
var path = require('path');
var nodeVersion = process.versions.node;
var parts = nodeVersion.split(".");

var cli = new Liftoff({
  name: 'fis',
  processTitle: 'fis',
  moduleName: 'fis3',
  configName: 'fis-conf',

  // only js supported!
  extensions: {
    '.js': null
  },

  v8flags: v8flags
});

cli.launch({
  cwd: argv.r || argv.root,
  configPath: argv.f || argv.file
}, function(env) {
  var fis;

  if (!env.modulePath) {
    logger.warning('Local `fis3` not found, use global version instead.');
    fis = require('../');
  } else {
    fis = require(env.modulePath);
  }

  if (argv.verbose) {
    fis.log.level = fis.log.L_ALL;
  }

  if (argv.c || argv.clean) {
    fis.cache.enable = false;
  }

  // chdir before requiring gulpfile to make sure
  // we let them chdir as needed
  // if (process.cwd() !== env.cwd) {
  //   process.chdir(env.cwd);
  //   logger.notice('Working directory changed to `%s`.', env.cwd);
  // }
  //

  process.env.NODE_ENV = process.env.NODE_ENV || argv.env || 'dev';

  fis.set({
    modules: {
      packager: 'map',
      deploy : 'default'
    }
  });

  fis.match('**', {
    deploy: fis.plugin('default')
  });

  fis.match('*.{js|css|html}', {
    preprocessor: fis.plugin('components')
  });

  fis.match('*.js', {
    postprocessor: fis.plugin('jswrapper'),
  });

  fis.env('production')
    .match('**', {
      spriter: fis.plugin('csssprites'),
      packager: fis.plugin('map'),
    })
    .match('*.js', {
      optimizer: fis.plugin('uglify-js')
    })
    .match('*.css', {
      optimizer: fis.plugin('clean-css')
    })
    .match('*.png', {
      optimizer: fis.plugin('png-compressor')
    });

  //exports cli object
  fis.cli = {};

  fis.cli.name = 'fis';

  //colors
  fis.cli.colors = require('colors');

  //commander object
  fis.cli.commander = null;

  //package.json
  fis.cli.info = fis.util.readJSON(path.dirname(__dirname) + '/package.json');

  //output help info
  fis.cli.help = function() {
    var content = [
      '',
      '  Usage: ' + fis.cli.name + ' <command>',
      '',
      '  Commands:',
      ''
    ];

    fis.cli.help.commands.forEach(function(name) {
      var cmd = fis.require('command', name);
      name = cmd.name || name;
      name = fis.util.pad(name, 12);
      content.push('    ' + name + (cmd.desc || ''));
    });

    content = content.concat([
      '',
      '  Options:',
      '',
      '    -h, --help     output usage information',
      '    -v, --version  output the version number',
      '    --no-color     disable colored output',
      ''
    ]);
    console.log(content.join('\n'));
  };

  fis.cli.help.commands = ['release', 'install', 'server'];

  //output version info
  fis.cli.version = function() {
    var content = [
      '',
      '  v' + fis.cli.info.version,
      '',
      ' __' + '/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'.bold.red + '__' + '/\\\\\\\\\\\\\\\\\\\\\\'.bold.yellow + '_____' + '/\\\\\\\\\\\\\\\\\\\\\\'.bold.green + '___',
      '  _' + '\\/\\\\\\///////////'.bold.red + '__' + '\\/////\\\\\\///'.bold.yellow + '____' + '/\\\\\\/////////\\\\\\'.bold.green + '_' + '       ',
      '   _' + '\\/\\\\\\'.bold.red + '_________________' + '\\/\\\\\\'.bold.yellow + '______' + '\\//\\\\\\'.bold.green + '______' + '\\///'.bold.green + '__',
      '    _' + '\\/\\\\\\\\\\\\\\\\\\\\\\'.bold.red + '_________' + '\\/\\\\\\'.bold.yellow + '_______' + '\\////\\\\\\'.bold.green + '_________' + '     ',
      '     _' + '\\/\\\\\\///////'.bold.red + '__________' + '\\/\\\\\\'.bold.yellow + '__________' + '\\////\\\\\\'.bold.green + '______' + '    ',
      '      _' + '\\/\\\\\\'.bold.red + '_________________' + '\\/\\\\\\'.bold.yellow + '_____________' + '\\////\\\\\\'.bold.green + '___' + '   ',
      '       _' + '\\/\\\\\\'.bold.red + '_________________' + '\\/\\\\\\'.bold.yellow + '______' + '/\\\\\\'.bold.green + '______' + '\\//\\\\\\'.bold.green + '__',
      '        _' + '\\/\\\\\\'.bold.red + '______________' + '/\\\\\\\\\\\\\\\\\\\\\\'.bold.yellow + '_' + '\\///\\\\\\\\\\\\\\\\\\\\\\/'.bold.green + '___',
      '         _' + '\\///'.bold.red + '______________' + '\\///////////'.bold.yellow + '____' + '\\///////////'.bold.green + '_____',
      ''
    ].join('\n');
    console.log(content);
  };

  function hasArgv(argv, search) {
    var pos = argv.indexOf(search);
    var ret = false;
    while (pos > -1) {
      argv.splice(pos, 1);
      pos = argv.indexOf(search);
      ret = true;
    }
    return ret;
  }

  //run cli tools
  fis.cli.run = function(argv) {

    if (hasArgv(argv, '--no-color')) {
      fis.cli.colors.mode = 'none';
    }

    var first = argv[2];
    if (argv.length < 3 || first === '-h' || first === '--help') {
      fis.cli.help();
    } else if (first === '-v' || first === '--version') {
      fis.cli.version();
    } else if (first[0] === '-') {
      fis.cli.help();
    } else {
      //register command
      var commander = fis.cli.commander = require('commander');
      var cmd = fis.require('command', argv[2]);
      cmd.register(
        commander
        .command(cmd.name || first)
        .usage(cmd.usage)
        .description(cmd.desc)
      );
      commander.parse(argv);
    }
  };

  fis.cli.run(process.argv);
});
<commit_msg>draft<commit_after>#!/usr/bin/env node

var Liftoff = require('liftoff');
var argv = require('minimist')(process.argv.slice(2));
var logger = require('../lib/log.js');
var v8flags = require('v8flags');
var path = require('path');
var nodeVersion = process.versions.node;
var parts = nodeVersion.split(".");

var cli = new Liftoff({
  name: 'fis',
  processTitle: 'fis',
  moduleName: 'fis3',
  configName: 'fis-conf',

  // only js supported!
  extensions: {
    '.js': null
  },

  v8flags: v8flags
});

cli.launch({
  cwd: argv.r || argv.root,
  configPath: argv.f || argv.file
}, function(env) {
  var fis;

  if (!env.modulePath) {
    logger.warning('Local `fis3` not found, use global version instead.');
    fis = require('../');
  } else {
    fis = require(env.modulePath);
  }

  if (argv.verbose) {
    fis.log.level = fis.log.L_ALL;
  }

  if (argv.c || argv.clean) {
    fis.cache.enable = false;
  }

  // chdir before requiring gulpfile to make sure
  // we let them chdir as needed
  // if (process.cwd() !== env.cwd) {
  //   process.chdir(env.cwd);
  //   logger.notice('Working directory changed to `%s`.', env.cwd);
  // }
  //

  process.env.NODE_ENV = process.env.NODE_ENV || argv.env || 'dev';

  fis.set({
    modules: {
      packager: 'map',
      deploy : 'default'
    }
  });

  fis.match('*.{js|css|html}', {
    preprocessor: fis.plugin('components')
  });

  fis.match('*.js', {
    postprocessor: fis.plugin('jswrapper'),
  });

  fis.env('production')
    .match('*.js', {
      optimizer: fis.plugin('uglify-js')
    })
    .match('*.css', {
      optimizer: fis.plugin('clean-css')
    })
    .match('*.png', {
      optimizer: fis.plugin('png-compressor')
    });

  //exports cli object
  fis.cli = {};

  fis.cli.name = 'fis';

  //colors
  fis.cli.colors = require('colors');

  //commander object
  fis.cli.commander = null;

  //package.json
  fis.cli.info = fis.util.readJSON(path.dirname(__dirname) + '/package.json');

  //output help info
  fis.cli.help = function() {
    var content = [
      '',
      '  Usage: ' + fis.cli.name + ' <command>',
      '',
      '  Commands:',
      ''
    ];

    fis.cli.help.commands.forEach(function(name) {
      var cmd = fis.require('command', name);
      name = cmd.name || name;
      name = fis.util.pad(name, 12);
      content.push('    ' + name + (cmd.desc || ''));
    });

    content = content.concat([
      '',
      '  Options:',
      '',
      '    -h, --help     output usage information',
      '    -v, --version  output the version number',
      '    --no-color     disable colored output',
      ''
    ]);
    console.log(content.join('\n'));
  };

  fis.cli.help.commands = ['release', 'install', 'server'];

  //output version info
  fis.cli.version = function() {
    var content = [
      '',
      '  v' + fis.cli.info.version,
      '',
      ' __' + '/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'.bold.red + '__' + '/\\\\\\\\\\\\\\\\\\\\\\'.bold.yellow + '_____' + '/\\\\\\\\\\\\\\\\\\\\\\'.bold.green + '___',
      '  _' + '\\/\\\\\\///////////'.bold.red + '__' + '\\/////\\\\\\///'.bold.yellow + '____' + '/\\\\\\/////////\\\\\\'.bold.green + '_' + '       ',
      '   _' + '\\/\\\\\\'.bold.red + '_________________' + '\\/\\\\\\'.bold.yellow + '______' + '\\//\\\\\\'.bold.green + '______' + '\\///'.bold.green + '__',
      '    _' + '\\/\\\\\\\\\\\\\\\\\\\\\\'.bold.red + '_________' + '\\/\\\\\\'.bold.yellow + '_______' + '\\////\\\\\\'.bold.green + '_________' + '     ',
      '     _' + '\\/\\\\\\///////'.bold.red + '__________' + '\\/\\\\\\'.bold.yellow + '__________' + '\\////\\\\\\'.bold.green + '______' + '    ',
      '      _' + '\\/\\\\\\'.bold.red + '_________________' + '\\/\\\\\\'.bold.yellow + '_____________' + '\\////\\\\\\'.bold.green + '___' + '   ',
      '       _' + '\\/\\\\\\'.bold.red + '_________________' + '\\/\\\\\\'.bold.yellow + '______' + '/\\\\\\'.bold.green + '______' + '\\//\\\\\\'.bold.green + '__',
      '        _' + '\\/\\\\\\'.bold.red + '______________' + '/\\\\\\\\\\\\\\\\\\\\\\'.bold.yellow + '_' + '\\///\\\\\\\\\\\\\\\\\\\\\\/'.bold.green + '___',
      '         _' + '\\///'.bold.red + '______________' + '\\///////////'.bold.yellow + '____' + '\\///////////'.bold.green + '_____',
      ''
    ].join('\n');
    console.log(content);
  };

  function hasArgv(argv, search) {
    var pos = argv.indexOf(search);
    var ret = false;
    while (pos > -1) {
      argv.splice(pos, 1);
      pos = argv.indexOf(search);
      ret = true;
    }
    return ret;
  }

  //run cli tools
  fis.cli.run = function(argv) {

    if (hasArgv(argv, '--no-color')) {
      fis.cli.colors.mode = 'none';
    }

    var first = argv[2];
    if (argv.length < 3 || first === '-h' || first === '--help') {
      fis.cli.help();
    } else if (first === '-v' || first === '--version') {
      fis.cli.version();
    } else if (first[0] === '-') {
      fis.cli.help();
    } else {
      //register command
      var commander = fis.cli.commander = require('commander');
      var cmd = fis.require('command', argv[2]);
      cmd.register(
        commander
        .command(cmd.name || first)
        .usage(cmd.usage)
        .description(cmd.desc)
      );
      commander.parse(argv);
    }
  };

  fis.cli.run(process.argv);
});
<|endoftext|>


<commit_before>/*! Pickyfill - Offline caching for picturefill responsive image polyfill. Author: Rich Trott | Copyright: Regents of University of California, 2012 | License: MIT */

(function( w ) {
    "use strict";

    var localStorage = w.localStorage,
        applicationCache = w.applicationCache,
        image,
        dataUri,
        pf_index_string,
        pf_index,
        canvasTest = document.createElement('canvas');

    // Don't run any of this stuff if application cache, localStorage or canvas are not available.
    if ( (! applicationCache) || (! localStorage) || (!(canvasTest.getContext && canvasTest.getContext('2d'))) ) {
            return;
    }

    pf_index_string = localStorage.getItem('pf_index') || '{}';
    pf_index = JSON.parse(pf_index_string);

    // We'll use this to clear the pickyfill cache when appcache updates.
    var clearCache = function () {
        localStorage.removeItem('pf_index');
        for (var prop in pf_index) {
            localStorage.removeItem(prop);
        }
    };

    // Unfortunately, reloading is the most reliable way to get stuff into the
    //  pickyfill cache. If you wait for the user to reload, they may be offline
    //  at that time. If we just had an updateready event, chances are very good
    //  that they are still online. Another possibility is to just try to reload
    //  the images that are currently shown, but there's no guarantee that those
    //  images are in the new page or that the current page isn't missing important
    //  images that will display in the new page and need to be cached.
    var refreshCache = function () {
        clearCache();
        w.location.reload();
    };

    // If appcache updates, refresh the pickyfill cache to get new items.
    // If appcache is obsolete, clear the pickyfill cache.
    // Appcache == IE10 or later == no need to worry about attachEvent (IE8 and earlier)
    // Anything that has appcache is going to have addEventListener.
    applicationCache.addEventListener('updateready', refreshCache, false);
    applicationCache.addEventListener('obsolete', clearCache, false);

    // If the event has already fired and we missed it, clear/refresh the pickyfill cache.
    if(applicationCache.status === applicationCache.UPDATEREADY) {
        refreshCache();
    }

    if (applicationCache.status === applicationCache.OBSOLETE) {
        clearCache();
    }

    var srcFromCacheRan = false;
    var srcFromCache = function ( ps ) {
        var sources, src, newSrc;

        // Loop the pictures
        for( var i = 0, il = ps.length; i < il; i++ ){
            if( ps[ i ].getAttribute( "data-picture" ) !== null ){

                sources = ps[ i ].getElementsByTagName( "div" );
                // See which ones are cached in localStorage. Use the cached value.
                for( var j = 0, jl = sources.length; j < jl; j++ ){
                    if ((src = sources[j].getAttribute( "data-src" )) !== null ) {
                        if ( pf_index.hasOwnProperty('pf_s_' + src)) {
                            newSrc = localStorage.getItem('pf_s_' + src);
                            if (newSrc !== null) {
                                sources[j].setAttribute('data-src', localStorage.getItem('pf_s_' + src));
                            }
                        }
                    }
                }
            }
        }
    };

    var cacheImage = function ( param ) {
        var canvas,
            ctx,
            imageSrc,
            me;

        me = param.target ? param.target : param;

        imageSrc = me.getAttribute("src");
        if ((imageSrc === null) || (imageSrc.length === 0) || (imageSrc.substr(0,5) === "data:")) {
            return;
        }

        canvas = w.document.createElement("canvas");
        canvas.width = me.width;
        canvas.height = me.height;

        ctx = canvas.getContext("2d");
        ctx.drawImage(me, 0, 0);
        try {
            dataUri = canvas.toDataURL();
        } catch (e) {
            // TODO: Improve error handling here. For now, if canvas.toDataURL()
            //   throws an exception, don't cache the image and move on.
            return;
        }

        // Do not cache if the resulting cache item will take more than 128Kb.
        if (dataUri.length > 131072) {
            return;
        }

        pf_index["pf_s_"+imageSrc] = 1;

        try {
            localStorage.setItem("pf_s_"+imageSrc, dataUri);
            localStorage.setItem("pf_index", JSON.stringify(pf_index));
        } catch (e) {
            // Caching failed. Remove item from index object so next cached item
            //   doesn't wrongly indicate this item was successfully cached.
            delete pf_index["pf_s_"+imageSrc];
        }
    };

    // Exit here if uncached. If updateready fires later, it will reload,
    //   and status will not be uncached on the that load.
    if (applicationCache.status === applicationCache.UNCACHED) {
        return;
    }
    w.picturefillOrig = w.picturefill;
    w.picturefill = function () {
        var ps = w.document.getElementsByTagName( "div" );

        if (! srcFromCacheRan ) {
            srcFromCacheRan = true;
            srcFromCache( ps );
        }

        w.picturefillOrig();

        // Loop the pictures
        for( var i = 0, il = ps.length; i < il; i++ ){
            if( ps[ i ].getAttribute( "data-picture" ) !== null ){
                image = ps[ i ].getElementsByTagName( "img" )[0];
                if (image) {
                    if (image.getAttribute("src") !== null) {
                        image.onload = cacheImage;
                        if (image.complete || image.readyState === 4) {
                            cacheImage(image);
                        }
                    }
                }
            }
        }
    };
    w.addEventListener('resize', w.picturefill, false);
    w.removeEventListener('resize', w.picturefillOrig, false);

}( this ));
<commit_msg>Don't do all the canvas stuff if we already have the image cached<commit_after>/*! Pickyfill - Offline caching for picturefill responsive image polyfill. Author: Rich Trott | Copyright: Regents of University of California, 2012 | License: MIT */

(function( w ) {
    "use strict";

    var localStorage = w.localStorage,
        applicationCache = w.applicationCache,
        image,
        dataUri,
        pf_index_string,
        pf_index,
        canvasTest = document.createElement('canvas');

    // Don't run any of this stuff if application cache, localStorage or canvas are not available.
    if ( (! applicationCache) || (! localStorage) || (!(canvasTest.getContext && canvasTest.getContext('2d'))) ) {
            return;
    }

    pf_index_string = localStorage.getItem('pf_index') || '{}';
    pf_index = JSON.parse(pf_index_string);

    // We'll use this to clear the pickyfill cache when appcache updates.
    var clearCache = function () {
        localStorage.removeItem('pf_index');
        for (var prop in pf_index) {
            localStorage.removeItem(prop);
        }
    };

    // Unfortunately, reloading is the most reliable way to get stuff into the
    //  pickyfill cache. If you wait for the user to reload, they may be offline
    //  at that time. If we just had an updateready event, chances are very good
    //  that they are still online. Another possibility is to just try to reload
    //  the images that are currently shown, but there's no guarantee that those
    //  images are in the new page or that the current page isn't missing important
    //  images that will display in the new page and need to be cached.
    var refreshCache = function () {
        clearCache();
        w.location.reload();
    };

    // If appcache updates, refresh the pickyfill cache to get new items.
    // If appcache is obsolete, clear the pickyfill cache.
    // Appcache == IE10 or later == no need to worry about attachEvent (IE8 and earlier)
    // Anything that has appcache is going to have addEventListener.
    applicationCache.addEventListener('updateready', refreshCache, false);
    applicationCache.addEventListener('obsolete', clearCache, false);

    // If the event has already fired and we missed it, clear/refresh the pickyfill cache.
    if(applicationCache.status === applicationCache.UPDATEREADY) {
        refreshCache();
    }

    if (applicationCache.status === applicationCache.OBSOLETE) {
        clearCache();
    }

    var srcFromCacheRan = false;
    var srcFromCache = function ( ps ) {
        var sources, src, newSrc;

        // Loop the pictures
        for( var i = 0, il = ps.length; i < il; i++ ){
            if( ps[ i ].getAttribute( "data-picture" ) !== null ){

                sources = ps[ i ].getElementsByTagName( "div" );
                // See which ones are cached in localStorage. Use the cached value.
                for( var j = 0, jl = sources.length; j < jl; j++ ){
                    if ((src = sources[j].getAttribute( "data-src" )) !== null ) {
                        if ( pf_index.hasOwnProperty('pf_s_' + src)) {
                            newSrc = localStorage.getItem('pf_s_' + src);
                            if (newSrc !== null) {
                                sources[j].setAttribute('data-src', localStorage.getItem('pf_s_' + src));
                            }
                        }
                    }
                }
            }
        }
    };

    var cacheImage = function ( param ) {
        var canvas,
            ctx,
            imageSrc,
            me;

        me = param.target ? param.target : param;

        imageSrc = me.getAttribute("src");
        if ((imageSrc === null) || (imageSrc.length === 0) ||
            (imageSrc.substr(0,5) === "data:") || (pf_index.hasOwnProperty('pf_s_' + imageSrc))) {
            return;
        }

        canvas = w.document.createElement("canvas");
        canvas.width = me.width;
        canvas.height = me.height;

        ctx = canvas.getContext("2d");
        ctx.drawImage(me, 0, 0);
        try {
            dataUri = canvas.toDataURL();
        } catch (e) {
            // TODO: Improve error handling here. For now, if canvas.toDataURL()
            //   throws an exception, don't cache the image and move on.
            return;
        }

        // Do not cache if the resulting cache item will take more than 128Kb.
        if (dataUri.length > 131072) {
            return;
        }

        pf_index["pf_s_"+imageSrc] = 1;

        try {
            localStorage.setItem("pf_s_"+imageSrc, dataUri);
            localStorage.setItem("pf_index", JSON.stringify(pf_index));
        } catch (e) {
            // Caching failed. Remove item from index object so next cached item
            //   doesn't wrongly indicate this item was successfully cached.
            delete pf_index["pf_s_"+imageSrc];
        }
    };

    // Exit here if uncached. If updateready fires later, it will reload,
    //   and status will not be uncached on the that load.
    if (applicationCache.status === applicationCache.UNCACHED) {
        return;
    }
    w.picturefillOrig = w.picturefill;
    w.picturefill = function () {
        var ps = w.document.getElementsByTagName( "div" );

        if (! srcFromCacheRan ) {
            srcFromCacheRan = true;
            srcFromCache( ps );
        }

        w.picturefillOrig();

        // Loop the pictures
        for( var i = 0, il = ps.length; i < il; i++ ){
            if( ps[ i ].getAttribute( "data-picture" ) !== null ){
                image = ps[ i ].getElementsByTagName( "img" )[0];
                if (image) {
                    if (image.getAttribute("src") !== null) {
                        image.onload = cacheImage;
                        if (image.complete || image.readyState === 4) {
                            cacheImage(image);
                        }
                    }
                }
            }
        }
    };
    w.addEventListener('resize', w.picturefill, false);
    w.removeEventListener('resize', w.picturefillOrig, false);

}( this ));
<|endoftext|>


<commit_before>(function () {
  angular
    .module("ng-geocoder")
    .directive("ngGeocoder", ngGeocoder);

  ngGeocoder.$inject = ["$timeout", "$templateCache", "ngGeocoderService"];

  function ngGeocoder ($timeout, $templateCache, ngGeocoderService) {
    var DEFAULT_TEMPLATE_URL = "/ng-geocoder/ng-geocoder.html";

    $templateCache.put(DEFAULT_TEMPLATE_URL, INCLUDE_FILE("ng-geocoder.html"));

    var directive = {
      "restrict": "AE",
      "scope": {
        "result": "=ngGeocoder",
        "inputId": "=",
        "wait": "=",
        "minLength": "=",
        "inputClass": "@",
        "placeholder": "@",
        "textSearching": "@",
        "textNoResults": "@",
        "maxHeight": "@"
      },
      "link": link,
      "templateUrl": geocoderTemplate
    };

    return directive;

    function link (scope, element, attributes) {
      var waitTimeout;

      var $el      = element[0];
      var form     = $el.closest("form");
      var input    = $el.querySelector(".ng-geocoder__input");
      var dropdown = $el.querySelector(".ng-geocoder__list");
      var placeId  = attributes.placeId;

      scope.index   = 0;
      scope.query   = "";
      scope.results = [];

      scope.selectItem   = selectItem;
      scope.displayList  = displayList;
      scope.inputKeydown = inputKeydown;

      if (form) form.addEventListener("keydown", formKeydown);

      input.addEventListener("blur",           inputBlur);
      input.addEventListener("focus",          inputFocus);
      input.addEventListener("input",          inputChanged);
      input.addEventListener("keydown",        inputKeydown);
      input.addEventListener("compositionend", inputChanged);

      if (placeId) {
        ngGeocoderService.geocodeById(placeId)
          .then(geocodedWithPlaceId);
      }

      function formKeydown (event) {
        var targetIsGeocoderInput = event.target.classList.contains("ng-geocoder__input");

        if (event.keyCode === 13 && targetIsGeocoderInput) {
          event.preventDefault();
          event.stopPropagation();
        }
      }

      function inputBlur (event) {
        $timeout(function () {
          scope.showList = false;
        }, 100);
      }

      function inputFocus (event) {
        scope.$apply(function () {
          scope.showList = true;
        });
      }

      function inputChanged (event) {
        var length = scope.query.length;

        if (length < scope.minLength) return;

        if (waitTimeout) { $timeout.cancel(waitTimeout); }

        waitTimeout = $timeout(search, scope.wait || 500);
      }

      function inputKeydown (event) {
        if (!event || !event.keyCode) return;

        var escPressed    = event.keyCode === 27;
        var enterPressed  = event.keyCode === 13;
        var arrowsPressed = event.keyCode === 38 || event.keyCode === 40;

        if (enterPressed || arrowsPressed || escPressed) {
          if (escPressed)    hideList();
          if (enterPressed)  selectItem(scope.index);
          if (arrowsPressed) handleArrowKeys(event.keyCode);

          event.preventDefault();
          event.stopPropagation();

          return false;
        }
      }

      function search () {
        scope.$apply(function () {
          scope.results     = [];
          scope.isEmpty     = false;
          scope.isSearching = true;
        });

        return ngGeocoderService.geocodeByQuery(scope.query, attributes.region)
          .then(geocodeSuccess);
      }

      function geocodeSuccess (results) {
        scope.index       = 0;
        scope.isEmpty     = results.length === 0;
        scope.results     = results;
        scope.showList    = true;
        scope.isSearching = false;
      }

      function geocodedWithPlaceId (results) {
        var result = results[0];

        if (result) {
          scope.query    = result.formatted_address;
          scope.result   = result;

          scope.showList = false;
        }
      }

      function displayList () {
        return scope.query.length >= scope.minLength && scope.showList;
      }

      function hideList () {
        input.blur();

        scope.$apply(function () {
          scope.showList = false;
        });
      }

      function selectItem (index) {
        $timeout(function () {
          scope.index    = index;
          scope.result   = scope.results[index];
          scope.query    = scope.result.formatted_address;

          scope.showList = false;
        }, 0);
      }

      function handleArrowKeys(key) {
        var index         = scope.index;
        var resultsLength = scope.results.length;

        var arrowUp   = key === 38;
        var arrowDown = key === 40;

        if (arrowUp && (index - 1 >= 0)) {
          index--;
        }

        if (arrowDown && (index + 1 < resultsLength)) {
          index++;
        }

        scope.$apply(function () {
          scope.index = index;
        });

        if (arrowUp   && scope.results.length) fixArrowUpScroll();
        if (arrowDown && scope.results.length) fixArrowDownScroll();
      }

      function fixArrowUpScroll() {
        var rowTop = dropdownRowTop();
        var height = dropdownRowOffsetHeight(getCurrentRow());

        if (rowTop < height) {
          dropdownScrollTo(rowTop - height);
        }
      }

      function fixArrowDownScroll () {
        var row = getCurrentRow();

        if (getDropdownHeight() < row.getBoundingClientRect().bottom) {
          dropdownScrollTo(dropdownRowOffsetHeight(row));
        }
      }

      function getCurrentRow () {
        return $el.querySelector(".ng-geocoder__list__item--focus");
      }

      function dropdownRowTop () {
        return getCurrentRow().getBoundingClientRect().top - (dropdown.getBoundingClientRect().top + parseInt(getComputedStyle(dropdown).paddingTop, 10));
      }

      function dropdownScrollTo (offset) {
        dropdown.scrollTop = dropdown.scrollTop + offset;
      }

      function getDropdownHeight () {
        return dropdown.getBoundingClientRect().top + parseInt(getComputedStyle(dropdown).maxHeight, 10);
      }

      function dropdownRowOffsetHeight (row) {
        var css = getComputedStyle(row);

        return row.offsetHeight + parseInt(css.marginTop, 10) + parseInt(css.marginBottom, 10);
      }
    }

    function geocoderTemplate (element, attributes) {
      return attributes.templateUrl || DEFAULT_TEMPLATE_URL
    }
  }
})();
<commit_msg>Change place Id geocoding on directive init<commit_after>(function () {
  angular
    .module("ng-geocoder")
    .directive("ngGeocoder", ngGeocoder);

  ngGeocoder.$inject = ["$timeout", "$templateCache", "ngGeocoderService"];

  function ngGeocoder ($timeout, $templateCache, ngGeocoderService) {
    var DEFAULT_TEMPLATE_URL = "/ng-geocoder/ng-geocoder.html";

    $templateCache.put(DEFAULT_TEMPLATE_URL, INCLUDE_FILE("ng-geocoder.html"));

    var directive = {
      "restrict": "AE",
      "scope": {
        "result": "=ngGeocoder",
        "wait": "=",
        "inputId": "=",
        "placeId": "=",
        "minLength": "=",
        "maxHeight": "@",
        "inputClass": "@",
        "placeholder": "@",
        "textSearching": "@",
        "textNoResults": "@"
      },
      "link": link,
      "templateUrl": geocoderTemplate
    };

    return directive;

    function link (scope, element, attributes) {
      var waitTimeout;

      var $el      = element[0];
      var form     = $el.closest("form");
      var input    = $el.querySelector(".ng-geocoder__input");
      var dropdown = $el.querySelector(".ng-geocoder__list");

      scope.index   = 0;
      scope.query   = "";
      scope.results = [];

      scope.selectItem   = selectItem;
      scope.displayList  = displayList;
      scope.inputKeydown = inputKeydown;

      scope.$watch("placeId", placeIdChanged);

      if (form) form.addEventListener("keydown", formKeydown);

      input.addEventListener("blur",           inputBlur);
      input.addEventListener("focus",          inputFocus);
      input.addEventListener("input",          inputChanged);
      input.addEventListener("keydown",        inputKeydown);
      input.addEventListener("compositionend", inputChanged);

      function formKeydown (event) {
        var targetIsGeocoderInput = event.target.classList.contains("ng-geocoder__input");

        if (event.keyCode === 13 && targetIsGeocoderInput) {
          event.preventDefault();
          event.stopPropagation();
        }
      }

      function inputBlur (event) {
        $timeout(function () {
          scope.showList = false;
        }, 100);
      }

      function inputFocus (event) {
        scope.$apply(function () {
          scope.showList = true;
        });
      }

      function inputChanged (event) {
        var length = scope.query.length;

        if (length < scope.minLength) return;

        if (waitTimeout) { $timeout.cancel(waitTimeout); }

        waitTimeout = $timeout(search, scope.wait || 500);
      }

      function inputKeydown (event) {
        if (!event || !event.keyCode) return;

        var escPressed    = event.keyCode === 27;
        var enterPressed  = event.keyCode === 13;
        var arrowsPressed = event.keyCode === 38 || event.keyCode === 40;

        if (enterPressed || arrowsPressed || escPressed) {
          if (escPressed)    hideList();
          if (enterPressed)  selectItem(scope.index);
          if (arrowsPressed) handleArrowKeys(event.keyCode);

          event.preventDefault();
          event.stopPropagation();

          return false;
        }
      }

      function search () {
        scope.$apply(function () {
          scope.results     = [];
          scope.isEmpty     = false;
          scope.isSearching = true;
        });

        return ngGeocoderService.geocodeByQuery(scope.query, attributes.region)
          .then(geocodeSuccess);
      }

      function geocodeSuccess (results) {
        scope.index       = 0;
        scope.isEmpty     = results.length === 0;
        scope.results     = results;
        scope.showList    = true;
        scope.isSearching = false;
      }

      function geocodedWithPlaceId (results) {
        var result = results[0];

        if (result) {
          scope.query    = result.formatted_address;
          scope.result   = result;

          scope.showList = false;
        }
      }

      function displayList () {
        return scope.query.length >= scope.minLength && scope.showList;
      }

      function hideList () {
        input.blur();

        scope.$apply(function () {
          scope.showList = false;
        });
      }

      function selectItem (index) {
        $timeout(function () {
          scope.index    = index;
          scope.result   = scope.results[index];
          scope.query    = scope.result.formatted_address;

          scope.showList = false;
        }, 0);
      }

      function handleArrowKeys(key) {
        var index         = scope.index;
        var resultsLength = scope.results.length;

        var arrowUp   = key === 38;
        var arrowDown = key === 40;

        if (arrowUp && (index - 1 >= 0)) {
          index--;
        }

        if (arrowDown && (index + 1 < resultsLength)) {
          index++;
        }

        scope.$apply(function () {
          scope.index = index;
        });

        if (arrowUp   && scope.results.length) fixArrowUpScroll();
        if (arrowDown && scope.results.length) fixArrowDownScroll();
      }

      function fixArrowUpScroll() {
        var rowTop = dropdownRowTop();
        var height = dropdownRowOffsetHeight(getCurrentRow());

        if (rowTop < height) {
          dropdownScrollTo(rowTop - height);
        }
      }

      function fixArrowDownScroll () {
        var row = getCurrentRow();

        if (getDropdownHeight() < row.getBoundingClientRect().bottom) {
          dropdownScrollTo(dropdownRowOffsetHeight(row));
        }
      }

      function getCurrentRow () {
        return $el.querySelector(".ng-geocoder__list__item--focus");
      }

      function dropdownRowTop () {
        return getCurrentRow().getBoundingClientRect().top - (dropdown.getBoundingClientRect().top + parseInt(getComputedStyle(dropdown).paddingTop, 10));
      }

      function dropdownScrollTo (offset) {
        dropdown.scrollTop = dropdown.scrollTop + offset;
      }

      function getDropdownHeight () {
        return dropdown.getBoundingClientRect().top + parseInt(getComputedStyle(dropdown).maxHeight, 10);
      }

      function dropdownRowOffsetHeight (row) {
        var css = getComputedStyle(row);

        return row.offsetHeight + parseInt(css.marginTop, 10) + parseInt(css.marginBottom, 10);
      }

      function placeIdChanged (placeId) {
        if (placeId) {
          return ngGeocoderService.geocodeById(placeId)
            .then(geocodedWithPlaceId);
        }
      }
    }

    function geocoderTemplate (element, attributes) {
      return attributes.templateUrl || DEFAULT_TEMPLATE_URL
    }
  }
})();
<|endoftext|>


<commit_before>import React from 'react';
import { SortableContainer, SortableElement, SortableHandle, arrayMove } from 'react-sortable-hoc';

class PlacesList extends React.Component {
  constructor(props) {
    super(props);
  }

  onEditDidClick(index) {
    this.props.handleEdit(index);
  }

  onSortEnd = ({ oldIndex, newIndex }) => {
    const places = arrayMove(this.props.places, oldIndex, newIndex);
    places.forEach((place, index) => place.sort = index);
    this.props.updateSort(places);
  }

  render() {
    if (!this.props.places) return null;
    this.props.places.forEach((place, index) => {
      if (!place.address || !place.address.lat || !place.address.lng) {
        this.props.places.splice(index, 1);
      }
    });

    const DragHandle = SortableHandle(() =>
      );

    const SortableItem = SortableElement(({ value }) => (

        <DragHandle />

          { value.place.title.length > 20
            ? value.place.title.substring(0, 20).trim() + '...' : value.place.title }

          { value.place.address.name
              ? value.place.address.name.length > 35
                ? value.place.address.name.substring(0, 35).trim() + '...'
                : value.place.address.name
            : (value.place.address.lat !== null && value.place.address.lng !== null)
              ? parseFloat(value.place.address.lat.toFixed(10)) + ', ' +  parseFloat(value.place.address.lng.toFixed(10))
              : '' }

           this.onEditDidClick(value.index) }>
            Edit

         this.props.copyToClipboard(value.place.id)}
          onMouseOut={() => this.props.onHoverOut(value.place.id)}>
          <span className="tooltiptext" id={`tool-tip-text--${value.place.id}`}>Copy to clipboard

         this.props.handleDelete(value.index) }
          src='assets/img/cross.png' />

    ));

    const SortableList = SortableContainer(({items}) => {
      var manualSort = function(a, b) {
          if (a.sort < 0 || b.sort < 0) return 1;
          if(a.sort  b.sort)
              return 1;

          return 0;
      };

      let list = items.sort(manualSort).map((value, index) => (
        <SortableItem
          key={ index }
          index={ index }
          value={{ place: value, index }} />
      ));
      return
{ list }
;
    });

    return this.props.places.length ? (
      <SortableList
        lockAxis='y'
        useDragHandle={ true }
        onSortEnd={ this.onSortEnd }
        items={ this.props.places }/>
    ) : (

    );
  }
}

export default PlacesList;
<commit_msg>copy query string<commit_after>import React from 'react';
import { SortableContainer, SortableElement, SortableHandle, arrayMove } from 'react-sortable-hoc';

class PlacesList extends React.Component {
  constructor(props) {
    super(props);
  }

  onEditDidClick(index) {
    this.props.handleEdit(index);
  }

  onSortEnd = ({ oldIndex, newIndex }) => {
    const places = arrayMove(this.props.places, oldIndex, newIndex);
    places.forEach((place, index) => place.sort = index);
    this.props.updateSort(places);
  }

  render() {
    if (!this.props.places) return null;
    this.props.places.forEach((place, index) => {
      if (!place.address || !place.address.lat || !place.address.lng) {
        this.props.places.splice(index, 1);
      }
    });

    const DragHandle = SortableHandle(() =>
      );

    const SortableItem = SortableElement(({ value }) => (

        <DragHandle />

          { value.place.title.length > 20
            ? value.place.title.substring(0, 20).trim() + '...' : value.place.title }

          { value.place.address.name
              ? value.place.address.name.length > 35
                ? value.place.address.name.substring(0, 35).trim() + '...'
                : value.place.address.name
            : (value.place.address.lat !== null && value.place.address.lng !== null)
              ? parseFloat(value.place.address.lat.toFixed(10)) + ', ' +  parseFloat(value.place.address.lng.toFixed(10))
              : '' }

           this.onEditDidClick(value.index) }>
            Edit

         this.props.copyToClipboard(value.place.id)}
          onMouseOut={() => this.props.onHoverOut(value.place.id)}>
          <span className="tooltiptext" id={`tool-tip-text--${value.place.id}`}>Copy Query String

         this.props.handleDelete(value.index) }
          src='assets/img/cross.png' />

    ));

    const SortableList = SortableContainer(({items}) => {
      var manualSort = function(a, b) {
          if (a.sort < 0 || b.sort < 0) return 1;
          if(a.sort  b.sort)
              return 1;

          return 0;
      };

      let list = items.sort(manualSort).map((value, index) => (
        <SortableItem
          key={ index }
          index={ index }
          value={{ place: value, index }} />
      ));
      return
{ list }
;
    });

    return this.props.places.length ? (
      <SortableList
        lockAxis='y'
        useDragHandle={ true }
        onSortEnd={ this.onSortEnd }
        items={ this.props.places }/>
    ) : (

    );
  }
}

export default PlacesList;
<|endoftext|>


<commit_before>import * as docCookies from '../../util/docCookies.js';

/* global BookReader */

/** @deprecated Exposed for backward compatibility */
BookReader.docCookies = docCookies;

/**
 * Plugin to remember the current page number in a cookie
 */
jQuery.extend(BookReader.defaultOptions, {
  enablePageResume: true,
  /** @type {string|null} eg '/', '/details/id' */
  resumeCookiePath: null,
});

/** @override */
BookReader.prototype.init = (function(super_) {
  return function() {
    super_.call(this);
    if (this.options.enablePageResume) {
      this.bind(BookReader.eventNames.fragmentChange, () => {
        const params = this.paramsFromCurrent();
        this.updateResumeValue(params.index);
      });
    }
  };
})(BookReader.prototype.init);

/**
 * Get's the page resume value, for remembering reader's page
 * Can be overriden for different implementation
 *
 * @return {number|null}
 */
BookReader.prototype.getResumeValue = function() {
  const val = BookReader.docCookies.getItem('br-resume');
  if (val !== null) return parseInt(val);
  else return null;
}

/**
 * Set's the page resume value, for remembering reader's page
 * Can be overriden for different implementation
 *
 * @param {Number} index leaf index
 * @param {string} [cookieName]
 */
BookReader.prototype.updateResumeValue = function(index, cookieName) {
  const ttl = new Date(+new Date + 12096e5); // 2 weeks
  const path = this.options.resumeCookiePath || window.location.pathname;
  BookReader.docCookies.setItem(cookieName || 'br-resume', index, ttl, path, null, false);
}
<commit_msg>Use browser's path for br-resume coookie<commit_after>import * as docCookies from '../../util/docCookies.js';

/* global BookReader */

/** @deprecated Exposed for backward compatibility */
BookReader.docCookies = docCookies;

/**
 * Plugin to remember the current page number in a cookie
 */
jQuery.extend(BookReader.defaultOptions, {
  enablePageResume: true,
  /** @type {string|null} eg '/', '/details/id' */
  resumeCookiePath: null,
});

/** @override */
BookReader.prototype.init = (function(super_) {
  return function() {
    super_.call(this);
    if (this.options.enablePageResume) {
      this.bind(BookReader.eventNames.fragmentChange, () => {
        const params = this.paramsFromCurrent();
        this.updateResumeValue(params.index);
      });
    }
  };
})(BookReader.prototype.init);

/**
 * Get's the page resume value, for remembering reader's page
 * Can be overriden for different implementation
 *
 * @return {number|null}
 */
BookReader.prototype.getResumeValue = function() {
  const val = BookReader.docCookies.getItem('br-resume');
  if (val !== null) return parseInt(val);
  else return null;
}

/**
 * Set's the page resume value, for remembering reader's page
 * Can be overriden for different implementation
 *
 * @param {Number} index leaf index
 * @param {string} [cookieName]
 */
BookReader.prototype.updateResumeValue = function(index, cookieName) {
  const ttl = new Date(+new Date + 12096e5); // 2 weeks
  // For multiple files in item, leave resumeCookiePath blank
  // It's likely we can now remove resumeCookiePath by new .match()
  // below using pathname up to /page/... or /mode/...
  const path = this.options.resumeCookiePath
    || window.location.pathname.match('.+?(?=/page/|/mode/|$)')[0];
  BookReader.docCookies.setItem(cookieName || 'br-resume', index, ttl, path, null, false);
}
<|endoftext|>