<commit_before>const {flowRight} = require('lodash');
const {mapKeyValues, mapQuery} = require('@nexes/mongo-utils');
const DomainEvents = require('@tryghost/domain-events');
const OfferCodeChangeEvent = require('../domain/events/OfferCodeChange');
const OfferCreatedEvent = require('../domain/events/OfferCreated');
const Offer = require('../domain/models/Offer');
const OfferStatus = require('../domain/models/OfferStatus');

const statusTransformer = mapKeyValues({
    key: {
        from: 'status',
        to: 'active'
    },
    values: [{
        from: 'active',
        to: true
    }, {
        from: 'archived',
        to: false
    }]
});

const rejectNonStatusTransformer = input => mapQuery(input, function (value, key) {
    if (key !== 'status') {
        return;
    }

    return {
        [key]: value
    };
});

const mongoTransformer = flowRight(statusTransformer, rejectNonStatusTransformer);

/**
 * @typedef {object} BaseOptions
 * @prop {import('knex').Transaction} transacting
 */

/**
 * @typedef {object} ListOptions
 * @prop {import('knex').Transaction} transacting
 * @prop {string} filter
 */

class OfferRepository {
    /**
     * @param {{forge: (data: object) => import('bookshelf').Model<Offer.OfferProps>}} OfferModel
     * @param {{forge: (data: object) => import('bookshelf').Model<any>}} OfferRedemptionModel
     */
    constructor(OfferModel, OfferRedemptionModel) {
        /** @private */
        this.OfferModel = OfferModel;
        /** @private */
        this.OfferRedemptionModel = OfferRedemptionModel;
    }

    /**
     * @template T
     * @param {(t: import('knex').Transaction) => Promise<T>} cb
     * @returns {Promise<T>}
     */
    async createTransaction(cb) {
        return this.OfferModel.transaction(cb);
    }

    /**
     * @param {string} name
     * @param {BaseOptions} [options]
     * @returns {Promise<boolean>}
     */
    async existsByName(name, options) {
        const model = await this.OfferModel.findOne({name}, options);
        if (!model) {
            return false;
        }
        return true;
    }

    /**
     * @param {string} code
     * @param {BaseOptions} [options]
     * @returns {Promise<boolean>}
     */
    async existsByCode(code, options) {
        const model = await this.OfferModel.findOne({code}, options);
        if (!model) {
            return false;
        }
        return true;
    }

    /**
     * @private
     * @param {import('bookshelf').Model<any>} model
     * @param {BaseOptions} options
     * @returns {Promise<Offer>}
     */
    async mapToOffer(model, options) {
        const json = model.toJSON();

        const count = await this.OfferRedemptionModel.where({offer_id: json.id}).count('id', {
            transacting: options.transacting
        });
        return Offer.create({
            id: json.id,
            name: json.name,
            code: json.code,
            display_title: json.portal_title,
            display_description: json.portal_description,
            type: json.discount_type === 'amount' ? 'fixed' : 'percent',
            amount: json.discount_amount,
            cadence: json.interval,
            currency: json.currency,
            duration: json.duration,
            duration_in_months: json.duration_in_months,
            redemptionCount: count,
            status: json.active ? 'active' : 'archived',
            tier: {
                id: json.product.id,
                name: json.product.name
            }
        }, null);
    }

    /**
     * @param {string} id
     * @param {BaseOptions} [options]
     * @returns {Promise<Offer>}
     */
    async getById(id, options) {
        const model = await this.OfferModel.findOne({id}, {
            ...options,
            withRelated: ['product']
        });

        if (!model) {
            return null;
        }

        return this.mapToOffer(model, options);
    }

    /**
     * @param {string} id stripe_coupon_id
     * @param {BaseOptions} [options]
     * @returns {Promise<Offer>}
     */
    async getByStripeCouponId(id, options) {
        const model = await this.OfferModel.findOne({stripe_coupon_id: id}, {
            ...options,
            withRelated: ['product']
        });

        if (!model) {
            return null;
        }

        return this.mapToOffer(model, options);
    }

    /**
     * @param {ListOptions} options
     * @returns {Promise<Offer[]>}
     */
    async getAll(options) {
        const models = await this.OfferModel.findAll({
            ...options,
            mongoTransformer,
            withRelated: ['product']
        });

        const mapOptions = {
            transacting: options && options.transacting
        };

        const offers = models.map(model => this.mapToOffer(model, mapOptions));

        return Promise.all(offers);
    }

    /**
     * @param {Offer} offer
     * @param {BaseOptions} [options]
     * @returns {Promise<void>}
     */
    async save(offer, options) {
        /** @type any */
        const data = {
            id: offer.id,
            name: offer.name.value,
            code: offer.code.value,
            portal_title: offer.displayTitle.value || null,
            portal_description: offer.displayDescription.value || null,
            discount_type: offer.type.value === 'fixed' ? 'amount' : 'percent',
            discount_amount: offer.amount.value,
            interval: offer.cadence.value,
            product_id: offer.tier.id,
            duration: offer.duration.value.type,
            duration_in_months: offer.duration.value.type === 'repeating' ? offer.duration.value.months : null,
            currency: offer.currency ? offer.currency.value : null,
            active: offer.status.equals(OfferStatus.create('active'))
        };

        if (offer.codeChanged) {
            const event = OfferCodeChangeEvent.create({
                offerId: offer.id,
                previousCode: offer.oldCode,
                currentCode: offer.code
            });
            DomainEvents.dispatch(event);
        }

        if (offer.isNew) {
            await this.OfferModel.add(data, options);
            const event = OfferCreatedEvent.create({offer});

            if (options.transacting) {
                // Only dispatch the event after the transaction has finished
                // Because else the offer won't be committed to the database yet
                options.transacting.executionPromise.then(() => {
                    DomainEvents.dispatch(event);
                });
            } else {
                DomainEvents.dispatch(event);
            }
        } else {
            await this.OfferModel.edit(data, {...options, id: data.id});
        }
    }
}

module.exports = OfferRepository;
<commit_msg>Fixed package import<commit_after>const {flowRight} = require('lodash');
const {mapKeyValues, mapQuery} = require('@tryghost/mongo-utils');
const DomainEvents = require('@tryghost/domain-events');
const OfferCodeChangeEvent = require('../domain/events/OfferCodeChange');
const OfferCreatedEvent = require('../domain/events/OfferCreated');
const Offer = require('../domain/models/Offer');
const OfferStatus = require('../domain/models/OfferStatus');

const statusTransformer = mapKeyValues({
    key: {
        from: 'status',
        to: 'active'
    },
    values: [{
        from: 'active',
        to: true
    }, {
        from: 'archived',
        to: false
    }]
});

const rejectNonStatusTransformer = input => mapQuery(input, function (value, key) {
    if (key !== 'status') {
        return;
    }

    return {
        [key]: value
    };
});

const mongoTransformer = flowRight(statusTransformer, rejectNonStatusTransformer);

/**
 * @typedef {object} BaseOptions
 * @prop {import('knex').Transaction} transacting
 */

/**
 * @typedef {object} ListOptions
 * @prop {import('knex').Transaction} transacting
 * @prop {string} filter
 */

class OfferRepository {
    /**
     * @param {{forge: (data: object) => import('bookshelf').Model<Offer.OfferProps>}} OfferModel
     * @param {{forge: (data: object) => import('bookshelf').Model<any>}} OfferRedemptionModel
     */
    constructor(OfferModel, OfferRedemptionModel) {
        /** @private */
        this.OfferModel = OfferModel;
        /** @private */
        this.OfferRedemptionModel = OfferRedemptionModel;
    }

    /**
     * @template T
     * @param {(t: import('knex').Transaction) => Promise<T>} cb
     * @returns {Promise<T>}
     */
    async createTransaction(cb) {
        return this.OfferModel.transaction(cb);
    }

    /**
     * @param {string} name
     * @param {BaseOptions} [options]
     * @returns {Promise<boolean>}
     */
    async existsByName(name, options) {
        const model = await this.OfferModel.findOne({name}, options);
        if (!model) {
            return false;
        }
        return true;
    }

    /**
     * @param {string} code
     * @param {BaseOptions} [options]
     * @returns {Promise<boolean>}
     */
    async existsByCode(code, options) {
        const model = await this.OfferModel.findOne({code}, options);
        if (!model) {
            return false;
        }
        return true;
    }

    /**
     * @private
     * @param {import('bookshelf').Model<any>} model
     * @param {BaseOptions} options
     * @returns {Promise<Offer>}
     */
    async mapToOffer(model, options) {
        const json = model.toJSON();

        const count = await this.OfferRedemptionModel.where({offer_id: json.id}).count('id', {
            transacting: options.transacting
        });
        return Offer.create({
            id: json.id,
            name: json.name,
            code: json.code,
            display_title: json.portal_title,
            display_description: json.portal_description,
            type: json.discount_type === 'amount' ? 'fixed' : 'percent',
            amount: json.discount_amount,
            cadence: json.interval,
            currency: json.currency,
            duration: json.duration,
            duration_in_months: json.duration_in_months,
            redemptionCount: count,
            status: json.active ? 'active' : 'archived',
            tier: {
                id: json.product.id,
                name: json.product.name
            }
        }, null);
    }

    /**
     * @param {string} id
     * @param {BaseOptions} [options]
     * @returns {Promise<Offer>}
     */
    async getById(id, options) {
        const model = await this.OfferModel.findOne({id}, {
            ...options,
            withRelated: ['product']
        });

        if (!model) {
            return null;
        }

        return this.mapToOffer(model, options);
    }

    /**
     * @param {string} id stripe_coupon_id
     * @param {BaseOptions} [options]
     * @returns {Promise<Offer>}
     */
    async getByStripeCouponId(id, options) {
        const model = await this.OfferModel.findOne({stripe_coupon_id: id}, {
            ...options,
            withRelated: ['product']
        });

        if (!model) {
            return null;
        }

        return this.mapToOffer(model, options);
    }

    /**
     * @param {ListOptions} options
     * @returns {Promise<Offer[]>}
     */
    async getAll(options) {
        const models = await this.OfferModel.findAll({
            ...options,
            mongoTransformer,
            withRelated: ['product']
        });

        const mapOptions = {
            transacting: options && options.transacting
        };

        const offers = models.map(model => this.mapToOffer(model, mapOptions));

        return Promise.all(offers);
    }

    /**
     * @param {Offer} offer
     * @param {BaseOptions} [options]
     * @returns {Promise<void>}
     */
    async save(offer, options) {
        /** @type any */
        const data = {
            id: offer.id,
            name: offer.name.value,
            code: offer.code.value,
            portal_title: offer.displayTitle.value || null,
            portal_description: offer.displayDescription.value || null,
            discount_type: offer.type.value === 'fixed' ? 'amount' : 'percent',
            discount_amount: offer.amount.value,
            interval: offer.cadence.value,
            product_id: offer.tier.id,
            duration: offer.duration.value.type,
            duration_in_months: offer.duration.value.type === 'repeating' ? offer.duration.value.months : null,
            currency: offer.currency ? offer.currency.value : null,
            active: offer.status.equals(OfferStatus.create('active'))
        };

        if (offer.codeChanged) {
            const event = OfferCodeChangeEvent.create({
                offerId: offer.id,
                previousCode: offer.oldCode,
                currentCode: offer.code
            });
            DomainEvents.dispatch(event);
        }

        if (offer.isNew) {
            await this.OfferModel.add(data, options);
            const event = OfferCreatedEvent.create({offer});

            if (options.transacting) {
                // Only dispatch the event after the transaction has finished
                // Because else the offer won't be committed to the database yet
                options.transacting.executionPromise.then(() => {
                    DomainEvents.dispatch(event);
                });
            } else {
                DomainEvents.dispatch(event);
            }
        } else {
            await this.OfferModel.edit(data, {...options, id: data.id});
        }
    }
}

module.exports = OfferRepository;
<|endoftext|>


<commit_before>/*
    // Clean version
    $(function() {
      $('.sortable').sortable({connectWith: '.sortable'}).disableSelection();
    });
//*/
//*
    $(function() {
      var debug = function(mesg) {
        $('#messages').append('
' + mesg + '
');
      };
      $('.sortable').sortable({
        connectWith: '.sortable',
        stop: function(e, ui) {
          var sender = ui.sender ? ui.sender[0].id : "(none)";
          var item = ui.item[0].id;
          var target = e.target.id;
          debug('ui.sender=' + sender + ', item=' + item + ', target=' + target);
          var data = {};
          $('ul.phase').each(function() {
            data[this.id] = $.map($(this).find('li.card'), function(y) { return y.id})
          })
          $.post('update/', data);
        }
      }).disableSelection();
    });
//*/

<commit_msg>js cleanup, add TODO for error function/display<commit_after>/*
    // Clean version
    $(function() {
      $('.sortable').sortable({connectWith: '.sortable'}).disableSelection();
    });
//*/
//*
    $(function() {
      var debug = function(mesg) {
        $('#messages').append('
' + mesg + '
');
      };
      $('.sortable').sortable({
        connectWith: '.sortable',
        stop: function(e, ui) {
          var sender = ui.sender ? ui.sender[0].id : "(none)";
          var item = ui.item[0].id;
          var target = e.target.id;
          debug('ui.sender=' + sender + ', item=' + item + ', target=' + target);
          var data = {};
          $('ul.phase').each(function() {
            data[this.id] = $.map($(this).find('li.card'), function(y) { return y.id})
          });
          // TODO:zjh - add error function to display debug info
          $.post('update/', data);
        }
      }).disableSelection();
    });
//*/

<|endoftext|>


<commit_before>'use strict';

var azureSubscriptionKey = process.env.AZURE_SUBSCRIPTION_KEY;
var azureRegion = process.env.AZURE_REGION;
const _dirname = '/data/';

async function downloadFile(url, header, dest) {
    console.log('downloadFile');
    console.log(url, header, dest);
    const { spawn } = require('child-process-promise');
    const curl = spawn('curl', ['-o', dest, '-O', url, '-H', header, '--silent']);
    curl.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    curl.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });
    await curl;
    return dest;
}

async function convertVideoToWav(pathToFile) {
    console.log("convertVideoToWav");
    var outputFile = _dirname + pathToFile.substring(pathToFile.lastIndexOf('/') + 1, pathToFile.lastIndexOf('.')) + '.wav';
    const { spawn } = require('child-process-promise');
    const ffmpeg = spawn('ffmpeg', ['-nostdin', '-i', pathToFile, '-c:a', 'pcm_s16le', '-ac', '1', '-y', '-ar', '16000', outputFile]);

    ffmpeg.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    ffmpeg.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });

    return await ffmpeg.then(result => { return Promise.resolve(outputFile) });
}

async function convertWavFileToSrt(pathToFile) {
    var outputFile = _dirname + pathToFile.substring(pathToFile.lastIndexOf('/') + 1, pathToFile.lastIndexOf('.')) + '.vtt';
    const { spawn } = require('child-process-promise');
    const dotnet = spawn('dotnet', ['/MSTranscription/Release/MSTranscription.dll', azureSubscriptionKey, azureRegion, pathToFile]);
    dotnet.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    dotnet.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });

    return await dotnet.then(result => {
        return Promise.resolve(outputFile)
    });
}

async function download_from_youtube_url(videoUrl, outputFile) {
    const { spawn } = require('child-process-promise');
    const youtubedl = spawn('youtube-dl', [videoUrl, '--format=18', '--output', outputFile]);

    youtubedl.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    youtubedl.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });
    await youtubedl;
    return outputFile;
}

async function hash_file(filename, algo) {
    const hasha = require('hasha');

    return await hasha.fromFile(filename, {algorithm: algo}).then(hash => {
        return Promise.resolve(hash);
    });
}

hash_file(_dirname + 'cookies.txt', 'md5').then(hash => { console.log(hash); });
hash_file(_dirname + 'cookies.txt', 'sha256').then(hash => { console.log(hash); });

module.exports = {
    convertVideoToWav: convertVideoToWav,
    convertWavFileToSrt: convertWavFileToSrt,
    downloadFile: downloadFile,
    download_from_youtube_url: download_from_youtube_url
}<commit_msg>thumbnails functionality completes, requiring package 'get-video-duration' to be installed<commit_after>'use strict';

var azureSubscriptionKey = process.env.AZURE_SUBSCRIPTION_KEY;
var azureRegion = process.env.AZURE_REGION;
const _dirname = '/data/';

async function downloadFile(url, header, dest) {
    console.log('downloadFile');
    console.log(url, header, dest);
    const { spawn } = require('child-process-promise');
    const curl = spawn('curl', ['-o', dest, '-O', url, '-H', header, '--silent']);
    curl.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    curl.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });
    await curl;
    return dest;
}

async function convertVideoToWav(pathToFile) {
    console.log("convertVideoToWav");
    var outputFile = _dirname + pathToFile.substring(pathToFile.lastIndexOf('/') + 1, pathToFile.lastIndexOf('.')) + '.wav';
    const { spawn } = require('child-process-promise');
    const ffmpeg = spawn('ffmpeg', ['-nostdin', '-i', pathToFile, '-c:a', 'pcm_s16le', '-ac', '1', '-y', '-ar', '16000', outputFile]);

    ffmpeg.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    ffmpeg.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });

    return await ffmpeg.then(result => { return Promise.resolve(outputFile) });
}

async function convertWavFileToSrt(pathToFile) {
    var outputFile = _dirname + pathToFile.substring(pathToFile.lastIndexOf('/') + 1, pathToFile.lastIndexOf('.')) + '.vtt';
    const { spawn } = require('child-process-promise');
    const dotnet = spawn('dotnet', ['/MSTranscription/Release/MSTranscription.dll', azureSubscriptionKey, azureRegion, pathToFile]);
    dotnet.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    dotnet.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });

    return await dotnet.then(result => {
        return Promise.resolve(outputFile)
    });
}

async function download_from_youtube_url(videoUrl, outputFile) {
    const { spawn } = require('child-process-promise');
    const youtubedl = spawn('youtube-dl', [videoUrl, '--format=18', '--output', outputFile]);

    youtubedl.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    youtubedl.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });
    await youtubedl;
    return outputFile;
}

async function hash_file(filename, algo) {
    const hasha = require('hasha');

    return await hasha.fromFile(filename, {algorithm: algo}).then(hash => {
        return Promise.resolve(hash);
    });
}

hash_file(_dirname + 'cookies.txt', 'md5').then(hash => { console.log(hash); });
hash_file(_dirname + 'cookies.txt', 'sha256').then(hash => { console.log(hash); });

async function get_thumbnails_from_video(pathToFile) {
    const { getVideoDurationInSeconds } = require('get-video-duration')

    var duration_one_fifth = await getVideoDurationInSeconds(pathToFile).then(duration => {
        duration = Math.round(duration / 5);
        let hours = Math.floor(duration / 3600);
        let minutes = Math.floor(duration / 60);
        let seconds = duration % 60;
        return Promise.resolve(hours + ':' + minutes + ':' + seconds);
    });

    var outputFile = _dirname + pathToFile.substring(pathToFile.lastIndexOf('/') + 1, pathToFile.lastIndexOf('.')) + '.jpg';
    const { spawn } = require('child-process-promise');
    const ffmpeg = spawn('ffmpeg', ['-ss', duration_one_fifth, '-i', pathToFile, '-vframes', '1', '-q:v', '2', outputFile]);

    ffmpeg.childProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    ffmpeg.childProcess.stderr.on('data', (data) => {
        console.log(`stderr: ${data}`);
    });

    return await ffmpeg.then(result => { return Promise.resolve(outputFile) });
}

module.exports = {
    convertVideoToWav: convertVideoToWav,
    convertWavFileToSrt: convertWavFileToSrt,
    downloadFile: downloadFile,
    download_from_youtube_url: download_from_youtube_url
}<|endoftext|>


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

export default class ContactUs extends Component {

  constructor(props) {
    super(props);
    this.contentProvider = this.props.contentProvider;
    this.state = this.contentProvider.get('landingPage').contactUs;
  }

  renderContactUsItems() {
    return this.state.contactUsItems.map( (v, i) => (

          <i className={`fa fa-${v.contactIcon} fa-2x`}>

{v.title}

{v.contactInfo}

    ));
  }

  renderSocialIcons() {
    const icons = this.state.socialProviders.map( (v, i) => (

<a href={v.url} className={`icon-${v.socialProviderId}`}>{v.label}

    ));
    return (

        {icons}

    );
  }

  render() {
    const year = 1900 + (new Date()).getYear();
    return (

{this.state.header}

{this.state.subtitle}

            {this.renderContactUsItems()}

                {this.renderSocialIcons()}

                 &copy Copyright {year} Webellion Ltd.

    );
  }
}
<commit_msg>Contact us section<commit_after>import React, {Component} from 'react';

export default class ContactUs extends Component {

  constructor(props) {
    super(props);
    this.contentProvider = this.props.contentProvider;
    this.state = this.contentProvider.get('landingPage').contactUs;
  }

  renderContactUsItems() {
    return this.state.contactUsItems.map( (v, i) => (

            <i className={`fa fa-${v.contactIcon} fa-2x`}>

{v.title}

{v.contactInfo}

    ));
  }

  renderSocialIcons() {
    const icons = this.state.socialProviders.map( (v, i) => (

<a href={v.url} className={`icon-${v.socialProviderId}`}>{v.label}

    ));
    return (

        {icons}

    );
  }

  render() {
    const year = 1900 + (new Date()).getYear();
    return (

{this.state.header}

{this.state.subtitle}

            {this.renderContactUsItems()}

                {this.renderSocialIcons()}

                 &copy Copyright {year} Webellion Ltd.

    );
  }
}
<|endoftext|>


<commit_before>/*
* name:     nodebukket.js
* author:   Chad Hobbs
* created:  140327
*
* description: This is the glory and wonder that is node bukket
*/

/* ----------------------------------------------------------------------------------------
* Module Name: mainApp
* Parameters:    TBD
* Returns:       TBD
* Description:   This is the main module
*  ----------------------------------------------------------------------------------------
*/

// Configuration Object
var config = {
	channels: ["#nodebukket"],
	server: "irc.freenode.net",
	botName: "nodebukket",
    port: 6667,
    debug: false,
    showErrors: false,
    autoRejoin: true,
    autoConnect: true,
    secure: false,
    selfSigned: false,
    certExpired: false,
    floodProtection: false,
    floodProtectionDelay: 1000,
    sasl: false,
    stripColors: false,
    // channelPrefixes: "&#",
    messageSplit: 512
};

// Get the lib
var irc = require("irc");

// Create the bot name
var bot = new irc.Client(config.server, config.botName, {
	channels: config.channels
});

// Listen for joins
bot.addListener("join", function(channel, who) {
	// Welcome them in!
	bot.say(channel, who + "...dude...welcome back!");
});

// Listen for any message, say to him/her in the room
bot.addListener("message", function(from, to, text, message) {

	bot.say(config.channels[0], "hola");
});

// Listen for kicks
bot.addListener("kick", function(channel, who, by, reason, message) {
	// Send them on their way
	bot.say(channel, "GTFO " + who + "!!!");
	bot.say(channel, reason + " is a shitty way to go...");
});

// Listen for any message, say to him/her in the room
bot.addListener("message", function(from, to, text, message) {

	bot.say(config.channels[0], "The following is what was recieved.");
	bot.say(config.channels[0], message.prefix);
	bot.say(config.channels[0], message.nick);
	bot.say(config.channels[0], message.user);
	bot.say(config.channels[0], message.host);
	bot.say(config.channels[0], message.server);
	bot.say(config.channels[0], message.rawCommand);
	bot.say(config.channels[0], message.command);
	bot.say(config.channels[0], message.commandType);
	bot.say(config.channels[0], message.args);
});
<commit_msg>inserting conditional into message test<commit_after>/*
* name:     nodebukket.js
* author:   Chad Hobbs
* created:  140327
*
* description: This is the glory and wonder that is node bukket
*/

/* ----------------------------------------------------------------------------------------
* Module Name: mainApp
* Parameters:    TBD
* Returns:       TBD
* Description:   This is the main module
*  ----------------------------------------------------------------------------------------
*/

// Configuration Object
var config = {
	channels: ["#nodebukket"],
	server: "irc.freenode.net",
	botName: "nodebukket",
    port: 6667,
    debug: false,
    showErrors: false,
    autoRejoin: true,
    autoConnect: true,
    secure: false,
    selfSigned: false,
    certExpired: false,
    floodProtection: false,
    floodProtectionDelay: 1000,
    sasl: false,
    stripColors: false,
    // channelPrefixes: "&#",
    messageSplit: 512
};

// Get the lib
var irc = require("irc");

// Create the bot name
var bot = new irc.Client(config.server, config.botName, {
	channels: config.channels
});

// Error handling
bot.addListener('error', function(message) {
	console.log('error: ', message);
});

// Listen for joins
bot.addListener("join", function(channel, who) {
	// Welcome them in!
	bot.say(channel, who + "...dude...welcome back!");
});

// Listen for any message, say to him/her in the room
bot.addListener("message", function(from, to, text, message) {

	bot.say(config.channels[0], "hola");
});

// Listen for kicks
bot.addListener("kick", function(channel, who, by, reason, message) {
	// Send them on their way
	bot.say(channel, "GTFO " + who + "!!!");
	bot.say(channel, reason + " is a shitty way to go...");
});

// Listen for any message, say to him/her in the room
bot.addListener("message", function(from, to, text, message) {

	if (text == "message") {
		bot.say(config.channels[0], "The following is what was recieved.");
		bot.say(config.channels[0], "prefix: " + message.prefix);
		bot.say(config.channels[0], "nick: " + message.nick);
		bot.say(config.channels[0], "user: " + message.user);
		bot.say(config.channels[0], "host: " + message.host);
		bot.say(config.channels[0], "server: " + message.server);
		bot.say(config.channels[0], "rawCommand: " + message.rawCommand);
		bot.say(config.channels[0], "command: " + message.command);
		bot.say(config.channels[0], "commandType: " + message.commandType);
	}
});
<|endoftext|>


<commit_before>
const expect = require('chai').expect;
const Mustache = require('mustache');
const Wax = require('../dist/mustache-wax.js');

describe('Wax for Mustache', () => {
    Wax(Mustache, {
        "uppercase": (str) => {
            return str.toUpperCase();
        },
        "lowercase": (str) => {
            return str.toLowerCase();
        },
        "lpad": (str, num, sep) => {
            sep = sep || " ";
            str = "" + str;
            let filler = "";
            while ((filler.length + str.length) < num) { filler += sep };
            return (filler + str).slice(-num);
        },
        "date": (dt) => {
            const lpad = Mustache.Formatters.lpad,
                day   = lpad(dt.getDate(), 2, "0"),
                month = lpad(dt.getMonth()+1, 2, "0");
            return  day + "/" + month + "/" + dt.getFullYear();
        },
        "add": (one, two) => {
            return one + two;
        },
        "wrap": (str, begin, end) => {
            return (begin + str + end);
        },
        "countArgs": (...args) => {
            return args.length;
        },
        "sumArgs": (...args) => {
            const l = args.length;
            let i = 0, sum = 0;
            for (; i < l; ++i) {
                sum += args[i];
            }
            return sum;
        }
    });

    describe("Normal expression without formatter", () => {
        it('Should keep backwards compatibility', () => {
            const data = {name:"john"};

            const result = Mustache.render("{{name}}", data);
            expect(result).to.equal(data.name);

            const result2 = Mustache.render("{{&name}}", data);
            expect(result2).to.equal(data.name);
        })
    });

    describe("Expression with just one formatter", () => {
        const fmt  =  Mustache.Formatters;
        const data = {
            name:"john",
            dob: new Date(1981,2,24)
        };

        it('Should call the formatter with the expression value as parameter', () => {
            const result1 = Mustache.render("{{ name | uppercase }}", data);
            expect(result1).to.equal(fmt.uppercase(data.name));

            const result2 = Mustache.render("{{{ dob | date }}}", data);
            expect(result2).to.equal(fmt.date(data.dob));

            const result3 = Mustache.render("{{ name | countArgs }}", data);
            expect(result3).to.equal('' + fmt.countArgs(''));
        })
    });

    describe( "Expressions with parameters", () => {
        const fmt  =  Mustache.Formatters;
        const data = { name: "john", age:20 };

        it('Should call formatter with one additional integer parameter', () => {
            const result1 = Mustache.render("{{ name | lpad:30 }}", data);
            expect(result1).to.equal(fmt.lpad(data.name, 30));
        })

        it('Should call formatter with one additional decimal parameter', () => {
            const result1 = Mustache.render("{{ age | add:0.5 }}", data);
            expect(result1).to.equal('' + fmt.add(data.age, 0.5));
        })

        it('Should call the formatter with one additional string parameter', () => {
            const result2 = Mustache.render("{{ name | add:' doe' }}", data);
            expect(result2).to.equal(fmt.add(data.name, ' doe'));
        })

        it('should call the formatter with multiple additional string parameters', () => {
            const result3 = Mustache.render("{{ name | wrap : '^' : '$' }}", data);
            expect(result3).to.equal(fmt.wrap(data.name, '^', '$'));
        })

        it('should call the formatter with multiple additional integer parameters', () => {
            const result4 = Mustache.render("{{ name | sumArgs: 1: 2: 3: 4: 5 }}", data);
            expect(result4).to.equal('' + fmt.sumArgs(data.name, 1, 2, 3, 4, 5));
        })

        it('should call the formatter with multiple additional decimal parameters', () => {
            const result5 = Mustache.render("{{ age | sumArgs: 0.1: 0.2: 0.3: 0.4: 0.5: 0.6: 0.7: 0.8: 0.9: 1.0 }}", data);
            expect(result5).to.equal('' + fmt.sumArgs(data.age, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0));
        })
    });

    describe( "Chained Formatters", () => {
        const fmt = Mustache.Formatters;
        const data = {name:"John Doe", age:30};

        it('Should call formatters in order', () => {
            const result1 = Mustache.render("{{ name | lowercase | uppercase }}", data);
            expect(result1).to.equal(fmt.uppercase(fmt.lowercase(data.name)));
        })

        it('Should support parameters for the formatters', () => {
            const result2 = Mustache.render("{{ name | lpad:10:'*' | lpad:20:'#' }}", data);
            expect(result2).to.equal(fmt.lpad(fmt.lpad(data.name, 10, '*'), 20, '#'));
        })

        it('Should support many formatters with parameters', () => {
            const result3 = Mustache.render("{{ age | add:10 | add:5 | add: 3 | add: -7 | add:-11 }}", data);
            expect(result3).to.equal('' + data.age);
        })
    });

    describe( "Parameter types", () => {
        const data = {zero:0, pi:3.14159, name:"john", last:"doe"};

        it('Should allow integer parameters', () => {
            const result1 = Mustache.render("{{ zero | add: 1 }}", data);
            expect(result1).to.equal('1');

            const result2 = Mustache.render("{{ zero | add: +1 }}", data);
            expect(result2).to.equal('1');

            const result3 = Mustache.render("{{ zero | add: -1 }}", data);
            expect(result3).to.equal('-1');
        })

        it('Should allow decimal parameters', () => {
            const result4 = Mustache.render("{{ zero | add: 1.25 }}", data);
            expect(result4).to.equal('1.25');

            const result5 = Mustache.render("{{ zero | add: +1.25 }}", data);
            expect(result5).to.equal('1.25');

            const result6 = Mustache.render("{{ zero | add: -1.25 }}", data);
            expect(result6).to.equal('-1.25');
        })

        it('Should allow other expressions as parameters', () => {
            const result7 = Mustache.render("{{ zero | add: pi }}", data);
            expect(result7).to.equal('' + data.pi);

            const result10 = Mustache.render("{{ name | add: last }}", data);
            expect(result10).to.equal("johndoe");
        })

        it('Should allow quoted string parameters', () => {
            const result8 = Mustache.render("{{ name | add: 'atan' }}", data);
            expect(result8).to.equal("johnatan");

            const result9 = Mustache.render("{{ name | add: \"atan\" }}", data);
            expect(result9).to.equal("johnatan");

            const result11 = Mustache.render("{{{ name | add: ' \"Big\" ' | add: last }}}", data);
            expect(result11).to.equal("john \"Big\" doe");

            const result12 = Mustache.render("{{{ name | add: \" 'Big' \" | add: last }}}", data);
            expect(result12).to.equal("john 'Big' doe");
        })
    });
});<commit_msg>added Mustache version to spec output<commit_after>
const expect = require('chai').expect;
const Mustache = require('mustache');
const Wax = require('../dist/mustache-wax.min.js');

describe(`Wax for Mustache ${Mustache.version}`, () => {
    Wax(Mustache, {
        "uppercase": (str) => {
            return str.toUpperCase();
        },
        "lowercase": (str) => {
            return str.toLowerCase();
        },
        "lpad": (str, num, sep) => {
            sep = sep || " ";
            str = "" + str;
            let filler = "";
            while ((filler.length + str.length) < num) { filler += sep };
            return (filler + str).slice(-num);
        },
        "date": (dt) => {
            const lpad = Mustache.Formatters.lpad,
                day   = lpad(dt.getDate(), 2, "0"),
                month = lpad(dt.getMonth()+1, 2, "0");
            return  day + "/" + month + "/" + dt.getFullYear();
        },
        "add": (one, two) => {
            return one + two;
        },
        "wrap": (str, begin, end) => {
            return (begin + str + end);
        },
        "countArgs": (...args) => {
            return args.length;
        },
        "sumArgs": (...args) => {
            const l = args.length;
            let i = 0, sum = 0;
            for (; i < l; ++i) {
                sum += args[i];
            }
            return sum;
        }
    });

    describe("Normal expression without formatter", () => {
        it('Should keep backwards compatibility', () => {
            const data = {name:"john"};

            const result = Mustache.render("{{name}}", data);
            expect(result).to.equal(data.name);

            const result2 = Mustache.render("{{&name}}", data);
            expect(result2).to.equal(data.name);
        })
    });

    describe("Expression with just one formatter", () => {
        const fmt  =  Mustache.Formatters;
        const data = {
            name:"john",
            dob: new Date(1981,2,24)
        };

        it('Should call the formatter with the expression value as parameter', () => {
            const result1 = Mustache.render("{{ name | uppercase }}", data);
            expect(result1).to.equal(fmt.uppercase(data.name));

            const result2 = Mustache.render("{{{ dob | date }}}", data);
            expect(result2).to.equal(fmt.date(data.dob));

            const result3 = Mustache.render("{{ name | countArgs }}", data);
            expect(result3).to.equal('' + fmt.countArgs(''));
        })
    });

    describe( "Expressions with parameters", () => {
        const fmt  =  Mustache.Formatters;
        const data = { name: "john", age:20 };

        it('Should call formatter with one additional integer parameter', () => {
            const result1 = Mustache.render("{{ name | lpad:30 }}", data);
            expect(result1).to.equal(fmt.lpad(data.name, 30));
        })

        it('Should call formatter with one additional decimal parameter', () => {
            const result1 = Mustache.render("{{ age | add:0.5 }}", data);
            expect(result1).to.equal('' + fmt.add(data.age, 0.5));
        })

        it('Should call the formatter with one additional string parameter', () => {
            const result2 = Mustache.render("{{ name | add:' doe' }}", data);
            expect(result2).to.equal(fmt.add(data.name, ' doe'));
        })

        it('should call the formatter with multiple additional string parameters', () => {
            const result3 = Mustache.render("{{ name | wrap : '^' : '$' }}", data);
            expect(result3).to.equal(fmt.wrap(data.name, '^', '$'));
        })

        it('should call the formatter with multiple additional integer parameters', () => {
            const result4 = Mustache.render("{{ name | sumArgs: 1: 2: 3: 4: 5 }}", data);
            expect(result4).to.equal('' + fmt.sumArgs(data.name, 1, 2, 3, 4, 5));
        })

        it('should call the formatter with multiple additional decimal parameters', () => {
            const result5 = Mustache.render("{{ age | sumArgs: 0.1: 0.2: 0.3: 0.4: 0.5: 0.6: 0.7: 0.8: 0.9: 1.0 }}", data);
            expect(result5).to.equal('' + fmt.sumArgs(data.age, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0));
        })
    });

    describe( "Chained Formatters", () => {
        const fmt = Mustache.Formatters;
        const data = {name:"John Doe", age:30};

        it('Should call formatters in order', () => {
            const result1 = Mustache.render("{{ name | lowercase | uppercase }}", data);
            expect(result1).to.equal(fmt.uppercase(fmt.lowercase(data.name)));
        })

        it('Should support parameters for the formatters', () => {
            const result2 = Mustache.render("{{ name | lpad:10:'*' | lpad:20:'#' }}", data);
            expect(result2).to.equal(fmt.lpad(fmt.lpad(data.name, 10, '*'), 20, '#'));
        })

        it('Should support many formatters with parameters', () => {
            const result3 = Mustache.render("{{ age | add:10 | add:5 | add: 3 | add: -7 | add:-11 }}", data);
            expect(result3).to.equal('' + data.age);
        })
    });

    describe( "Parameter types", () => {
        const data = {zero:0, pi:3.14159, name:"john", last:"doe"};

        it('Should allow integer parameters', () => {
            const result1 = Mustache.render("{{ zero | add: 1 }}", data);
            expect(result1).to.equal('1');

            const result2 = Mustache.render("{{ zero | add: +1 }}", data);
            expect(result2).to.equal('1');

            const result3 = Mustache.render("{{ zero | add: -1 }}", data);
            expect(result3).to.equal('-1');
        })

        it('Should allow decimal parameters', () => {
            const result4 = Mustache.render("{{ zero | add: 1.25 }}", data);
            expect(result4).to.equal('1.25');

            const result5 = Mustache.render("{{ zero | add: +1.25 }}", data);
            expect(result5).to.equal('1.25');

            const result6 = Mustache.render("{{ zero | add: -1.25 }}", data);
            expect(result6).to.equal('-1.25');
        })

        it('Should allow other expressions as parameters', () => {
            const result7 = Mustache.render("{{ zero | add: pi }}", data);
            expect(result7).to.equal('' + data.pi);

            const result10 = Mustache.render("{{ name | add: last }}", data);
            expect(result10).to.equal("johndoe");
        })

        it('Should allow quoted string parameters', () => {
            const result8 = Mustache.render("{{ name | add: 'atan' }}", data);
            expect(result8).to.equal("johnatan");

            const result9 = Mustache.render("{{ name | add: \"atan\" }}", data);
            expect(result9).to.equal("johnatan");

            const result11 = Mustache.render("{{{ name | add: ' \"Big\" ' | add: last }}}", data);
            expect(result11).to.equal("john \"Big\" doe");

            const result12 = Mustache.render("{{{ name | add: \" 'Big' \" | add: last }}}", data);
            expect(result12).to.equal("john 'Big' doe");
        })
    });
});<|endoftext|>


<commit_before>const path = require('path');
const assert = require('assert');
const sander = require('sander');
const fixturify = require('fixturify');
const rollup = require('../../dist/rollup');
const { extend, loadConfig } = require('../utils.js');

const samples = path.resolve(__dirname, 'samples');

const FORMATS = ['es', 'cjs', 'amd', 'system'];

describe('chunking form', () => {
	sander.readdirSync(samples).sort().forEach(dir => {
		if (dir[0] === '.') return; // .DS_Store...

		const config = loadConfig(samples + '/' + dir + '/_config.js');

		if (config.skipIfWindows && process.platform === 'win32') return;
		if (!config.options) {
			config.options = {};
		}

		const options = extend(
			{},
			{
				input: [samples + '/' + dir + '/main.js'],
				experimentalCodeSplitting: true,
				experimentalDynamicImport: true,
				onwarn: msg => {
					if (/No name was provided for/.test(msg)) return;
					if (/as external dependency/.test(msg)) return;
					console.error(msg);
				}
			},
			config.options
		);

		(config.skip ? describe.skip : config.solo ? describe.only : describe)(dir, () => {
			let promise;
			const createBundle = () => promise || (promise = rollup.rollup(options));

			FORMATS.forEach(format => {
				it('generates ' + format, () => {
					process.chdir(samples + '/' + dir);

					return createBundle().then(bundle => {
						const options = extend({}, config.options, {
							dir: samples + '/' + dir + '/_actual/' + format,
							format,
							indent: !('indent' in config.options) ? true : config.options.indent,
						});

						sander.rimrafSync(options.dir);

						return bundle.write(options).then(() => {
							const actualFiles = fixturify.readSync(path.join(samples, dir, '_actual', format));

							let expectedFiles;
							try {
								expectedFiles = fixturify.readSync(path.join(samples, dir, '_expected', format));
							} catch (err) {
								expectedFiles = [];
							}

							assert.deepEqual(Object.keys(actualFiles), Object.keys(expectedFiles));

							Object.keys(actualFiles).forEach(fileName => {
								assert.strictEqual(actualFiles[fileName], expectedFiles[fileName], 'Unexpected output for ' + fileName);
							});
						});
					});
				});
			});
		});
	});
});
<commit_msg>revert chunking form test change<commit_after>const path = require('path');
const assert = require('assert');
const sander = require('sander');
const fixturify = require('fixturify');
const rollup = require('../../dist/rollup');
const { extend, loadConfig } = require('../utils.js');

const samples = path.resolve(__dirname, 'samples');

const FORMATS = ['es', 'cjs', 'amd', 'system'];

describe('chunking form', () => {
	sander.readdirSync(samples).sort().forEach(dir => {
		if (dir[0] === '.') return; // .DS_Store...

		const config = loadConfig(samples + '/' + dir + '/_config.js');

		if (config.skipIfWindows && process.platform === 'win32') return;
		if (!config.options) {
			config.options = {};
		}

		const options = extend(
			{},
			{
				input: [samples + '/' + dir + '/main.js'],
				experimentalCodeSplitting: true,
				experimentalDynamicImport: true,
				onwarn: msg => {
					if (/No name was provided for/.test(msg)) return;
					if (/as external dependency/.test(msg)) return;
					console.error(msg);
				}
			},
			config.options
		);

		(config.skip ? describe.skip : config.solo ? describe.only : describe)(dir, () => {
			let promise;
			const createBundle = () => promise || (promise = rollup.rollup(options));

			FORMATS.forEach(format => {
				it('generates ' + format, () => {
					process.chdir(samples + '/' + dir);

					return createBundle().then(bundle => {
						const options = extend({}, config.options, {
							dir: samples + '/' + dir + '/_actual/' + format,
							format,
							indent: !('indent' in config.options) ? true : config.options.indent,
						});

						sander.rimrafSync(options.dir);

						return bundle.write(options).then(() => {
							const actualFiles = fixturify.readSync(path.join(samples, dir, '_actual', format));

							let expectedFiles;
							try {
								expectedFiles = fixturify.readSync(path.join(samples, dir, '_expected', format));
							} catch (err) {
								expectedFiles = [];
							}

							assert.deepEqual(actualFiles, expectedFiles);
						});
					});
				});
			});
		});
	});
});
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    grunt.initConfig({
        yeoman: yeomanConfig,

        jshint: {
            files: [yeomanConfig.app+'/**/*.js', '!'+yeomanConfig.app+'/bower_components/**/*.js'],
            options: {
                jshintrc: '.jshintrc'
            }
        },

        requirejs: {
            dist: {
                options: {
                    baseUrl: yeomanConfig.app + '/scripts',
                    dir: yeomanConfig.dist + '/scripts',
                    mainConfigFile: yeomanConfig.app + '/scripts/app.build.js',
                    name: "main",
                    optimize: 'none',
                    preserveLicenseComments: false,
                    useStrict: true,
                    wrap: true
                }
            }
        },
        clean: ["dist/*"],
        copy: {
            dist: {
                files: [
                { expand: true, dot: true, cwd: yeomanConfig.app, dest: yeomanConfig.dist, src: [
                        'index.html'
                    ]}
                ]
            },
            bower_libs: {
                files: [
                    {expand: true, cwd: yeomanConfig.app+'/bower_components/', src: ['**'], dest: yeomanConfig.dist +'/bower_components/'}
                ]
            },
            amd_not_compiled: {
                files: [
                    {expand: true, cwd: yeomanConfig.app+'/scripts/', src: ['**'], dest: yeomanConfig.dist +'/scripts/'}
                ]
            }
        },
        concat: {
            amd_not_compiled: {
                src: [yeomanConfig.app+'/scripts/app.build.js', yeomanConfig.app+'/scripts/main.js'],
                dest: yeomanConfig.dist +'/scripts/main.js'
            }
        }/*,
        jasmine : {
            src : '<%= pkg.name %>.js',
            options : {
                host: 'http://127.0.0.1:8000/',
                keepRunner:true,*/
                //specs : 'spec/**/*.js',
                /*helpers: ['src/vendor/sinon-1.7.1.js', 'src/vendor/jquery.js', 'src/vendor/jasmine-jquery.js'],
                template: require('grunt-template-jasmine-requirejs'),
                templateOptions: {
                    requireConfig: {
                        baseUrl: yeomanConfig.app + '/scripts',
                        dir: yeomanConfig.dist+ '/scripts',
                        mainConfigFile: yeomanConfig.app + '/scripts/app.build.js'

                    }
                }
            }
        }*/

    });

    grunt.registerTask('deploy', [ 'clean', 'copy:dist', 'copy:bower_libs', 'requirejs' ]);
    grunt.registerTask('build', [ 'clean', 'copy:dist', 'copy:bower_libs', 'copy:amd_not_compiled', 'concat:amd_not_compiled']);

};

<commit_msg>making use of grunt-bower-requirejs<commit_after>module.exports = function (grunt) {
    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    grunt.initConfig({
        yeoman: yeomanConfig,

        jshint: {
            files: [yeomanConfig.app+'/**/*.js', '!'+yeomanConfig.app+'/bower_components/**/*.js'],
            options: {
                jshintrc: '.jshintrc'
            }
        },
        requirejs: {
            dist: {
                options: {
                    baseUrl: yeomanConfig.app + '/scripts',
                    dir: yeomanConfig.dist + '/scripts',
                    mainConfigFile: yeomanConfig.app + '/scripts/app.build.js',
                    name: "main",
                    optimize: 'none',
                    preserveLicenseComments: false,
                    useStrict: true,
                    wrap: true
                }
            }
        },
        bower: {
            target: {
                options: {
                    exclude: ['requirejs']
                },
                rjsConfig: yeomanConfig.app + '/scripts/app.build.js'
            }
        },
        clean: ["dist/*"],
        copy: {
            dist: {
                files: [
                { expand: true, dot: true, cwd: yeomanConfig.app, dest: yeomanConfig.dist, src: [
                        'index.html'
                    ]}
                ]
            },
            bower_libs: {
                files: [
                    {expand: true, cwd: yeomanConfig.app+'/bower_components/', src: ['**'], dest: yeomanConfig.dist +'/bower_components/'}
                ]
            },
            amd_not_compiled: {
                files: [
                    {expand: true, cwd: yeomanConfig.app+'/scripts/', src: ['**'], dest: yeomanConfig.dist +'/scripts/'}
                ]
            }
        },
        concat: {
            amd_not_compiled: {
                src: [yeomanConfig.app+'/scripts/app.build.js', yeomanConfig.app+'/scripts/main.js'],
                dest: yeomanConfig.dist +'/scripts/main.js'
            }
        }/*,
        jasmine : {
            src : '<%= pkg.name %>.js',
            options : {
                host: 'http://127.0.0.1:8000/',
                keepRunner:true,*/
                //specs : 'spec/**/*.js',
                /*helpers: ['src/vendor/sinon-1.7.1.js', 'src/vendor/jquery.js', 'src/vendor/jasmine-jquery.js'],
                template: require('grunt-template-jasmine-requirejs'),
                templateOptions: {
                    requireConfig: {
                        baseUrl: yeomanConfig.app + '/scripts',
                        dir: yeomanConfig.dist+ '/scripts',
                        mainConfigFile: yeomanConfig.app + '/scripts/app.build.js'

                    }
                }
            }
        }*/

    });

    //remember to run 'grunt bower' every time a new packge is installed
    grunt.registerTask('deploy', [ 'jshint', 'clean', 'copy:dist', /*'copy:bower_libs',*/ 'bower', 'requirejs' ]);
    grunt.registerTask('build', [ 'jshint', 'clean', 'copy:dist', /*'copy:bower_libs',*/ 'copy:amd_not_compiled', 'bower', 'concat:amd_not_compiled']);

};

<|endoftext|>


<commit_before>var bsCredentials;
var canUseBS = false;

try {
  bsCredentials = require(__dirname + '/browserStack.json');
  canUseBS = true;
} catch (e) {
  console.warn("Can't load credentials from browserStack.json, fallback to Puppeteer");
}

module.exports = function (config) {
  config.set({
    // global config of your BrowserStack account
    browserStack: canUseBS && bsCredentials,

    // define browsers
    customLaunchers: {
      bs_ie11_win7: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '11',
        os: 'WINDOWS',
        os_version: '7'
      },
      bs_ie9_win7: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '9',
        os: 'WINDOWS',
        os_version: '7'
      },
      bs_ie8_win7: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '8',
        os: 'WINDOWS',
        os_version: '7'
      },
      bs_edge_win10: {
        base: 'BrowserStack',
        browser: 'edge',
        browser_version: '12',
        os: 'WINDOWS',
        os_version: '10'
      },
      bs_chrome_win10: {
        base: 'BrowserStack',
        browser: 'chrome',
        browser_version: '46',
        os: 'WINDOWS',
        os_version: '10'
      },
      bs_chrome_winxp: {
        base: 'BrowserStack',
        browser: 'chrome',
        browser_version: '46',
        os: 'WINDOWS',
        os_version: 'XP'
      },
      bs_firefox_win10: {
        base: 'BrowserStack',
        browser: 'firefox',
        browser_version: '42',
        os: 'WINDOWS',
        os_version: '10'
      },
      bs_safari_elcap: {
        base: 'BrowserStack',
        browser: 'safari',
        os: 'OS X',
        os_version: 'El Capitan'
      },
      bs_safari_mavericks: {
        base: 'BrowserStack',
        browser: 'safari',
        os: 'OS X',
        os_version: 'Mavericks'
      },
      bs_ios8: {
        base: 'BrowserStack',
        device: 'iPhone 6',
        os: 'ios',
        os_version: '8.0'
      },
      bs_ios6: {
        base: 'BrowserStack',
        device: 'iPhone 5',
        os: 'ios',
        os_version: '6.0'
      },
      bs_android44: {
        base: 'BrowserStack',
        device: 'Samsung Galaxy S5',
        os: 'android',
        os_version: '4.4'
      }
    },

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: canUseBS ? [
      'bs_ie11_win7',
      'bs_ie9_win7',
      'bs_ie8_win7',
      'bs_edge_win10',
      'bs_chrome_win10',
      //'bs_chrome_winxp',
      'bs_firefox_win10',
      'bs_safari_elcap',
      //'bs_safari_mavericks',
      'bs_ios8',
      //'bs_ios6',
      'bs_android44'
    ] : ['ChromeHeadless'],

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: './',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: [
      'node_modules/@babel/polyfill/dist/polyfill.min.js',
      'node_modules/console-polyfill/index.js',
      'tests/input/*.js'
    ],

    // list of files to exclude
    exclude: [
      'karma.conf.js'
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'tests/input/*.js': ['webpack']
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    webpack: {
      devtool: false,
      performance: {
        hints: false
      },
      output: {
        filename: '[name].js'
      },
      resolve: {
        modules: ['node_modules', '.']
      },
      module: require('./webpack.config').module
    }
  });
};
<commit_msg>Fix Travis (I hope)<commit_after>var bsCredentials;
var canUseBS = false;

try {
  bsCredentials = require(__dirname + '/browserStack.json');
  canUseBS = true;
} catch (e) {
  console.warn("Can't load credentials from browserStack.json, fallback to Puppeteer");
}

module.exports = function (config) {
  config.set({
    // global config of your BrowserStack account
    browserStack: canUseBS && bsCredentials,

    // define browsers
    customLaunchers: {
      bs_ie11_win7: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '11',
        os: 'WINDOWS',
        os_version: '7'
      },
      bs_ie9_win7: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '9',
        os: 'WINDOWS',
        os_version: '7'
      },
      bs_ie8_win7: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '8',
        os: 'WINDOWS',
        os_version: '7'
      },
      bs_edge_win10: {
        base: 'BrowserStack',
        browser: 'edge',
        browser_version: '12',
        os: 'WINDOWS',
        os_version: '10'
      },
      bs_chrome_win10: {
        base: 'BrowserStack',
        browser: 'chrome',
        browser_version: '46',
        os: 'WINDOWS',
        os_version: '10'
      },
      bs_chrome_winxp: {
        base: 'BrowserStack',
        browser: 'chrome',
        browser_version: '46',
        os: 'WINDOWS',
        os_version: 'XP'
      },
      bs_firefox_win10: {
        base: 'BrowserStack',
        browser: 'firefox',
        browser_version: '42',
        os: 'WINDOWS',
        os_version: '10'
      },
      bs_safari_elcap: {
        base: 'BrowserStack',
        browser: 'safari',
        os: 'OS X',
        os_version: 'El Capitan'
      },
      bs_safari_mavericks: {
        base: 'BrowserStack',
        browser: 'safari',
        os: 'OS X',
        os_version: 'Mavericks'
      },
      bs_ios8: {
        base: 'BrowserStack',
        device: 'iPhone 6',
        os: 'ios',
        os_version: '8.0'
      },
      bs_ios6: {
        base: 'BrowserStack',
        device: 'iPhone 5',
        os: 'ios',
        os_version: '6.0'
      },
      bs_android44: {
        base: 'BrowserStack',
        device: 'Samsung Galaxy S5',
        os: 'android',
        os_version: '4.4'
      },

      ChromeHeadless: {
        flags: [
          '--no-sandbox',
          '--disable-setuid-sandbox'
        ]
      }
    },

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: canUseBS ? [
      'bs_ie11_win7',
      'bs_ie9_win7',
      'bs_ie8_win7',
      'bs_edge_win10',
      'bs_chrome_win10',
      //'bs_chrome_winxp',
      'bs_firefox_win10',
      'bs_safari_elcap',
      //'bs_safari_mavericks',
      'bs_ios8',
      //'bs_ios6',
      'bs_android44'
    ] : ['ChromeHeadless'],

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: './',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: [
      'node_modules/@babel/polyfill/dist/polyfill.min.js',
      'node_modules/console-polyfill/index.js',
      'tests/input/*.js'
    ],

    // list of files to exclude
    exclude: [
      'karma.conf.js'
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'tests/input/*.js': ['webpack']
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    webpack: {
      devtool: false,
      performance: {
        hints: false
      },
      output: {
        filename: '[name].js'
      },
      resolve: {
        modules: ['node_modules', '.']
      },
      module: require('./webpack.config').module
    }
  });
};
<|endoftext|>


<commit_before>var myApp = angular.module('myApp', []);
myApp.controller('getQuotationsAndComments', ['$scope', '$http', '$element', '$filter', '$location', '$anchorScroll',function ($scope, $http, $location, $anchorScroll) {

    $scope.quotations = [];
    $scope.comments = [];
    $scope.inputQuotation = "";
    $scope.inputComment = "";
    $scope.curQuotationKey = "";
    var quotationAnchorTime;
    var commentAnchorTime;
    var quotationKey = {};
    var commentKey = {};
    var isAddWrongCount = false;
    var isAddRightCount = false;
    function addQuotations (quotations, isNew) {
        if (isNew) {
            quotationKey[quotations[0].key] = true;
            $scope.quotations.unshift(quotations[0]);
        } else {
            var len = quotations.length, i=0;
            while(i<len) {
                if (!quotationKey[quotations[i].key]) {
                    quotationKey[quotations[i].key] = true;
                    $scope.quotations.push(quotations[i]);
                }
                i++;
            }
        }
    }
    function addComments (comments,isNewQuotation, isNewComment) {
        if (!$scope.curQuotationKey) {
            return;
        }
        var i = 0, len = comments.length;
        while (i < len) {
            comments[i].displayTime = moment(comments[i].time*1000).format('YYYY-MM-DD hh:mm:ss');
            i++;
        }
        if (isNewQuotation) {
            commentKey = {};
            $scope.comments = comments;
        } else {
            var len = comments.length, i=0;
            while(i<len) {
                if (!commentKey[comments[i].key]) {
                    quotationKey[comments[i].key] = true;
                    if (isNewComment){
                        $scope.comments.unshift(comments[i]);
                    } else {
                        $scope.comments.push(comments[i]);
                    }
                }
                i++;
            }
        }

    }
    function sendRequest(data, method, url, onCompleted) {
        var req = {
            method: method,
            url: url,
            data: data
        };
        $http(req).success(function (data, status, heads, config) {
            onCompleted(data, status, heads, config);
        })
    }
    $scope.init = function () {
        addQuotations(quotations, false);
        if ($scope.quotations.length>0) {
            $scope.getComments($scope.quotations[0]);
        }
    };
    $scope.submitQuotation = function () {
        //TODO: valid check
        if($scope.inputQuotation.length === 0) {
            return;
        }
        var postData = {
            quotation: $scope.inputQuotation
        };
        var url = 'http://localhost:3000/quotations/create';
        sendRequest(postData, 'POST', url, function (data, status, heads, config) {
            if (data && data.quotation) {
                addQuotations([data.quotation], true);
                $scope.inputQuotation = "";
                $scope.getComments(data.quotation);
                var commentNode = document.getElementById('content_right');
                angular.element(commentNode).css('marginTop', 0 + 'px');

            }
        });
    };
    $scope.searchQuotation = function () {
        //TODO: valid check
        return;
        if ($scope.inputQuotation.length === 0) {
            return;
        }
        var url = 'http://localhost:3000/quotations/search?search_string='+$scope.inputQuotation;
        sendRequest(null, "GET", url, function (data, status, heads, config) {
            if (data&& data.quotations) {
                $scope.quotations = [];
                quotationKey = {};
                addQuotations(quotations, false);
            }
        })
    };
    $scope.submitComment = function () {
        //TODO: valid check
        if($scope.inputComment.length === 0) {
            return;
        }
        var postData = {
            comment: $scope.inputComment
        };
        var url = 'http://localhost:3000/quotations/'+$scope.curQuotationKey+'/comment/create';
        sendRequest(postData, 'POST', url, function (data, status, heads, config) {
            if (data && data.comment) {
                addComments([data.comment], false, true);
                $scope.inputComment = "";
                $scope.commentTip = "";
            }
        });
    };
    $scope.getComments = function (quotation) {
        if (!quotation.key) {
            return;
        }
        var isNewQuotation,url;
        if ($scope.curQuotationKey != quotation.key || $scope.comments.length === 0) {
            $scope.curQuotationKey = quotation.key;
            isNewQuotation = true;
            url = 'http://localhost:3000/quotations/'+$scope.curQuotationKey+'/comments';
            sendRequest(null, "GET", url, function(data, status, heads, config) {
                if (data && data.comments) {
                    if (data.comments.length > 0){
                        $scope.commentTip = '';
                    } else {
                        $scope.commentTip = '暂无评论';
                    }
                    addComments(data.comments, isNewQuotation, false);
                }
            });
        }

    };
    $scope.moveCommentShowRegion = function ($event) {
        var node = $event.currentTarget || $event.srcElement;
        while (node.nodeName != 'LI') {
            node = node.parentNode;
        }
        var offsetTop = angular.element(node).prop('offsetTop');
        var commentNode = document.getElementById('content_right');
        angular.element(commentNode).css('marginTop', offsetTop + 'px');
    };
    $scope.getMoreQuotation = function (cb) {
        if ($scope.quotations.length > 0) {

            var anchor_time = $scope.quotations[$scope.quotations.length-1].entry_time*1000;

            var url = 'http://localhost:3000/quotations?anchor_time='+anchor_time;
            sendRequest(null, "GET", url, function (data, status, heads, config) {
                if (data&&data.quotations) {
                    addQuotations(data.quotations, false);
                    if (cb) {
                        cb();
                    }
                }
            });
        }
    };
    $scope.getMoreComments = function (cb) {
        var url;
        if (!$scope.curQuotationKey) {
            return;
        } else {

            var anchorTime;
            if ($scope.comments.length>0) {
                anchorTime = $scope.comments[$scope.comments.length-1].time;
            } else {
                anchorTime = moment().format('x');
            }
            url = 'http://localhost:3000/quotations/'+$scope.curQuotationKey+'/comments?anchor_time='+anchorTime;
            sendRequest(null, "GET", url, function (data, status, heads, config) {
                if (data&&data.comments) {
                    addComments(data.comments, false, false);
                    if (cb) {
                        cb();
                    }
                }
            })
        }
    };
    $scope.addWrongCount = function (quotation) {
        if (isAddWrongCount) {
            return;
        }
        var url = "http://localhost:3000/quotations/"+$scope.curQuotationKey+"/wrong_count/count"
        sendRequest(null,'PUT',url, function (data, status, heads, config) {
            if (data && data.result) {
                isAddWrongCount = true;
                quotation.wrong_count =parseInt(quotation.wrong_count)+1;
            }
        });
    };
    $scope.addRightCount = function (quotation) {
        if (isAddRightCount) {
            return;
        }
        var url = "http://localhost:3000/quotations/"+$scope.curQuotationKey+"/right_count/count"
        sendRequest(null,'PUT',url, function (data, status, heads, config) {
            if (data && data.result) {
                isAddRightCount = true;
                quotation.right_count =parseInt(quotation.right_count)+1;
            }
        });
    };
}]);

myApp.filter('comment_reverse', function () {
    return function (comments) {
        return comments.slice().reverse();
    }
});

window.onscroll = function () {
    var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    var pageHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    if (Math.abs(pageHeight - scrollTop - windowHeight) < 10) {
        var angularEle =  document.querySelector("[ng-controller=getQuotationsAndComments]");
        var loadingEle = document.getElementById('quotation_loading');
        loadingEle.style.display = 'block';
        angular.element(angularEle).scope().getMoreQuotation(function () {
            loadingEle.style.display = 'none';
        });
    }
};

function onDivScroll() {
    var ele = document.getElementById('comment_show_region');
    if (ele.scrollTop === 0) {
        var loadingEle = document.getElementById('comment_loading');
        loadingEle.style.display = 'block';
        angular.element(ele).scope().getMoreComments(function () {
            loadingEle.style.display = 'none';
        });
    }
}<commit_msg>fix the unixtime bug for browser and server<commit_after>var myApp = angular.module('myApp', []);
myApp.controller('getQuotationsAndComments', ['$scope', '$http', '$element', '$filter', '$location', '$anchorScroll',function ($scope, $http, $location, $anchorScroll) {

    $scope.quotations = [];
    $scope.comments = [];
    $scope.inputQuotation = "";
    $scope.inputComment = "";
    $scope.curQuotationKey = "";
    var quotationAnchorTime;
    var commentAnchorTime;
    var quotationKey = {};
    var commentKey = {};
    var isAddWrongCount = false;
    var isAddRightCount = false;
    function addQuotations (quotations, isNew) {
        if (isNew) {
            quotationKey[quotations[0].key] = true;
            $scope.quotations.unshift(quotations[0]);
        } else {
            var len = quotations.length, i=0;
            while(i<len) {
                if (!quotationKey[quotations[i].key]) {
                    quotationKey[quotations[i].key] = true;
                    $scope.quotations.push(quotations[i]);
                }
                i++;
            }
        }
    }
    function addComments (comments,isNewQuotation, isNewComment) {
        if (!$scope.curQuotationKey) {
            return;
        }
        var i = 0, len = comments.length;
        while (i < len) {
            comments[i].displayTime = moment(comments[i].time*1000).format('YYYY-MM-DD hh:mm:ss');
            i++;
        }
        if (isNewQuotation) {
            commentKey = {};
            $scope.comments = comments;
        } else {
            var len = comments.length, i=0;
            while(i<len) {
                if (!commentKey[comments[i].key]) {
                    quotationKey[comments[i].key] = true;
                    if (isNewComment){
                        $scope.comments.unshift(comments[i]);
                    } else {
                        $scope.comments.push(comments[i]);
                    }
                }
                i++;
            }
        }

    }
    function sendRequest(data, method, url, onCompleted) {
        var req = {
            method: method,
            url: url,
            data: data
        };
        $http(req).success(function (data, status, heads, config) {
            onCompleted(data, status, heads, config);
        })
    }
    $scope.init = function () {
        addQuotations(quotations, false);
        if ($scope.quotations.length>0) {
            $scope.getComments($scope.quotations[0]);
        }
    };
    $scope.submitQuotation = function () {
        //TODO: valid check
        if($scope.inputQuotation.length === 0) {
            return;
        }
        var postData = {
            quotation: $scope.inputQuotation
        };
        var url = 'http://localhost:3000/quotations/create';
        sendRequest(postData, 'POST', url, function (data, status, heads, config) {
            if (data && data.quotation) {
                addQuotations([data.quotation], true);
                $scope.inputQuotation = "";
                $scope.getComments(data.quotation);
                var commentNode = document.getElementById('content_right');
                angular.element(commentNode).css('marginTop', 0 + 'px');

            }
        });
    };
    $scope.searchQuotation = function () {
        //TODO: valid check
        return;
        if ($scope.inputQuotation.length === 0) {
            return;
        }
        var url = 'http://localhost:3000/quotations/search?search_string='+$scope.inputQuotation;
        sendRequest(null, "GET", url, function (data, status, heads, config) {
            if (data&& data.quotations) {
                $scope.quotations = [];
                quotationKey = {};
                addQuotations(quotations, false);
            }
        })
    };
    $scope.submitComment = function () {
        //TODO: valid check
        if($scope.inputComment.length === 0) {
            return;
        }
        var postData = {
            comment: $scope.inputComment
        };
        var url = 'http://localhost:3000/quotations/'+$scope.curQuotationKey+'/comment/create';
        sendRequest(postData, 'POST', url, function (data, status, heads, config) {
            if (data && data.comment) {
                addComments([data.comment], false, true);
                $scope.inputComment = "";
                $scope.commentTip = "";
            }
        });
    };
    $scope.getComments = function (quotation) {
        if (!quotation.key) {
            return;
        }
        var isNewQuotation,url;
        if ($scope.curQuotationKey != quotation.key || $scope.comments.length === 0) {
            $scope.curQuotationKey = quotation.key;
            isNewQuotation = true;
            url = 'http://localhost:3000/quotations/'+$scope.curQuotationKey+'/comments';
            sendRequest(null, "GET", url, function(data, status, heads, config) {
                if (data && data.comments) {
                    if (data.comments.length > 0){
                        $scope.commentTip = '';
                    } else {
                        $scope.commentTip = '暂无评论';
                    }
                    addComments(data.comments, isNewQuotation, false);
                }
            });
        }

    };
    $scope.moveCommentShowRegion = function ($event) {
        var node = $event.currentTarget || $event.srcElement;
        while (node.nodeName != 'LI') {
            node = node.parentNode;
        }
        var offsetTop = angular.element(node).prop('offsetTop');
        var commentNode = document.getElementById('content_right');
        angular.element(commentNode).css('marginTop', offsetTop + 'px');
    };
    $scope.getMoreQuotation = function (cb) {
        if ($scope.quotations.length > 0) {

            var anchor_time = $scope.quotations[$scope.quotations.length-1].entry_time*1000;

            var url = 'http://localhost:3000/quotations?anchor_time='+anchor_time;
            sendRequest(null, "GET", url, function (data, status, heads, config) {
                if (data&&data.quotations) {
                    addQuotations(data.quotations, false);
                    if (cb) {
                        cb();
                    }
                }
            });
        }
    };
    $scope.getMoreComments = function (cb) {
        var url;
        if (!$scope.curQuotationKey) {
            return;
        } else {

            var anchorTime;
            if ($scope.comments.length>0) {
                anchorTime = $scope.comments[$scope.comments.length-1].time*1000;
            } else {
                anchorTime = moment().format('x');
            }
            url = 'http://localhost:3000/quotations/'+$scope.curQuotationKey+'/comments?anchor_time='+anchorTime;
            sendRequest(null, "GET", url, function (data, status, heads, config) {
                if (data&&data.comments) {
                    addComments(data.comments, false, false);
                    if (cb) {
                        cb();
                    }
                }
            })
        }
    };
    $scope.addWrongCount = function (quotation) {
        if (isAddWrongCount) {
            return;
        }
        var url = "http://localhost:3000/quotations/"+$scope.curQuotationKey+"/wrong_count/count"
        sendRequest(null,'PUT',url, function (data, status, heads, config) {
            if (data && data.result) {
                isAddWrongCount = true;
                quotation.wrong_count =parseInt(quotation.wrong_count)+1;
            }
        });
    };
    $scope.addRightCount = function (quotation) {
        if (isAddRightCount) {
            return;
        }
        var url = "http://localhost:3000/quotations/"+$scope.curQuotationKey+"/right_count/count"
        sendRequest(null,'PUT',url, function (data, status, heads, config) {
            if (data && data.result) {
                isAddRightCount = true;
                quotation.right_count =parseInt(quotation.right_count)+1;
            }
        });
    };
}]);

myApp.filter('comment_reverse', function () {
    return function (comments) {
        return comments.slice().reverse();
    }
});

window.onscroll = function () {
    var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    var pageHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    if (Math.abs(pageHeight - scrollTop - windowHeight) < 10) {
        var angularEle =  document.querySelector("[ng-controller=getQuotationsAndComments]");
        var loadingEle = document.getElementById('quotation_loading');
        loadingEle.style.display = 'block';
        angular.element(angularEle).scope().getMoreQuotation(function () {
            loadingEle.style.display = 'none';
        });
    }
};

function onDivScroll() {
    var ele = document.getElementById('comment_show_region');
    if (ele.scrollTop === 0) {
        var loadingEle = document.getElementById('comment_loading');
        loadingEle.style.display = 'block';
        angular.element(ele).scope().getMoreComments(function () {
            loadingEle.style.display = 'none';
        });
    }
}<|endoftext|>


<commit_before>/**
 * save content to zebedee, making it in progress in a collection.
 * @param collectionId
 * @param path
 * @param content
 * @param overwriteExisting - should the content be overwritten if it already exists?
 * @param recursive - should we recurse the directory of the file and make all files under it in progress?
 * @param success
 * @param error
 */
function postContent(collectionId, path, content, overwriteExisting, recursive, success, error) {
      isUpdatingModal.add();

    // Temporary workaround for content disappearing from bulletins - store last 10 saves to local storage and update with server response later
    postToLocalStorage(collectionId, path, content);

    var safePath = checkPathSlashes(path);
    if (safePath === '/') {
        safePath = '';          // edge case for home
    }

    if (Florence.globalVars.welsh) {
        var url = "/zebedee/content/" + collectionId + "?uri=" + safePath + "/data_cy.json";
        var toAddLang = JSON.parse(content);
        toAddLang.description.language = 'cy';
        content = JSON.stringify(toAddLang);
    } else {
        var url = "/zebedee/content/" + collectionId + "?uri=" + safePath + "/data.json";
    }

    var url = url + '&overwriteExisting=' + overwriteExisting;
    var url = url + '&recursive=' + recursive;

    var date = new Date();
    date = date.getHours() + ":" + date.getMinutes() + "." + date.getMilliseconds();
    console.log("[" + date + "] Post page content: \n", JSON.parse(content));

    $.ajax({
        url: url,
        dataType: 'json',
        contentType: 'application/json',
        type: 'POST',
        //data: cleanedUpJSON,
        data: content,
        success: function (response) {
            isUpdatingModal.remove();
            addLocalPostResponse(response);
            success(response);
        },
        error: function (response) {
            isUpdatingModal.remove();
            addLocalPostResponse(response);
            if (error) {
                error(response);
            } else {
                handleApiError(response);
            }
        }
    });
}

function postToLocalStorage(collectionId, path, content) {
    var newSaveTime = new Date();
    var newId = collectionId;
    var newPath = path;
    var newContent = JSON.parse(content);

    var localBackup = localStorage.getItem('localBackup');

    if (localBackup == null) {
        // If storage item doesn't exist yet initialise it with first save
        localBackup = [
            {
                collectionId: newId,
                content: newContent,
                path: newPath,
                saveTime: newSaveTime,
                postResponse: ''
            }
        ]
    } else {
        // Parse string back into JSON for reading and writing
        localBackup = JSON.parse(localBackup);

        var backupLength = localBackup.length;

        // Remove oldest entry if array is full
        if (backupLength == 10) {
            localBackup.pop();
        }

        // Add new entry to the top of the array
        localBackup.unshift(
            {
                collectionId: newId,
                content: newContent,
                path: newPath,
                saveTime: newSaveTime,
                postResponse: ''
            }
        );
    }

    localBackup = JSON.stringify(localBackup);
    localStorage.setItem('localBackup', localBackup);
}

function addLocalPostResponse(response) {
    var localBackup = JSON.parse(localStorage.getItem('localBackup'));
    localBackup[0].postResponse = response;
    localStorage.setItem('localBackup', JSON.stringify(localBackup));
}
<commit_msg>Removed commented out code<commit_after>/**
 * save content to zebedee, making it in progress in a collection.
 * @param collectionId
 * @param path
 * @param content
 * @param overwriteExisting - should the content be overwritten if it already exists?
 * @param recursive - should we recurse the directory of the file and make all files under it in progress?
 * @param success
 * @param error
 */
function postContent(collectionId, path, content, overwriteExisting, recursive, success, error) {
      isUpdatingModal.add();

    // Temporary workaround for content disappearing from bulletins - store last 10 saves to local storage and update with server response later
    postToLocalStorage(collectionId, path, content);

    var safePath = checkPathSlashes(path);
    if (safePath === '/') {
        safePath = '';          // edge case for home
    }

    if (Florence.globalVars.welsh) {
        var url = "/zebedee/content/" + collectionId + "?uri=" + safePath + "/data_cy.json";
        var toAddLang = JSON.parse(content);
        toAddLang.description.language = 'cy';
        content = JSON.stringify(toAddLang);
    } else {
        var url = "/zebedee/content/" + collectionId + "?uri=" + safePath + "/data.json";
    }

    var url = url + '&overwriteExisting=' + overwriteExisting;
    var url = url + '&recursive=' + recursive;

    var date = new Date();
    date = date.getHours() + ":" + date.getMinutes() + "." + date.getMilliseconds();
    console.log("[" + date + "] Post page content: \n", JSON.parse(content));

    $.ajax({
        url: url,
        dataType: 'json',
        contentType: 'application/json',
        type: 'POST',
        data: content,
        success: function (response) {
            isUpdatingModal.remove();
            addLocalPostResponse(response);
            success(response);
        },
        error: function (response) {
            isUpdatingModal.remove();
            addLocalPostResponse(response);
            if (error) {
                error(response);
            } else {
                handleApiError(response);
            }
        }
    });
}

function postToLocalStorage(collectionId, path, content) {
    var newSaveTime = new Date();
    var newId = collectionId;
    var newPath = path;
    var newContent = JSON.parse(content);

    var localBackup = localStorage.getItem('localBackup');

    if (localBackup == null) {
        // If storage item doesn't exist yet initialise it with first save
        localBackup = [
            {
                collectionId: newId,
                content: newContent,
                path: newPath,
                saveTime: newSaveTime,
                postResponse: ''
            }
        ]
    } else {
        // Parse string back into JSON for reading and writing
        localBackup = JSON.parse(localBackup);

        var backupLength = localBackup.length;

        // Remove oldest entry if array is full
        if (backupLength == 10) {
            localBackup.pop();
        }

        // Add new entry to the top of the array
        localBackup.unshift(
            {
                collectionId: newId,
                content: newContent,
                path: newPath,
                saveTime: newSaveTime,
                postResponse: ''
            }
        );
    }

    localBackup = JSON.stringify(localBackup);
    localStorage.setItem('localBackup', localBackup);
}

function addLocalPostResponse(response) {
    var localBackup = JSON.parse(localStorage.getItem('localBackup'));
    localBackup[0].postResponse = response;
    localStorage.setItem('localBackup', JSON.stringify(localBackup));
}
<|endoftext|>