<commit_before>/*
  Format
    - People are listed in the order they're mentioned in Genesis.
    - Each number in a 'spouses' or 'children' array is the index of another person.
    - If a property is omitted, it is unknown.
    - Every data point present for each person cites a scripture reference under "references".

  people.json
    - This file (people.js) is a concise version of
    people.json and is used to generate people.json.
    - The people.json file adds a "father" and "mother" property to
    every person mentioned under a "children" property in this file.
    - So these are all the properties which can appear in a person object in people.json:
      - names: array of strings
      - title: string
      - gender: string
      - spouses: array of person indices
      - children: array of person indices
      - father: person index
      - mother: person index
      - ageOfFatherAtBirth: integer
      - yearsLived: integer
      - otherChildren: boolean
      - references: object
*/

var peopleData = {
  people: {
    adam: {
      names: ['Adam', 'Man'],
      gender: 'male',
      spouses: ['eve'],
      children: ['cain','abel','seth'],
      yearsLived: 930,
      otherChildren: true,
      references: {
        names: ['Gen 2:23', 'Gen 2:20'],
        gender: 'Gen 3:20',
        spouses: ['Gen 3:20'],
        children: ['Gen 4:1', 'Gen 4:2', 'Gen 4:25'],
        yearsLived: 'Gen 5:5',
        otherChildren: 'Gen 5:4'
      }
    },
    eve: {
      names: ['Eve', 'Woman'],
      gender: 'female',
      spouses: ['adam'],
      children: ['cain','abel','seth'],
      otherChildren: true,
      references: {
        names: ['Gen 2:23', 'Gen 3:20'],
        gender: 'Gen 3:20',
        spouses: ['Gen 3:20'],
        children: ['Gen 4:1', 'Gen 4:2', 'Gen 4:25'],
        otherChildren: 'Gen 5:4'
      }
    },
    cain: {
      names: ['Cain'],
      gender: 'male',
      spouses: ['wife_of_cain'],
      children: ['enoch'],
      references: {
        names: ['Gen 4:1'],
        gender: 'Gen 4:1',
        spouses: ['Gen 4:17'],
        children: ['Gen 4:17']
      }
    },
    wife_of_cain: {
      title: 'Cain\'s wife',
      gender: 'female',
      spouses: ['cain'],
      children: ['enoch'],
      references: {
        title: 'Gen 4:17',
        gender: 'Gen 4:17',
        spouses: ['Gen 4:17'],
        children: ['Gen 4:17']
      }
    },
    abel: {
      names: ['Abel'],
      gender: 'male',
      children: [],
      references: {
        names: ['Gen 4:2'],
        gender: 'Gen 4:2',
        children: []
      }
    },
    enoch: {
      names: ['Enoch'],
      gender: 'male',
      children: ['irad'],
      references: {
        names: ['Gen 4:17'],
        gender: 'Gen 4:17',
        children: ['Gen 4:18']
      }
    },
    irad: {
      names: ['Irad'],
      gender: 'male',
      children: ['mehujael'],
      references: {
        names: ['Gen 4:18'],
        gender: 'Gen 4:18',
        children: ['Gen 4:18']
      }
    },
    mehujael: {
      names: ['Mehujael'],
      gender: 'male',
      children: ['methushael'],
      references: {
        names: ['Gen 4:18'],
        gender: 'Gen 4:18',
        children: ['Gen 4:18']
      }
    },
    methushael: {
      names: ['Methushael'],
      gender: 'male',
      children: ['lamech'],
      references: {
        names: ['Gen 4:18'],
        gender: 'Gen 4:18',
        children: ['Gen 4:18']
      }
    },
    lamech: {
      names: ['Lamech'],
      gender: 'male',
      spouses: ['adah','zillah'],
      children: ['jabal','jubal','tubal','naamah'],
      references: {
        names: ['Gen 4:18'],
        gender: 'Gen 4:18',
        spouses: ['Gen 4:19', 'Gen 4:19'],
        children: ['Gen 4:20','Gen 4:21','Gen 4:22','Gen 4:22']
      }
    },
    adah: {
      names: ['Adah'],
      gender: 'female',
      spouses: ['lamech'],
      children: ['jabal','jubal'],
      references: {
        names: ['Gen 4:19'],
        gender: 'Gen 4:19',
        spouses: ['Gen 4:19'],
        children: ['Gen 4:20','Gen 4:20-21']
      }
    },
    zillah: {
      names: ['Zillah'],
      gender: 'female',
      spouses: ['lamech'],
      children: ['tubal','naamah'],
      references: {
        names: ['Gen 4:19'],
        gender: 'Gen 4:19',
        spouses: ['Gen 4:19'],
        children: ['Gen 4:22','Gen 4:22']
      }
    },
    jabal: {
      names: ['Jabal'],
      gender: 'male',
      references: {
        names: ['Gen 4:20'],
        gender: 'Gen 4:20'
      }
    },
    jubal: {
      names: ['Jubal'],
      gender: 'male',
      references: {
        names: ['Gen 4:21'],
        gender: 'Gen 4:21'
      }
    },
    tubal: {
      names: ['Tubal-cain'],
      gender: 'male',
      references: {
        names: ['Gen 4:22'],
        gender: 'Gen 4:22'
      }
    },
    naamah: {
      names: ['Naamah'],
      gender: 'female',
      references: {
        names: ['Gen 4:22'],
        gender: 'Gen 4:22'
      }
    },
    seth: {
      names: ['Seth'],
      gender: 'male',
      children: ['enosh'],
      ageOfFatherAtBirth: 130,
      otherChildren: true,
      yearsLived: 912,
      references: {
        names: ['Gen 4:25'],
        gender: 'Gen 4:25',
        children: ['Gen 4:26'],
        ageOfFatherAtBirth: 'Gen 5:3',
        otherChildren: 'Gen 5:7',
        yearsLived: 'Gen 5:8'
      }
    },
    enosh: {
      names: ['Enosh'],
      gender: 'male',
      children: ['kenan'],
      ageOfFatherAtBirth: 105,
      otherChildren: true,
      yearsLived: 905,
      references: {
        names: ['Gen 4:26'],
        gender: 'Gen 4:26',
        children: ['Gen 5:9'],
        ageOfFatherAtBirth: 'Gen 5:6',
        otherChildren: 'Gen 5:10',
        yearsLived: 'Gen 5:11'
      }
    },
    kenan: {
      names: ['Kenan'],
      gender: 'male',
      children: ['mahalalel'],
      ageOfFatherAtBirth: 90,
      otherChildren: true,
      yearsLived: 910,
      references: {
        names: ['Gen 5:9'],
        gender: 'Gen 5:12',
        children: ['Gen 5:12'],
        ageOfFatherAtBirth: 'Gen 5:9',
        otherChildren: 'Gen 5:13',
        yearsLived: 'Gen 5:14'
      }
    },
    mahalalel: {
      names: ['Mahalalel'],
      gender: 'male',
      children: ['jared'],
      ageOfFatherAtBirth: 70,
      otherChildren: true,
      yearsLived: 895,
      references: {
        names: ['Gen 5:12'],
        gender: 'Gen 5:15',
        children: ['Gen 5:15'],
        ageOfFatherAtBirth: 'Gen 5:12',
        otherChildren: 'Gen 5:16',
        yearsLived: 'Gen 5:17'
      }
    },
    jared: {
      names: ['Jared'],
      gender: 'male',
      children: ['enoch2'],
      ageOfFatherAtBirth: 65,
      otherChildren: true,
      yearsLived: 962,
      references: {
        names: ['Gen 5:15'],
        gender: 'Gen 5:18',
        children: ['Gen 5:18'],
        ageOfFatherAtBirth: 'Gen 5:15',
        otherChildren: 'Gen 5:19',
        yearsLived: 'Gen 5:20'
      }
    },
    enoch2: {
      names: ['Enoch'],
      gender: 'male',
      children: ['methuselah'],
      ageOfFatherAtBirth: 62,
      otherChildren: true,
      yearsLived: 365,
      references: {
        names: ['Gen 5:18'],
        gender: 'Gen 5:21',
        children: ['Gen 5:21'],
        ageOfFatherAtBirth: 'Gen 5:18',
        otherChildren: 'Gen 5:22',
        yearsLived: 'Gen 5:23'
      }
    },
    methuselah: {
      names: ['Methuselah'],
      gender: 'male',
      children: ['lamech2'],
      ageOfFatherAtBirth: 65,
      otherChildren: true,
      yearsLived: 969,
      references: {
        names: ['Gen 5:21'],
        gender: 'Gen 5:25',
        children: ['Gen 5:25'],
        ageOfFatherAtBirth: 'Gen 5:21',
        otherChildren: 'Gen 5:26',
        yearsLived: 'Gen 5:27'
      }
    },
    lamech2: {
      names: ['Lamech'],
      gender: 'male',
      children: ['noah'],
      ageOfFatherAtBirth: 187,
      otherChildren: true,
      yearsLived: 777,
      references: {
        names: ['Gen 5:25'],
        gender: 'Gen 5:28',
        children: ['Gen 5:28-29'],
        ageOfFatherAtBirth: 'Gen 5:25',
        otherChildren: 'Gen 5:30',
        yearsLived: 'Gen 5:31'
      }
    },
    noah: {
      names: ['Noah'],
      gender: 'male',
      spouses: ['wife_of_noah'],
      children: ['shem', 'ham', 'japheth'],
      ageOfFatherAtBirth: 182,
      references: {
        names: ['Gen 5:28-29'],
        gender: 'Gen 5:28-29',
        spouses: ['Gen 6:18'],
        children: ['Gen 5:32', 'Gen 5:32', 'Gen 5:32'],
        ageOfFatherAtBirth: 'Gen 5:28-29'
      }
    },
    wife_of_noah: {
      title: 'Noah\'s wife',
      gender: 'female',
      spouses: ['noah'],
      children: ['shem', 'ham', 'japheth'],
      references: {
        title: 'Gen 6:18',
        gender: 'Gen 6:18',
        spouses: ['Gen 6:18'],
        children: ['Gen 5:32', 'Gen 5:32', 'Gen 5:32']
      }
    },
    shem: {
      names: ['Shem'],
      gender: 'male',
      spouses: ['wife_of_shem'],
      references: {
        names: ['Gen 5:32'],
        gender: 'Gen 6:10',
        spouses: ['Gen 6:18']
      }
    },
    ham: {
      names: ['Ham'],
      gender: 'male',
      spouses: ['wife_of_ham'],
      references: {
        names: ['Gen 5:32'],
        gender: 'Gen 6:10',
        spouses: ['Gen 6:18']
      }
    },
    japheth: {
      names: ['Japheth'],
      gender: 'male',
      spouses: ['wife_of_japheth'],
      references: {
        names: ['Gen 5:32'],
        gender: 'Gen 6:10',
        spouses: ['Gen 6:18']
      }
    },
    wife_of_shem: {
      title: 'Shem\'s wife',
      gender: 'female',
      spouses: ['shem'],
      references: {
        title: 'Gen 6:18',
        gender: 'Gen 6:18',
        spouses: ['Gen 6:18']
      }
    },
    wife_of_ham: {
      title: 'Ham\'s wife',
      gender: 'female',
      spouses: ['ham'],
      references: {
        title: 'Gen 6:18',
        gender: 'Gen 6:18',
        spouses: ['Gen 6:18']
      }
    },
    wife_of_japheth: {
      title: 'Japheth\'s wife',
      gender: 'female',
      spouses: ['japheth'],
      references: {
        title: 'Gen 6:18',
        gender: 'Gen 6:18',
        spouses: ['Gen 6:18']
      }
    }
  }
};<commit_msg>add noah's age, update json<commit_after>/*
  Format
    - People are listed in the order they're mentioned in Genesis.
    - Each number in a 'spouses' or 'children' array is the index of another person.
    - If a property is omitted, it is unknown.
    - Every data point present for each person cites a scripture reference under "references".

  people.json
    - This file (people.js) is a concise version of
    people.json and is used to generate people.json.
    - The people.json file adds a "father" and "mother" property to
    every person mentioned under a "children" property in this file.
    - So these are all the properties which can appear in a person object in people.json:
      - names: array of strings
      - title: string
      - gender: string
      - spouses: array of person indices
      - children: array of person indices
      - father: person index
      - mother: person index
      - ageOfFatherAtBirth: integer
      - yearsLived: integer
      - otherChildren: boolean
      - references: object
*/

var peopleData = {
  people: {
    adam: {
      names: ['Adam', 'Man'],
      gender: 'male',
      spouses: ['eve'],
      children: ['cain','abel','seth'],
      yearsLived: 930,
      otherChildren: true,
      references: {
        names: ['Gen 2:23', 'Gen 2:20'],
        gender: 'Gen 3:20',
        spouses: ['Gen 3:20'],
        children: ['Gen 4:1', 'Gen 4:2', 'Gen 4:25'],
        yearsLived: 'Gen 5:5',
        otherChildren: 'Gen 5:4'
      }
    },
    eve: {
      names: ['Eve', 'Woman'],
      gender: 'female',
      spouses: ['adam'],
      children: ['cain','abel','seth'],
      otherChildren: true,
      references: {
        names: ['Gen 2:23', 'Gen 3:20'],
        gender: 'Gen 3:20',
        spouses: ['Gen 3:20'],
        children: ['Gen 4:1', 'Gen 4:2', 'Gen 4:25'],
        otherChildren: 'Gen 5:4'
      }
    },
    cain: {
      names: ['Cain'],
      gender: 'male',
      spouses: ['wife_of_cain'],
      children: ['enoch'],
      references: {
        names: ['Gen 4:1'],
        gender: 'Gen 4:1',
        spouses: ['Gen 4:17'],
        children: ['Gen 4:17']
      }
    },
    wife_of_cain: {
      title: 'Cain\'s wife',
      gender: 'female',
      spouses: ['cain'],
      children: ['enoch'],
      references: {
        title: 'Gen 4:17',
        gender: 'Gen 4:17',
        spouses: ['Gen 4:17'],
        children: ['Gen 4:17']
      }
    },
    abel: {
      names: ['Abel'],
      gender: 'male',
      children: [],
      references: {
        names: ['Gen 4:2'],
        gender: 'Gen 4:2',
        children: []
      }
    },
    enoch: {
      names: ['Enoch'],
      gender: 'male',
      children: ['irad'],
      references: {
        names: ['Gen 4:17'],
        gender: 'Gen 4:17',
        children: ['Gen 4:18']
      }
    },
    irad: {
      names: ['Irad'],
      gender: 'male',
      children: ['mehujael'],
      references: {
        names: ['Gen 4:18'],
        gender: 'Gen 4:18',
        children: ['Gen 4:18']
      }
    },
    mehujael: {
      names: ['Mehujael'],
      gender: 'male',
      children: ['methushael'],
      references: {
        names: ['Gen 4:18'],
        gender: 'Gen 4:18',
        children: ['Gen 4:18']
      }
    },
    methushael: {
      names: ['Methushael'],
      gender: 'male',
      children: ['lamech'],
      references: {
        names: ['Gen 4:18'],
        gender: 'Gen 4:18',
        children: ['Gen 4:18']
      }
    },
    lamech: {
      names: ['Lamech'],
      gender: 'male',
      spouses: ['adah','zillah'],
      children: ['jabal','jubal','tubal','naamah'],
      references: {
        names: ['Gen 4:18'],
        gender: 'Gen 4:18',
        spouses: ['Gen 4:19', 'Gen 4:19'],
        children: ['Gen 4:20','Gen 4:21','Gen 4:22','Gen 4:22']
      }
    },
    adah: {
      names: ['Adah'],
      gender: 'female',
      spouses: ['lamech'],
      children: ['jabal','jubal'],
      references: {
        names: ['Gen 4:19'],
        gender: 'Gen 4:19',
        spouses: ['Gen 4:19'],
        children: ['Gen 4:20','Gen 4:20-21']
      }
    },
    zillah: {
      names: ['Zillah'],
      gender: 'female',
      spouses: ['lamech'],
      children: ['tubal','naamah'],
      references: {
        names: ['Gen 4:19'],
        gender: 'Gen 4:19',
        spouses: ['Gen 4:19'],
        children: ['Gen 4:22','Gen 4:22']
      }
    },
    jabal: {
      names: ['Jabal'],
      gender: 'male',
      references: {
        names: ['Gen 4:20'],
        gender: 'Gen 4:20'
      }
    },
    jubal: {
      names: ['Jubal'],
      gender: 'male',
      references: {
        names: ['Gen 4:21'],
        gender: 'Gen 4:21'
      }
    },
    tubal: {
      names: ['Tubal-cain'],
      gender: 'male',
      references: {
        names: ['Gen 4:22'],
        gender: 'Gen 4:22'
      }
    },
    naamah: {
      names: ['Naamah'],
      gender: 'female',
      references: {
        names: ['Gen 4:22'],
        gender: 'Gen 4:22'
      }
    },
    seth: {
      names: ['Seth'],
      gender: 'male',
      children: ['enosh'],
      ageOfFatherAtBirth: 130,
      otherChildren: true,
      yearsLived: 912,
      references: {
        names: ['Gen 4:25'],
        gender: 'Gen 4:25',
        children: ['Gen 4:26'],
        ageOfFatherAtBirth: 'Gen 5:3',
        otherChildren: 'Gen 5:7',
        yearsLived: 'Gen 5:8'
      }
    },
    enosh: {
      names: ['Enosh'],
      gender: 'male',
      children: ['kenan'],
      ageOfFatherAtBirth: 105,
      otherChildren: true,
      yearsLived: 905,
      references: {
        names: ['Gen 4:26'],
        gender: 'Gen 4:26',
        children: ['Gen 5:9'],
        ageOfFatherAtBirth: 'Gen 5:6',
        otherChildren: 'Gen 5:10',
        yearsLived: 'Gen 5:11'
      }
    },
    kenan: {
      names: ['Kenan'],
      gender: 'male',
      children: ['mahalalel'],
      ageOfFatherAtBirth: 90,
      otherChildren: true,
      yearsLived: 910,
      references: {
        names: ['Gen 5:9'],
        gender: 'Gen 5:12',
        children: ['Gen 5:12'],
        ageOfFatherAtBirth: 'Gen 5:9',
        otherChildren: 'Gen 5:13',
        yearsLived: 'Gen 5:14'
      }
    },
    mahalalel: {
      names: ['Mahalalel'],
      gender: 'male',
      children: ['jared'],
      ageOfFatherAtBirth: 70,
      otherChildren: true,
      yearsLived: 895,
      references: {
        names: ['Gen 5:12'],
        gender: 'Gen 5:15',
        children: ['Gen 5:15'],
        ageOfFatherAtBirth: 'Gen 5:12',
        otherChildren: 'Gen 5:16',
        yearsLived: 'Gen 5:17'
      }
    },
    jared: {
      names: ['Jared'],
      gender: 'male',
      children: ['enoch2'],
      ageOfFatherAtBirth: 65,
      otherChildren: true,
      yearsLived: 962,
      references: {
        names: ['Gen 5:15'],
        gender: 'Gen 5:18',
        children: ['Gen 5:18'],
        ageOfFatherAtBirth: 'Gen 5:15',
        otherChildren: 'Gen 5:19',
        yearsLived: 'Gen 5:20'
      }
    },
    enoch2: {
      names: ['Enoch'],
      gender: 'male',
      children: ['methuselah'],
      ageOfFatherAtBirth: 62,
      otherChildren: true,
      yearsLived: 365,
      references: {
        names: ['Gen 5:18'],
        gender: 'Gen 5:21',
        children: ['Gen 5:21'],
        ageOfFatherAtBirth: 'Gen 5:18',
        otherChildren: 'Gen 5:22',
        yearsLived: 'Gen 5:23'
      }
    },
    methuselah: {
      names: ['Methuselah'],
      gender: 'male',
      children: ['lamech2'],
      ageOfFatherAtBirth: 65,
      otherChildren: true,
      yearsLived: 969,
      references: {
        names: ['Gen 5:21'],
        gender: 'Gen 5:25',
        children: ['Gen 5:25'],
        ageOfFatherAtBirth: 'Gen 5:21',
        otherChildren: 'Gen 5:26',
        yearsLived: 'Gen 5:27'
      }
    },
    lamech2: {
      names: ['Lamech'],
      gender: 'male',
      children: ['noah'],
      ageOfFatherAtBirth: 187,
      otherChildren: true,
      yearsLived: 777,
      references: {
        names: ['Gen 5:25'],
        gender: 'Gen 5:28',
        children: ['Gen 5:28-29'],
        ageOfFatherAtBirth: 'Gen 5:25',
        otherChildren: 'Gen 5:30',
        yearsLived: 'Gen 5:31'
      }
    },
    noah: {
      names: ['Noah'],
      gender: 'male',
      spouses: ['wife_of_noah'],
      children: ['shem', 'ham', 'japheth'],
      ageOfFatherAtBirth: 182,
      yearsLived: 950,
      references: {
        names: ['Gen 5:28-29'],
        gender: 'Gen 5:28-29',
        spouses: ['Gen 6:18'],
        children: ['Gen 5:32', 'Gen 5:32', 'Gen 5:32'],
        ageOfFatherAtBirth: 'Gen 5:28-29',
        yearsLived: 'Gen 9:29'
      }
    },
    wife_of_noah: {
      title: 'Noah\'s wife',
      gender: 'female',
      spouses: ['noah'],
      children: ['shem', 'ham', 'japheth'],
      references: {
        title: 'Gen 6:18',
        gender: 'Gen 6:18',
        spouses: ['Gen 6:18'],
        children: ['Gen 5:32', 'Gen 5:32', 'Gen 5:32']
      }
    },
    shem: {
      names: ['Shem'],
      gender: 'male',
      spouses: ['wife_of_shem'],
      references: {
        names: ['Gen 5:32'],
        gender: 'Gen 6:10',
        spouses: ['Gen 6:18']
      }
    },
    ham: {
      names: ['Ham'],
      gender: 'male',
      spouses: ['wife_of_ham'],
      references: {
        names: ['Gen 5:32'],
        gender: 'Gen 6:10',
        spouses: ['Gen 6:18']
      }
    },
    japheth: {
      names: ['Japheth'],
      gender: 'male',
      spouses: ['wife_of_japheth'],
      references: {
        names: ['Gen 5:32'],
        gender: 'Gen 6:10',
        spouses: ['Gen 6:18']
      }
    },
    wife_of_shem: {
      title: 'Shem\'s wife',
      gender: 'female',
      spouses: ['shem'],
      references: {
        title: 'Gen 6:18',
        gender: 'Gen 6:18',
        spouses: ['Gen 6:18']
      }
    },
    wife_of_ham: {
      title: 'Ham\'s wife',
      gender: 'female',
      spouses: ['ham'],
      references: {
        title: 'Gen 6:18',
        gender: 'Gen 6:18',
        spouses: ['Gen 6:18']
      }
    },
    wife_of_japheth: {
      title: 'Japheth\'s wife',
      gender: 'female',
      spouses: ['japheth'],
      references: {
        title: 'Gen 6:18',
        gender: 'Gen 6:18',
        spouses: ['Gen 6:18']
      }
    }
  }
};<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var path = require('path');
var chalk = require('chalk');
var pty = require('pty.js');
var cwd = process.cwd();

module.exports = function(grunt){

    grunt.registerTask('ec2_create_keypair', function(name){
        if (arguments.length === 0) {
            grunt.fatal([
                'You should provide a key-pair name.',
                'e.g: ' + chalk.yellow('grunt ec2_create_keypair:name')
            ].join('\n'));
        }

        var output = '';
        var done = this.async();
        var cli = pty.spawn('aws', [
            'ec2', 'create-key-pair', '--key-name', name
        ], { env: conf() });

        grunt.log.writeln('Creating EC2 Key Pair named %s...', chalk.cyan(name));

        cli.on('data', function(data){
            output += data;
        });

        cli.on('error', function(err){
            grunt.fatal(err);
        });

        cli.on('end', function(){
            var json;
            try {
                json = JSON.parse(output);
            } catch (e) {
                grunt.log.warn(output);
            }

            var name = json.KeyName;
            var privateKey = json.KeyPair.KeyMaterial;
            var file = path.join(cwd, 'deploy/private', name + '.pem');

            fs.writeFile(file, privateKey, 'ascii', function(err){
                if (err) { grunt.fatal(err); }

                grunt.log.writeln('EC2 Key Pair dumped to disk, at' + chalk.cyan('./deploy/private'));
                done();
            });
        });
    });
};
<commit_msg>fixed inconsistency with awscli vs docs<commit_after>'use strict';

var fs = require('fs');
var path = require('path');
var chalk = require('chalk');
var pty = require('pty.js');
var cwd = process.cwd();

module.exports = function(grunt){

    grunt.registerTask('ec2_create_keypair', function(name){
        if (arguments.length === 0) {
            grunt.fatal([
                'You should provide a key-pair name.',
                'e.g: ' + chalk.yellow('grunt ec2_create_keypair:name')
            ].join('\n'));
        }

        var output = '';
        var done = this.async();
        var cli = pty.spawn('aws', [
            'ec2', 'create-key-pair', '--key-name', name
        ], { env: conf() });

        grunt.log.writeln('Creating EC2 Key Pair named %s...', chalk.cyan(name));

        cli.on('data', function(data){
            output += data;
        });

        cli.on('error', function(err){
            grunt.fatal(err);
        });

        cli.on('end', function(){
            var json;
            try {
                json = JSON.parse(output);
            } catch (e) {
                grunt.log.warn(output);
            }

            var name = json.KeyName;
            var privateKey = json.KeyMaterial;
            var file = path.join(cwd, 'deploy/private', name + '.pem');

            fs.writeFile(file, privateKey, 'ascii', function(err){
                if (err) { grunt.fatal(err); }

                grunt.log.writeln('EC2 Key Pair dumped to disk, at' + chalk.cyan('./deploy/private'));
                done();
            });
        });
    });
};
<|endoftext|>


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

module.exports = () => [
    {
        mode: 'production',
        entry: ['@babel/polyfill', path.resolve(__dirname, 'src/rich-text-editor-bundle.js')],
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'rich-text-editor-bundle.js'
        },
        resolve: {
            extensions: ['.js', '.jsx', '.ts', '.tsx', '.json']
        },
        externals: {
            baconjs: 'Bacon'
        },
        module: {
            rules: [
                {
                    test: /\.(js|jsx|ts|tsx|json)$/,
                    exclude: path.resolve(__dirname, 'node_modules'),
                    use: {
                        loader: 'ts-loader',
                        options: {
                            onlyCompileBundledFiles: true,
                            transpileOnly: true,
                            compilerOptions: { target: 'es5' }
                        }
                    }
                }
            ]
        },
        stats: 'errors-only',
        performance: {
            hints: false
        }
    }
]
<commit_msg>Exclude jquery from bundle<commit_after>const path = require('path')

module.exports = () => [
    {
        mode: 'production',
        entry: ['@babel/polyfill', path.resolve(__dirname, 'src/rich-text-editor-bundle.js')],
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'rich-text-editor-bundle.js'
        },
        resolve: {
            extensions: ['.js', '.jsx', '.ts', '.tsx', '.json']
        },
        externals: {
            baconjs: 'Bacon',
            jquery: '$'
        },
        module: {
            rules: [
                {
                    test: /\.(js|jsx|ts|tsx|json)$/,
                    exclude: path.resolve(__dirname, 'node_modules'),
                    use: {
                        loader: 'ts-loader',
                        options: {
                            onlyCompileBundledFiles: true,
                            transpileOnly: true,
                            compilerOptions: { target: 'es5' }
                        }
                    }
                }
            ]
        },
        stats: 'errors-only',
        performance: {
            hints: false
        }
    }
]
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2009 Sergiy Kovalchuk (serg472@gmail.com)
 *
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Following code is based on Element.mask() implementation from ExtJS framework (http://extjs.com/)
 *
 */
;(function($){

	/**
	 * Displays loading mask over selected element(s). Accepts both single and multiple selectors.
	 *
	 * @param label Text message that will be displayed on top of the mask besides a spinner (optional).
	 * 				If not provided only mask will be displayed without a label or a spinner.
	 * @param delay Delay in milliseconds before element is masked (optional). If unmask() is called
	 *              before the delay times out, no mask is displayed. This can be used to prevent unnecessary
	 *              mask display for quick processes.
	 */
	$.fn.mask = function(label, delay){
		$(this).each(function() {
			if(delay !== undefined && delay > 0) {
		        var element = $(this);
		        element.data("_mask_timeout", setTimeout(function() { $.maskElement(element, label)}, delay));
			} else {
				$.maskElement($(this), label);
			}
		});
	};

	/**
	 * Removes mask from the element(s). Accepts both single and multiple selectors.
	 */
	$.fn.unmask = function(){
		$(this).each(function() {
			$.unmaskElement($(this));
		});
	};

	/**
	 * Checks if a single element is masked. Returns false if mask is delayed or not displayed.
	 */
	$.fn.isMasked = function(){
		return this.hasClass("masked");
	};

	/**
	 * Show or update the upload progressbar
	 */
	$.fn.maskProgress = function(value){
		$(this).each(function() {
			$.maskProgress($(this), value);
		});
	};

	$.maskElement = function(element, label){

		//if this element has delayed mask scheduled then remove it and display the new one
		if (element.data("_mask_timeout") !== undefined) {
			clearTimeout(element.data("_mask_timeout"));
			element.removeData("_mask_timeout");
		}

		if(element.isMasked()) {
			$.unmaskElement(element);
		}

		if(element.css("position") == "static") {
			element.addClass("masked-relative");
		}

		element.addClass("masked");

		var maskDiv = $('

');

		//auto height fix for IE
		if(navigator.userAgent.toLowerCase().indexOf("msie") > -1){
			maskDiv.height(element.height() + parseInt(element.css("padding-top")) + parseInt(element.css("padding-bottom")));
			maskDiv.width(element.width() + parseInt(element.css("padding-left")) + parseInt(element.css("padding-right")));
		}

		//fix for z-index bug with selects in IE6
		if(navigator.userAgent.toLowerCase().indexOf("msie 6") > -1){
			element.find("select").addClass("masked-hidden");
		}

		element.append(maskDiv);

		if ($(element).progressbar != undefined) {
			var maskProgressDiv = $('

');
			element.append(maskProgressDiv);
			element.find(".loadmask-progress").progressbar({value: 0});
		}
		if(label !== undefined) {
			var maskMsgDiv = $('

');
			maskMsgDiv.append('
' + label + '
');
			element.append(maskMsgDiv);

			//calculate center position
			maskMsgDiv.css("top", Math.round(element.height() / 2 - (maskMsgDiv.height() - parseInt(maskMsgDiv.css("padding-top")) - parseInt(maskMsgDiv.css("padding-bottom"))) / 2)+"px");
			maskMsgDiv.css("left", Math.round(element.width() / 2 - (maskMsgDiv.width() - parseInt(maskMsgDiv.css("padding-left")) - parseInt(maskMsgDiv.css("padding-right"))) / 2)+"px");

			maskMsgDiv.show();
		}
	};

	$.maskProgress = function(element, value){
		if ($(element).progressbar != undefined) {
			element.find(".loadmask-progress").show().progressbar('option', 'value', value);
			element.find(".loadmask-msg").hide();
		}
	};

	$.unmaskElement = function(element){
		return;
		//if this element has delayed mask scheduled then remove it
		if (element.data("_mask_timeout") !== undefined) {
			clearTimeout(element.data("_mask_timeout"));
			element.removeData("_mask_timeout");
		}

		element.find(".loadmask-msg,.loadmask-progress,.loadmask").remove();
		element.removeClass("masked");
		element.removeClass("masked-relative");
		element.find("select").removeClass("masked-hidden");
	};

})(jQuery);<commit_msg>Removed some debug for upload postgres bar<commit_after>/**
 * Copyright (c) 2009 Sergiy Kovalchuk (serg472@gmail.com)
 *
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Following code is based on Element.mask() implementation from ExtJS framework (http://extjs.com/)
 *
 */
;(function($){

	/**
	 * Displays loading mask over selected element(s). Accepts both single and multiple selectors.
	 *
	 * @param label Text message that will be displayed on top of the mask besides a spinner (optional).
	 * 				If not provided only mask will be displayed without a label or a spinner.
	 * @param delay Delay in milliseconds before element is masked (optional). If unmask() is called
	 *              before the delay times out, no mask is displayed. This can be used to prevent unnecessary
	 *              mask display for quick processes.
	 */
	$.fn.mask = function(label, delay){
		$(this).each(function() {
			if(delay !== undefined && delay > 0) {
		        var element = $(this);
		        element.data("_mask_timeout", setTimeout(function() { $.maskElement(element, label)}, delay));
			} else {
				$.maskElement($(this), label);
			}
		});
	};

	/**
	 * Removes mask from the element(s). Accepts both single and multiple selectors.
	 */
	$.fn.unmask = function(){
		$(this).each(function() {
			$.unmaskElement($(this));
		});
	};

	/**
	 * Checks if a single element is masked. Returns false if mask is delayed or not displayed.
	 */
	$.fn.isMasked = function(){
		return this.hasClass("masked");
	};

	/**
	 * Show or update the upload progressbar
	 */
	$.fn.maskProgress = function(value){
		$(this).each(function() {
			$.maskProgress($(this), value);
		});
	};

	$.maskElement = function(element, label){

		//if this element has delayed mask scheduled then remove it and display the new one
		if (element.data("_mask_timeout") !== undefined) {
			clearTimeout(element.data("_mask_timeout"));
			element.removeData("_mask_timeout");
		}

		if(element.isMasked()) {
			$.unmaskElement(element);
		}

		if(element.css("position") == "static") {
			element.addClass("masked-relative");
		}

		element.addClass("masked");

		var maskDiv = $('

');

		//auto height fix for IE
		if(navigator.userAgent.toLowerCase().indexOf("msie") > -1){
			maskDiv.height(element.height() + parseInt(element.css("padding-top")) + parseInt(element.css("padding-bottom")));
			maskDiv.width(element.width() + parseInt(element.css("padding-left")) + parseInt(element.css("padding-right")));
		}

		//fix for z-index bug with selects in IE6
		if(navigator.userAgent.toLowerCase().indexOf("msie 6") > -1){
			element.find("select").addClass("masked-hidden");
		}

		element.append(maskDiv);

		if ($(element).progressbar != undefined) {
			var maskProgressDiv = $('

');
			element.append(maskProgressDiv);
			element.find(".loadmask-progress").progressbar({value: 0});
		}
		if(label !== undefined) {
			var maskMsgDiv = $('

');
			maskMsgDiv.append('
' + label + '
');
			element.append(maskMsgDiv);

			//calculate center position
			maskMsgDiv.css("top", Math.round(element.height() / 2 - (maskMsgDiv.height() - parseInt(maskMsgDiv.css("padding-top")) - parseInt(maskMsgDiv.css("padding-bottom"))) / 2)+"px");
			maskMsgDiv.css("left", Math.round(element.width() / 2 - (maskMsgDiv.width() - parseInt(maskMsgDiv.css("padding-left")) - parseInt(maskMsgDiv.css("padding-right"))) / 2)+"px");

			maskMsgDiv.show();
		}
	};

	$.maskProgress = function(element, value){
		if ($(element).progressbar != undefined) {
			element.find(".loadmask-progress").show().progressbar('option', 'value', value);
			element.find(".loadmask-msg").hide();
		}
	};

	$.unmaskElement = function(element){
		//if this element has delayed mask scheduled then remove it
		if (element.data("_mask_timeout") !== undefined) {
			clearTimeout(element.data("_mask_timeout"));
			element.removeData("_mask_timeout");
		}

		element.find(".loadmask-msg,.loadmask-progress,.loadmask").remove();
		element.removeClass("masked");
		element.removeClass("masked-relative");
		element.find("select").removeClass("masked-hidden");
	};

})(jQuery);<|endoftext|>


<commit_before>/**
 * jQuery Formset 1.3-pre
 * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
 * @requires jQuery 1.2.6 or later
 *
 * Copyright (c) 2009, Stanislaus Madueke
 * All rights reserved.
 *
 * Licensed under the New BSD License
 * See: http://www.opensource.org/licenses/bsd-license.php
 */

/**
 * Events
 *
 * initialized.formset -- Triggered when a formset is first initialized.
 * row_removed.formset -- Triggered when a row is removed. Receives the
 *                        removed row as an extra parameter if it's
 *                        hidden rather than destroyed.
 * row_added.formset   -- Triggered when a row is added. Receives the
 *                        new row as an extra parameter.
 * reordered.formset   -- Triggered when the order of rows is changed by user
 *                        drag and drop.
 */

;(function($) {
    "use strict";

    // Formset Class Definition
    // ========================

    var Formset = function (el, options) {
        this.options = $.extend({}, Formset.DEFAULTS, options);
        this.$el = $(el);
        this.totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS');
        this.maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS');

        this.init();
    };

    Formset.DEFAULTS = {
        prefix: 'form',                  // The form prefix for your django formset
        rowSelector: null,               // The jQuery selector to identify rows of the formset
        formTemplate: null,              // The jQuery selection cloned to generate new form instances
        addTrigger: 'Add Another',
        deleteTrigger: 'Remove',
        deleteWrapper: null,             // jQuery selector for which element delete button should be appended to
        addCssClass: 'add-row',          // CSS class applied to the add link
        addWrapper: null,                // jQuery selector for which element add button should be appended to
        deleteCssClass: 'delete-row',    // CSS class applied to the delete link
        formCssClass: 'dynamic-form',    // CSS class applied to each form in a formset
        keepFieldValues: '',             // jQuery selector for fields whose values should be kept when the form is cloned
        sortableHandle: null,            // jQuery selector for what part of each form row is draggable
        sortableField: null,             // Name of field which keeps track of order index
    };

    Formset.childElementSelector = 'input,select,textarea,label,div,a';

    Formset.log = function () {
        /*global console:true */
        if (window.console && console.log)
            console.log('[formset] ' + Array.prototype.join.call(arguments, ' ') );
    };
    Formset.warn = function () {
        if (window.console && console.log)
            console.warn('[formset] ' + Array.prototype.join.call(arguments, ' ') );
    }

    Formset.prototype.init = function () {
        // Find all children of wrapper or all descendents matching options.rowSelector:
        var formset = this, // useful for subscope below
            options = this.options,
            initial_rows = this.current_rows();

        // Initialize each of the current rows:
        initial_rows.each(function () {
            var row = $(this),
                del = row.find('input:checkbox[id $= "-DELETE"]');
            if (del.length) {
                // If you specify "can_delete = True" when creating an inline formset,
                // Django adds a checkbox to each form in the formset.
                // Replace the default checkbox with a hidden field:
                if (del.is(':checked')) {
                    // If an inline formset containing deleted forms fails validation, make sure
                    // we keep the forms hidden (thanks for the bug report and suggested fix Mike)
                    del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" value="on" />');
                    row.hide();
                } else {
                    del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" />');
                }
                // Hide any labels associated with the DELETE checkbox:
                $('label[for="' + del.attr('id') + '"]').hide();
                del.remove();
            }
            row.addClass(options.formCssClass);
            if (row.is(':visible')) {
                formset.insertDeleteLink(row);
            }
        });

        this.insertAddLink();

        // If sortableField is set, initialize sortables
        if (options.sortableField !== null) this.initSortable();

        // Trigger the initialized event:
        this.$el.trigger('initialized.formset');
        Formset.log("Initialized formset with " + initial_rows.length + " initial rows.");
    };

    Formset.prototype.initSortable = function () {
        var formset = this, // useful for subscope below
            options = this.options,
            sortable_options = {opacity: .5, axis: "y"};

        if (!("sortable" in $.fn)) {
            // If jQuery UI sortable is not included, short-circuit:
            Formset.warn("jQuery UI Sortable component required for sortable formsets. http://jqueryui.com/");
            return;
        }

        // If a row selector is specified, limit sortables to that selector:
        if (options.rowSelector !== null) sortable_options.items = options.rowSelector;
        // If a handle is specified:
        if (options.sortableHandle !== null) sortable_options.handle = options.sortableHandle;
        // Add a callback for renumbering the fields:
        sortable_options.update = function (e, data) {
            formset.refreshRowOrderFields();
            // Trigger a reorder event
            formset.$el.trigger('reordered.formset');
            Formset.log("Formset items reordered.");
        };

        this.$el.sortable(sortable_options);

        // Ensure all rows have an order index:
        if (options.sortableField !== null) this.refreshRowOrderFields();

        Formset.log("Initialized drag-and-drop sorting.")
    };

    Formset.prototype.refreshRowOrderFields = function () {
        var formset = this,
            options = this.options,
            rows = this.current_rows();
        rows.each(function (i, v) {
            var sortableFieldSelector;
            if (formset.options.sortableField) {
                // find a field that matches id=id_prefix-*-orderfield:
                sortableFieldSelector = "[id^='id_"+options.prefix+"-'][id$='"+options.sortableField+"']"
                $(sortableFieldSelector, this).val(i+1);
            };
        });
    }

    Formset.prototype.current_rows = function () {
        var options = this.options;
        return (options.rowSelector === null) ? this.$el.children() : this.$el.find(options.rowSelector);
    };

    Formset.prototype.insertAddLink = function () {
        // Generate the add button:
        var formset = this, // useful for subscope below
            options = this.options,
            add_link = this.add_link = $(options.addTrigger),
            current_rows = this.current_rows(),
            hideAddButton = !this.showAddButton(),
                addButton, template;
            if (options.formTemplate) {
                // If a form template was specified, we'll clone it to generate new form instances:
                template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate);
            } else {
                // Otherwise, use the last form in the formset; this works much better if you've got
                // extra (>= 1) forms (thnaks to justhamade for pointing this out):
                template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id');
                template.find('input:hidden[id $= "-DELETE"]').remove();
                // Clear all cloned fields, except those the user wants to keep (thanks to brunogola for the suggestion):
                template.find(Formset.childElementSelector).not(options.keepFieldValues).each(function() {
                    var elem = $(this);
                    // If this is a checkbox or radiobutton, uncheck it.
                    // This fixes Issue 1, reported by Wilson.Andrew.J:
                    if (elem.is('input:checkbox') || elem.is('input:radio')) {
                        elem.attr('checked', false);
                    } else {
                        elem.val('');
                    }
                });
            }
            // FIXME: Perhaps using $.data would be a better idea?
            options.formTemplate = template;

            // Generate the add button.
            if (options.addWrapper !== null) {
                // If a wrapper selector is specified, append the add
                // button to the element matching that selector.
                $(options.addWrapper).append(add_link);
            } else if (current_rows.attr('tagName') == 'TR') {
                // If forms are laid out as table rows, insert the
                // "add" button in a new table row:
                var numCols = current_rows.eq(0).children().length,   // This is a bit of an assumption :|
                    buttonRow = $('

').addClass(options.formCssClass + '-add');
                buttonRow.find('td').append(add_link)
                current_rows.parent().append(buttonRow);
                if (hideAddButton) buttonRow.hide();
            } else {
                // Otherwise, insert it immediately after the last form:
                current_rows.filter(':last').after(add_link);
                if (hideAddButton) add_link.hide();
            }
            add_link.click(function (e) {
                e.preventDefault();
                formset.addRow();
            });
    };

    Formset.prototype.insertDeleteLink = function (row) {
        var options = this.options,
            // Create a new DOM element:
            delete_link = $(options.deleteTrigger);
        // Store the associated row as data on the delete link:
        delete_link.data('formset.row', row);
        // Store the associated formset as data on the delete link:
        delete_link.data('formset', this);
        // Find the appropriate place to append the delete link:
        if (options.deleteWrapper !== null){
            // If a wrapper selector is specified, append to an
            // element matching that selector within the row:
            row.find(options.deleteWrapper).append(delete_link)
        } else if (row.is('tr')) {
            // If the forms are laid out in table rows, insert
            // the remove button into the last table cell:
            row.children(':last').append(delete_link);
        } else if (row.is('ul') || row.is('OL')) {
            // If they're laid out as an ordered/unordered list,
            // insert an
 after the last list item:
            row.append(delete_link.wrap('

'));
        } else {
            // Otherwise, just insert the remove button as the
            // last child element of the form's container:
            row.append(delete_link);
        }
        // Bind the click event for the delete link:
        delete_link.click(function(e) {
            var $this = $(this),
                row = $this.data('formset.row'),
                formset = $this.data('formset');
            e.preventDefault()
            return formset.removeRow(row);
        });

        Formset.log("Added delete link to row.");
    };

    Formset.prototype.removeRow = function (row) {
        // Remove a row, with the row passed as a jQuery object.
        var formset = this, // useful for subscope below
            options = this.options,
            del = row.find('input:hidden[id $= "-DELETE"]'),
            buttonRow = $(this.add_link).parents('tr.' + options.formCssClass + '-add').get(0) ? $(this.add_link).parents('tr.' + options.formCssClass + '-add') : this.add_link,
            forms;
        if (del.length) {
            // We're dealing with an inline formset.
            // Rather than remove this form from the DOM, we'll mark it as deleted
            // and hide it, then let Django handle the deleting:
            del.val('on');
            row.hide();
            forms = $('.' + options.formCssClass).not(':hidden');
        } else {
            row.remove();
            // Update the TOTAL_FORMS count:
            forms = this.current_rows();
            this.totalForms.val(forms.length);
        }
        for (var i=0, formCount=this.current_rows().length; i<formCount; i++) {
            if (!del.length) {
                // Also update names and IDs for all child controls (if this isn't
                // a delete-able inline formset) so they remain in sequence:
                forms.eq(i).find(Formset.childElementSelector).each(function() {
                    formset.updateElementIndex($(this), i);
                });
            }
        }

        // Check if we need to show the add button:
        if (buttonRow.is(':hidden') && this.showAddButton()) buttonRow.show();

        // Trigger the row_removed event:
        this.$el.trigger('row_removed.formset', [row]);
        Formset.log("Removed a row.");

        return false;
    };

    Formset.prototype.addRow = function (row) {
        var formset = this, // useful for subscope below
            options = this.options,
            formCount = parseInt(this.totalForms.val()),
            row = options.formTemplate.clone(true).removeClass('formset-custom-template'),
            buttonRow = $(this.add_link).parents('tr.' + options.formCssClass + '-add').get(0) ? $(this.add_link).parents('tr.' + options.formCssClass + '-add') : null;
        if (buttonRow !== null) {
            // If this is a table, insert before the button row.
            row.insertBefore(buttonRow).show();
        } else {
            this.current_rows().filter(':last').after(row)
        }
        this.insertDeleteLink(row);
        this.updateRowIndex(row, formCount);
        this.totalForms.val(formCount + 1);
        // Check if we've exceeded the maximum allowed number of forms:
        if (buttonRow !== null) {
            // If it's a table, hide the hold row:
            if (!this.showAddButton()) buttonRow.hide();
        } else {
            if (!this.showAddButton()) this.add_link.hide();
        }
        // If rows are orderable, ensure they all get an order index:
        if (options.sortableField !== null) this.refreshRowOrderFields();

        // Trigger the row_added event:
        this.$el.trigger('row_added.formset', [row]);
        Formset.log("Added a row. Current row count: " + this.totalForms.val() + ". Max row count: " + this.maxForms.val() + ".");

        return false;
    };

    Formset.prototype.updateRowIndex = function (row, ndx) {
        var formset = this;
        row.find(Formset.childElementSelector).each(function() {
            formset.updateElementIndex($(this), ndx);
        });
    };

    Formset.prototype.showAddButton = function () {
        return this.maxForms.length == 0 ||   // For Django versions pre 1.2
            (this.maxForms.val() == '' || (this.maxForms.val() - this.totalForms.val() > 0))
    };

    Formset.prototype.updateElementIndex = function(elem, ndx) {
        var prefix = this.options.prefix,
            idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-'),
            replacement = prefix + '-' + ndx + '-';
        if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement));
        if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement));
        if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement));
        if (elem.attr('href')) elem.attr('href', elem.attr('href').replace(idRegex, replacement));
    },

    // Plugin Definition
    // =================

    $.fn.formset = function (options) {
        // Should be called on an element that is a parent or ancestor
        // of the formset rows.
        return this.each(function () {
            var $this = $(this),
                data = $(this).data('formset'),
                options_ = typeof options == 'object' && options;
            // Instatiate formset on element if it not already.
            if (!data) return $this.data('formset', new Formset(this, options_));
            // If a string was passed to the function, interpret as an API command.
            if (typeof options_ == 'string') return data[option_]();
        });
    };

})(jQuery);
<commit_msg>Add link now appended *after* formset container instead of inside.<commit_after>/**
 * jQuery Formset 1.3-pre
 * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
 * @requires jQuery 1.2.6 or later
 *
 * Copyright (c) 2009, Stanislaus Madueke
 * All rights reserved.
 *
 * Licensed under the New BSD License
 * See: http://www.opensource.org/licenses/bsd-license.php
 */

/**
 * Events
 *
 * initialized.formset -- Triggered when a formset is first initialized.
 * row_removed.formset -- Triggered when a row is removed. Receives the
 *                        removed row as an extra parameter if it's
 *                        hidden rather than destroyed.
 * row_added.formset   -- Triggered when a row is added. Receives the
 *                        new row as an extra parameter.
 * reordered.formset   -- Triggered when the order of rows is changed by user
 *                        drag and drop.
 */

;(function($) {
    "use strict";

    // Formset Class Definition
    // ========================

    var Formset = function (el, options) {
        this.options = $.extend({}, Formset.DEFAULTS, options);
        this.$el = $(el);
        this.totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS');
        this.maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS');

        this.init();
    };

    Formset.DEFAULTS = {
        prefix: 'form',                  // The form prefix for your django formset
        rowSelector: null,               // The jQuery selector to identify rows of the formset
        formTemplate: null,              // The jQuery selection cloned to generate new form instances
        addTrigger: 'Add Another',
        deleteTrigger: 'Remove',
        deleteWrapper: null,             // jQuery selector for which element delete button should be appended to
        addCssClass: 'add-row',          // CSS class applied to the add link
        addWrapper: null,                // jQuery selector for which element add button should be appended to
        deleteCssClass: 'delete-row',    // CSS class applied to the delete link
        formCssClass: 'dynamic-form',    // CSS class applied to each form in a formset
        keepFieldValues: '',             // jQuery selector for fields whose values should be kept when the form is cloned
        sortableHandle: null,            // jQuery selector for what part of each form row is draggable
        sortableField: null,             // Name of field which keeps track of order index
    };

    Formset.childElementSelector = 'input,select,textarea,label,div,a';

    Formset.log = function () {
        /*global console:true */
        if (window.console && console.log)
            console.log('[formset] ' + Array.prototype.join.call(arguments, ' ') );
    };
    Formset.warn = function () {
        if (window.console && console.log)
            console.warn('[formset] ' + Array.prototype.join.call(arguments, ' ') );
    }

    Formset.prototype.init = function () {
        // Find all children of wrapper or all descendents matching options.rowSelector:
        var formset = this, // useful for subscope below
            options = this.options,
            initial_rows = this.current_rows();

        // Initialize each of the current rows:
        initial_rows.each(function () {
            var row = $(this),
                del = row.find('input:checkbox[id $= "-DELETE"]');
            if (del.length) {
                // If you specify "can_delete = True" when creating an inline formset,
                // Django adds a checkbox to each form in the formset.
                // Replace the default checkbox with a hidden field:
                if (del.is(':checked')) {
                    // If an inline formset containing deleted forms fails validation, make sure
                    // we keep the forms hidden (thanks for the bug report and suggested fix Mike)
                    del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" value="on" />');
                    row.hide();
                } else {
                    del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" />');
                }
                // Hide any labels associated with the DELETE checkbox:
                $('label[for="' + del.attr('id') + '"]').hide();
                del.remove();
            }
            row.addClass(options.formCssClass);
            if (row.is(':visible')) {
                formset.insertDeleteLink(row);
            }
        });

        this.insertAddLink();

        // If sortableField is set, initialize sortables
        if (options.sortableField !== null) this.initSortable();

        // Trigger the initialized event:
        this.$el.trigger('initialized.formset');
        Formset.log("Initialized formset with " + initial_rows.length + " initial rows.");
    };

    Formset.prototype.initSortable = function () {
        var formset = this, // useful for subscope below
            options = this.options,
            sortable_options = {opacity: .5, axis: "y"};

        if (!("sortable" in $.fn)) {
            // If jQuery UI sortable is not included, short-circuit:
            Formset.warn("jQuery UI Sortable component required for sortable formsets. http://jqueryui.com/");
            return;
        }

        // If a row selector is specified, limit sortables to that selector:
        if (options.rowSelector !== null) sortable_options.items = options.rowSelector;
        // If a handle is specified:
        if (options.sortableHandle !== null) sortable_options.handle = options.sortableHandle;
        // Add a callback for renumbering the fields:
        sortable_options.update = function (e, data) {
            formset.refreshRowOrderFields();
            // Trigger a reorder event
            formset.$el.trigger('reordered.formset');
            Formset.log("Formset items reordered.");
        };

        this.$el.sortable(sortable_options);

        // Ensure all rows have an order index:
        if (options.sortableField !== null) this.refreshRowOrderFields();

        Formset.log("Initialized drag-and-drop sorting.")
    };

    Formset.prototype.refreshRowOrderFields = function () {
        var formset = this,
            options = this.options,
            rows = this.current_rows();
        rows.each(function (i, v) {
            var sortableFieldSelector;
            if (formset.options.sortableField) {
                // find a field that matches id=id_prefix-*-orderfield:
                sortableFieldSelector = "[id^='id_"+options.prefix+"-'][id$='"+options.sortableField+"']"
                $(sortableFieldSelector, this).val(i+1);
            };
        });
    }

    Formset.prototype.current_rows = function () {
        var options = this.options;
        return (options.rowSelector === null) ? this.$el.children() : this.$el.find(options.rowSelector);
    };

    Formset.prototype.insertAddLink = function () {
        // Generate the add button:
        var formset = this, // useful for subscope below
            options = this.options,
            add_link = this.add_link = $(options.addTrigger),
            current_rows = this.current_rows(),
            hideAddButton = !this.showAddButton(),
                addButton, template;

            // TODO: This template deducing code should be more robust and separate from the insertAddLink function
            if (options.formTemplate) {
                // If a form template was specified, we'll clone it to generate new form instances:
                template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate);
            } else {
                // Otherwise, use the last form in the formset; this works much better if you've got
                // extra (>= 1) forms (thnaks to justhamade for pointing this out):
                template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id');
                template.find('input:hidden[id $= "-DELETE"]').remove();
                // Clear all cloned fields, except those the user wants to keep (thanks to brunogola for the suggestion):
                template.find(Formset.childElementSelector).not(options.keepFieldValues).each(function() {
                    var elem = $(this);
                    // If this is a checkbox or radiobutton, uncheck it.
                    // This fixes Issue 1, reported by Wilson.Andrew.J:
                    if (elem.is('input:checkbox') || elem.is('input:radio')) {
                        elem.attr('checked', false);
                    } else {
                        elem.val('');
                    }
                });
            }
            // FIXME: Perhaps using $.data would be a better idea?
            options.formTemplate = template;

            // Generate the add button.
            if (options.addWrapper !== null) {
                // If a wrapper selector is specified, append the add
                // button to the element matching that selector.
                $(options.addWrapper).append(add_link);
            } else if (current_rows.attr('tagName') == 'TR') {
                // If forms are laid out as table rows, insert the
                // "add" button in a new table row:
                var numCols = current_rows.eq(0).children().length,   // This is a bit of an assumption :|
                    buttonRow = $('

').addClass(options.formCssClass + '-add');
                buttonRow.find('td').append(add_link)
                current_rows.parent().append(buttonRow);
                if (hideAddButton) buttonRow.hide();
            } else {
                // Otherwise, insert it immediately after formset container:
                this.$el.after(add_link);
                if (hideAddButton) add_link.hide();
            }
            add_link.click(function (e) {
                e.preventDefault();
                formset.addRow();
            });
    };

    Formset.prototype.insertDeleteLink = function (row) {
        var options = this.options,
            // Create a new DOM element:
            delete_link = $(options.deleteTrigger);
        // Store the associated row as data on the delete link:
        delete_link.data('formset.row', row);
        // Store the associated formset as data on the delete link:
        delete_link.data('formset', this);
        // Find the appropriate place to append the delete link:
        if (options.deleteWrapper !== null){
            // If a wrapper selector is specified, append to an
            // element matching that selector within the row:
            row.find(options.deleteWrapper).append(delete_link)
        } else if (row.is('tr')) {
            // If the forms are laid out in table rows, insert
            // the remove button into the last table cell:
            row.children(':last').append(delete_link);
        } else if (row.is('ul') || row.is('OL')) {
            // If they're laid out as an ordered/unordered list,
            // insert an
 after the last list item:
            row.append(delete_link.wrap('

'));
        } else {
            // Otherwise, just insert the remove button as the
            // last child element of the form's container:
            row.append(delete_link);
        }
        // Bind the click event for the delete link:
        delete_link.click(function(e) {
            var $this = $(this),
                row = $this.data('formset.row'),
                formset = $this.data('formset');
            e.preventDefault()
            return formset.removeRow(row);
        });

        Formset.log("Added delete link to row.");
    };

    Formset.prototype.removeRow = function (row) {
        // Remove a row, with the row passed as a jQuery object.
        var formset = this, // useful for subscope below
            options = this.options,
            del = row.find('input:hidden[id $= "-DELETE"]'),
            buttonRow = $(this.add_link).parents('tr.' + options.formCssClass + '-add').get(0) ? $(this.add_link).parents('tr.' + options.formCssClass + '-add') : this.add_link,
            forms;
        if (del.length) {
            // We're dealing with an inline formset.
            // Rather than remove this form from the DOM, we'll mark it as deleted
            // and hide it, then let Django handle the deleting:
            del.val('on');
            row.hide();
            forms = $('.' + options.formCssClass).not(':hidden');
        } else {
            row.remove();
            // Update the TOTAL_FORMS count:
            forms = this.current_rows();
            this.totalForms.val(forms.length);
        }
        for (var i=0, formCount=this.current_rows().length; i<formCount; i++) {
            if (!del.length) {
                // Also update names and IDs for all child controls (if this isn't
                // a delete-able inline formset) so they remain in sequence:
                forms.eq(i).find(Formset.childElementSelector).each(function() {
                    formset.updateElementIndex($(this), i);
                });
            }
        }

        // Check if we need to show the add button:
        if (buttonRow.is(':hidden') && this.showAddButton()) buttonRow.show();

        // Trigger the row_removed event:
        this.$el.trigger('row_removed.formset', [row]);
        Formset.log("Removed a row.");

        return false;
    };

    Formset.prototype.addRow = function (row) {
        var formset = this, // useful for subscope below
            options = this.options,
            formCount = parseInt(this.totalForms.val()),
            row = options.formTemplate.clone(true).removeClass('formset-custom-template'),
            buttonRow = $(this.add_link).parents('tr.' + options.formCssClass + '-add').get(0) ? $(this.add_link).parents('tr.' + options.formCssClass + '-add') : null;
        if (buttonRow !== null) {
            // If this is a table, insert before the button row.
            row.insertBefore(buttonRow).show();
        } else {
            this.current_rows().filter(':last').after(row)
        }
        this.insertDeleteLink(row);
        this.updateRowIndex(row, formCount);
        this.totalForms.val(formCount + 1);
        // Check if we've exceeded the maximum allowed number of forms:
        if (buttonRow !== null) {
            // If it's a table, hide the hold row:
            if (!this.showAddButton()) buttonRow.hide();
        } else {
            if (!this.showAddButton()) this.add_link.hide();
        }
        // If rows are orderable, ensure they all get an order index:
        if (options.sortableField !== null) this.refreshRowOrderFields();

        // Trigger the row_added event:
        this.$el.trigger('row_added.formset', [row]);
        Formset.log("Added a row. Current row count: " + this.totalForms.val() + ". Max row count: " + this.maxForms.val() + ".");

        return false;
    };

    Formset.prototype.updateRowIndex = function (row, ndx) {
        var formset = this;
        row.find(Formset.childElementSelector).each(function() {
            formset.updateElementIndex($(this), ndx);
        });
    };

    Formset.prototype.showAddButton = function () {
        return this.maxForms.length == 0 ||   // For Django versions pre 1.2
            (this.maxForms.val() == '' || (this.maxForms.val() - this.totalForms.val() > 0))
    };

    Formset.prototype.updateElementIndex = function(elem, ndx) {
        var prefix = this.options.prefix,
            idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-'),
            replacement = prefix + '-' + ndx + '-';
        if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement));
        if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement));
        if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement));
        if (elem.attr('href')) elem.attr('href', elem.attr('href').replace(idRegex, replacement));
    },

    // Plugin Definition
    // =================

    $.fn.formset = function (options) {
        // Should be called on an element that is a parent or ancestor
        // of the formset rows.
        return this.each(function () {
            var $this = $(this),
                data = $(this).data('formset'),
                options_ = typeof options == 'object' && options;
            // Instatiate formset on element if it not already.
            if (!data) return $this.data('formset', new Formset(this, options_));
            // If a string was passed to the function, interpret as an API command.
            if (typeof options_ == 'string') return data[option_]();
        });
    };

})(jQuery);
<|endoftext|>


<commit_before>'use strict';

angular.module('products').controller('ProductsController', ['$scope', '$stateParams', '$location', 'Products',
	function($scope, $stateParams, $location, Products) {

    // List Categories
    $scope.find = function() {
      $scope.products = Products.query();
    };

    // CREATE new Category
    $scope.create = function() {
      // Create new Product object
      var product = new Products ({
        category: this.category,
        name: this.name,
        quantityPerUnit: this.quantityPerUnit,
        unitPrice: this.unitPrice,
        unitsInStock: this.unitsInStock,
        unitsOnOrder: this.unitsOnOrder
      });

      // Redirect after save
      product.$save(function(response) {
        $location.path('products/' + response._id);

        // Clear form fields
        $scope.name = '';
      }, function(errorResponse) {
        $scope.error = errorResponse.data.message;
      });
    };

	}
]);
<commit_msg>Add Read single Product method to Angular Controller.<commit_after>'use strict';

angular.module('products').controller('ProductsController', ['$scope', '$stateParams', '$location', 'Products',
	function($scope, $stateParams, $location, Products) {

    // List Products
    $scope.find = function() {
      $scope.products = Products.query();
    };

    // CREATE new Product
    $scope.create = function() {
      // Create new Product object
      var product = new Products ({
        category: this.category,
        name: this.name,
        quantityPerUnit: this.quantityPerUnit,
        unitPrice: this.unitPrice,
        unitsInStock: this.unitsInStock,
        unitsOnOrder: this.unitsOnOrder
      });

      // Redirect after save
      product.$save(function(response) {
        $location.path('products/' + response._id);

        // Clear form fields
        $scope.name = '';
      }, function(errorResponse) {
        $scope.error = errorResponse.data.message;
      });
    };

    // READ single Product
    $scope.findOne = function() {
      $scope.product = Products.get({
        productId: $stateParams.productId
      });
    };

	}
]);
<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

// Provides a helper that can highlight a given control
sap.ui.define('sap/ui/debug/Highlighter', [
	"sap/ui/thirdparty/jquery",
	"sap/base/util/uid",
	"sap/ui/dom/jquery/rect" // jQuery Plugin "rect"
	],
	function(jQuery, uid) {
	"use strict";

	/**
	 * Creates a new highlighter object without displaying it.
	 *
	 * The DOM node is not created until the first call to method {@link #highlight}.
	 *
	 * @param {string} [sId] id that is used by the new highlighter
	 * @param {boolean} [bFilled] whether the box of the highlighter is partially opaque (20%), defaults to false
	 * @param {string} [sColor] the CSS color of the border and the box (defaults to blue)
	 * @param {int} [iBorderWidth] the width of the border
	 *
	 * @class Helper class to display a colored rectangle around and above a given DOM node
	 * @author Frank Weigel
	 * @since 0.8.7
	 * @public
	 * @alias sap.ui.debug.Highlighter
	 */
	var Highlighter = function(sId, bFilled, sColor, iBorderWidth) {
		this.sId = sId || uid();
		this.bFilled = (bFilled == true);
		this.sColor = sColor || 'blue';
		if ( isNaN(iBorderWidth ) ) {
			this.iBorderWidth = 2;
		} else if ( iBorderWidth <= 0 ) {
			this.iBorderWidth = 0;
		} else {
			this.iBorderWidth = iBorderWidth;
		}
	};

	/**
	 * Shows a rectangle/box that surrounds the given DomRef.
	 *
	 * If this is the first call to {@link #highlight} for this instance, then
	 * a DOM node for the highlighter is created in the same document as the given oDomRef.
	 *
	 * Note: As the DOM node is reused across multiple calls, the highlighter must only be used
	 * within a single document.
	 */
	Highlighter.prototype.highlight = function(oDomRef) {
		if (!oDomRef || !oDomRef.parentNode) {
			return;
		}

		var oHighlightRect = (this.sId ? window.document.getElementById(this.sId) : null);
		if (!oHighlightRect) {
			oHighlightRect = oDomRef.ownerDocument.createElement("DIV");
			oHighlightRect.setAttribute("id", this.sId);
			oHighlightRect.style.position = "absolute";
			oHighlightRect.style.border = this.iBorderWidth + "px solid " + this.sColor;
			oHighlightRect.style.display = "none";
			oHighlightRect.style.margin = "0px";
			oHighlightRect.style.padding = "0px";
			if ( this.bFilled ) {
				oHighlightRect.innerHTML = "

";
			}
			oDomRef.ownerDocument.body.appendChild(oHighlightRect);
		}
		var oRect = jQuery(oDomRef).rect();
		oHighlightRect.style.top = (oRect.top - this.iBorderWidth) + "px";
		oHighlightRect.style.left = (oRect.left - this.iBorderWidth) + "px";
		oHighlightRect.style.width = (oRect.width) + "px";
		oHighlightRect.style.height = (oRect.height) + "px";
		oHighlightRect.style.display = "block";
	};

	/**
	 * Hides the rectangle/box if it is currently shown.
	 */
	Highlighter.prototype.hide = function() {
		var oHighlightRect = (this.sId ? window.document.getElementById(this.sId) : null);
		if (!oHighlightRect) {
			return;
		}
		oHighlightRect.style.display = "none";
	};

	return Highlighter;

}, /* bExport= */ true);<commit_msg>[INTERNAL] debug.Highlighter: avoid inline styles, use CSSOM<commit_after>/*!
 * ${copyright}
 */

// Provides a helper that can highlight a given control
sap.ui.define('sap/ui/debug/Highlighter', [
	"sap/ui/thirdparty/jquery",
	"sap/base/util/uid",
	"sap/ui/dom/jquery/rect" // jQuery Plugin "rect"
	],
	function(jQuery, uid) {
	"use strict";

	/**
	 * Creates a new highlighter object without displaying it.
	 *
	 * The DOM node is not created until the first call to method {@link #highlight}.
	 *
	 * @param {string} [sId] id that is used by the new highlighter
	 * @param {boolean} [bFilled] whether the box of the highlighter is partially opaque (20%), defaults to false
	 * @param {string} [sColor] the CSS color of the border and the box (defaults to blue)
	 * @param {int} [iBorderWidth] the width of the border
	 *
	 * @class Helper class to display a colored rectangle around and above a given DOM node
	 * @author Frank Weigel
	 * @since 0.8.7
	 * @public
	 * @alias sap.ui.debug.Highlighter
	 */
	var Highlighter = function(sId, bFilled, sColor, iBorderWidth) {
		this.sId = sId || uid();
		this.bFilled = (bFilled == true);
		this.sColor = sColor || 'blue';
		if ( isNaN(iBorderWidth ) ) {
			this.iBorderWidth = 2;
		} else if ( iBorderWidth <= 0 ) {
			this.iBorderWidth = 0;
		} else {
			this.iBorderWidth = iBorderWidth;
		}
	};

	/**
	 * Shows a rectangle/box that surrounds the given DomRef.
	 *
	 * If this is the first call to {@link #highlight} for this instance, then
	 * a DOM node for the highlighter is created in the same document as the given oDomRef.
	 *
	 * Note: As the DOM node is reused across multiple calls, the highlighter must only be used
	 * within a single document.
	 */
	Highlighter.prototype.highlight = function(oDomRef) {
		if (!oDomRef || !oDomRef.parentNode) {
			return;
		}

		var oHighlightRect = (this.sId ? window.document.getElementById(this.sId) : null);
		if (!oHighlightRect) {
			oHighlightRect = oDomRef.ownerDocument.createElement("div");
			oHighlightRect.setAttribute("id", this.sId);
			oHighlightRect.style.position = "absolute";
			oHighlightRect.style.border = this.iBorderWidth + "px solid " + this.sColor;
			oHighlightRect.style.display = "none";
			oHighlightRect.style.margin = "0px";
			oHighlightRect.style.padding = "0px";
			if ( this.bFilled ) {
				var oFiller = oDomRef.ownerDocument.createElement("div");
				oFiller.textContent = "\u00a0";
				oFiller.style.backgroundColor = this.sColor;
				oFiller.style.opacity = "0.2";
				oFiller.style.height = "100%";
				oFiller.style.width = "100%";
				oHighlightRect.appendChild(oFiller);
			}
			oDomRef.ownerDocument.body.appendChild(oHighlightRect);
		}
		var oRect = jQuery(oDomRef).rect();
		oHighlightRect.style.top = (oRect.top - this.iBorderWidth) + "px";
		oHighlightRect.style.left = (oRect.left - this.iBorderWidth) + "px";
		oHighlightRect.style.width = (oRect.width) + "px";
		oHighlightRect.style.height = (oRect.height) + "px";
		oHighlightRect.style.display = "block";
	};

	/**
	 * Hides the rectangle/box if it is currently shown.
	 */
	Highlighter.prototype.hide = function() {
		var oHighlightRect = (this.sId ? window.document.getElementById(this.sId) : null);
		if (!oHighlightRect) {
			return;
		}
		oHighlightRect.style.display = "none";
	};

	return Highlighter;

}, /* bExport= */ true);<|endoftext|>


<commit_before>
var emptyOption = [{label:"", value:""}];
function retrieveProtocols() {
	var protocolType = document.getElementById("protocolType").value;
	ProtocolManager.getProtocolNames(protocolType, populateProtocolNames);
}
function resetProtocols() {
	dwr.util.removeAllOptions("protocolName");
	dwr.util.addOptions("protocolName", emptyOption, "value", "label");
	resetProtocolFiles();
}
function populateProtocolNames(protocolNames) {
	resetProtocols();
	dwr.util.addOptions("protocolName", protocolNames);
	dwr.util.addOptions("protocolName", ["[Other]"]);
}
function retrieveProtocolFileVersions() {
	var protocolName = document.getElementById("protocolName").value;
	var protocolType = document.getElementById("protocolType").value;
	ProtocolManager.getProtocolFiles(protocolType, protocolName, populateProtocolFileVersions);
}
function resetProtocolFiles() {
	dwr.util.removeAllOptions("protocolFileId");
	dwr.util.addOptions("protocolFileId", emptyOption, "value", "label");
	writeLink(null);
}
function populateProtocolFileVersions(protocolFiles) {
	resetProtocolFiles();
	dwr.util.addOptions("protocolFileId", protocolFiles, "domainFileId", "domainFileVersion");
	dwr.util.addOptions("protocolFileId", ["[Other]"]);
}
function retrieveProtocolFile() {
	var fileId = document.getElementById("protocolFileId").value;
	//ProtocolManager.findProtocolFileById(fileId, writeLink); //not working on linux
	ProtocolManager.getProtocolFileUriById(fileId, writeLink);
	if (document.getElementById("updatedUri") != null) {
		ProtocolManager.getProtocolFileUriById(fileId, function (data) {
			document.getElementById("updatedUri").value = data;
		});
	}
	if (document.getElementById("updatedName") != null) {
		ProtocolManager.getProtocolFileNameById(fileId, function (data) {
			document.getElementById("updatedName").value = data;
		});
	}
	if (document.getElementById("updatedVersion") != null) {
		ProtocolManager.getProtocolFileVersionById(fileId, function (data) {
			document.getElementById("updatedVersion").value = data;
		});
	}
}
function writeLink(uri) {
	var fileId = document.getElementById("protocolFileId").value;
	if (uri != null) {
		var fileUri = uri;
		if (fileUri != null) {
			document.getElementById("protocolFileLink").innerHTML = "" + fileUri + "";
		} else {
			document.getElementById("protocolFileLink").innerHTML = "";
		}
	} else {
		document.getElementById("protocolFileLink").innerHTML = "";
	}
}

//not working on linux
function writeLink0(protocolFile) {
	var fileId = document.getElementById("protocolFileId").value;
	if (protocolFile != null) {
		var fileUri = protocolFile.domainUri;
		if (fileUri != null) {
			document.getElementById("protocolFileLink").innerHTML = "" + fileUri + "";
		} else {
			document.getElementById("protocolFileLink").innerHTML = "";
		}
	} else {
		document.getElementById("protocolFileLink").innerHTML = "";
	}
}

function setProtocolNameDropdown() {
	var searchLocations = getSelectedOptions(document.getElementById("searchLocations"));
	DWRProtocolManager.getProtocolTypes(searchLocations, function (data) {
			dwr.util.removeAllOptions("protocolType");
			dwr.util.addOptions("protocolType", data);
		});

	return false;
}

<commit_msg>fixed an error.<commit_after>
var emptyOption = [{label:"", value:""}];
function retrieveProtocols() {
	var protocolType = document.getElementById("protocolType").value;
	ProtocolManager.getProtocolNames(protocolType, populateProtocolNames);
}
function resetProtocols() {
	dwr.util.removeAllOptions("protocolName");
	dwr.util.addOptions("protocolName", emptyOption, "value", "label");
	resetProtocolFiles();
}
function populateProtocolNames(protocolNames) {
	resetProtocols();
	dwr.util.addOptions("protocolName", protocolNames);
	dwr.util.addOptions("protocolName", ["[Other]"]);
}
function retrieveProtocolFileVersions() {
	var protocolName = document.getElementById("protocolName").value;
	var protocolType = document.getElementById("protocolType").value;
	ProtocolManager.getProtocolFiles(protocolType, protocolName, populateProtocolFileVersions);
}
function resetProtocolFiles() {
	dwr.util.removeAllOptions("protocolFileId");
	dwr.util.addOptions("protocolFileId", emptyOption, "value", "label");
	writeLink(null);
}
function populateProtocolFileVersions(protocolFiles) {
	resetProtocolFiles();
	dwr.util.addOptions("protocolFileId", protocolFiles, "domainFileId", "domainFileVersion");
	dwr.util.addOptions("protocolFileId", ["[Other]"]);
}
function retrieveProtocolFile() {
	var fileId = document.getElementById("protocolFileId").value;
	//ProtocolManager.findProtocolFileById(fileId, writeLink); //not working on linux
	ProtocolManager.getProtocolFileUriById(fileId, writeLink);
	if (document.getElementById("updatedUri") != null) {
		ProtocolManager.getProtocolFileUriById(fileId, function (data) {
			document.getElementById("updatedUri").value = data;
		});
	}
	if (document.getElementById("updatedName") != null) {
		ProtocolManager.getProtocolFileNameById(fileId, function (data) {
			document.getElementById("updatedName").value = data;
		});
	}
	if (document.getElementById("updatedVersion") != null) {
		ProtocolManager.getProtocolFileVersionById(fileId, function (data) {
			document.getElementById("updatedVersion").value = data;
		});
	}
}
function writeLink(uri) {
	var fileId = document.getElementById("protocolFileId").value;
	if (uri != null) {
		var fileUri = uri;
		if (fileUri != null) {
			document.getElementById("protocolFileLink").innerHTML = "" + fileUri + "";
		} else {
			document.getElementById("protocolFileLink").innerHTML = "";
		}
	} else {
		document.getElementById("protocolFileLink").innerHTML = "";
	}
}

//not working on linux
function writeLink0(protocolFile) {
	var fileId = document.getElementById("protocolFileId").value;
	if (protocolFile != null) {
		var fileUri = protocolFile.domainUri;
		if (fileUri != null) {
			document.getElementById("protocolFileLink").innerHTML = "" + fileUri + "";
		} else {
			document.getElementById("protocolFileLink").innerHTML = "";
		}
	} else {
		document.getElementById("protocolFileLink").innerHTML = "";
	}
}

function setProtocolNameDropdown() {
	var searchLocations = getSelectedOptions(document.getElementById("searchLocations"));
	ProtocolManager.getProtocolTypes(searchLocations, function (data) {
			dwr.util.removeAllOptions("protocolType");
			dwr.util.addOptions("protocolType", data);
		});

	return false;
}

<|endoftext|>


<commit_before>var $ = require("jquery");

/*
 * Get all drop points via the API that have changed since the time given.
 */
function update_drop_points(ts) {
    var date = Date.now()/1000;
    $.ajax({
        type: "POST",
        url: apiurl,
        data: {
            action: "dp_json",
            ts: ts
        },
        dataType: "json",
        success: function (response) {
            $.extend(true, drop_points, response);
            for (var num in response) {
                refresh_drop_point(num);
            }
        },
        complete: function () {
            setTimeout(function() {
                update_drop_points(date);
            }, 120000);
        }
    });
}

/*
 * Refresh the given drop point in the map, list etc.
 *
 * This function is intended to be called whenever the drop point has changed,
  * either by an update from the API or locally.
 */
global.refresh_drop_point = function(num) {
    if (typeof map != "undefined") {
        draw_marker(num);
    }
    if (typeof dt != "undefined") {
        draw_row(num);
    }
};

global.init_drop_point_refreshing = function() {
    setTimeout(function() {
        update_drop_points(Date.now()/1000);
    }, 120000);
};

/* vim: set expandtab ts=4 sw=4: */
<commit_msg>Fix polling<commit_after>var $ = require("jquery");

/*
 * Get all drop points via the API that have changed since the time given.
 */
function update_drop_points(ts) {
    var _ts = Date.now()/1000;
    $.ajax({
        type: "POST",
        url: apiurl,
        data: {
            action: "dp_json",
            ts: ts
        },
        dataType: "json",
        success: function (response) {
            $.extend(true, drop_points, response);
            for (var num in response) {
                refresh_drop_point(num);
            }
        },
        complete: function () {
            setTimeout(function() {
                update_drop_points(_ts);
            }, 120000);
        }
    });
}

/*
 * Refresh the given drop point in the map, list etc.
 *
 * This function is intended to be called whenever the drop point has changed,
  * either by an update from the API or locally.
 */
global.refresh_drop_point = function(num) {
    if (typeof map != "undefined") {
        draw_marker(num);
    }
    if (typeof dt != "undefined") {
        draw_row(num);
    }
};

global.init_drop_point_refreshing = function() {
    var ts = Date.now()/1000;
    setTimeout(function() {
        update_drop_points(ts);
    }, 120000);
};

/* vim: set expandtab ts=4 sw=4: */
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const config = require('./config');
const moment = require('moment');
const spawn = require('child_process').spawn;
const Promise = require('bluebird');
const AWS = require('aws-sdk');
AWS.config.loadFromPath(path.join(__dirname,'credentials.json'));
const s3 = new AWS.S3();

function Picture(){

  this.filepath;
  this.keyname;
  this.url;

  this.getUrl = function(expires){
    expires = expires ? expires : 60;
    var params = {Bucket: config.aws_s3_bucket, Key: this.keyname, Expires: expires};
    this.url = s3.getSignedUrl('getObject', params);
  	return this.url;
  }
}

var captureProc = null;
function takePicture() {
  return new Promise(function(resolve){

    if(captureProc != null) {
      captureProc.kill();
      captureProc = null;
	  }

    var date = moment.utc();
    var datestr = date.format('YYYYMMDDHHmmss');
    var filename = datestr+".jpg";
    var filepath = path.join(config.capture_dir, filename);
    var keyname = date.format("YYYY/MM/DD/") + filename;
    var args = ["-awb", "auto", "-ex", "auto", "-w", config.capture_width, "-h", config.capture_height, "-vf", "-o", filepath];

    console.info(keyname + "\tcapture started")
    captureProc = spawn('raspistill', args);
    console.info(keyname + "\tcapture complete")

    var picture = new Picture();
    picture.filepath = filepath;
    picture.keyname = keyname;

    captureProc.on('close', function(code){
      resolve(picture);
	  });
  });
}

function uploadPicture(picture) {
  return new Promise(function(resolve, reject){
    fs.readFile(picture.filepath, function(err, data) {
      if(err) throw err;

      var s3bucket = new AWS.S3({params: {Bucket: config.aws_s3_bucket }});
      var params = {
        Key: picture.keyname,
        Body: data
      };

      console.info(picture.keyname + "\tupload started");
      s3bucket.upload(params, function (err, data) {
        if (err) {
        	reject(err);
        } else {
          console.info(picture.keyname + "\tupload complete");
          resolve(picture);
        }
      });
	  });
  });
}

function deleteFile(picture) {
  return new Promise(function(resolve, reject){
    fs.unlink(picture.filepath, function(err){
      if (err) throw err;
      console.info(picture.keyname + "\tdeleted local file\t" + picture.filepath);
      resolve(picture);
    });
  });
}

function capture(){
  takePicture()
    .then(uploadPicture)
    .then(deleteFile)
    .then(function(picture){
      console.info(picture.keyname + "\turl created\t" + picture.getUrl(60));
    });
}

var interval;
var pid_path = path.join(__dirname,'pilapse.pid');

function start(){
  fs.readFile(pid_path, function(err, data){
    if (!err) {

      throw new Error('Process '+ data +' already running from '+pid_path);

    } else {

      var pid = String(process.pid);
      fs.writeFile(pid_path, pid, function(err) {
        if (err) throw err;
      });

      console.info("process\tstarting timelapse\t" + config.capture_frequency + " seconds");

      capture(); // take picture on start
      interval = setInterval(function(){
        capture();
      }, config.capture_frequency * 1000)

    }
  });
}

function stop(){

  fs.unlink(pid_path, function(err){
    if (err) throw err;
  });

  if(interval) clearInterval(interval);
  console.info("process\thalting timelapse");
}

// MAIN :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

// Let's get this party started, right?

start();
process.on('SIGTERM', stop);
process.on('SIGINT', stop);
<commit_msg>Removing pid file management.  Instead handling this in the init.d service.<commit_after>const fs = require('fs');
const path = require('path');
const config = require('./config');
const moment = require('moment');
const spawn = require('child_process').spawn;
const Promise = require('bluebird');
const AWS = require('aws-sdk');
AWS.config.loadFromPath(path.join(__dirname,'credentials.json'));
const s3 = new AWS.S3();

function Picture(){

  this.filepath;
  this.keyname;
  this.url;

  this.getUrl = function(expires){
    expires = expires ? expires : 60;
    var params = {Bucket: config.aws_s3_bucket, Key: this.keyname, Expires: expires};
    this.url = s3.getSignedUrl('getObject', params);
  	return this.url;
  }
}

var captureProc = null;
function takePicture() {
  return new Promise(function(resolve){

    if(captureProc != null) {
      captureProc.kill();
      captureProc = null;
	  }

    var date = moment.utc();
    var datestr = date.format('YYYYMMDDHHmmss');
    var filename = datestr+".jpg";
    var filepath = path.join(config.capture_dir, filename);
    var keyname = date.format("YYYY/MM/DD/") + filename;
    var args = ["-awb", "auto", "-ex", "auto", "-w", config.capture_width, "-h", config.capture_height, "-vf", "-o", filepath];

    console.info(keyname + "\tcapture started")
    captureProc = spawn('raspistill', args);
    console.info(keyname + "\tcapture complete")

    var picture = new Picture();
    picture.filepath = filepath;
    picture.keyname = keyname;

    captureProc.on('close', function(code){
      resolve(picture);
	  });
  });
}

function uploadPicture(picture) {
  return new Promise(function(resolve, reject){
    fs.readFile(picture.filepath, function(err, data) {
      if(err) throw err;

      var s3bucket = new AWS.S3({params: {Bucket: config.aws_s3_bucket }});
      var params = {
        Key: picture.keyname,
        Body: data
      };

      console.info(picture.keyname + "\tupload started");
      s3bucket.upload(params, function (err, data) {
        if (err) {
        	reject(err);
        } else {
          console.info(picture.keyname + "\tupload complete");
          resolve(picture);
        }
      });
	  });
  });
}

function deleteFile(picture) {
  return new Promise(function(resolve, reject){
    fs.unlink(picture.filepath, function(err){
      if (err) throw err;
      console.info(picture.keyname + "\tdeleted local file\t" + picture.filepath);
      resolve(picture);
    });
  });
}

function capture(){
  takePicture()
    .then(uploadPicture)
    .then(deleteFile)
    .then(function(picture){
      console.info(picture.keyname + "\turl created\t" + picture.getUrl(60));
    });
}

var interval;
function start(){
  console.info("process\tstarting timelapse\t" + config.capture_frequency + " seconds");
  capture(); // take picture on start
  interval = setInterval(function(){
    capture();
  }, config.capture_frequency * 1000)
}

function stop(){
  if(interval) clearInterval(interval);
  console.info("process\thalting timelapse");
}

// MAIN :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

// Let's get this party started, right?

start();
process.on('SIGTERM', stop);
process.on('SIGINT', stop);
<|endoftext|>