<commit_before>'use strict';

const expect = require('chai').expect,
    fail = expect.fail,
    JDLField = require('../../../lib/core/jdl_field'),
    JDLValidation = require('../../../lib/core/jdl_validation');

describe('JDLField', function () {
  describe('::new', function () {
    describe('when not passing any argument', function () {
      it('fails', function () {
        try {
          new JDLField();
          fail();
        } catch (error) {
          expect(error.name).to.eq('NullPointerException');
        }
      });
    });
    describe('when not passing the name or the type', function () {
      it('fails', function () {
        try {
          new JDLField({name: null, type: 'String'});
          fail();
        } catch (error) {
          expect(error.name).to.eq('NullPointerException');
        }
        try {
          new JDLField({name: 'abc', type: null});
          fail();
        } catch (error) {
          expect(error.name).to.eq('NullPointerException');
        }
      });
    });
    describe('when passing arguments', function () {
      it('creates a new instance', function () {
        var args = {
          name: 'abc',
          type: 'String',
          comment: 'comment',
          validations: [new JDLValidation()]
        };
        var field = new JDLField(args);
        expect(field.name).to.eq(args.name);
        expect(field.type).to.eq(args.type);
        expect(field.comment).to.eq(args.comment);
        expect(field.validations).to.deep.eq(args.validations);
      });
    });
  });
  describe('::isValid', function() {
    describe('when checking the validity of an object', function() {
      it('returns false', function() {
        expect(JDLField.isValid(null)).to.be.false;
        expect(JDLField.isValid(undefined)).to.be.false;
      });
    });
    describe('when checking the validity of an object without a name attribute', function() {
      it('returns false', function() {
        expect(JDLField.isValid({type: 'String'})).to.be.false;
      });
    });
    describe('when checking the validity of an object without a type attribute', function() {
      it('returns false', function() {
        expect(JDLField.isValid({name: 'myField'})).to.be.false;
      });
    });
    describe('when checking the validity of an object with a name and a type attribute', function() {
      it('returns true', function() {
        expect(JDLField.isValid({name: 'myField', type: 'String'})).to.be.true;
      });
    });
  });
  describe('#toString', function () {
    describe('without comment', function () {
      it('stringifies the fields', function () {
        var args = {
          name: 'abc',
          type: 'String'
        };
        var field = new JDLField(args);
        expect(field.toString()).to.eq(`${args.name} ${args.type}`);
      });
    });
    describe('without any validation', function () {
      it('stringifies the fields', function () {
        var args = {
          name: 'abc',
          type: 'String',
          comment: 'comment'
        };
        var field = new JDLField(args);
        expect(field.toString()).to.eq(`/**\n * ${args.comment}\n */\n`
            + `${args.name} ${args.type}`);
      });
    });
    describe('with everything', function () {
      it('stringifies the field', function () {
        var args = {
          name: 'abc',
          type: 'String',
          comment: 'comment',
          validations: [new JDLValidation(), new JDLValidation({
            name: 'minlength',
            value: 42
          })]
        };
        var field = new JDLField(args);
        expect(field.toString()).to.eq(`/**\n * ${args.comment}\n */\n`
            + `${args.name} ${args.type} ${args.validations[0].name} `
            + `${args.validations[1].name}(${args.validations[1].value})`);
      });
    });
  });
});
<commit_msg>Cleaned up tests<commit_after>'use strict';

const expect = require('chai').expect,
    fail = expect.fail,
    JDLField = require('../../../lib/core/jdl_field'),
    JDLValidation = require('../../../lib/core/jdl_validation');

describe('JDLField', function () {
  describe('::new', function () {
    describe('when not passing any argument', function () {
      it('fails', function () {
        try {
          new JDLField();
          fail();
        } catch (error) {
          expect(error.name).to.eq('NullPointerException');
        }
      });
    });
    describe('when not passing the name or the type', function () {
      it('fails', function () {
        try {
          new JDLField({name: null, type: 'String'});
          fail();
        } catch (error) {
          expect(error.name).to.eq('NullPointerException');
        }
        try {
          new JDLField({name: 'abc', type: null});
          fail();
        } catch (error) {
          expect(error.name).to.eq('NullPointerException');
        }
      });
    });
    describe('when passing arguments', function () {
      it('creates a new instance', function () {
        var args = {
          name: 'abc',
          type: 'String',
          comment: 'comment',
          validations: [new JDLValidation()]
        };
        var field = new JDLField(args);
        expect(field.name).to.eq(args.name);
        expect(field.type).to.eq(args.type);
        expect(field.comment).to.eq(args.comment);
        expect(field.validations).to.deep.eq(args.validations);
      });
    });
  });
  describe('::isValid', function() {
    describe('when checking the validity of an invalid object', function() {
      describe('because it is nil or undefined', function() {
        it('returns false', function() {
          expect(JDLField.isValid(null)).to.be.false;
          expect(JDLField.isValid(undefined)).to.be.false;
        });
      });
      describe('without a name attribute', function() {
        it('returns false', function() {
          expect(JDLField.isValid({type: 'String'})).to.be.false;
        });
      });
      describe('without a type attribute', function() {
        it('returns false', function() {
          expect(JDLField.isValid({name: 'myField'})).to.be.false;
        });
      });
    });
    describe('when checking the validity of a valid object', function() {
      it('returns true', function() {
        expect(JDLField.isValid({name: 'myField', type: 'String'})).to.be.true;
      });
    });
  });
  describe('#toString', function () {
    describe('without comment', function () {
      it('stringifies the fields', function () {
        var args = {
          name: 'abc',
          type: 'String'
        };
        var field = new JDLField(args);
        expect(field.toString()).to.eq(`${args.name} ${args.type}`);
      });
    });
    describe('without any validation', function () {
      it('stringifies the fields', function () {
        var args = {
          name: 'abc',
          type: 'String',
          comment: 'comment'
        };
        var field = new JDLField(args);
        expect(field.toString()).to.eq(`/**\n * ${args.comment}\n */\n`
            + `${args.name} ${args.type}`);
      });
    });
    describe('with everything', function () {
      it('stringifies the field', function () {
        var args = {
          name: 'abc',
          type: 'String',
          comment: 'comment',
          validations: [new JDLValidation(), new JDLValidation({
            name: 'minlength',
            value: 42
          })]
        };
        var field = new JDLField(args);
        expect(field.toString()).to.eq(`/**\n * ${args.comment}\n */\n`
            + `${args.name} ${args.type} ${args.validations[0].name} `
            + `${args.validations[1].name}(${args.validations[1].value})`);
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

const FOLDER = '8haeeqygx59lzbsn';
const OCR_URL = `https://pdftotext.com`;
const RESTAURANT_CITY_LIFE = 'CITY_LIFE';
const RESTAURANT_ANTARES = 'ANTARES';

const requestPDF = require('request-promise-native').defaults({ json: true, baseUrl: OCR_URL });
const requestMessages = require('request-promise-native').defaults({ json: true });
const requestRestaurant = require('request').defaults({ encoding: null });
const fileType = require('file-type');

const now = new Date();
const DATE = `${now.getDate()}_${now.getMonth()+1}_${now.getFullYear()}`;

const RESTAURANT_PARAMETERS = {
    [RESTAURANT_CITY_LIFE]: {
        pdfUrl: 'http://www.cityliferistorante.it/upload/',
        name: 'City Life',
        logo: 'http://www.cityliferistorante.it/img/city_logo.png',
    },
    [RESTAURANT_ANTARES]: {
        pdfUrl: 'http://antaresristorante.it/upload/',
        name: 'Antares',
        logo: 'http://antaresristorante.it/images/antares.png',
    },
};

const getFile = url => new Promise((resolve, reject) => requestRestaurant(url, (err, res, data) => {
    if (err) {
        return reject(err);
    }
    const dataType = fileType(data);

    if (!dataType || dataType.ext !== 'pdf') {
        return reject(new Error('Not pdf'));
    }
    resolve(data);
}));

const getFilename = () => `menu_pranzo_${DATE}_16_00`;
const getRestaurantName = restaurant => RESTAURANT_PARAMETERS[restaurant]['name'];
const getRestaurantLogo = restaurant => RESTAURANT_PARAMETERS[restaurant]['logo'];
const getRestaurantFileUrl = restaurant => `${RESTAURANT_PARAMETERS[restaurant]['pdfUrl']}${getFilename()}.pdf`;
const getShareUrl = pdfUrl => `https://docs.google.com/viewerng/viewer?url=${pdfUrl}&usp=sharing`;

const sendHipchat = (restaurant, text) => {
    const { env: { HIPCHAT_URL } } = process;
    const PDF_URL = getRestaurantFileUrl(restaurant);
    const NAME = getRestaurantName(restaurant);
    const LOGO = getRestaurantLogo(restaurant);
    const SHARE_URL = getShareUrl(PDF_URL);
    const HUMAN_DATE = DATE.replace(/_/g, '/');

    return HIPCHAT_URL
        ? requestMessages.post(HIPCHAT_URL, {
            body: {
                color: 'green',
                message: `<a href=${SHARE_URL}><img src=${LOGO}><br><br>Menu ${NAME} del <b>${HUMAN_DATE}</b></a><br><br>${text.replace('\n', '<br>')}`,
                notify: true,
                message_format: 'html',
            }
        })
        : Promise.resolve();
};

const sendSlack = (restaurant, text) => {
    const { env: { SLACK_URL } } = process;
    const PDF_URL = getRestaurantFileUrl(restaurant);
    const NAME = getRestaurantName(restaurant);
    const LOGO = getRestaurantLogo(restaurant);
    const SHARE_URL = getShareUrl(PDF_URL);
    const HUMAN_DATE = DATE.replace(/_/g, '/');

    return SLACK_URL
        ? requestMessages.post(SLACK_URL, {
            body: {
                username: NAME,
                icon_url: LOGO,
                attachments: [
                    {
                        text,
                        fallback: `Menu del ${HUMAN_DATE}`,
                        title: `Menu del ${HUMAN_DATE}`,
                        title_link: SHARE_URL,
                        color: 'good',
                        thumb_url: LOGO,
                        author_icon: LOGO,
                        author_name: NAME,
                    }
                ]
            }
        })
        : Promise.resolve();
};

const sendPushbullet = (restaurant, text) => {
    const { env: { PUSHBULLET_TOKEN } } = process;
    const PDF_URL = getRestaurantFileUrl(restaurant);
    const NAME = getRestaurantName(restaurant);
    const SHARE_URL = getShareUrl(PDF_URL);
    const HUMAN_DATE = DATE.replace(/_/g, '/');

    return PUSHBULLET_TOKEN
        ? requestMessages.post('https://api.pushbullet.com/v2/pushes', {
            body: {
                type: 'link',
                body: text,
                title: `Menu ${NAME} del ${HUMAN_DATE}`,
                url: SHARE_URL,
                channel_tag: 'antares'
            },
            headers: {
                'access-token': PUSHBULLET_TOKEN,
            }
        })
        : Promise.resolve();
};

const getMenu = restaurant => {
    const FILENAME = getFilename();
    const FILENAME_TXT = `${FILENAME}.txt`;
    const FILENAME_PDF = `${FILENAME}.pdf`;
    const PDF_URL = getRestaurantFileUrl(restaurant);
    const JOB_ID = Math.random().toString(16).substring(5);

    return getFile(PDF_URL)
        .then(file => requestPDF.post(`/upload/${FOLDER}`, {
            formData: {
                file: {
                    value: file,
                    options: {
                        filename: FILENAME_PDF,
                        contentType: 'application/pdf'
                    }
                },
                id: JOB_ID,
            }
        }))
        .then(data => {
            console.log(data);
            return requestPDF(`/convert/${FOLDER}/${JOB_ID}`, {
                qs: {
                    rnd: '0.16389987427930808'
                }
            })
        })
        .then(data => {
            console.log(data);
            if (data.status !== 'success') {
                throw new Error('Error during OCR start');
            }
            return new Promise(resolve => setTimeout(resolve, 2000));
        })
        .then(() => requestPDF(`/status/${FOLDER}/${JOB_ID}`))
        .then(data  => {
            console.log(data);
            if (data.status !== 'success') {
                throw new Error('Error during OCR status check');
            }
            return requestPDF(`/files/${FOLDER}/${JOB_ID}/${FILENAME_TXT}`)
        })
        .then(text => text
            .replace(/.*PASTA AL POMODORO\.?$/gsm, '')
            .split('\n')
            .filter(Boolean)
            .filter(row => row.match(/€ *[0-9]*[0-9],*\.*[0-9][0-9]/) === null)
            .filter(row => row.match(/PRIM.*/) === null)
            .filter(row => row.match(/SECOND.*/) === null)
            .filter(row => row.match(/PIATT.*/) === null)
            .filter(row => row.match(/BUON.*/) === null)
            .filter(row => row.match(/Buon.*/) === null)
            .filter(row => row.match(/UNICO.*/) === null)
            .filter(row => row.match(/BIS.*/) === null)
            .filter(row => row.match(/RISO.*INGLESE.*/) === null)
            .join('\n')
            .replace(/€.*/, '')
            .replace(/\.\n/g, '\n')
        )
        .then(text => Promise.all([
            sendHipchat(restaurant, text),
            sendSlack(restaurant, text),
            sendPushbullet(restaurant, text),
        ]));
};

module.exports = (context, cb) => {
    process.env = {
        ...process.env,
        ...context.secrets,
    };
    return Promise.all([RESTAURANT_ANTARES, RESTAURANT_CITY_LIFE].map(getMenu))
        .then(() => cb(null, 'ok'))
        .catch(cb);
};
<commit_msg>Capitalize each row<commit_after>'use strict';

const FOLDER = '8haeeqygx59lzbsn';
const OCR_URL = `https://pdftotext.com`;
const RESTAURANT_CITY_LIFE = 'CITY_LIFE';
const RESTAURANT_ANTARES = 'ANTARES';

const requestPDF = require('request-promise-native').defaults({ json: true, baseUrl: OCR_URL });
const requestMessages = require('request-promise-native').defaults({ json: true });
const requestRestaurant = require('request').defaults({ encoding: null });
const fileType = require('file-type');

const now = new Date();
const DATE = `${now.getDate()}_${now.getMonth()+1}_${now.getFullYear()}`;

const RESTAURANT_PARAMETERS = {
    [RESTAURANT_CITY_LIFE]: {
        pdfUrl: 'http://www.cityliferistorante.it/upload/',
        name: 'City Life',
        logo: 'http://www.cityliferistorante.it/img/city_logo.png',
    },
    [RESTAURANT_ANTARES]: {
        pdfUrl: 'http://antaresristorante.it/upload/',
        name: 'Antares',
        logo: 'http://antaresristorante.it/images/antares.png',
    },
};

const getFile = url => new Promise((resolve, reject) => requestRestaurant(url, (err, res, data) => {
    if (err) {
        return reject(err);
    }
    const dataType = fileType(data);

    if (!dataType || dataType.ext !== 'pdf') {
        return reject(new Error('Not pdf'));
    }
    resolve(data);
}));

const getFilename = () => `menu_pranzo_${DATE}_16_00`;
const getRestaurantName = restaurant => RESTAURANT_PARAMETERS[restaurant]['name'];
const getRestaurantLogo = restaurant => RESTAURANT_PARAMETERS[restaurant]['logo'];
const getRestaurantFileUrl = restaurant => `${RESTAURANT_PARAMETERS[restaurant]['pdfUrl']}${getFilename()}.pdf`;
const getShareUrl = pdfUrl => `https://docs.google.com/viewerng/viewer?url=${pdfUrl}&usp=sharing`;

const sendHipchat = (restaurant, text) => {
    const { env: { HIPCHAT_URL } } = process;
    const PDF_URL = getRestaurantFileUrl(restaurant);
    const NAME = getRestaurantName(restaurant);
    const LOGO = getRestaurantLogo(restaurant);
    const SHARE_URL = getShareUrl(PDF_URL);
    const HUMAN_DATE = DATE.replace(/_/g, '/');

    return HIPCHAT_URL
        ? requestMessages.post(HIPCHAT_URL, {
            body: {
                color: 'green',
                message: `<a href=${SHARE_URL}><img src=${LOGO}><br><br>Menu ${NAME} del <b>${HUMAN_DATE}</b></a><br><br>${text.replace('\n', '<br>')}`,
                notify: true,
                message_format: 'html',
            }
        })
        : Promise.resolve();
};

const sendSlack = (restaurant, text) => {
    const { env: { SLACK_URL } } = process;
    const PDF_URL = getRestaurantFileUrl(restaurant);
    const NAME = getRestaurantName(restaurant);
    const LOGO = getRestaurantLogo(restaurant);
    const SHARE_URL = getShareUrl(PDF_URL);
    const HUMAN_DATE = DATE.replace(/_/g, '/');

    return SLACK_URL
        ? requestMessages.post(SLACK_URL, {
            body: {
                username: NAME,
                icon_url: LOGO,
                attachments: [
                    {
                        text,
                        fallback: `Menu del ${HUMAN_DATE}`,
                        title: `Menu del ${HUMAN_DATE}`,
                        title_link: SHARE_URL,
                        color: 'good',
                        thumb_url: LOGO,
                        author_icon: LOGO,
                        author_name: NAME,
                    }
                ]
            }
        })
        : Promise.resolve();
};

const sendPushbullet = (restaurant, text) => {
    const { env: { PUSHBULLET_TOKEN } } = process;
    const PDF_URL = getRestaurantFileUrl(restaurant);
    const NAME = getRestaurantName(restaurant);
    const SHARE_URL = getShareUrl(PDF_URL);
    const HUMAN_DATE = DATE.replace(/_/g, '/');

    return PUSHBULLET_TOKEN
        ? requestMessages.post('https://api.pushbullet.com/v2/pushes', {
            body: {
                type: 'link',
                body: text,
                title: `Menu ${NAME} del ${HUMAN_DATE}`,
                url: SHARE_URL,
                channel_tag: 'antares'
            },
            headers: {
                'access-token': PUSHBULLET_TOKEN,
            }
        })
        : Promise.resolve();
};

const getMenu = restaurant => {
    const FILENAME = getFilename();
    const FILENAME_TXT = `${FILENAME}.txt`;
    const FILENAME_PDF = `${FILENAME}.pdf`;
    const PDF_URL = getRestaurantFileUrl(restaurant);
    const JOB_ID = Math.random().toString(16).substring(5);

    return getFile(PDF_URL)
        .then(file => requestPDF.post(`/upload/${FOLDER}`, {
            formData: {
                file: {
                    value: file,
                    options: {
                        filename: FILENAME_PDF,
                        contentType: 'application/pdf'
                    }
                },
                id: JOB_ID,
            }
        }))
        .then(data => {
            console.log(data);
            return requestPDF(`/convert/${FOLDER}/${JOB_ID}`, {
                qs: {
                    rnd: '0.16389987427930808'
                }
            })
        })
        .then(data => {
            console.log(data);
            if (data.status !== 'success') {
                throw new Error('Error during OCR start');
            }
            return new Promise(resolve => setTimeout(resolve, 2000));
        })
        .then(() => requestPDF(`/status/${FOLDER}/${JOB_ID}`))
        .then(data  => {
            console.log(data);
            if (data.status !== 'success') {
                throw new Error('Error during OCR status check');
            }
            return requestPDF(`/files/${FOLDER}/${JOB_ID}/${FILENAME_TXT}`)
        })
        .then(text => text
            .replace(/.*PASTA AL POMODORO\.?$/gsm, '')
            .split('\n')
            .filter(Boolean)
            .filter(row => row.match(/€ *[0-9]*[0-9],*\.*[0-9][0-9]/) === null)
            .filter(row => row.match(/PRIM.*/) === null)
            .filter(row => row.match(/SECOND.*/) === null)
            .filter(row => row.match(/PIATT.*/) === null)
            .filter(row => row.match(/BUON.*/) === null)
            .filter(row => row.match(/Buon.*/) === null)
            .filter(row => row.match(/UNICO.*/) === null)
            .filter(row => row.match(/BIS.*/) === null)
            .filter(row => row.match(/RISO.*INGLESE.*/) === null)
            .map(row => `${row[0]}${row.slice(1).toLowerCase()}`)
            .join('\n')
            .replace(/€.*/, '')
            .replace(/\.\n/g, '\n')
        )
        .then(text => Promise.all([
            sendHipchat(restaurant, text),
            sendSlack(restaurant, text),
            sendPushbullet(restaurant, text),
        ]));
};

module.exports = (context, cb) => {
    process.env = {
        ...process.env,
        ...context.secrets,
    };
    return Promise.all([RESTAURANT_ANTARES, RESTAURANT_CITY_LIFE].map(getMenu))
        .then(() => cb(null, 'ok'))
        .catch(cb);
};
<|endoftext|>


<commit_before>var Observable = require('vjs/lib/observable')
var app = require('../../../lib/app')

var readyPlayer = new Observable({
  id: "",
  duration: {
    $val: 100,
    // $on: {
    //   $change: function () {
    //     app.controls.play.selector.$attributes.max.set({
    //       $val: 10
    //     })
    //   }
    // }
  }
})

kWidget.addReadyCallback(function(playerId) {
  kdp = readyPlayer.id = document.getElementById(playerId)
  setInfo(kdp)
  setTime(kdp)
  // doSeek(kdp)
})

var setTime = function (playerId) {
  console.log(playerId)
  playerId.addJsListener("playerUpdatePlayhead", function(data) {
    app.controls.play.elapsed.$text.$val = Math.floor(data)
    app.controls.play.selector.$attributes.value.$val = Math.floor(data)
  })
}

var setInfo = function (title) {
  kdp.addJsListener('kdpReady', function() {
    app.title.$text.$val = readyPlayer.id.evaluate('{mediaProxy.entry.name}')
    app.title.description.$text.$val = readyPlayer.id.evaluate('{mediaProxy.entry.description}')
    app.controls.play.selector.$attributes.max.$val = readyPlayer.id.evaluate('{mediaProxy.entry.duration}')
    app.controls.play.duration.$text.$val = readyPlayer.id.evaluate('{mediaProxy.entry.duration}')
  })
}

var doSeek = function (kdp) {
  kdp.kBind('playerSeekEnd', function() {
    setTimeout(function() {
      kdp.sendNotification('doPause');
    }, 2000)
  });
  var seekDone = false;
  kdp.kBind('playerUpdatePlayhead', function() {
    if (!seekDone) {
      kdp.sendNotification('doSeek', 30);
    }
    seekDone = true;
  });
  kdp.kBind('mediaReady', function() {
    kdp.sendNotification('doPlay');
  })
}

exports.readyPlayer = readyPlayer
exports.setTime = setTime
exports.setInfo = setInfo
exports.doSeek = doSeek
<commit_msg>fixed seekbar again<commit_after>var Observable = require('vjs/lib/observable')
var app = require('../../../lib/app')

var readyPlayer = new Observable({
  id: "",
  duration: {
    $val: 100,
    // $on: {
    //   $change: function () {
    //     app.controls.play.selector.$attributes.max.set({
    //       $val: 10
    //     })
    //   }
    // }
  }
})

kWidget.addReadyCallback(function(playerId) {
  kdp = readyPlayer.id = document.getElementById(playerId)
  setInfo(kdp)
  setTime(kdp)
  // doSeek(kdp)
})

var setTime = function (playerId) {
  playerId.addJsListener("playerUpdatePlayhead", function(data) {
    app.controls.play.elapsed.$text.$val = Math.floor(data)
    app.controls.play.selector.$node.value = Math.floor(data)
  })
}

var setInfo = function (title) {
  kdp.addJsListener('kdpReady', function() {
    app.title.$text.$val = readyPlayer.id.evaluate('{mediaProxy.entry.name}')
    app.title.description.$text.$val = readyPlayer.id.evaluate('{mediaProxy.entry.description}')
    app.controls.play.selector.$attributes.max.$val = readyPlayer.id.evaluate('{mediaProxy.entry.duration}')
    app.controls.play.duration.$text.$val = readyPlayer.id.evaluate('{mediaProxy.entry.duration}')
  })
}

var doSeek = function (kdp) {
  kdp.kBind('playerSeekEnd', function() {
    setTimeout(function() {
      kdp.sendNotification('doPause');
    }, 2000)
  });
  var seekDone = false;
  kdp.kBind('playerUpdatePlayhead', function() {
    if (!seekDone) {
      kdp.sendNotification('doSeek', 30);
    }
    seekDone = true;
  });
  kdp.kBind('mediaReady', function() {
    kdp.sendNotification('doPlay');
  })
}

exports.readyPlayer = readyPlayer
exports.setTime = setTime
exports.setInfo = setInfo
exports.doSeek = doSeek
<|endoftext|>


<commit_before>/*****************************************************************************
 * Tillegg som automatiserer utlån, stikkseddel-utskrift og hentebeskjed
 * for mottatte dokumenter.
 * slik at man slipper å tabbe ned til dokid-feltet.
 *****************************************************************************/
$.bibduck.plugins.push({
    name: 'IMO auto-stikk',
	bestnr: '',

	send_hentb: function(bibsys, callback) {
		bibsys.resetPointer();
		bibsys.send('hentb,\n');
		bibsys.wait_for('Kryss av for ønsket valg', [16,8], function() {
			bibsys.send('X\n');
			bibsys.wait_for([
				['Hentebeskjed er sendt', [1,1], function() {
					$.bibduck.log('Ok, hentebeskjed sendt!');
					bibsys.resetPointer();
					if (callback !== undefined) {
						bibsys.bringToFront();
						callback(bibsys);
					}
				}],
				['Registrer eventuell melding', [8,5], function() {
					$.bibduck.log('Ok, vi stanser her');
					bibsys.bringToFront();
				}]
			]);
		});
	},

	stikkseddel: function(bibsys) {
		var sid = -1,
			splug,
			that = this;
		for (var j = 0; j < $.bibduck.plugins.length; j += 1) {
            if ($.bibduck.plugins[j].hasOwnProperty('name') && $.bibduck.plugins[j].name === 'Stikkseddel-tillegg') {
				sid = j;
				break;
			}
		}
		if (sid === -1) {
			$.bibduck.log('Fant ikke stikkseddel-tillegg', 'error');
			return;
		}
		splug = $.bibduck.plugins[sid];
		$.bibduck.log('Hello ' + sid);
		splug.lag_stikkseddel(bibsys, function(data) {
			$.bibduck.log('stikkseddel ferdig');
			if (data.patron.kind === 'person' && data.patron.beststed === data.beststed) {
				$.bibduck.log('skal ikke sendes. La oss sente hentb');
				that.send_hentb(bibsys);
			}
		});
	},

    update: function (bibsys) {
        var dokid,
			bestnr,
			innid,
            cursorpos,
			laan,
			that = this;

		if ($.bibduck.libnr === '1030310') {
			// Eksperimentelt tillegg, foreløpig skrur vi det bare på for UREAL

			// Har vi mottatt noe?
			if (bibsys.get(1, 11, 20) === 'er mottatt') {

				$.bibduck.bringToFront(); // to avoid accidental key presses

				// Hva da?
				bestnr = bibsys.get(1, 1, 9);
				if (bestnr !== this.bestnr) {
					this.bestnr = bestnr;
					innid = bibsys.get(1, 31, 39);
					dokid = bibsys.get(4, 42, 50);
					laan = bibsys.get(8, 37, 37);
					ltid = bibsys.get(5, 13, 22);
					ltnavn = bibsys.get(5, 26, 61);

					if (laan === 'L') {
						$.bibduck.log('Mottok lån');
						$.bibduck.log('>  Bestnr: ' + bestnr + ', innid: ' + innid + ', dokid: ' + dokid);
						bibsys.resetPointer();
						bibsys.send('reg,\n');
						bibsys.wait_for('Registrere utlån', 2, function() {
							bibsys.send('\n');
							bibsys.wait_for([
								['Dokumentet er reservert for annen låntaker!', [1,1], function() {
									bibsys.send('\n');
									bibsys.wait_for('Lån registrert', [1,1], function() {
										that.stikkseddel(bibsys);
									});
								}],
								['Lån registrert', [1,1], function() {
									that.stikkseddel(bibsys);
								}]
							]);
						});

					} else {
						$.bibduck.log('Mottok kopi');
						$.bibduck.log('  Bestnr: ' + bestnr + ', innid: ' + innid + ', dokid: ' + dokid);
						bibsys.resetPointer();
						that.send_hentb(bibsys, function() {
							var ltnavn = bibsys.get(1, 34, 79);
							// Nå kan vi skrive ut navn og dato
							// Egentlig kan vi gjøre det direkte nå. Vi har både ltid og navn,
							// men inntil videre kan vi sende til ltsøk for å bruke kyrres navn og dato
							bibsys.send('ltsø,' + ltid + '\n');
							bibsys.wait_for('Ltid', [7,1], function() {
								bibsys.send('\n');
								bibsys.bringToFront();
							});
						});
					}
				}
			}
        }
    }
});
<commit_msg>Skrur på imott-auto for INF også<commit_after>/*****************************************************************************
 * Tillegg som automatiserer utlån, stikkseddel-utskrift og hentebeskjed
 * for mottatte dokumenter.
 * slik at man slipper å tabbe ned til dokid-feltet.
 *****************************************************************************/
$.bibduck.plugins.push({
    name: 'IMO auto-stikk',
	bestnr: '',

	send_hentb: function(bibsys, callback) {
		bibsys.resetPointer();
		bibsys.send('hentb,\n');
		bibsys.wait_for('Kryss av for ønsket valg', [16,8], function() {
			bibsys.send('X\n');
			bibsys.wait_for([
				['Hentebeskjed er sendt', [1,1], function() {
					$.bibduck.log('Ok, hentebeskjed sendt!');
					bibsys.resetPointer();
					if (callback !== undefined) {
						bibsys.bringToFront();
						callback(bibsys);
					}
				}],
				['Registrer eventuell melding', [8,5], function() {
					$.bibduck.log('Ok, vi stanser her');
					bibsys.bringToFront();
				}]
			]);
		});
	},

	stikkseddel: function(bibsys) {
		var sid = -1,
			splug,
			that = this;
		for (var j = 0; j < $.bibduck.plugins.length; j += 1) {
            if ($.bibduck.plugins[j].hasOwnProperty('name') && $.bibduck.plugins[j].name === 'Stikkseddel-tillegg') {
				sid = j;
				break;
			}
		}
		if (sid === -1) {
			$.bibduck.log('Fant ikke stikkseddel-tillegg', 'error');
			return;
		}
		splug = $.bibduck.plugins[sid];
		$.bibduck.log('Hello ' + sid);
		splug.lag_stikkseddel(bibsys, function(data) {
			$.bibduck.log('stikkseddel ferdig');
			if (data.patron.kind === 'person' && data.patron.beststed === data.beststed) {
				$.bibduck.log('skal ikke sendes. La oss sente hentb');
				that.send_hentb(bibsys);
			}
		});
	},

    update: function (bibsys) {
        var dokid,
			bestnr,
			innid,
            cursorpos,
			laan,
			that = this;

		if ($.bibduck.libnr === '1030310' || $.bibduck.libnr === '1030317') {
			// Eksperimentelt tillegg, foreløpig skrur vi det bare på for UREAL og UREALINF

			// Har vi mottatt noe?
			if (bibsys.get(1, 11, 20) === 'er mottatt') {

				$.bibduck.bringToFront(); // to avoid accidental key presses

				// Hva da?
				bestnr = bibsys.get(1, 1, 9);
				if (bestnr !== this.bestnr) {
					this.bestnr = bestnr;
					innid = bibsys.get(1, 31, 39);
					dokid = bibsys.get(4, 42, 50);
					laan = bibsys.get(8, 37, 37);
					ltid = bibsys.get(5, 13, 22);
					ltnavn = bibsys.get(5, 26, 61);

					if (laan === 'L') {
						$.bibduck.log('Mottok lån');
						$.bibduck.log('>  Bestnr: ' + bestnr + ', innid: ' + innid + ', dokid: ' + dokid);
						bibsys.resetPointer();
						bibsys.send('reg,\n');
						bibsys.wait_for('Registrere utlån', 2, function() {
							bibsys.send('\n');
							bibsys.wait_for([
								['Dokumentet er reservert for annen låntaker!', [1,1], function() {
									bibsys.send('\n');
									bibsys.wait_for('Lån registrert', [1,1], function() {
										that.stikkseddel(bibsys);
									});
								}],
								['Lån registrert', [1,1], function() {
									that.stikkseddel(bibsys);
								}]
							]);
						});

					} else {
						$.bibduck.log('Mottok kopi');
						$.bibduck.log('  Bestnr: ' + bestnr + ', innid: ' + innid + ', dokid: ' + dokid);
						bibsys.resetPointer();
						that.send_hentb(bibsys, function() {
							var ltnavn = bibsys.get(1, 34, 79);
							// Nå kan vi skrive ut navn og dato
							// Egentlig kan vi gjøre det direkte nå. Vi har både ltid og navn,
							// men inntil videre kan vi sende til ltsøk for å bruke kyrres navn og dato
							bibsys.send('ltsø,' + ltid + '\n');
							bibsys.wait_for('Ltid', [7,1], function() {
								bibsys.send('\n');
								bibsys.bringToFront();
							});
						});
					}
				}
			}
        }
    }
});
<|endoftext|>


<commit_before>
var eggnog = require('../eggnog');
var config = require('./config.js');
var path = require('path');

var ctx = eggnog.newContext({
	nodeModulesAt: __dirname
});

ctx.addDirectory(__dirname + '/lib');

var cli = ctx.main();

cli(__dirname);
<commit_msg>Fix eggnog version<commit_after>
var eggnog = require('eggnog');
var config = require('./config.js');
var path = require('path');

var ctx = eggnog.newContext({
	nodeModulesAt: __dirname
});

ctx.addDirectory(__dirname + '/lib');

var cli = ctx.main();

cli(__dirname);
<|endoftext|>


<commit_before>'use strict';

var afDropzone = function(form, url, target, maxSize) {
	if ($(form).hasClass('dz-default')) return;

	var afdz = new Dropzone(form, {
		url:				url,
		thumbnailWidth:		200,
		thumbnailHeight:	200,
		maxFilesize:		maxSize || 32,
		clickable:			target,
		dictDefaultMessage:	'',
		withCredentials:	true,

		init: function() {
			this.on('addedfile', function(file){
				$(file.previewElement).insertAfter(target);
			});
		},

		success: function(file, text) {
			$(text).insertAfter( $(file.previewElement) );
			$(file.previewElement).remove();
		},

		error: function(file, message) {
			if (file.retry === undefined) file.retry = 0;
			file.retry++;
			if (file.retry < 3) {
				afdz.uploadFile(file);
			} else {
				console.log(file, message);
				alert('File: ' + file.name + '\n\n' + message);
				$(file.previewElement).remove();
			}
		},
	});
};
<commit_msg>Attempting to fix Dropzone bug<commit_after>'use strict';

var afDropzone = function(form, url, target, maxSize) {
	$(form).each(function(idx, item) {
		if ($(item).element.dropzone) return;

		var afdz = new Dropzone(item, {
			url:				url,
			thumbnailWidth:		200,
			thumbnailHeight:	200,
			maxFilesize:		maxSize || 32,
			clickable:			target,
			dictDefaultMessage:	'',
			withCredentials:	true,

			init: function() {
				this.on('addedfile', function(file){
					$(file.previewElement).insertAfter(target);
				});
			},

			success: function(file, text) {
				$(text).insertAfter( $(file.previewElement) );
				$(file.previewElement).remove();
			},

			error: function(file, message) {
				if (file.retry === undefined) file.retry = 0;
				file.retry++;
				if (file.retry < 3) {
					afdz.uploadFile(file);
				} else {
					console.log(file, message);
					alert('File: ' + file.name + '\n\n' + message);
					$(file.previewElement).remove();
				}
			},
		});
	});
};
<|endoftext|>


<commit_before>import {
  bulkUploadRemoteSamples,
  createSample,
  markSampleUploaded,
  uploadFileToUrlWithRetries,
} from "~/api";
import { map } from "lodash/fp";

import { bulkUploadWithMetadata } from "~/api/metadata";
import { putWithCSRF } from "./core";

// TODO(mark): Implement back-end for basespace sample uploading.
export const bulkUploadBasespace = async ({ samples, metadata }) => {
  return {
    sample_ids: map("id", samples),
  };
};

export const bulkUploadRemote = ({ samples, metadata }) =>
  metadata
    ? bulkUploadWithMetadata(samples, metadata)
    : bulkUploadRemoteSamples(samples);

export const bulkUploadLocalWithMetadata = ({
  samples,
  sampleNamesToFiles,
  metadata,
  onCreateSamplesError,
  onUploadProgress,
  onUploadError,
  onAllUploadsComplete,
  onMarkSampleUploadedError,
}) => {
  // Store the upload progress of file names, so we can track when
  // everything is done.
  const fileNamesToProgress = {};
  const markedUploaded = {};
  let allUploadsCompleteRan = false;

  // This function needs access to fileNamesToProgress.
  const onFileUploadSuccess = (sampleName, sampleId) => {
    const sampleFiles = sampleNamesToFiles[sampleName];
    // If every file for this sample is uploaded, mark it as uploaded.
    if (
      !markedUploaded[sampleName] &&
      sampleFiles.every(f => fileNamesToProgress[f.name] === 100)
    ) {
      markedUploaded[sampleName] = true;
      markSampleUploaded(sampleId)
        .then(() => {
          // If every file-to-upload in this batch is done uploading
          if (
            !allUploadsCompleteRan &&
            Object.keys(sampleNamesToFiles).every(
              sampleName => markedUploaded[sampleName]
            )
          ) {
            allUploadsCompleteRan = true;
            onAllUploadsComplete();
          }
        })
        .catch(() => onMarkSampleUploadedError(sampleName));
    }
  };

  bulkUploadWithMetadata(samples, metadata)
    .then(response => {
      if (response.errors.length > 0) {
        onCreateSamplesError(response.errors);
      }

      // After successful sample creation, upload each sample's input files to the presigned URLs
      response.samples.forEach(sample => {
        const sampleName = sample.name;
        const files = sampleNamesToFiles[sampleName];

        files.map((file, i) => {
          const url = sample.input_files[i].presigned_url;

          uploadFileToUrlWithRetries(file, url, {
            onUploadProgress: e => {
              const percent = Math.round(e.loaded * 100 / e.total);
              fileNamesToProgress[file.name] = percent;
              if (onUploadProgress) {
                onUploadProgress(percent, file);
              }
            },
            onSuccess: () => onFileUploadSuccess(sampleName, sample.id),
            onError: error => onUploadError(file, error),
          });
        });
      });
    })
    .catch(e => {
      if (onCreateSamplesError) {
        onCreateSamplesError(e);
      }
    });
};

// TODO(mark): Remove this endpoint once we launch the new sample upload flow
export const bulkUploadLocal = ({
  sampleNamesToFiles,
  project,
  hostId,
  onCreateSampleError,
  onUploadProgress,
  onUploadError,
  onAllUploadsComplete,
  onMarkSampleUploadedError,
}) => {
  // Store the upload progress of file names, so we can track when
  // everything is done.
  const fileNamesToProgress = {};
  const markedUploaded = {};
  let allUploadsCompleteRan = false;

  // This function needs access to fileNamesToProgress.
  const onFileUploadSuccess = (sampleName, sampleId) => {
    const sampleFiles = sampleNamesToFiles[sampleName];
    // If every file for this sample is uploaded, mark it as uploaded.
    if (
      !markedUploaded[sampleName] &&
      sampleFiles.every(f => fileNamesToProgress[f.name] === 100)
    ) {
      markedUploaded[sampleName] = true;
      markSampleUploaded(sampleId)
        .then(() => {
          // If every file-to-upload in this batch is done uploading
          if (
            !allUploadsCompleteRan &&
            Object.keys(sampleNamesToFiles).every(
              sampleName => markedUploaded[sampleName]
            )
          ) {
            allUploadsCompleteRan = true;
            window.onbeforeunload = null;
            onAllUploadsComplete();
          }
        })
        .catch(onMarkSampleUploadedError);
    }
  };

  // Latest browsers will only show a generic warning
  window.onbeforeunload = () =>
    "Uploading is in progress. Are you sure you want to exit?";

  // Send an API call to create new samples with the expected files
  for (const [sampleName, files] of Object.entries(sampleNamesToFiles)) {
    createSample(sampleName, project.name, hostId, files, "local")
      .then(response => {
        // After successful sample creation, upload to the presigned URLs returned
        const sampleId = response.id;
        startUploadHeartbeat(sampleId);
        files.map((file, i) => {
          const url = response.input_files[i].presigned_url;

          uploadFileToUrlWithRetries(file, url, {
            onUploadProgress: e => {
              const percent = Math.round(e.loaded * 100 / e.total);
              fileNamesToProgress[file.name] = percent;
              if (onUploadProgress) {
                onUploadProgress(percent, file);
              }
            },
            onSuccess: () => onFileUploadSuccess(sampleName, sampleId),
            onError: error => onUploadError(file, error),
          });
        });
      })
      .catch(error => {
        if (onCreateSampleError) {
          onCreateSampleError(error, sampleName);
        }
      });
  }
};

// Local uploads go directly from the browser to S3, so we don't know if an upload was interrupted.
// Ping the heartbeat endpoint periodically to say the browser is actively uploading this sample.
export const startUploadHeartbeat = async sampleId => {
  const interval = 60000; // 60 sec
  setInterval(() => {
    putWithCSRF(`/samples/${sampleId}/upload_heartbeat.json`).catch(() =>
      // eslint-disable-next-line no-console
      console.error("Can't connect to IDseq server.")
    );
  }, interval);
};
<commit_msg>Fix issue with file upload triggering pipeline before uploads complete (#2396)<commit_after>import {
  bulkUploadRemoteSamples,
  createSample,
  markSampleUploaded,
  uploadFileToUrlWithRetries,
} from "~/api";
import { map } from "lodash/fp";

import { bulkUploadWithMetadata } from "~/api/metadata";
import { putWithCSRF } from "./core";

// TODO(mark): Implement back-end for basespace sample uploading.
export const bulkUploadBasespace = async ({ samples, metadata }) => {
  return {
    sample_ids: map("id", samples),
  };
};

export const bulkUploadRemote = ({ samples, metadata }) =>
  metadata
    ? bulkUploadWithMetadata(samples, metadata)
    : bulkUploadRemoteSamples(samples);

export const bulkUploadLocalWithMetadata = ({
  samples,
  sampleNamesToFiles,
  metadata,
  onCreateSamplesError,
  onUploadProgress,
  onUploadError,
  onAllUploadsComplete,
  onMarkSampleUploadedError,
}) => {
  // Store the upload progress of file names, so we can track when
  // everything is done.
  const fileNamesToProgress = {};
  const markedUploaded = {};
  let allUploadsCompleteRan = false;

  // This function needs access to fileNamesToProgress.
  const onFileUploadSuccess = (sampleName, sampleId) => {
    const sampleFiles = sampleNamesToFiles[sampleName];
    // If every file for this sample is uploaded, mark it as uploaded.
    if (
      !markedUploaded[sampleName] &&
      sampleFiles.every(f => fileNamesToProgress[f.name] === 100)
    ) {
      markedUploaded[sampleName] = true;
      markSampleUploaded(sampleId)
        .then(() => {
          // If every file-to-upload in this batch is done uploading
          if (
            !allUploadsCompleteRan &&
            Object.keys(sampleNamesToFiles).every(
              sampleName => markedUploaded[sampleName]
            )
          ) {
            allUploadsCompleteRan = true;
            onAllUploadsComplete();
          }
        })
        .catch(() => onMarkSampleUploadedError(sampleName));
    }
  };

  bulkUploadWithMetadata(samples, metadata)
    .then(response => {
      if (response.errors.length > 0) {
        onCreateSamplesError(response.errors);
      }

      // After successful sample creation, upload each sample's input files to the presigned URLs
      response.samples.forEach(sample => {
        const sampleName = sample.name;
        const files = sampleNamesToFiles[sampleName];

        files.map((file, i) => {
          const url = sample.input_files[i].presigned_url;

          uploadFileToUrlWithRetries(file, url, {
            onUploadProgress: e => {
              const percent = Math.floor(e.loaded * 100 / e.total);
              fileNamesToProgress[file.name] = percent;
              if (onUploadProgress) {
                onUploadProgress(percent, file);
              }
            },
            onSuccess: () => {
              fileNamesToProgress[file.name] = 100;
              onFileUploadSuccess(sampleName, sample.id);
            },
            onError: error => onUploadError(file, error),
          });
        });
      });
    })
    .catch(e => {
      if (onCreateSamplesError) {
        onCreateSamplesError(e);
      }
    });
};

// TODO(mark): Remove this endpoint once we launch the new sample upload flow
export const bulkUploadLocal = ({
  sampleNamesToFiles,
  project,
  hostId,
  onCreateSampleError,
  onUploadProgress,
  onUploadError,
  onAllUploadsComplete,
  onMarkSampleUploadedError,
}) => {
  // Store the upload progress of file names, so we can track when
  // everything is done.
  const fileNamesToProgress = {};
  const markedUploaded = {};
  let allUploadsCompleteRan = false;

  // This function needs access to fileNamesToProgress.
  const onFileUploadSuccess = (sampleName, sampleId) => {
    const sampleFiles = sampleNamesToFiles[sampleName];
    // If every file for this sample is uploaded, mark it as uploaded.
    if (
      !markedUploaded[sampleName] &&
      sampleFiles.every(f => fileNamesToProgress[f.name] === 100)
    ) {
      markedUploaded[sampleName] = true;
      markSampleUploaded(sampleId)
        .then(() => {
          // If every file-to-upload in this batch is done uploading
          if (
            !allUploadsCompleteRan &&
            Object.keys(sampleNamesToFiles).every(
              sampleName => markedUploaded[sampleName]
            )
          ) {
            allUploadsCompleteRan = true;
            window.onbeforeunload = null;
            onAllUploadsComplete();
          }
        })
        .catch(onMarkSampleUploadedError);
    }
  };

  // Latest browsers will only show a generic warning
  window.onbeforeunload = () =>
    "Uploading is in progress. Are you sure you want to exit?";

  // Send an API call to create new samples with the expected files
  for (const [sampleName, files] of Object.entries(sampleNamesToFiles)) {
    createSample(sampleName, project.name, hostId, files, "local")
      .then(response => {
        // After successful sample creation, upload to the presigned URLs returned
        const sampleId = response.id;
        startUploadHeartbeat(sampleId);
        files.map((file, i) => {
          const url = response.input_files[i].presigned_url;

          uploadFileToUrlWithRetries(file, url, {
            onUploadProgress: e => {
              const percent = Math.round(e.loaded * 100 / e.total);
              fileNamesToProgress[file.name] = percent;
              if (onUploadProgress) {
                onUploadProgress(percent, file);
              }
            },
            onSuccess: () => onFileUploadSuccess(sampleName, sampleId),
            onError: error => onUploadError(file, error),
          });
        });
      })
      .catch(error => {
        if (onCreateSampleError) {
          onCreateSampleError(error, sampleName);
        }
      });
  }
};

// Local uploads go directly from the browser to S3, so we don't know if an upload was interrupted.
// Ping the heartbeat endpoint periodically to say the browser is actively uploading this sample.
export const startUploadHeartbeat = async sampleId => {
  const interval = 60000; // 60 sec
  setInterval(() => {
    putWithCSRF(`/samples/${sampleId}/upload_heartbeat.json`).catch(() =>
      // eslint-disable-next-line no-console
      console.error("Can't connect to IDseq server.")
    );
  }, interval);
};
<|endoftext|>


<commit_before>var change_language = function(current_cnt, current_btn, hidden_cnt, hidden_btn, duration) {
	if (current_cnt.is(':visible')) {
		current_cnt.hide();
		current_btn.removeClass('active');
		hidden_cnt.fadeToggle(duration);
		hidden_btn.addClass('active');
	}
}

$(function() {
	if (dataviva.language == 'en' && $("[name='content-en']").length)
		$("[name='content-en']").fadeToggle()
	else
		$("[name='content-pt']").fadeToggle();

	var fade_duration = 800;

	$('#to-pt').on('click', function() {
		console.log(1);
		change_language(
			$("[name='content-en']"),
			$('#to-en'),
			$("[name='content-pt']"),
			$('#to-pt'),
			fade_duration
		);
	});

	$('#to-en').on('click', function() {
		change_language(
			$("[name='content-pt']"),
			$('#to-pt'),
			$("[name='content-en']"),
			$('#to-en'),
			fade_duration
		);
	});
});
<commit_msg>Removes unnecessary code<commit_after>var change_language = function(current_cnt, current_btn, hidden_cnt, hidden_btn, duration) {
	if (current_cnt.is(':visible')) {
		current_cnt.hide();
		current_btn.removeClass('active');
		hidden_cnt.fadeToggle(duration);
		hidden_btn.addClass('active');
	}
}

$(function() {
	if (dataviva.language == 'en' && $("[name='content-en']").length)
		$("[name='content-en']").fadeToggle()
	else
		$("[name='content-pt']").fadeToggle();

	var fade_duration = 800;

	$('#to-pt').on('click', function() {
		change_language(
			$("[name='content-en']"),
			$('#to-en'),
			$("[name='content-pt']"),
			$('#to-pt'),
			fade_duration
		);
	});

	$('#to-en').on('click', function() {
		change_language(
			$("[name='content-pt']"),
			$('#to-pt'),
			$("[name='content-en']"),
			$('#to-en'),
			fade_duration
		);
	});
});
<|endoftext|>


<commit_before>
function startBanner() {
  var c = document.getElementById("trigBan")
  var w, h, frame = 0

  const MAX_ROWS = 200
  const MAX_COLS = 200

  var grid = Array(MAX_ROWS * MAX_COLS)

  const framesPerSecond = 16

  var ctx = c.getContext('2d')

  const trigRad = 25, trigGap = 2, trigRound = 5, trigStroke = 0, defaultColor = "#000", defaultOutline = "#FFF"

  const gradientColors = [
    makeColor(186, 225, 255),
    makeColor(36, 36, 36)]
  const gradientSteps = 64

  var calculatedGradient

  function makeColor(r, g, b) {
    return {r: r, g: g, b: b}
  }

  function rgb(col) {
    r = Math.floor(col.r)
    g = Math.floor(col.g)
    b = Math.floor(col.b)
    return ["rgb(",r,",",g,",",b,")"].join("")
  }

  function makeColorGrad(cols, steps) {
    colors = Array(steps)
    for (var idx = 0; idx < steps; idx++) {
      colors[idx] = rgb(colorGrad(cols, idx / steps))
    }
    return colors
  }

  function colorGrad(cols, step) {
    step = Math.min(1, Math.max(0, step))
    step *= cols.length - 1
    var col1 = cols[Math.floor(step)]
    var col2 = cols[Math.ceil(step)]

    step %= 1

    var r1 = col1.r ** 2, r2 = col2.r ** 2
    var g1 = col1.g ** 2, g2 = col2.g ** 2
    var b1 = col1.b ** 2, b2 = col2.b ** 2

    return makeColor(
      Math.sqrt(r1 + (r2 - r1) * step),
      Math.sqrt(g1 + (g2 - g1) * step),
      Math.sqrt(b1 + (b2 - b1) * step)
    )
  }

  function getTrigCoords(center, radius, angle) {
    trigs = []
    var i = 0

    for (i = 0; i < 3; i++) {
      var rot = angle + i * 2 * Math.PI / 3
      trigs.push(makePoint(center.x + radius * getCos(rot),
                           center.y + radius * getSin(rot)))
    }
    return trigs
  }

  function roundedPolyQuick(ctx, points, cornerRadius) {
    ctx.lineJoin = "round"
    ctx.lineWidth = cornerRadius
    ctx.moveTo(Math.floor(points[0].x), Math.floor(points[0].y))
    for (var idx = 1; idx < points.length; idx++) {
      ctx.lineTo(Math.floor(points[idx].x), Math.floor(points[idx].y))
    }
    ctx.closePath()
  }

  // Fine function Blindman67 on stackoverflow
  //   https://stackoverflow.com/questions/44855794/html5-canvas-triangle-with-rounded-corners
  //   I should be better at math being CS student but it's been a while since
  //   trig and algebra classes.
  // ctx is the context to add the path to
  // points is a array of points [{x :?, y: ?},...
  // radius is the max rounding radius
  // this creates a closed polygon.
  // To draw you must call between
  //    ctx.beginPath();
  //    roundedPoly(ctx, points, radius);
  //    ctx.stroke();
  //    ctx.fill();
  // as it only adds a path and does not render.
  function roundedPoly(points, radiusAll) {
    var i, x, y, len, p1, p2, p3, v1, v2, sinA, sinA90, radDirection, drawDirection, angle, halfAngle, cRadius, lenOut,radius;
    // convert 2 points into vector form, polar form, and normalised
    var asVec = function(p, pp, v) {
      v.x = pp.x - p.x;
      v.y = pp.y - p.y;
      v.len = Math.sqrt(v.x * v.x + v.y * v.y);
      v.nx = v.x / v.len;
      v.ny = v.y / v.len;
      v.ang = Math.atan2(v.ny, v.nx);
    }
    radius = radiusAll;
    v1 = {};
    v2 = {};
    len = points.length;
    p1 = points[len - 1];

    draw_cmds = []
    // for each point
    for (i = 0; i < len; i++) {
      p2 = points[(i) % len];
      p3 = points[(i + 1) % len];
      //-----------------------------------------
      // Part 1
      asVec(p2, p1, v1);
      asVec(p2, p3, v2);
      sinA = v1.nx * v2.ny - v1.ny * v2.nx;
      sinA90 = v1.nx * v2.nx - v1.ny * -v2.ny;
      angle = Math.asin(sinA);
      //-----------------------------------------
      radDirection = 1;
      drawDirection = false;
      if (sinA90 < 0) {
        if (angle < 0) {
          angle = Math.PI + angle;
        } else {
          angle = Math.PI - angle;
          radDirection = -1;
          drawDirection = true;
        }
      } else {
        if (angle > 0) {
          radDirection = -1;
          drawDirection = true;
        }
      }
      if(p2.radius !== undefined){
          radius = p2.radius;
      }else{
          radius = radiusAll;
      }
      //-----------------------------------------
      // Part 2
      halfAngle = angle / 2;
      //-----------------------------------------

      //-----------------------------------------
      // Part 3
      lenOut = Math.abs(Math.cos(halfAngle) * radius / getSin(halfAngle));
      //-----------------------------------------

      //-----------------------------------------
      // Special part A
      if (lenOut > Math.min(v1.len / 2, v2.len / 2)) {
        lenOut = Math.min(v1.len / 2, v2.len / 2);
        cRadius = Math.abs(lenOut * Math.sin(halfAngle) / getCos(halfAngle));
      } else {
        cRadius = radius;
      }
      //-----------------------------------------
      // Part 4
      x = p2.x + v2.nx * lenOut;
      y = p2.y + v2.ny * lenOut;
      //-----------------------------------------
      // Part 5
      x += -v2.ny * cRadius * radDirection;
      y += v2.nx * cRadius * radDirection;
      //-----------------------------------------
      // Part 6
      draw_cmds.push([x, y, cRadius, v1.ang + Math.PI / 2 * radDirection, v2.ang - Math.PI / 2 * radDirection, drawDirection])
      //-----------------------------------------
      p1 = p2;
      p2 = p3;
    }
    return draw_cmds
  }

  function makePoint(x, y) {
    return {x: x, y: y}
  }

  function pointDelta(p1, p2) {
    return makePoint(p2.x - p1.x, p2.y - p1.y)
  }

  class Triangle {
    constructor (center, radius, angle, fillColor, lineColor, lineWidth, cornerRounding) {
      this.center = center
      this.radius = radius
      this.angle = angle
      this.fillColor = fillColor
      this.lineColor = lineColor
      this.lineWidth = lineWidth
      this.cornerRounding = cornerRounding
    }

    calcDraw () {
      this.draw_cmds = roundedPoly(getTrigCoords(this.center, this.radius, this.angle), this.cornerRounding);
    }

    getTranslated (newCenter) {
      var newTrig = new Triangle(newCenter, this.radius, this.angle, this.fillColor, this.lineColor, this.lineWidth, this.conrnerRounding)
      newTrig.draw_cmds = []
      var delta = pointDelta(this.center, newCenter)
      var dx = delta.x
      var dy = delta.y

      for (var cmd_idx = 0; cmd_idx < this.draw_cmds.length; cmd_idx++) {
        var cmd = this.draw_cmds[cmd_idx]
        newTrig.draw_cmds.push([cmd[0] + dx, cmd[1] + dy, cmd[2], cmd[3], cmd[4]])
      }
      return newTrig
    }

    draw (ctx) {
      ctx.lineWidth = this.lineWidth;
      ctx.fillStyle = this.fillColor;
      ctx.strokeStyle = this.fillColor;
      ctx.beginPath();
      if (!this.draw_cmds) {
        this.calcDraw()
      }
      this.draw_cmds.map((cmds) => ctx.arc(cmds[0], cmds[1], cmds[2], cmds[3], cmds[4]))
      ctx.closePath();
      //ctx.stroke();
      ctx.fill();
    }
  }

  function updateDims() {
    w = c.width = c.scrollWidth;
    h = c.height = c.scrollHeight;
  }

  var cosMemo = {}
  var sinMemo = {}

  function getCos(rot) {
    if (!(rot in cosMemo)) {
      cosMemo[rot] = Math.cos(rot)
    }
    return cosMemo[rot]
  }

  function getSin(rot) {
    if (!(rot in sinMemo)) {
      sinMemo[rot] = Math.sin(rot)
    }
    return sinMemo[rot]
  }

  function dist(p1, p2) {
    return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2)
  }

  function render() {
    ctx.clearRect(0, 0, w, h);

    var horizOffset = Math.sqrt(3) * trigRad + trigGap * 2
    var vertOffset = trigRad * 3 / 2 + trigGap

    var rows = Math.min(Math.round(h / vertOffset), MAX_ROWS)
    var cols = Math.min(Math.ceil(w / horizOffset + 1) * 2, MAX_COLS)

    var min_x = 0, max_x = (Math.floor(cols / 2) + 0.5) * horizOffset,
        min_y = 0, max_y = rows * vertOffset + trigRad / 2
    var min_point = makePoint(min_x, min_y),
        max_point = makePoint(max_x, max_y)
    var max_dist = dist(min_point, max_point)

    var render = 0

    for (var row = 0; row < rows; row ++) {
      for (var col = 0; col < cols; col ++) {
        //center, radius, angle, fillColor, lineColor, lineWidth, cornerRounding
        if (row + col > frame) {
          continue
        }

        var trig = getTriangle(row, col, vertOffset, horizOffset)
        var center = trig.center
        var triCol = calculatedGradient[Math.max(0, Math.min(calculatedGradient.length - 1, Math.floor(dist(center, mousePos) / max_dist * calculatedGradient.length)))]
        trig.fillColor = triCol
        trig.draw(ctx)

        render ++
      }
    }
  }

  var even_trig = new Triangle(makePoint(0, 0), trigRad, Math.PI / 2,
    defaultColor, defaultOutline, trigStroke, trigRound),
    odd_trig = new Triangle(makePoint(0, 0), trigRad, Math.PI * 3 / 2,
    defaultColor, defaultOutline, trigStroke, trigRound)
  even_trig.calcDraw()
  odd_trig.calcDraw()

  function getTriangle(row, col, vertOffset, horizOffset) {
    var point = row * MAX_COLS + col

    if (!grid[point]) {
      var center = makePoint(
        (Math.floor(col / 2)  + (col % 2) * 0.5 + (row % 2) * -0.5) * horizOffset,
        row * vertOffset + (col % 2 == 0 ? 0 : trigRad / 2))
      var trig = col % 2 == 0 ? even_trig.getTranslated(center) : odd_trig.getTranslated(center)
      grid[point] = trig
    }

    return grid[point]
  }

  function anim() {
    setTimeout(function() {
      window.requestAnimationFrame( anim )

      ++frame

      updateDims()

      render()
    }, 1000 / framesPerSecond);
  }

  function init() {
    updateDims()
    calculatedGradient = makeColorGrad(gradientColors, gradientSteps)
    if (c != null) {
      anim()
    }
  }

  var mousePos = makePoint(0, 0)

  function getMousePos(canvas, evt) {
      var rect = canvas.getBoundingClientRect();
      return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
      };
  }

  window.addEventListener('mousemove', function(evt) {
    mousePos = getMousePos(c, evt);
  }, false);
  init()
}

window.addEventListener('load', () => {
  startBanner()
});
<commit_msg>Changed triangle dimensions<commit_after>
function startBanner() {
  var c = document.getElementById("trigBan")
  var w, h, frame = 0

  const MAX_ROWS = 200
  const MAX_COLS = 200

  var grid = Array(MAX_ROWS * MAX_COLS)

  const framesPerSecond = 16

  var ctx = c.getContext('2d')

  const trigRad = 35, trigGap = 5, trigRound = 5, trigStroke = 0, defaultColor = "#000", defaultOutline = "#FFF"

  const gradientColors = [
    makeColor(186, 225, 255),
    makeColor(36, 36, 36)]
  const gradientSteps = 64

  var calculatedGradient

  function makeColor(r, g, b) {
    return {r: r, g: g, b: b}
  }

  function rgb(col) {
    r = Math.floor(col.r)
    g = Math.floor(col.g)
    b = Math.floor(col.b)
    return ["rgb(",r,",",g,",",b,")"].join("")
  }

  function makeColorGrad(cols, steps) {
    colors = Array(steps)
    for (var idx = 0; idx < steps; idx++) {
      colors[idx] = rgb(colorGrad(cols, idx / steps))
    }
    return colors
  }

  function colorGrad(cols, step) {
    step = Math.min(1, Math.max(0, step))
    step *= cols.length - 1
    var col1 = cols[Math.floor(step)]
    var col2 = cols[Math.ceil(step)]

    step %= 1

    var r1 = col1.r ** 2, r2 = col2.r ** 2
    var g1 = col1.g ** 2, g2 = col2.g ** 2
    var b1 = col1.b ** 2, b2 = col2.b ** 2

    return makeColor(
      Math.sqrt(r1 + (r2 - r1) * step),
      Math.sqrt(g1 + (g2 - g1) * step),
      Math.sqrt(b1 + (b2 - b1) * step)
    )
  }

  function getTrigCoords(center, radius, angle) {
    trigs = []
    var i = 0

    for (i = 0; i < 3; i++) {
      var rot = angle + i * 2 * Math.PI / 3
      trigs.push(makePoint(center.x + radius * getCos(rot),
                           center.y + radius * getSin(rot)))
    }
    return trigs
  }

  function roundedPolyQuick(ctx, points, cornerRadius) {
    ctx.lineJoin = "round"
    ctx.lineWidth = cornerRadius
    ctx.moveTo(Math.floor(points[0].x), Math.floor(points[0].y))
    for (var idx = 1; idx < points.length; idx++) {
      ctx.lineTo(Math.floor(points[idx].x), Math.floor(points[idx].y))
    }
    ctx.closePath()
  }

  // Fine function Blindman67 on stackoverflow
  //   https://stackoverflow.com/questions/44855794/html5-canvas-triangle-with-rounded-corners
  //   I should be better at math being CS student but it's been a while since
  //   trig and algebra classes.
  // ctx is the context to add the path to
  // points is a array of points [{x :?, y: ?},...
  // radius is the max rounding radius
  // this creates a closed polygon.
  // To draw you must call between
  //    ctx.beginPath();
  //    roundedPoly(ctx, points, radius);
  //    ctx.stroke();
  //    ctx.fill();
  // as it only adds a path and does not render.
  function roundedPoly(points, radiusAll) {
    var i, x, y, len, p1, p2, p3, v1, v2, sinA, sinA90, radDirection, drawDirection, angle, halfAngle, cRadius, lenOut,radius;
    // convert 2 points into vector form, polar form, and normalised
    var asVec = function(p, pp, v) {
      v.x = pp.x - p.x;
      v.y = pp.y - p.y;
      v.len = Math.sqrt(v.x * v.x + v.y * v.y);
      v.nx = v.x / v.len;
      v.ny = v.y / v.len;
      v.ang = Math.atan2(v.ny, v.nx);
    }
    radius = radiusAll;
    v1 = {};
    v2 = {};
    len = points.length;
    p1 = points[len - 1];

    draw_cmds = []
    // for each point
    for (i = 0; i < len; i++) {
      p2 = points[(i) % len];
      p3 = points[(i + 1) % len];
      //-----------------------------------------
      // Part 1
      asVec(p2, p1, v1);
      asVec(p2, p3, v2);
      sinA = v1.nx * v2.ny - v1.ny * v2.nx;
      sinA90 = v1.nx * v2.nx - v1.ny * -v2.ny;
      angle = Math.asin(sinA);
      //-----------------------------------------
      radDirection = 1;
      drawDirection = false;
      if (sinA90 < 0) {
        if (angle < 0) {
          angle = Math.PI + angle;
        } else {
          angle = Math.PI - angle;
          radDirection = -1;
          drawDirection = true;
        }
      } else {
        if (angle > 0) {
          radDirection = -1;
          drawDirection = true;
        }
      }
      if(p2.radius !== undefined){
          radius = p2.radius;
      }else{
          radius = radiusAll;
      }
      //-----------------------------------------
      // Part 2
      halfAngle = angle / 2;
      //-----------------------------------------

      //-----------------------------------------
      // Part 3
      lenOut = Math.abs(Math.cos(halfAngle) * radius / getSin(halfAngle));
      //-----------------------------------------

      //-----------------------------------------
      // Special part A
      if (lenOut > Math.min(v1.len / 2, v2.len / 2)) {
        lenOut = Math.min(v1.len / 2, v2.len / 2);
        cRadius = Math.abs(lenOut * Math.sin(halfAngle) / getCos(halfAngle));
      } else {
        cRadius = radius;
      }
      //-----------------------------------------
      // Part 4
      x = p2.x + v2.nx * lenOut;
      y = p2.y + v2.ny * lenOut;
      //-----------------------------------------
      // Part 5
      x += -v2.ny * cRadius * radDirection;
      y += v2.nx * cRadius * radDirection;
      //-----------------------------------------
      // Part 6
      draw_cmds.push([x, y, cRadius, v1.ang + Math.PI / 2 * radDirection, v2.ang - Math.PI / 2 * radDirection, drawDirection])
      //-----------------------------------------
      p1 = p2;
      p2 = p3;
    }
    return draw_cmds
  }

  function makePoint(x, y) {
    return {x: x, y: y}
  }

  function pointDelta(p1, p2) {
    return makePoint(p2.x - p1.x, p2.y - p1.y)
  }

  class Triangle {
    constructor (center, radius, angle, fillColor, lineColor, lineWidth, cornerRounding) {
      this.center = center
      this.radius = radius
      this.angle = angle
      this.fillColor = fillColor
      this.lineColor = lineColor
      this.lineWidth = lineWidth
      this.cornerRounding = cornerRounding
    }

    calcDraw () {
      this.draw_cmds = roundedPoly(getTrigCoords(this.center, this.radius, this.angle), this.cornerRounding);
    }

    getTranslated (newCenter) {
      var newTrig = new Triangle(newCenter, this.radius, this.angle, this.fillColor, this.lineColor, this.lineWidth, this.conrnerRounding)
      newTrig.draw_cmds = []
      var delta = pointDelta(this.center, newCenter)
      var dx = delta.x
      var dy = delta.y

      for (var cmd_idx = 0; cmd_idx < this.draw_cmds.length; cmd_idx++) {
        var cmd = this.draw_cmds[cmd_idx]
        newTrig.draw_cmds.push([cmd[0] + dx, cmd[1] + dy, cmd[2], cmd[3], cmd[4]])
      }
      return newTrig
    }

    draw (ctx) {
      ctx.lineWidth = this.lineWidth;
      ctx.fillStyle = this.fillColor;
      ctx.strokeStyle = this.fillColor;
      ctx.beginPath();
      if (!this.draw_cmds) {
        this.calcDraw()
      }
      this.draw_cmds.map((cmds) => ctx.arc(cmds[0], cmds[1], cmds[2], cmds[3], cmds[4]))
      ctx.closePath();
      //ctx.stroke();
      ctx.fill();
    }
  }

  function updateDims() {
    w = c.width = c.scrollWidth;
    h = c.height = c.scrollHeight;
  }

  var cosMemo = {}
  var sinMemo = {}

  function getCos(rot) {
    if (!(rot in cosMemo)) {
      cosMemo[rot] = Math.cos(rot)
    }
    return cosMemo[rot]
  }

  function getSin(rot) {
    if (!(rot in sinMemo)) {
      sinMemo[rot] = Math.sin(rot)
    }
    return sinMemo[rot]
  }

  function dist(p1, p2) {
    return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2)
  }

  function render() {
    ctx.clearRect(0, 0, w, h);

    var horizOffset = Math.sqrt(3) * trigRad + trigGap * 2
    var vertOffset = trigRad * 3 / 2 + trigGap

    var rows = Math.min(Math.round(h / vertOffset), MAX_ROWS)
    var cols = Math.min(Math.ceil(w / horizOffset + 1) * 2, MAX_COLS)

    var min_x = 0, max_x = (Math.floor(cols / 2) + 0.5) * horizOffset,
        min_y = 0, max_y = rows * vertOffset + trigRad / 2
    var min_point = makePoint(min_x, min_y),
        max_point = makePoint(max_x, max_y)
    var max_dist = dist(min_point, max_point)

    var render = 0

    for (var row = 0; row < rows; row ++) {
      for (var col = 0; col < cols; col ++) {
        //center, radius, angle, fillColor, lineColor, lineWidth, cornerRounding
        if (row + col > frame) {
          continue
        }

        var trig = getTriangle(row, col, vertOffset, horizOffset)
        var center = trig.center
        var triCol = calculatedGradient[Math.max(0, Math.min(calculatedGradient.length - 1, Math.floor(dist(center, mousePos) / max_dist * calculatedGradient.length)))]
        trig.fillColor = triCol
        trig.draw(ctx)

        render ++
      }
    }
  }

  var even_trig = new Triangle(makePoint(0, 0), trigRad, Math.PI / 2,
    defaultColor, defaultOutline, trigStroke, trigRound),
    odd_trig = new Triangle(makePoint(0, 0), trigRad, Math.PI * 3 / 2,
    defaultColor, defaultOutline, trigStroke, trigRound)
  even_trig.calcDraw()
  odd_trig.calcDraw()

  function getTriangle(row, col, vertOffset, horizOffset) {
    var point = row * MAX_COLS + col

    if (!grid[point]) {
      var center = makePoint(
        (Math.floor(col / 2)  + (col % 2) * 0.5 + (row % 2) * -0.5) * horizOffset,
        row * vertOffset + (col % 2 == 0 ? 0 : trigRad / 2))
      var trig = col % 2 == 0 ? even_trig.getTranslated(center) : odd_trig.getTranslated(center)
      grid[point] = trig
    }

    return grid[point]
  }

  function anim() {
    setTimeout(function() {
      window.requestAnimationFrame( anim )

      ++frame

      updateDims()

      render()
    }, 1000 / framesPerSecond);
  }

  function init() {
    updateDims()
    calculatedGradient = makeColorGrad(gradientColors, gradientSteps)
    if (c != null) {
      anim()
    }
  }

  var mousePos = makePoint(0, 0)

  function getMousePos(canvas, evt) {
      var rect = canvas.getBoundingClientRect();
      return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
      };
  }

  window.addEventListener('mousemove', function(evt) {
    mousePos = getMousePos(c, evt);
  }, false);
  init()
}

window.addEventListener('load', () => {
  startBanner()
});
<|endoftext|>


<commit_before>/*
 * grunt-migrate
 * https://github.com/ericsaboia/migrate-database
 *
 * Copyright (c) 2014 Eric Saboia
 * Licensed under the MIT license.
 */

 /**
 * Module dependencies.
 */

var fs = require('fs')
  , async = require('async')
  , _ = require('lodash')
;

/**
 * Expose `Migrate`.
 */

module.exports = Migrate;

/**
 * Initialize a new migration `Migrate` with the given `grunt, adapter, path and steps`
 *
 * @param {Object} grunt
 * @param {Adapter} adapter
 * @param {String} path
 * @param {Number} steps
 * @api private
 */

function Migrate (grunt, adapter, path, steps) {
  this.grunt = grunt;
  this.adapter = adapter;
  this.path = path;
  this.steps = steps;
}

/**
 * creates a new migration with the given 'name' and call 'callback(err)'.
 *
 * @param {String} name
 * @param {Function} callback
 * @api public
 */

Migrate.prototype.create = function (name, callback) {
  if (!fs.existsSync(this.path))
    fs.mkdirSync(this.path);

  name = Date.now() + '_' + name + '.js';

  fs.createReadStream(__dirname + '/../../templates/migration.js')
      .pipe(fs.createWriteStream(this.path + '/' + name))
      .on('close', callback);

  this.grunt.log.writeln("Creating '%s'", name);
}

/**
 * Run down migrations and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Migrate.prototype.down = function(callback) {
  var that = this;
  that.adapter.list('down', function (err, migrated) {
    that.go('down', migrated, callback);
  });
};

/**
 * Run up migrations and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Migrate.prototype.up = function(callback) {
  var that = this;
  that.adapter.list('up', function (err, migrated) {
    var toMigrate = _.difference( migrationsAt(that.path), migrated ).sort();
    that.go('up', toMigrate, callback);
  });
};

/**
 * Walk through migrations in the given direction and call 'callback(err)'.
 *
 * @param {String} direction
 * @param {Array} toMigrate
 * @param {Function} callback
 * @api private
 */

Migrate.prototype.go = function (direction, toMigrate, callback) {
  if (this.steps) toMigrate = toMigrate.splice(0, this.steps);
  async.eachSeries(toMigrate, this.migrate(direction), callback);
};

/**
 * Run each migration in the given direction.
 *
 * @param {String} direction
 * @api private
 */

Migrate.prototype.migrate = function (direction) {
  var that = this;

  return function (migrationName, callback) {
    that.grunt.log.writeln("%s: %s", direction, migrationName);

    var migration = require(that.path + '/' + migrationName);
    migration[direction](function (err) {
      err? callback(err) : that.saveStateOf(migrationName, direction, callback);
    });
  }
};

/**
 * Insert or remove a migration from the database and call 'callback(err)'.
 *
 * @param {String} migration
 * @param {String} direction
 * @param {Function} callback
 * @api private
 */

Migrate.prototype.saveStateOf = function (migration, direction, callback) {
  var method = (direction == 'up') ? 'insert' : 'remove';
  this.adapter[method](migration, callback);
}

function migrationsAt (path) {
  return fs.readdirSync(path).filter(function(file){
    return file.match(/^\d+.*\.js$/);
  }).map(function (file) {
    return file.replace('.js', '');
  })
}<commit_msg>ability to add an initializer<commit_after>/*
 * grunt-migrate
 * https://github.com/ericsaboia/migrate-database
 *
 * Copyright (c) 2014 Eric Saboia
 * Licensed under the MIT license.
 */

 /**
 * Module dependencies.
 */

var fs = require('fs')
  , async = require('async')
  , _ = require('lodash')
  , path = require('path')
;

/**
 * Expose `Migrate`.
 */

module.exports = Migrate;

/**
 * Initialize a new migration `Migrate` with the given `grunt, adapter, path and steps`
 *
 * @param {Object} grunt
 * @param {Adapter} adapter
 * @param {String} path
 * @param {Number} steps
 * @api private
 */

function Migrate (grunt, adapter, config, steps) {
  // Load initializer
  if (config.initializerPath)
    require( path.resolve(config.initializerPath) );

  this.grunt = grunt;
  this.adapter = adapter;
  this.path = path.resolve(config.path);
  this.steps = steps;
}

/**
 * creates a new migration with the given 'name' and call 'callback(err)'.
 *
 * @param {String} name
 * @param {Function} callback
 * @api public
 */

Migrate.prototype.create = function (name, callback) {
  if (!fs.existsSync(this.path))
    fs.mkdirSync(this.path);

  name = Date.now() + '_' + name + '.js';

  fs.createReadStream(__dirname + '/../../templates/migration.js')
      .pipe(fs.createWriteStream(this.path + '/' + name))
      .on('close', callback);

  this.grunt.log.writeln("Creating '%s'", name);
}

/**
 * Run down migrations and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Migrate.prototype.down = function(callback) {
  var that = this;
  that.adapter.list('down', function (err, migrated) {
    that.go('down', migrated, callback);
  });
};

/**
 * Run up migrations and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Migrate.prototype.up = function(callback) {
  var that = this;
  that.adapter.list('up', function (err, migrated) {
    var toMigrate = _.difference( migrationsAt(that.path), migrated ).sort();
    that.go('up', toMigrate, callback);
  });
};

/**
 * Walk through migrations in the given direction and call 'callback(err)'.
 *
 * @param {String} direction
 * @param {Array} toMigrate
 * @param {Function} callback
 * @api private
 */

Migrate.prototype.go = function (direction, toMigrate, callback) {
  if (this.steps) toMigrate = toMigrate.splice(0, this.steps);
  async.eachSeries(toMigrate, this.migrate(direction), callback);
};

/**
 * Run each migration in the given direction.
 *
 * @param {String} direction
 * @api private
 */

Migrate.prototype.migrate = function (direction) {
  var that = this;

  return function (migrationName, callback) {
    that.grunt.log.writeln("%s: %s", direction, migrationName);

    var migration = require(that.path + '/' + migrationName);
    migration[direction](function (err) {
      err? callback(err) : that.saveStateOf(migrationName, direction, callback);
    });
  }
};

/**
 * Insert or remove a migration from the database and call 'callback(err)'.
 *
 * @param {String} migration
 * @param {String} direction
 * @param {Function} callback
 * @api private
 */

Migrate.prototype.saveStateOf = function (migration, direction, callback) {
  var method = (direction == 'up') ? 'insert' : 'remove';
  this.adapter[method](migration, callback);
}

function migrationsAt (path) {
  return fs.readdirSync(path).filter(function(file){
    return file.match(/^\d+.*\.js$/);
  }).map(function (file) {
    return file.replace('.js', '');
  })
}<|endoftext|>


<commit_before>  var add_new_plot = function(optarg){
    optarg = optarg || {};

    nplots += 1;
    var div_id = "plot" + String(nplots) + "-" + report_name;
    var html = '

'
    report_div.append(html);
    return div_id;
  }

  var make_scatter_plot = function(plot_title, series, optarg){

    optarg = optarg || {};
    var div_id = add_new_plot(optarg);

    console.log("series = ", series);

    // plot data
    var chart = new Highcharts.Chart({
      chart: { type: 'scatter',  zoomType: 'xy', renderTo: div_id },
      credits: {  enabled: false  },
      title : { text : plot_title,},
      xAxis: { title: { text: optarg.xtitle } },
      yAxis: { title: { text: optarg.ytitle},  min: optarg.ymin },
      plotOptions: {
        scatter: {
          marker: { radius: 10 },
          tooltip: {
            headerFormat: '{series.name}
',
            pointFormat: optarg.pointFormat || '{point.name}',
          }
        }
      },
      series : series,
    });
    return chart;
  }

  var make_bar_plot = function(plot_title, xcategories, series, optarg){

    optarg = optarg || {};
    var div_id = add_new_plot(optarg);

    $('#'+div_id).highcharts({
      chart: {     type: 'column', zoomType: 'x' },
      credits: {  enabled: false  },
      title : {   text : plot_title },
      xAxis: {        categories: xcategories  },
      series : series,
    });
  }

  // make_bar_plot('test hist', ['a','b','c'], [{name:'test', data:[1,2,3]}]);

  var make_series = function(xcol, ycol, optarg){
    optarg = optarg || {};
    var sdat = [];
    var series = [ {name: optarg.name || "Data", data: sdat} ];
    data['data'].forEach(function(x){
      if (x[xcol]==null){ return; }
      if (x[xcol]==null){ return; }
      xv = Number(x[xcol]);
      yv = Number(x[ycol]);
      sdat.push({x: xv, y: yv, name: x[optarg.namecol || 'course_id']});
    });

    if (optarg.fit_line){
      series[0]['regression'] = true;
      series[0]['regressionSettings'] = { type: 'linear',
                                         // states: { hover: { lineWidth: 0 } },
                                         enableMouseTracking: false,
                                        }
    }

    return series;
  }
<commit_msg>add horizontal bar chart to standard cr plotting js<commit_after>  var add_new_plot = function(optarg){
    optarg = optarg || {};

    nplots += 1;
    var div_id = "plot" + String(nplots) + "-" + report_name;
    var html = '

'
    report_div.append(html);
    return div_id;
  }

  var make_scatter_plot = function(plot_title, series, optarg){
    // x-y scatter plot

    optarg = optarg || {};
    var div_id = add_new_plot(optarg);

    console.log("series = ", series);

    // plot data
    var chart = new Highcharts.Chart({
      chart: { type: 'scatter',  zoomType: 'xy', renderTo: div_id },
      credits: {  enabled: false  },
      title : { text : plot_title,},
      xAxis: { title: { text: optarg.xtitle } },
      yAxis: { title: { text: optarg.ytitle},  min: optarg.ymin },
      plotOptions: {
        scatter: {
          marker: { radius: 10 },
          tooltip: {
            headerFormat: '{series.name}
',
            pointFormat: optarg.pointFormat || '{point.name}',
          }
        }
      },
      series : series,
    });
    return chart;
  }

  var make_bar_plot = function(plot_title, xcategories, series, optarg){
    // vertical bar chart (e.g. for histograms)
    // example:
    //     make_bar_plot('test hist', ['a','b','c'], [{name:'test', data:[1,2,3]}]);

    optarg = optarg || {};
    var div_id = add_new_plot(optarg);

    $('#'+div_id).highcharts({
      chart: {     type: 'column', zoomType: 'x' },
      credits: {  enabled: false  },
      title : {   text : plot_title },
      xAxis: {        categories: xcategories  },
      series : series,
    });
  }

  var make_horizontal_bar_plot = function(plot_title, xcategories, series, optarg){
    // horizontal bar chart
    // example:
    //     make_horizontal_bar_plot('test hist', ['a','b','c'], [{name:'test', data:[1,2,3]}]);

    optarg = optarg || {};
    var div_id = add_new_plot(optarg);

    $('#'+div_id).highcharts({
      chart: {     type: 'bar', zoomType: 'x' },
      credits: {  enabled: false  },
      title : {   text : plot_title },
      xAxis: {        categories: xcategories  },
      yAxis: { title: { text: optarg.ytitle},  min: optarg.ymin },
      series : series,
      legend: {reversed: true},
      plotOptions: { series: { stacking: optarg.stacking } },
    });
  }

  var make_series = function(xcol, ycol, optarg){
    optarg = optarg || {};
    var sdat = [];
    var series = [ {name: optarg.name || "Data", data: sdat} ];
    data['data'].forEach(function(x){
      if (x[xcol]==null){ return; }
      if (x[xcol]==null){ return; }
      xv = Number(x[xcol]);
      yv = Number(x[ycol]);
      sdat.push({x: xv, y: yv, name: x[optarg.namecol || 'course_id']});
    });

    if (optarg.fit_line){
      series[0]['regression'] = true;
      series[0]['regressionSettings'] = { type: 'linear',
                                         // states: { hover: { lineWidth: 0 } },
                                         enableMouseTracking: false,
                                        }
    }

    return series;
  }
<|endoftext|>