<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

/*global Windows:true */

var cordova = require('cordova'),
    Media = require('org.apache.cordova.media.Media');

var MediaError = require('org.apache.cordova.media.MediaError');

module.exports = {
    mediaCaptureMrg:null,

    // Initiates the audio file
    create:function(win, lose, args) {
        var id = args[0];
        var src = args[1];
        var thisM = Media.get(id);
        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);

        Media.prototype.node = null;

        var fn = src.split('.').pop(); // gets the file extension
        if (thisM.node === null) {
            if (fn === 'mp3' || fn === 'wma' || fn === 'wma' ||
                fn === 'cda' || fn === 'adx' || fn === 'wm' ||
                fn === 'm3u' || fn === 'wmx') {
                thisM.node = new Audio(src);
                thisM.node.load();
                var dur = thisM.node.duration;
                if (isNaN(dur)) {
                    dur = -1;
                }
                Media.onStatus(id, Media.MEDIA_DURATION, dur);
            }
            else {
                lose && lose({code:MediaError.MEDIA_ERR_ABORTED});
            }
        }
    },

    // Start playing the audio
    startPlayingAudio:function(win, lose, args) {
        var id = args[0];
        //var src = args[1];
        //var options = args[2];
        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);

        (Media.get(id)).node.play();
    },

    // Stops the playing audio
    stopPlayingAudio:function(win, lose, args) {
        var id = args[0];
        try {
            (Media.get(id)).node.pause();
            (Media.get(id)).node.currentTime = 0;
            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
            win();
        } catch (err) {
            lose("Failed to stop: "+err);
        }
    },

    // Seeks to the position in the audio
    seekToAudio:function(win, lose, args) {
        var id = args[0];
        var milliseconds = args[1];
        try {
            (Media.get(id)).node.currentTime = milliseconds / 1000;
            win();
        } catch (err) {
            lose("Failed to seek: "+err);
        }
    },

    // Pauses the playing audio
    pausePlayingAudio:function(win, lose, args) {
        var id = args[0];
        var thisM = Media.get(id);
        try {
            thisM.node.pause();
            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
        } catch (err) {
            lose("Failed to pause: "+err);
        }
    },

    // Gets current position in the audio
    getCurrentPositionAudio:function(win, lose, args) {
        var id = args[0];
        try {
            var p = (Media.get(id)).node.currentTime;
            Media.onStatus(id, Media.MEDIA_POSITION, p);
            win(p);
        } catch (err) {
            lose(err);
        }
    },

    // Start recording audio
    startRecordingAudio:function(win, lose, args) {
        var id = args[0];
        var src = args[1];
        // Initialize device
        Media.prototype.mediaCaptureMgr = null;
        var thisM = (Media.get(id));
        var captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
        captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio;
        thisM.mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
        thisM.mediaCaptureMgr.addEventListener("failed", lose);

        thisM.mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) {
            thisM.mediaCaptureMgr.addEventListener("recordlimitationexceeded", lose);
            thisM.mediaCaptureMgr.addEventListener("failed", lose);

            // Start recording
            Windows.Storage.KnownFolders.musicLibrary.createFileAsync(src, Windows.Storage.CreationCollisionOption.replaceExisting).done(function (newFile) {
                var storageFile = newFile;
                var encodingProfile = null;
                switch (newFile.fileType) {
                    case '.m4a':
                        encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createM4a(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
                        break;
                    case '.mp3':
                        encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp3(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
                        break;
                    case '.wma':
                        encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createWma(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
                        break;
                    default:
                        lose("Invalid file type for record");
                        break;
                }
                thisM.mediaCaptureMgr.startRecordToStorageFileAsync(encodingProfile, storageFile).done(win, lose);
            }, lose);
        }, lose);
    },

    // Stop recording audio
    stopRecordingAudio:function(win, lose, args) {
        var id = args[0];
        var thisM = Media.get(id);
        thisM.mediaCaptureMgr.stopRecordAsync().done(win, lose);
    },

    // Release the media object
    release:function(win, lose, args) {
        var id = args[0];
        var thisM = Media.get(id);
        try {
            delete thisM.node;
        } catch (err) {
            lose("Failed to release: "+err);
        }
    },
    setVolume:function(win, lose, args) {
        var id = args[0];
        var volume = args[1];
        var thisM = Media.get(id);
        thisM.volume = volume;
    }
};

require("cordova/exec/proxy").add("Media",module.exports);
<commit_msg>CB-7454 Adds support for m4a audio format for Windows<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

/*global Windows:true */

var cordova = require('cordova'),
    Media = require('org.apache.cordova.media.Media');

var MediaError = require('org.apache.cordova.media.MediaError');

module.exports = {
    mediaCaptureMrg:null,

    // Initiates the audio file
    create:function(win, lose, args) {
        var id = args[0];
        var src = args[1];
        var thisM = Media.get(id);
        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);

        Media.prototype.node = null;

        var fn = src.split('.').pop(); // gets the file extension
        if (thisM.node === null) {
            if (fn === 'mp3' || fn === 'wma' || fn === 'wma' ||
                fn === 'cda' || fn === 'adx' || fn === 'wm' ||
                fn === 'm3u' || fn === 'wmx' || fn === 'm4a') {
                thisM.node = new Audio(src);
                thisM.node.load();
                var dur = thisM.node.duration;
                if (isNaN(dur)) {
                    dur = -1;
                }
                Media.onStatus(id, Media.MEDIA_DURATION, dur);
            }
            else {
                lose && lose({code:MediaError.MEDIA_ERR_ABORTED});
            }
        }
    },

    // Start playing the audio
    startPlayingAudio:function(win, lose, args) {
        var id = args[0];
        //var src = args[1];
        //var options = args[2];
        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);

        (Media.get(id)).node.play();
    },

    // Stops the playing audio
    stopPlayingAudio:function(win, lose, args) {
        var id = args[0];
        try {
            (Media.get(id)).node.pause();
            (Media.get(id)).node.currentTime = 0;
            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
            win();
        } catch (err) {
            lose("Failed to stop: "+err);
        }
    },

    // Seeks to the position in the audio
    seekToAudio:function(win, lose, args) {
        var id = args[0];
        var milliseconds = args[1];
        try {
            (Media.get(id)).node.currentTime = milliseconds / 1000;
            win();
        } catch (err) {
            lose("Failed to seek: "+err);
        }
    },

    // Pauses the playing audio
    pausePlayingAudio:function(win, lose, args) {
        var id = args[0];
        var thisM = Media.get(id);
        try {
            thisM.node.pause();
            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
        } catch (err) {
            lose("Failed to pause: "+err);
        }
    },

    // Gets current position in the audio
    getCurrentPositionAudio:function(win, lose, args) {
        var id = args[0];
        try {
            var p = (Media.get(id)).node.currentTime;
            Media.onStatus(id, Media.MEDIA_POSITION, p);
            win(p);
        } catch (err) {
            lose(err);
        }
    },

    // Start recording audio
    startRecordingAudio:function(win, lose, args) {
        var id = args[0];
        var src = args[1];
        // Initialize device
        Media.prototype.mediaCaptureMgr = null;
        var thisM = (Media.get(id));
        var captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
        captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio;
        thisM.mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
        thisM.mediaCaptureMgr.addEventListener("failed", lose);

        thisM.mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) {
            thisM.mediaCaptureMgr.addEventListener("recordlimitationexceeded", lose);
            thisM.mediaCaptureMgr.addEventListener("failed", lose);

            // Start recording
            Windows.Storage.KnownFolders.musicLibrary.createFileAsync(src, Windows.Storage.CreationCollisionOption.replaceExisting).done(function (newFile) {
                var storageFile = newFile;
                var encodingProfile = null;
                switch (newFile.fileType) {
                    case '.m4a':
                        encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createM4a(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
                        break;
                    case '.mp3':
                        encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp3(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
                        break;
                    case '.wma':
                        encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createWma(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
                        break;
                    default:
                        lose("Invalid file type for record");
                        break;
                }
                thisM.mediaCaptureMgr.startRecordToStorageFileAsync(encodingProfile, storageFile).done(win, lose);
            }, lose);
        }, lose);
    },

    // Stop recording audio
    stopRecordingAudio:function(win, lose, args) {
        var id = args[0];
        var thisM = Media.get(id);
        thisM.mediaCaptureMgr.stopRecordAsync().done(win, lose);
    },

    // Release the media object
    release:function(win, lose, args) {
        var id = args[0];
        var thisM = Media.get(id);
        try {
            delete thisM.node;
        } catch (err) {
            lose("Failed to release: "+err);
        }
    },
    setVolume:function(win, lose, args) {
        var id = args[0];
        var volume = args[1];
        var thisM = Media.get(id);
        thisM.volume = volume;
    }
};

require("cordova/exec/proxy").add("Media",module.exports);
<|endoftext|>


<commit_before>'use strict'
var gulp = require('gulp');
var gulpTypescript = require('gulp-tsc');
var insert = require('gulp-insert');
var mocha = require('gulp-mocha');
var nodeResolve = require('rollup-plugin-node-resolve');
var rename = require('gulp-rename');
var rollup = require('rollup');
var rollupTypescript = require('rollup-plugin-typescript');
var strip = require('gulp-strip-comments');
var typescript = require('typescript');
var uglify = require('gulp-uglify');

var tests = [
    { name: 'NavigationRouting', to: 'navigationRouting.test.js' },
    { name: 'StateConfig', to: 'stateConfig.test.js' },
    { name: 'Navigation', to: 'navigation.test.js' },
    { name: 'NavigationData', to: 'navigationData.test.js' },
    { name: 'FluentNavigation', to: 'fluentNavigation.test.js' },
    { name: 'NavigationLink', to: 'navigationLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'NavigationBackLink', to: 'navigationBackLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'RefreshLink', to: 'refreshLink.test.js', folder: 'React', ext: 'tsx' }
];
function rollupTestTask(name, file, to) {
    return rollup.rollup({
        entry: file,
        external: ['assert', 'react', 'enzyme', 'enzyme-adapter-react-16', 'jsdom'],
        plugins: [
            rollupTypescript({
                typescript: typescript,
                importHelpers: true,
                target: 'es3',
                module: 'es6',
                jsx: 'react'
            }),
            nodeResolve({ jsnext: true, main: true })
        ]
    }).then((bundle) => {
        bundle.write({
            format: 'cjs',
            dest: to
        });
    });
}
function testTask(file) {
    return gulp.src(file)
        .pipe(mocha({ reporter: 'progress' }));
}
var testTasks = tests.reduce((tasks, test) => {
    var folder = './Navigation' + (test.folder || '') + '/test/';
    var file = folder + test.name + 'Test.' + (test.ext || 'ts');
    var to = './build/dist/' + test.to;
    gulp.task('RollupTest' + test.name, () => rollupTestTask(test.name, file, to));
    gulp.task('Test' + test.name, ['RollupTest' + test.name], () => testTask(to));
    tasks.push('Test' + test.name);
    return tasks;
}, []);
gulp.task('test', testTasks);

var items = [
    require('./build/npm/navigation/package.json'),
    Object.assign({ globals: { react: 'React' } },
        require('./build/npm/navigation-react/package.json')),
    Object.assign({ globals: { knockout: 'ko' } },
        require('./build/npm/navigation-knockout/package.json')),
    Object.assign({ globals: { angular: 'angular' } },
        require('./build/npm/navigation-angular/package.json')),
    Object.assign({ globals: { '@cycle/dom': 'CycleDOM', rx: 'Rx' } },
        require('./build/npm/navigation-cycle/package.json')),
    Object.assign({ globals: { 'inferno-component': 'InfernoComponent',
            'inferno-create-element': 'InfernoCreateElement' } },
        require('./build/npm/navigation-inferno/package.json')),
    Object.assign({ globals: { navigation: 'Navigation', react: 'React' } },
        require('./build/npm/navigation-react-mobile/package.json'),
        require('./NavigationReactMobile/src/tsconfig.json')),
    Object.assign({ globals: { react: 'React', 'react-native': 'ReactNative',
            'd3-interpolate': 'd3', 'd3-ease': 'd3' } },
        require('./build/npm/navigation-react-native/package.json'),
        require('./NavigationReactNative/src/tsconfig.json')),
];
function rollupTask(name, file, to, globals) {
    return rollup.rollup({
        entry: file,
        external: Object.keys(globals),
        plugins: [
            rollupTypescript({
                typescript: typescript,
                importHelpers: true,
                target: 'es3',
                module: 'es6',
                jsx: 'react'
            }),
            nodeResolve({ jsnext: true, main: true })
        ]
    }).then((bundle) => {
        bundle.write({
            format: 'iife',
            moduleName: name,
            globals: Object.assign({ navigation: 'Navigation'}, globals),
            dest: './build/dist/' + to
        });
    });
}
function buildTask(file, details) {
    var info = `/**
 * ${details.name} v${details.version}
 * (c) Graham Mendick - ${details.homepage}
 * License: ${details.license}
 */
`;
    return gulp.src('./build/dist/' + file)
        .pipe(strip())
        .pipe(insert.prepend(info))
        .pipe(gulp.dest('./build/dist'))
        .pipe(rename(file.replace(/js$/, 'min.js')))
        .pipe(uglify())
        .pipe(insert.prepend(info))
        .pipe(gulp.dest('./build/dist'));
}
function packageTask(name, file, details) {
    return gulp.src(file)
        .pipe(gulpTypescript(details.compilerOptions))
        .pipe(gulp.dest('./build/npm/' + name + '/lib'));
}
var itemTasks = items.reduce((tasks, item) => {
    var packageName = item.name;
    var upperName = packageName.replace(/\b./g, (val) => val.toUpperCase());
    var name = upperName.replace(/-/g, '');
    var tsFrom = './' + name + '/src/' + name + '.ts';
    var jsTo = packageName.replace(/-/g, '.') + '.js';
    item.name = upperName.replace(/-/g, ' ');
    gulp.task('Rollup' + name, () => rollupTask(name, tsFrom, jsTo, item.globals || {}));
    gulp.task('Build' + name, ['Rollup' + name], () => buildTask(jsTo, item));
    gulp.task('Package' + name, () => packageTask(packageName, tsFrom, item));
    tasks.buildTasks.push('Build' + name);
    tasks.packageTasks.push('Package' + name);
    return tasks;
}, { buildTasks: [], packageTasks: [] });
gulp.task('build', itemTasks.buildTasks);
gulp.task('package', itemTasks.packageTasks);
<commit_msg>Used react plugin tsconfig to support tsx<commit_after>'use strict'
var gulp = require('gulp');
var gulpTypescript = require('gulp-tsc');
var insert = require('gulp-insert');
var mocha = require('gulp-mocha');
var nodeResolve = require('rollup-plugin-node-resolve');
var rename = require('gulp-rename');
var rollup = require('rollup');
var rollupTypescript = require('rollup-plugin-typescript');
var strip = require('gulp-strip-comments');
var typescript = require('typescript');
var uglify = require('gulp-uglify');

var tests = [
    { name: 'NavigationRouting', to: 'navigationRouting.test.js' },
    { name: 'StateConfig', to: 'stateConfig.test.js' },
    { name: 'Navigation', to: 'navigation.test.js' },
    { name: 'NavigationData', to: 'navigationData.test.js' },
    { name: 'FluentNavigation', to: 'fluentNavigation.test.js' },
    { name: 'NavigationLink', to: 'navigationLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'NavigationBackLink', to: 'navigationBackLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'RefreshLink', to: 'refreshLink.test.js', folder: 'React', ext: 'tsx' }
];
function rollupTestTask(name, file, to) {
    return rollup.rollup({
        entry: file,
        external: ['assert', 'react', 'enzyme', 'enzyme-adapter-react-16', 'jsdom'],
        plugins: [
            rollupTypescript({
                typescript: typescript,
                importHelpers: true,
                target: 'es3',
                module: 'es6',
                jsx: 'react'
            }),
            nodeResolve({ jsnext: true, main: true })
        ]
    }).then((bundle) => {
        bundle.write({
            format: 'cjs',
            dest: to
        });
    });
}
function testTask(file) {
    return gulp.src(file)
        .pipe(mocha({ reporter: 'progress' }));
}
var testTasks = tests.reduce((tasks, test) => {
    var folder = './Navigation' + (test.folder || '') + '/test/';
    var file = folder + test.name + 'Test.' + (test.ext || 'ts');
    var to = './build/dist/' + test.to;
    gulp.task('RollupTest' + test.name, () => rollupTestTask(test.name, file, to));
    gulp.task('Test' + test.name, ['RollupTest' + test.name], () => testTask(to));
    tasks.push('Test' + test.name);
    return tasks;
}, []);
gulp.task('test', testTasks);

var items = [
    require('./build/npm/navigation/package.json'),
    Object.assign({ globals: { react: 'React' } },
        require('./build/npm/navigation-react/package.json'),
        require('./NavigationReact/src/tsconfig.json')),
    Object.assign({ globals: { knockout: 'ko' } },
        require('./build/npm/navigation-knockout/package.json')),
    Object.assign({ globals: { angular: 'angular' } },
        require('./build/npm/navigation-angular/package.json')),
    Object.assign({ globals: { '@cycle/dom': 'CycleDOM', rx: 'Rx' } },
        require('./build/npm/navigation-cycle/package.json')),
    Object.assign({ globals: { 'inferno-component': 'InfernoComponent',
            'inferno-create-element': 'InfernoCreateElement' } },
        require('./build/npm/navigation-inferno/package.json')),
    Object.assign({ globals: { navigation: 'Navigation', react: 'React' } },
        require('./build/npm/navigation-react-mobile/package.json'),
        require('./NavigationReactMobile/src/tsconfig.json')),
    Object.assign({ globals: { react: 'React', 'react-native': 'ReactNative',
            'd3-interpolate': 'd3', 'd3-ease': 'd3' } },
        require('./build/npm/navigation-react-native/package.json'),
        require('./NavigationReactNative/src/tsconfig.json')),
];
function rollupTask(name, file, to, globals) {
    return rollup.rollup({
        entry: file,
        external: Object.keys(globals),
        plugins: [
            rollupTypescript({
                typescript: typescript,
                importHelpers: true,
                target: 'es3',
                module: 'es6',
                jsx: 'react'
            }),
            nodeResolve({ jsnext: true, main: true })
        ]
    }).then((bundle) => {
        bundle.write({
            format: 'iife',
            moduleName: name,
            globals: Object.assign({ navigation: 'Navigation'}, globals),
            dest: './build/dist/' + to
        });
    });
}
function buildTask(file, details) {
    var info = `/**
 * ${details.name} v${details.version}
 * (c) Graham Mendick - ${details.homepage}
 * License: ${details.license}
 */
`;
    return gulp.src('./build/dist/' + file)
        .pipe(strip())
        .pipe(insert.prepend(info))
        .pipe(gulp.dest('./build/dist'))
        .pipe(rename(file.replace(/js$/, 'min.js')))
        .pipe(uglify())
        .pipe(insert.prepend(info))
        .pipe(gulp.dest('./build/dist'));
}
function packageTask(name, file, details) {
    return gulp.src(file)
        .pipe(gulpTypescript(details.compilerOptions))
        .pipe(gulp.dest('./build/npm/' + name + '/lib'));
}
var itemTasks = items.reduce((tasks, item) => {
    var packageName = item.name;
    var upperName = packageName.replace(/\b./g, (val) => val.toUpperCase());
    var name = upperName.replace(/-/g, '');
    var tsFrom = './' + name + '/src/' + name + '.ts';
    var jsTo = packageName.replace(/-/g, '.') + '.js';
    item.name = upperName.replace(/-/g, ' ');
    gulp.task('Rollup' + name, () => rollupTask(name, tsFrom, jsTo, item.globals || {}));
    gulp.task('Build' + name, ['Rollup' + name], () => buildTask(jsTo, item));
    gulp.task('Package' + name, () => packageTask(packageName, tsFrom, item));
    tasks.buildTasks.push('Build' + name);
    tasks.packageTasks.push('Package' + name);
    return tasks;
}, { buildTasks: [], packageTasks: [] });
gulp.task('build', itemTasks.buildTasks);
gulp.task('package', itemTasks.packageTasks);
<|endoftext|>


<commit_before>//////////////////////////////////////////
// Needle -- Node.js HTTP Client
// Written by Tomás Pollak <tomas@forkhq.com>
// (c) 2012 - Fork Ltd.
// MIT Licensed
//////////////////////////////////////////

var fs = require('fs'),
    http = require('http'),
    https = require('https'),
    iconv = require('iconv-lite'),
    url_parse = require('url').parse,
    stringify = require('qs').stringify,
    multipart = require('./multipart');

var version = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString()).version,
    debug = !!process.env.DEBUG;

exports.version = version;
try { var unzip = require('zlib').unzip } catch(e) { /* zlib not supported */ }

var default_user_agent = "Needle/" + version;
default_user_agent += " (Node.js " + process.version + "; " + process.platform + " " + process.arch + ")";

var node_tls_opts = 'agent pfx key passphrase cert ca ciphers rejectUnauthorized';

var parsers = {
  'application/json': function(data, callback){
    try {
      callback(null, data && JSON.parse(data));
    } catch(e) {
      callback(e, data);
    }
  }
};

try {
  var xml2js = require('xml2js');
  parsers['application/xml'] = function(data, callback){
    var xml_parser = new xml2js.Parser();
    xml_parser.parseString(data, callback);
  };
} catch(e) { /* xml2js not found */ }

var Needle = {

  default_boundary: '--------------------NODENEEDLEHTTPCLIENT',
  default_user_agent: default_user_agent,

  request: function(uri, method, data, options, callback){

    var self = this, post_data = null;
    var callback = (typeof options == 'function') ? options : callback;
    var options = options || {};
    if (uri.indexOf('http') == -1) uri = 'http://' + uri;

    var config = {
      base_opts: {},
      proxy: options.proxy,
      encoding: options.encoding || (options.multipart ? 'binary' : 'utf8'),
      parse_response: options.parse === false ? false : true,
      follow: options.follow === false ? 0 : options.follow || 10, // 10 by default
      timeout: (typeof options.timeout == 'number') ? options.timeout : 10000
    }

    node_tls_opts.split(' ').forEach(function(key){
      if (typeof options[key] != 'undefined'){
        config.base_opts[key] = options[key];
        if (typeof options.agent == 'undefined')
          config.base_opts.agent = false; // otherwise tls options are skipped
      }
    });

    config.headers = {
      "User-Agent": options.user_agent || this.default_user_agent,
      "Connection": "close",
      "Accept": "*/*"
    }

    if (options.compressed && typeof unzip != 'undefined')
      config.headers['Accept-Encoding'] = 'gzip,deflate';

    for (h in options.headers)
      config.headers[h] = options.headers[h];

    if (options.username && options.password){
      var b = new Buffer([options.username, options.password].join(':'));
      var auth_header = options.proxy ? 'Proxy-Authorization' : 'Authorization';
      config.headers[auth_header] = 'Basic ' + b.toString('base64');
    }

    if (data){
      if (options.multipart){

        var boundary = options.boundary || this.default_boundary;
        return multipart.build(data, boundary, function(err, body){

          if (err) throw(err);
          config.headers['Content-Type'] = 'multipart/form-data; boundary=' + boundary;
          config.headers['Content-Length'] = body.length;
          self.send_request(1, method, uri, config, body, callback);

        });

      } else {
        post_data = (typeof(data) === "string") ? data : stringify(data);
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        config.headers['Content-Length'] = post_data.length;
      }

    }

    this.send_request(1, method, uri, config, post_data, callback);
  },

  get_request_opts: function(method, uri, config){
    var opts = config.base_opts, proxy = config.proxy;
    var remote = proxy ? url_parse(proxy) : url_parse(uri);

    opts.host = remote.hostname;
    opts.port = remote.port || (remote.protocol == 'https:' ? 443 : 80);
    opts.protocol = remote.protocol;
    opts.path = proxy ? uri : remote.pathname + (remote.search || '');
    opts.method = method;
    opts.headers = config.headers;
    opts.headers["Host"] = proxy ? url_parse(uri).hostname : remote.hostname;

    return opts;
  },

  send_request: function(count, method, uri, config, post_data, callback){

    var self = this, timer,
        request_opts = this.get_request_opts(method, uri, config),
        protocol = request_opts.protocol == 'https:' ? https : http;

    var request = protocol.request(request_opts, function(resp){

      if (timer) clearTimeout(timer);

      if ([301, 302].indexOf(resp.statusCode) != -1 && resp.headers.location){
        if (count <= config.follow)
          return self.send_request(++count, 'GET', resp.headers.location, config, null, callback);
        else if (config.follow > 0)
          return callback(new Error('Redirect loop in ' + resp.headers.location));
      }

      var chunks = [], length = 0,
          compressed = /gzip|deflate/.test(resp.headers['content-encoding']),
          mime = self.parse_content_type(resp.headers['content-type']);

      var response_opts = {
        parse_response: config.parse_response,
        content_type: mime.type,
        charset: mime.charset,
        utf8: mime.charset && mime.charset.match(/utf-?8$/i)
      }

    // response.setEncoding(response_opts.utf8 ? 'utf8' : 'binary');

      resp.on('data', function(chunk){
        chunks.push(chunk);
        length += chunk.length;
      });

      resp.on('end', function(){

        var body = new Buffer(length), pos = 0;
        for (var i = 0, len = chunks.length; i < len; i++){
          chunks[i].copy(body, pos);
          pos += chunks[i].length;
        }

        if (typeof unzip != 'undefined' && compressed)
          unzip(body, function(err, buff){
            self.response_end(response_opts, resp, buff, callback);
          });
        else
          self.response_end(response_opts, resp, body, callback);

      });

    });

    if (config.timeout > 0) {
      timer = setTimeout(function() {
        request.abort();
      }, config.timeout)
    }

    request.on('error', function(err) {
      if (debug) console.log('Error on request: ' + err.toString());
      if (timer) clearTimeout(timer);
      if (callback) callback(err || new Error("Unkown error on request."));
    });

    if (post_data) request.write(post_data, config.encoding);
    request.end();

  },

  parse_content_type: function(header){
    if (!header || header == '') return {};

    var charset, split = header.split(';');
    try { charset = split[1].match(/charset=(.+)/)[1] } catch (e) { /* not found */ }

    return { type: split[0], charset: charset };
  },

  response_end: function(opts, response, body, callback){

    if (debug) console.log(response.headers);
    if (!callback) return;

    if (opts.parse_response && parsers[opts.content_type]) {
      parsers[opts.content_type](body.toString(), function(err, result){
        callback(err, response, result);
      });
    } else {
      if (!opts.utf8 && opts.charset)
        body = iconv.decode(body, opts.charset);

      callback(null, response, body.toString());
    }

  }

}

exports.head = function(uri, options, callback){
  return Needle.request(uri, 'HEAD', null, options, callback);
}

exports.get = function(uri, options, callback){
  return Needle.request(uri, 'GET', null, options, callback);
}

exports.post = function(uri, data, options, callback){
  if (!data || typeof data == 'function') throw('POST request expects data.');
  return Needle.request(uri, 'POST', data, options, callback);
}

exports.put = function(uri, data, options, callback){
  if (!data || typeof data == 'function') throw('PUT request expects data.');
  return Needle.request(uri, 'PUT', data, options, callback);
}

exports.delete = function(uri, data, options, callback){
  return Needle.request(uri, 'DELETE', null, options, callback);
}
<commit_msg>Require iconv-lite only if needed.<commit_after>//////////////////////////////////////////
// Needle -- Node.js HTTP Client
// Written by Tomás Pollak <tomas@forkhq.com>
// (c) 2012 - Fork Ltd.
// MIT Licensed
//////////////////////////////////////////

var fs = require('fs'),
    http = require('http'),
    https = require('https'),
    url_parse = require('url').parse,
    stringify = require('qs').stringify,
    multipart = require('./multipart');

var version = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString()).version,
    debug = !!process.env.DEBUG;

exports.version = version;
try { var unzip = require('zlib').unzip } catch(e) { /* zlib not supported */ }

var default_user_agent = "Needle/" + version;
default_user_agent += " (Node.js " + process.version + "; " + process.platform + " " + process.arch + ")";

var node_tls_opts = 'agent pfx key passphrase cert ca ciphers rejectUnauthorized';

var parsers = {
  'application/json': function(data, callback){
    try {
      callback(null, data && JSON.parse(data));
    } catch(e) {
      callback(e, data);
    }
  }
};

try {
  var xml2js = require('xml2js');
  parsers['application/xml'] = function(data, callback){
    var xml_parser = new xml2js.Parser();
    xml_parser.parseString(data, callback);
  };
} catch(e) { /* xml2js not found */ }

var Needle = {

  default_boundary: '--------------------NODENEEDLEHTTPCLIENT',
  default_user_agent: default_user_agent,

  request: function(uri, method, data, options, callback){

    var self = this, post_data = null;
    var callback = (typeof options == 'function') ? options : callback;
    var options = options || {};
    if (uri.indexOf('http') == -1) uri = 'http://' + uri;

    var config = {
      base_opts: {},
      proxy: options.proxy,
      encoding: options.encoding || (options.multipart ? 'binary' : 'utf8'),
      parse_response: options.parse === false ? false : true,
      follow: options.follow === false ? 0 : options.follow || 10, // 10 by default
      timeout: (typeof options.timeout == 'number') ? options.timeout : 10000
    }

    node_tls_opts.split(' ').forEach(function(key){
      if (typeof options[key] != 'undefined'){
        config.base_opts[key] = options[key];
        if (typeof options.agent == 'undefined')
          config.base_opts.agent = false; // otherwise tls options are skipped
      }
    });

    config.headers = {
      "User-Agent": options.user_agent || this.default_user_agent,
      "Connection": "close",
      "Accept": "*/*"
    }

    if (options.compressed && typeof unzip != 'undefined')
      config.headers['Accept-Encoding'] = 'gzip,deflate';

    for (h in options.headers)
      config.headers[h] = options.headers[h];

    if (options.username && options.password){
      var b = new Buffer([options.username, options.password].join(':'));
      var auth_header = options.proxy ? 'Proxy-Authorization' : 'Authorization';
      config.headers[auth_header] = 'Basic ' + b.toString('base64');
    }

    if (data){
      if (options.multipart){

        var boundary = options.boundary || this.default_boundary;
        return multipart.build(data, boundary, function(err, body){

          if (err) throw(err);
          config.headers['Content-Type'] = 'multipart/form-data; boundary=' + boundary;
          config.headers['Content-Length'] = body.length;
          self.send_request(1, method, uri, config, body, callback);

        });

      } else {
        post_data = (typeof(data) === "string") ? data : stringify(data);
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        config.headers['Content-Length'] = post_data.length;
      }

    }

    this.send_request(1, method, uri, config, post_data, callback);
  },

  get_request_opts: function(method, uri, config){
    var opts = config.base_opts, proxy = config.proxy;
    var remote = proxy ? url_parse(proxy) : url_parse(uri);

    opts.host = remote.hostname;
    opts.port = remote.port || (remote.protocol == 'https:' ? 443 : 80);
    opts.protocol = remote.protocol;
    opts.path = proxy ? uri : remote.pathname + (remote.search || '');
    opts.method = method;
    opts.headers = config.headers;
    opts.headers["Host"] = proxy ? url_parse(uri).hostname : remote.hostname;

    return opts;
  },

  send_request: function(count, method, uri, config, post_data, callback){

    var self = this, timer,
        request_opts = this.get_request_opts(method, uri, config),
        protocol = request_opts.protocol == 'https:' ? https : http;

    var request = protocol.request(request_opts, function(resp){

      if (timer) clearTimeout(timer);

      if ([301, 302].indexOf(resp.statusCode) != -1 && resp.headers.location){
        if (count <= config.follow)
          return self.send_request(++count, 'GET', resp.headers.location, config, null, callback);
        else if (config.follow > 0)
          return callback(new Error('Redirect loop in ' + resp.headers.location));
      }

      var chunks = [], length = 0,
          compressed = /gzip|deflate/.test(resp.headers['content-encoding']),
          mime = self.parse_content_type(resp.headers['content-type']);

      var response_opts = {
        parse_response: config.parse_response,
        content_type: mime.type,
        charset: mime.charset,
        utf8: mime.charset && mime.charset.match(/utf-?8$/i)
      }

    // response.setEncoding(response_opts.utf8 ? 'utf8' : 'binary');

      resp.on('data', function(chunk){
        chunks.push(chunk);
        length += chunk.length;
      });

      resp.on('end', function(){

        var body = new Buffer(length), pos = 0;
        for (var i = 0, len = chunks.length; i < len; i++){
          chunks[i].copy(body, pos);
          pos += chunks[i].length;
        }

        if (typeof unzip != 'undefined' && compressed)
          unzip(body, function(err, buff){
            self.response_end(response_opts, resp, buff, callback);
          });
        else
          self.response_end(response_opts, resp, body, callback);

      });

    });

    if (config.timeout > 0) {
      timer = setTimeout(function() {
        request.abort();
      }, config.timeout)
    }

    request.on('error', function(err) {
      if (debug) console.log('Error on request: ' + err.toString());
      if (timer) clearTimeout(timer);
      if (callback) callback(err || new Error("Unkown error on request."));
    });

    if (post_data) request.write(post_data, config.encoding);
    request.end();

  },

  parse_content_type: function(header){
    if (!header || header == '') return {};

    var charset, arr = header.split(';');
    try { charset = arr[1].match(/charset=(.+)/)[1] } catch (e) { /* not found */ }

    return { type: arr[0], charset: charset };
  },

  response_end: function(opts, response, body, callback){

    if (debug) console.log(response.headers);
    if (!callback) return;

    if (opts.parse_response && parsers[opts.content_type]) {
      parsers[opts.content_type](body.toString(), function(err, result){
        callback(err, response, result);
      });
    } else {
      if (!opts.utf8 && opts.charset)
        body = require('iconv-lite').decode(body, opts.charset);

      callback(null, response, body.toString());
    }

  }

}

exports.head = function(uri, options, callback){
  return Needle.request(uri, 'HEAD', null, options, callback);
}

exports.get = function(uri, options, callback){
  return Needle.request(uri, 'GET', null, options, callback);
}

exports.post = function(uri, data, options, callback){
  if (!data || typeof data == 'function') throw('POST request expects data.');
  return Needle.request(uri, 'POST', data, options, callback);
}

exports.put = function(uri, data, options, callback){
  if (!data || typeof data == 'function') throw('PUT request expects data.');
  return Needle.request(uri, 'PUT', data, options, callback);
}

exports.delete = function(uri, data, options, callback){
  return Needle.request(uri, 'DELETE', null, options, callback);
}
<|endoftext|>


<commit_before>//                         __
//   _________ _____  ____/ /_  __
//  / ___/ __ `/ __ \/ __  / / / /
// / /__/ /_/ / / / / /_/ / /_/ /
// \___/\__,_/_/ /_/\__,_/\__, /
//                       /____/
//
// @brief  : a micro bbs system based on duoshuo.com apis
// @author : 新浪微博@郭宇 [turing](http://guoyu.me)

var server = require('express-scaffold'),
    configs = require('./configs.getcandy.json'),
    models = require('./models/index'),
    ctrlers = require('./ctrlers/index'),
    routes = require('./routes/index');

new server(configs)
    .models(models)
    .ctrlers(ctrlers)
    .routes(routes)
    .run();<commit_msg>0.1.7: remove getcandy.js<commit_after><|endoftext|>


<commit_before>var ssllabs = require('node-ssllabs');
var https = require('https');
var file = 'public/top-1m.csv';
var port = 8080;
var url = {
	name: null,
	valid_to: null,
	cipher: null,
	grade: null,
	ssl: true
}
var EXPIRING = 0;
var STABLE = 1;
var NO_SSL = 2;
var SHA1 = 3;

var pause = false;
var names = [];
var reading_complete = false;

var time = new Date();
rl = require('readline').createInterface({
	input: require('fs').createReadStream(file)
});

rl.on('line', function (line) {
	names.push(line.split(',')[1]);
});

rl.on('close', function (line) {
	reading_complete = true;
	console.log((new Date()) - time);
});

function scan_urls(url_array, stable_array, expiring_array, no_ssl_array, sha1_array, i, j, date, rl) {
	if (!reading_complete){
		setInterval(scan_urls(url_array, stable_array, expiring_array, no_ssl_array, sha1_array, i, j, date, rl), 1000);
		return;
	}

	while (i < names.length) {
		check_ssl(names[i]);
		i++;
	}
	function ciph(str){
		a= str.split("-");
		for(i=0;i<=a.length;i++){
			if(a[i]=="SHA"){
				return true;
			}else{
				return false;
			}
		}

	}
	function check_ssl(target) {
		var new_url = Object.create(url);
		new_url.name = target;
		var options = {
		    host: target,
		    port: 443,
		    method: 'GET'
		};
		https.request(options, function(res) {
			new_url.valid_to = res.connection.getPeerCertificate().valid_to;
			new_url.cipher = res.connection.getCipher().name;
			url_array.push(new_url);
			if (ciph(new_url.cipher)) {
				sha1_array.push(new_url);
			}
			if (date >= (new Date(new_url.valid_to))) {
				//if within date
				expiring_array.push(new_url);
				//console.log("Expiring: " + new_url.valid_to);
			} else {
				//if outside range
				stable_array.push(new_url);
			}
			j++;
		}).on('error', function(e) {
			new_url.ssl = false;
			url_array.push(new_url);
			no_ssl_array.push(new_url);
			j++;
			return;
		}).end();

		ssllabs.scan(target, function (err, host) {
		    if (err || !(host.endpoints)) {
			    return;
			}
			host.endpoints.forEach(function (endpoint) {
			    new_url.grade = endpoint.grade;
			});
		});
	}
}

var express = require('express')
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);

server.listen(port);
console.log("Listening");
app.use(express.static('public'));

io.on('connection', function (socket) {
	console.log("Connection");
	socket.url_array = [];
	socket.stable_array = [];
	socket.expiring_array = [];
	socket.no_ssl_array = [];
	socket.sha1_array = [];
	socket.i = 0;
	socket.j = 0;
	socket.rl = null;

	socket.emit('initialize');

	socket.on('start', function (data) {
		date = new Date(data);
		scan_urls(socket.url_array, socket.stable_array, socket.expiring_array, socket.no_ssl_array, socket.sha1_array, socket.i, socket.j, date, socket.rl);
	});

	socket.on('update_me', function (data) {
		// data has attributes type (of url), page
		var urls_to_send = null;
		data = JSON.parse(data);
		var first = data.page * 20;
		switch (data.type) {
			case EXPIRING:
				var last = Math.min((data.page + 1) * 20, socket.expiring_array.length);
				urls_to_send = socket.expiring_array.slice( first, last );
				break;
			case STABLE:
				var last = Math.min((data.page + 1) * 20, socket.stable_array.length);
				urls_to_send = socket.stable_array.slice( first, last );
				break;
			case NO_SSL:
				var last = Math.min((data.page + 1) * 20, socket.no_ssl_array.length);
				urls_to_send = socket.no_ssl_array.slice( first, last );
				break;
			case SHA1:
				var last = Math.min((data.page + 1) * 20, socket.sha1_array.length);
				urls_to_send = socket.sha1_array.slice( first, last );
				break;
		}
		var return_data = {
			urls_to_send: urls_to_send,
			num_total: socket.url_array.length,
			num_expired: socket.expiring_array.length,
			num_stable: socket.stable_array.length,
			num_sha1: socket.sha1_array.length
		};
		return_data = JSON.stringify(return_data);
		socket.emit('update', return_data);;
	});

	socket.on('url', function(data){
		//data has attribute name (of url)
		var found = false;
		data = JSON.parse(data);
		for (var a = 0; a < socket.url_array.length; a++) {
			if (socket.url_array[a].name == data.name) {
				found = true;
				console.log(socket.url_array[a].valid_to);
				var return_data = JSON.stringify(socket.url_array[a]);
				socket.emit('url', return_data);
				break;
			}
		}
		if (!found) {
			socket.emit('not_found');
		}
	});

	socket.on('pause', function(){
		if (rl) {
			rl.pause();
		}
		console.log("paused");
	});

	socket.on('resume', function(){
		if (rl) {
			rl.resume();
		}
		console.log("resumed");
	});
});
<commit_msg>Update server.js<commit_after>var ssllabs = require('node-ssllabs');
var https = require('https');
var file = 'public/top-1m.csv';
var port = 8080;
var url = {
	name: null,
	valid_to: null,
	cipher: null,
	grade: null,
	ssl: true
}
var EXPIRING = 0;
var STABLE = 1;
var NO_SSL = 2;
var SHA1 = 3;

var pause = false;
var names = [];
var reading_complete = false;

var time = new Date();
rl = require('readline').createInterface({
	input: require('fs').createReadStream(file)
});

rl.on('line', function (line) {
	names.push(line.split(',')[1]);
});

rl.on('close', function (line) {
	reading_complete = true;
	console.log((new Date()) - time);
});

function scan_urls(url_array, stable_array, expiring_array, no_ssl_array, sha1_array, i, j, date, rl) {
	if (!reading_complete){
		setInterval(scan_urls(url_array, stable_array, expiring_array, no_ssl_array, sha1_array, i, j, date, rl), 1000);
		return;
	}

	while (i < names.length) {
		check_ssl(names[i]);
		i++;
	}
	function ciph(str){
		a= str.split("-");
		for(i=0;i<=a.length;i++){
			if(a[i]=="SHA"){
				return true;
			}
		}
		return false;

	}
	function check_ssl(target) {
		var new_url = Object.create(url);
		new_url.name = target;
		var options = {
		    host: target,
		    port: 443,
		    method: 'GET'
		};
		https.request(options, function(res) {
			new_url.valid_to = res.connection.getPeerCertificate().valid_to;
			new_url.cipher = res.connection.getCipher().name;
			url_array.push(new_url);
			if (ciph(new_url.cipher)) {
				sha1_array.push(new_url);
			}
			if (date >= (new Date(new_url.valid_to))) {
				//if within date
				expiring_array.push(new_url);
				//console.log("Expiring: " + new_url.valid_to);
			} else {
				//if outside range
				stable_array.push(new_url);
			}
			j++;
		}).on('error', function(e) {
			new_url.ssl = false;
			url_array.push(new_url);
			no_ssl_array.push(new_url);
			j++;
			return;
		}).end();

		ssllabs.scan(target, function (err, host) {
		    if (err || !(host.endpoints)) {
			    return;
			}
			host.endpoints.forEach(function (endpoint) {
			    new_url.grade = endpoint.grade;
			});
		});
	}
}

var express = require('express')
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);

server.listen(port);
console.log("Listening");
app.use(express.static('public'));

io.on('connection', function (socket) {
	console.log("Connection");
	socket.url_array = [];
	socket.stable_array = [];
	socket.expiring_array = [];
	socket.no_ssl_array = [];
	socket.sha1_array = [];
	socket.i = 0;
	socket.j = 0;
	socket.rl = null;

	socket.emit('initialize');

	socket.on('start', function (data) {
		date = new Date(data);
		scan_urls(socket.url_array, socket.stable_array, socket.expiring_array, socket.no_ssl_array, socket.sha1_array, socket.i, socket.j, date, socket.rl);
	});

	socket.on('update_me', function (data) {
		// data has attributes type (of url), page
		var urls_to_send = null;
		data = JSON.parse(data);
		var first = data.page * 20;
		switch (data.type) {
			case EXPIRING:
				var last = Math.min((data.page + 1) * 20, socket.expiring_array.length);
				urls_to_send = socket.expiring_array.slice( first, last );
				break;
			case STABLE:
				var last = Math.min((data.page + 1) * 20, socket.stable_array.length);
				urls_to_send = socket.stable_array.slice( first, last );
				break;
			case NO_SSL:
				var last = Math.min((data.page + 1) * 20, socket.no_ssl_array.length);
				urls_to_send = socket.no_ssl_array.slice( first, last );
				break;
			case SHA1:
				var last = Math.min((data.page + 1) * 20, socket.sha1_array.length);
				urls_to_send = socket.sha1_array.slice( first, last );
				break;
		}
		var return_data = {
			urls_to_send: urls_to_send,
			num_total: socket.url_array.length,
			num_expired: socket.expiring_array.length,
			num_stable: socket.stable_array.length,
			num_sha1: socket.sha1_array.length
		};
		return_data = JSON.stringify(return_data);
		socket.emit('update', return_data);;
	});

	socket.on('url', function(data){
		//data has attribute name (of url)
		var found = false;
		data = JSON.parse(data);
		for (var a = 0; a < socket.url_array.length; a++) {
			if (socket.url_array[a].name == data.name) {
				found = true;
				console.log(socket.url_array[a].valid_to);
				var return_data = JSON.stringify(socket.url_array[a]);
				socket.emit('url', return_data);
				break;
			}
		}
		if (!found) {
			socket.emit('not_found');
		}
	});

	socket.on('pause', function(){
		if (rl) {
			rl.pause();
		}
		console.log("paused");
	});

	socket.on('resume', function(){
		if (rl) {
			rl.resume();
		}
		console.log("resumed");
	});
});
<|endoftext|>


<commit_before>/*global module:false*/
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    pkg : '<json:package.json>',
    meta : {
      banner : '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
        '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
        '<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
        '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
        ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
    },
    coffee : {
      helpers : {
        src  : 'spec/coffeescripts/helpers/*.coffee',
        dest : 'spec/javascripts/helpers'
      },
      specs : {
        src  : 'spec/coffeescripts/*.coffee',
        dest : 'spec/javascripts'
      },
      plugin : {
        src  : 'js/*.coffee',
        dest : 'js'
      }
    },
    jasmine : {
      src     : ['js/libs/**/*.js', 'js/*[^(min)].js', 'spec/javascripts/libs/**/*.js'],
      helpers : 'spec/javascripts/helpers/**/*.js',
      specs   : 'spec/javascripts/**/*.js'
    },
    watch : {
      files: ['<config:coffee.helpers.src>', '<config:coffee.specs.src>', '<config:coffee.plugin.src>'],
      tasks: 'coffee growl:coffee jasmine growl:jasmine'
    },
    growl : {
      coffee : {
        title   : 'CoffeeScript',
        message : 'Compiled successfully'
      },
      jasmine : {
        title   : 'Jasmine',
        message : 'Tests passed successfully'
      }
    },
    min : {
      dist : {
        src  : ['<banner:meta.banner>', 'js/<%= pkg.name %>.js'],
        dest : 'js/<%= pkg.name %>.min.js'
      }
    }
  });

  // Lib tasks.
  grunt.loadNpmTasks('grunt-growl');
  grunt.loadNpmTasks('grunt-jasmine-runner');
  grunt.loadNpmTasks('grunt-coffee');

  // Default task.
  grunt.registerTask('default', 'coffee growl:coffee jasmine growl:jasmine');

  // Travis CI task.
  grunt.registerTask('travis', 'coffee jasmine');
};
<commit_msg>med<commit_after>/*global module:false*/
module.exports = function(grunt) {

  grunt.initConfig({
    pkg : '<json:package.json>',
    meta : {
      banner : '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
        '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
        '<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
        '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
        ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
    },
    coffee : {
      helpers : {
        src  : 'spec/coffeescripts/helpers/*.coffee',
        dest : 'spec/javascripts/helpers'
      },
      specs : {
        src  : 'spec/coffeescripts/*.coffee',
        dest : 'spec/javascripts'
      },
      plugin : {
        src  : 'js/*.coffee',
        dest : 'js'
      }
    },
    jasmine : {
      src     : ['js/libs/**/*.js', 'js/*[^(min)].js', 'spec/javascripts/libs/**/*.js'],
      helpers : 'spec/javascripts/helpers/**/*.js',
      specs   : 'spec/javascripts/**/*.js'
    },
    watch : {
      files: ['<config:coffee.helpers.src>', '<config:coffee.specs.src>', '<config:coffee.plugin.src>'],
      tasks: 'coffee growl:coffee jasmine growl:jasmine'
    },
    growl : {
      coffee : {
        title   : 'CoffeeScript',
        message : 'Compiled successfully'
      },
      jasmine : {
        title   : 'Jasmine',
        message : 'Tests passed successfully'
      }
    },
    min : {
      dist : {
        src  : ['<banner:meta.banner>', 'js/<%= pkg.name %>.js'],
        dest : 'js/<%= pkg.name %>.min.js'
      }
    }
  });

  // Lib tasks.
  grunt.loadNpmTasks('grunt-growl');
  grunt.loadNpmTasks('grunt-jasmine-runner');
  grunt.loadNpmTasks('grunt-coffee');

  // Default task.
  grunt.registerTask('default', 'coffee growl:coffee jasmine growl:jasmine');

  // Travis CI task.
  grunt.registerTask('travis', 'coffee jasmine');
};
<|endoftext|>


<commit_before>import AbstractModuleRoute from 'hospitalrun/routes/abstract-module-route';
import UserSession from "hospitalrun/mixins/user-session";
export default AbstractModuleRoute.extend(UserSession,{
    addCapability: 'add_appointment',
    allowSearch: false,
    currentScreenTitle: 'Appointment List',
    editTitle: 'Edit Appointment',
    newTitle: 'New Appointment',
    moduleName: 'appointments',
    newButtonText: '+ new appointment',
    sectionTitle: 'Appointments',

    actions: {
        createVisit: function(appointment) {
            var visitProps = appointment.getProperties('startDate', 'endDate', 'location', 'patient'),
                visit;
            visitProps.visitType = appointment.get('appointmentType');
            visitProps.examiner = appointment.get('provider');
            visit = this.get('store').createRecord('visit', visitProps);
            this.transitionTo('visits.edit', visit);
        }
    },

    additionalModels: [{
        name: 'physicianList',
        findArgs: ['lookup','physician_list']
    },  {
        name: 'locationList',
        findArgs: ['lookup','visit_location_list']
    }, {
        name: 'visitTypesList',
        findArgs: ['lookup','visit_types']
    }],

    subActions: [{
        text: 'This Week',
        linkTo: 'appointments.index'
    }, {
        text: 'Today',
        linkTo: 'appointments.today'
    }, {
        text: 'Search',
        linkTo: 'appointments.search'
    }]
});<commit_msg>Fixed creation of visit from appointment<commit_after>import AbstractModuleRoute from 'hospitalrun/routes/abstract-module-route';
import UserSession from "hospitalrun/mixins/user-session";
export default AbstractModuleRoute.extend(UserSession,{
    addCapability: 'add_appointment',
    allowSearch: false,
    currentScreenTitle: 'Appointment List',
    editTitle: 'Edit Appointment',
    newTitle: 'New Appointment',
    moduleName: 'appointments',
    newButtonText: '+ new appointment',
    sectionTitle: 'Appointments',

    actions: {
        createVisit: function(appointment) {
            var visitProps = appointment.getProperties('startDate', 'endDate', 'location', 'patient');
            visitProps.visitType = appointment.get('appointmentType');
            visitProps.examiner = appointment.get('provider');
            this.transitionTo('visits.edit', 'new').then(function(newRoute) {
                newRoute.currentModel.setProperties(visitProps);
            }.bind(this));
        }
    },

    additionalModels: [{
        name: 'physicianList',
        findArgs: ['lookup','physician_list']
    },  {
        name: 'locationList',
        findArgs: ['lookup','visit_location_list']
    }, {
        name: 'visitTypesList',
        findArgs: ['lookup','visit_types']
    }],

    subActions: [{
        text: 'This Week',
        linkTo: 'appointments.index'
    }, {
        text: 'Today',
        linkTo: 'appointments.today'
    }, {
        text: 'Search',
        linkTo: 'appointments.search'
    }]
});<|endoftext|>


<commit_before>console.log("Loading core plugins...");
console.time("Core plugins loaded");

var gulpCore = require('gulp'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    plugins = gulpLoadPlugins({
        pattern: [
            'gulp-*',
            'gulp.*',
            'karma-*',
            'del',
            'globby',
            'lodash',
            'main-bower-files',
            'minimatch',
            'newman',
            'run-sequence',
            'json5'
        ],
        rename: {
            'gulp-angular-templatecache': 'templateCache'
        }
    }),
    gulp = plugins.help(gulpCore),
    _ = require('lodash'),
    browserSync = require('browser-sync').create()
;

console.timeEnd("Core plugins loaded");

console.log('browserSync', _.functions(browserSync));

var paths = {
    src: {
        base: 'app/src',
        get scripts(){
            return [this.base + '/**/*.js', '!'+this.base + '/**/*.spec.js']
        },
        get templates(){
            return this.base + '/**/*.tpl.html'
        },
        get styles(){
            return this.base + '/styles/**/*.less'
        },
        get assets(){
            return this.base + '/assets/images/**/*'
        },
        get tests(){
            return this.base + '/**/*.spec.js'
        }
    },
    dest: {
        base: 'app/build',
        get scripts(){
            return this.base+ '/js'
        },
        get appStyles(){
            return this.base + '/css/**/*.css'
        },
        get css(){
            return this.base + '/css'
        },
        get vendor(){
            return this.base + '/vendor'
        },
        get assets(){
            return this.base + '/assets'
        },
        get coverage(){
            return 'reports/**/lcov.info'
        }
    }
};

gulp.task('bower:install', 'installs bower dependencies', [],  function() {

    return plugins.bower({ cwd: './app', cmd: 'install'}, ['--allow-root']);

});

gulp.task('clean', 'deletes all build files', [], function(cb) {
    plugins.del([paths.dest.base], cb);
});

gulp.task('scripts', 'processes javascript files', [], function () {
    return gulp.src(paths.src.scripts)
        //.pipe(watch(paths.src.scripts))
        .pipe(plugins.ngAnnotate())
        .pipe(gulp.dest(paths.dest.scripts))
    ;
});

gulp.task('templates-watch', 'watches template files for changes [not working]', ['templates'], browserSync.reload);
gulp.task('templates', 'builds template files', [], function(){
    return gulp.src(paths.src.templates)
        .pipe(plugins.templateCache({
            root: "templates/",
            standalone: true
        }))
        .pipe(plugins.concat('templates.js'))
        .pipe(gulp.dest(paths.dest.scripts))
    ;
});

gulp.task('styles', 'compiles stylesheets', [], function(){
    return gulp.src(paths.src.styles)
        //.pipe(watch(paths.src.styles))
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.less())
        //.pipe(concatCss('app.css'))
        .pipe(plugins.sourcemaps.write('./maps'))
        .pipe(gulp.dest(paths.dest.css))
        //.on('end', function(){
        //    browserSync.reload();
        //})
    ;
});

gulp.task('assets', 'copies asset files', [], function(){
    return gulp.src(paths.src.assets)
        .pipe(gulp.dest(paths.dest.assets));
});

gulp.task('bower:build', 'compiles frontend vendor files', [], function(cb) {

    var files = plugins.mainBowerFiles({
            includeDev: true,
            paths: {
                bowerDirectory: 'app/bower_components',
                bowerJson: 'app/bower.json'
            }
        }),
        jsFilter = plugins.filter('**/*.js'),
        cssFilter = plugins.filter(['**/*.css', '**/*.css.map']),
        everythingElseFilter = plugins.filter(['**/*', '!**/*.css', '!**/*.js', '!**/*.map', '!**/*.less']),
        onError = function(cb){
            console.error(cb);
        };

    if (!files.length) {
        return cb();
    }

    gulp.src(files, {base: 'app/bower_components'})
        //javascript
        .pipe(jsFilter)
        //.pipe(sourcemaps.init())
        //.pipe(concat('vendor.js'))
        //.pipe(sourcemaps.write('./maps'))
        .on('error', onError)
        .pipe(gulp.dest(paths.dest.vendor+'/js'))
        .pipe(jsFilter.restore())
        //css
        .pipe(cssFilter)
        //.pipe(sourcemaps.init())
        //.pipe(concat('vendor.css'))
        //.pipe(sourcemaps.write('./maps'))

        .pipe(plugins.replace('../fonts/fontawesome', '/vendor/assets/font-awesome/fonts/fontawesome'))
        .on('error', onError)
        .pipe(gulp.dest(paths.dest.vendor+'/css'))
        .pipe(cssFilter.restore())

        //else
        .pipe(everythingElseFilter)
        .pipe(gulp.dest(paths.dest.vendor+'/assets'))
        .on('end', cb);

});

var getIndexFiles = function(conf){

    conf = conf || {};

    var config = _.defaults(conf, {
        devDeps: false //developer dependencies
    });

    var vendorFiles = plugins.mainBowerFiles({
        includeDev: config.devDeps,
        paths: {
            bowerDirectory: 'app/bower_components',
            bowerJson: 'app/bower.json'
        }
    });

    vendorFiles = vendorFiles.map(function(path){
        return path.replace(/\\/g, "\/").replace(/^.+bower_components\//i, '');
    });

    var files = {
        scripts: {
            app: plugins.globby.sync(paths.dest.scripts+'/**/*.js').map(function(path){
                return path.replace('app/build/', '');
            }),
            vendor: vendorFiles.filter(plugins.minimatch.filter("*.js", {matchBase: true})).map(function(path){
                return 'vendor/js/'+path;
            })
        },
        styles: {
            app: plugins.globby.sync(paths.dest.appStyles).map(function(path){
                return path.replace('app/build/', '');
            }),
            vendor: vendorFiles.filter(plugins.minimatch.filter("*.css", {matchBase: true})).map(function(path){
                return 'vendor/css/'+path;
            })
        }
    };

    return files;

};

gulp.task('index', 'processes index.html file', [], function(){

    var files = getIndexFiles();

    return gulp.src(paths.src.base+'/index.html')
        .pipe(plugins.template(files))
        .pipe(gulp.dest(paths.dest.base))
    ;

});

// The default task (called when you run `gulp` from cli)
gulp.task('default', 'default task', ['build']);

gulp.task('build', 'runs build sequence for frontend', function (cb){
    plugins.runSequence('clean',
        //'bower:install',
        ['scripts', 'templates', 'styles', 'assets', 'bower:build'],
        'index',
        cb);
});

gulp.task('watch', 'starts up browsersync server and runs task watchers', [], function() {

    /**
     * @todo resolve why this file watcher is required for browsersync to function
     * It should be possible to just add a watch task that fires reload when task runs
     * See `templates-watch` method above which does not work
     */

    browserSync.watch(paths.dest.base+'**', function (event, file) {
        if (event === "change") {
            browserSync.reload();
        }
    });

    browserSync.init({
        proxy: "http://local.app.nglume.io"
    });

    gulp.watch(paths.src.templates, ['templates']);

});

gulp.task('test:app',  'unit tests the frontend', [], function(){

    var files = getIndexFiles({
        devDeps: true
    });
    var testFiles = files.scripts.vendor
        .map(function(path){
            return 'app/build/'+path;
        })
        .concat(plugins.globby.sync(paths.src.scripts))
        .concat(plugins.globby.sync(paths.src.tests))
    ;

    testFiles.push('app/build/js/templates.js');

    return gulp.src(testFiles)
        .pipe(plugins.karma({
            configFile: 'karma.conf.js',
            action: 'run'
        }))
        .on('error', function(err) {
            // Make sure failed tests cause gulp to exit non-zero
            throw err;
        });

});

gulp.task('test:api', 'unit tests the api', [], function(){

    return gulp.src('api/phpunit.xml')
        .pipe(plugins.phpunit('./api/vendor/bin/phpunit', {
            notify: true,
            coverageClover: './reports/coverage/api/clover.xml'
        }))
        .on('error', function(err){
            plugins.notify.onError(testNotification('fail', 'phpunit'));
            throw err;
        })
        .pipe(plugins.notify(testNotification('pass', 'phpunit')))
    ;

});

gulp.task('test:postman', 'integration tests the api', [], function(callback){ //@todo fix postman not connecting with travis ci, or not returning exitcodes

    var fs = require('fs');

    var collectionJson = plugins.json5.parse(fs.readFileSync("./api/postman/nglume.json.postman_collection", 'utf8'));

    var envFile = "./api/postman/nglume-local.postman_environment";

    if (process.env.TRAVIS){
        envFile = "./api/postman/nglume-travisci.postman_environment";
    }

    var environment = plugins.json5.parse(fs.readFileSync(envFile, "utf-8")); // environment file (in parsed json format)

    if (!!process.env.NGINX_PORT_8080_TCP){ //if we are executing from a docker container

        var hostEntry = _.find(environment.values, {'key':'host'}); //find the host key entry
        hostEntry.value = process.env.NGINX_PORT_8080_TCP_ADDR + ':8080'; //rewrite it to the nginx container tcp address

    }

    if (!!process.env.MAILCATCHER_PORT_1080_TCP){ //if we are executing from a docker container with mailcatcher connection

        var mcHostEntry = _.find(environment.values, {'key':'mailcatcherHost'}); //find the host key entry
        mcHostEntry.value = process.env.MAILCATCHER_PORT_1080_TCP_ADDR + ':1080'; //rewrite it to the mailcatcher container tcp address

    }

    var newmanOptions = {
        envJson: environment,
        asLibrary: true,
        stopOnError: false,
        exitCode: true
    };

    plugins.newman.execute(collectionJson, newmanOptions, function(exitCode){

        console.log('exit code', exitCode);

        if (exitCode !== 0){
            throw new Error("Postman tests failed!");
        }

        callback();
    });

});

gulp.task('test', 'executes all unit and integration tests', ['test:app', 'test:api', 'test:postman']);

gulp.task('coveralls', 'generates code coverage for the frontend', [], function(){
    gulp.src(paths.dest.coverage)
        .pipe(plugins.coveralls());
});

function testNotification(status, pluginName, override) {
    var options = {
        title:   ( status == 'pass' ) ? 'Tests Passed' : 'Tests Failed',
        message: ( status == 'pass' ) ? '\n\nAll tests have passed!\n\n' : '\n\nOne or more tests failed...\n\n',
        icon:    __dirname + '/node_modules/gulp-' + pluginName +'/assets/test-' + status + '.png'
    };
    options = _.merge(options, override);
    return options;
}
<commit_msg>Added watchers for styles, scripts assets and index<commit_after>console.log("Loading core plugins...");
console.time("Core plugins loaded");

var gulpCore = require('gulp'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    plugins = gulpLoadPlugins({
        pattern: [
            'gulp-*',
            'gulp.*',
            'karma-*',
            'del',
            'globby',
            'lodash',
            'main-bower-files',
            'minimatch',
            'newman',
            'run-sequence',
            'json5'
        ],
        rename: {
            'gulp-angular-templatecache': 'templateCache'
        }
    }),
    gulp = plugins.help(gulpCore),
    _ = require('lodash'),
    browserSync = require('browser-sync').create()
;

console.timeEnd("Core plugins loaded");

console.log('browserSync', _.functions(browserSync));

var paths = {
    src: {
        base: 'app/src',
        get scripts(){
            return [this.base + '/**/*.js', '!'+this.base + '/**/*.spec.js']
        },
        get templates(){
            return this.base + '/**/*.tpl.html'
        },
        get styles(){
            return this.base + '/styles/**/*.less'
        },
        get assets(){
            return this.base + '/assets/images/**/*'
        },
        get tests(){
            return this.base + '/**/*.spec.js'
        }
    },
    dest: {
        base: 'app/build',
        get scripts(){
            return this.base+ '/js'
        },
        get appStyles(){
            return this.base + '/css/**/*.css'
        },
        get css(){
            return this.base + '/css'
        },
        get vendor(){
            return this.base + '/vendor'
        },
        get assets(){
            return this.base + '/assets'
        },
        get coverage(){
            return 'reports/**/lcov.info'
        }
    }
};

gulp.task('bower:install', 'installs bower dependencies', [],  function() {

    return plugins.bower({ cwd: './app', cmd: 'install'}, ['--allow-root']);

});

gulp.task('clean', 'deletes all build files', [], function(cb) {
    plugins.del([paths.dest.base], cb);
});

gulp.task('scripts', 'processes javascript files', [], function () {
    return gulp.src(paths.src.scripts)
        //.pipe(watch(paths.src.scripts))
        .pipe(plugins.ngAnnotate())
        .pipe(gulp.dest(paths.dest.scripts))
    ;
});

gulp.task('templates-watch', 'watches template files for changes [not working]', ['templates'], browserSync.reload);
gulp.task('templates', 'builds template files', [], function(){
    return gulp.src(paths.src.templates)
        .pipe(plugins.templateCache({
            root: "templates/",
            standalone: true
        }))
        .pipe(plugins.concat('templates.js'))
        .pipe(gulp.dest(paths.dest.scripts))
    ;
});

gulp.task('styles', 'compiles stylesheets', [], function(){
    return gulp.src(paths.src.styles)
        //.pipe(watch(paths.src.styles))
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.less())
        //.pipe(concatCss('app.css'))
        .pipe(plugins.sourcemaps.write('./maps'))
        .pipe(gulp.dest(paths.dest.css))
        //.on('end', function(){
        //    browserSync.reload();
        //})
    ;
});

gulp.task('assets', 'copies asset files', [], function(){
    return gulp.src(paths.src.assets)
        .pipe(gulp.dest(paths.dest.assets));
});

gulp.task('bower:build', 'compiles frontend vendor files', [], function(cb) {

    var files = plugins.mainBowerFiles({
            includeDev: true,
            paths: {
                bowerDirectory: 'app/bower_components',
                bowerJson: 'app/bower.json'
            }
        }),
        jsFilter = plugins.filter('**/*.js'),
        cssFilter = plugins.filter(['**/*.css', '**/*.css.map']),
        everythingElseFilter = plugins.filter(['**/*', '!**/*.css', '!**/*.js', '!**/*.map', '!**/*.less']),
        onError = function(cb){
            console.error(cb);
        };

    if (!files.length) {
        return cb();
    }

    gulp.src(files, {base: 'app/bower_components'})
        //javascript
        .pipe(jsFilter)
        //.pipe(sourcemaps.init())
        //.pipe(concat('vendor.js'))
        //.pipe(sourcemaps.write('./maps'))
        .on('error', onError)
        .pipe(gulp.dest(paths.dest.vendor+'/js'))
        .pipe(jsFilter.restore())
        //css
        .pipe(cssFilter)
        //.pipe(sourcemaps.init())
        //.pipe(concat('vendor.css'))
        //.pipe(sourcemaps.write('./maps'))

        .pipe(plugins.replace('../fonts/fontawesome', '/vendor/assets/font-awesome/fonts/fontawesome'))
        .on('error', onError)
        .pipe(gulp.dest(paths.dest.vendor+'/css'))
        .pipe(cssFilter.restore())

        //else
        .pipe(everythingElseFilter)
        .pipe(gulp.dest(paths.dest.vendor+'/assets'))
        .on('end', cb);

});

var getIndexFiles = function(conf){

    conf = conf || {};

    var config = _.defaults(conf, {
        devDeps: false //developer dependencies
    });

    var vendorFiles = plugins.mainBowerFiles({
        includeDev: config.devDeps,
        paths: {
            bowerDirectory: 'app/bower_components',
            bowerJson: 'app/bower.json'
        }
    });

    vendorFiles = vendorFiles.map(function(path){
        return path.replace(/\\/g, "\/").replace(/^.+bower_components\//i, '');
    });

    var files = {
        scripts: {
            app: plugins.globby.sync(paths.dest.scripts+'/**/*.js').map(function(path){
                return path.replace('app/build/', '');
            }),
            vendor: vendorFiles.filter(plugins.minimatch.filter("*.js", {matchBase: true})).map(function(path){
                return 'vendor/js/'+path;
            })
        },
        styles: {
            app: plugins.globby.sync(paths.dest.appStyles).map(function(path){
                return path.replace('app/build/', '');
            }),
            vendor: vendorFiles.filter(plugins.minimatch.filter("*.css", {matchBase: true})).map(function(path){
                return 'vendor/css/'+path;
            })
        }
    };

    return files;

};

gulp.task('index', 'processes index.html file', [], function(){

    var files = getIndexFiles();

    return gulp.src(paths.src.base+'/index.html')
        .pipe(plugins.template(files))
        .pipe(gulp.dest(paths.dest.base))
    ;

});

// The default task (called when you run `gulp` from cli)
gulp.task('default', 'default task', ['build']);

gulp.task('build', 'runs build sequence for frontend', function (cb){
    plugins.runSequence('clean',
        //'bower:install',
        ['scripts', 'templates', 'styles', 'assets', 'bower:build'],
        'index',
        cb);
});

gulp.task('watch', 'starts up browsersync server and runs task watchers', [], function() {

    /**
     * @todo resolve why this file watcher is required for browsersync to function
     * It should be possible to just add a watch task that fires reload when task runs
     * See `templates-watch` method above which does not work
     */

    browserSync.watch(paths.dest.base+'/**', function (event, file) {
        if (event === "change") {
            browserSync.reload();
        }
    });

    browserSync.init({
        proxy: "http://local.app.nglume.io"
    });

    gulp.watch(paths.src.templates, ['templates']);
    gulp.watch(paths.src.scripts, ['scripts']);
    gulp.watch(paths.src.styles, ['styles']);
    gulp.watch(paths.src.assets, ['assets']);
    gulp.watch(paths.src.base+'/index.html', ['index']);

});

gulp.task('test:app',  'unit tests the frontend', [], function(){

    var files = getIndexFiles({
        devDeps: true
    });
    var testFiles = files.scripts.vendor
        .map(function(path){
            return 'app/build/'+path;
        })
        .concat(plugins.globby.sync(paths.src.scripts))
        .concat(plugins.globby.sync(paths.src.tests))
    ;

    testFiles.push('app/build/js/templates.js');

    return gulp.src(testFiles)
        .pipe(plugins.karma({
            configFile: 'karma.conf.js',
            action: 'run'
        }))
        .on('error', function(err) {
            // Make sure failed tests cause gulp to exit non-zero
            throw err;
        });

});

gulp.task('test:api', 'unit tests the api', [], function(){

    return gulp.src('api/phpunit.xml')
        .pipe(plugins.phpunit('./api/vendor/bin/phpunit', {
            notify: true,
            coverageClover: './reports/coverage/api/clover.xml'
        }))
        .on('error', function(err){
            plugins.notify.onError(testNotification('fail', 'phpunit'));
            throw err;
        })
        .pipe(plugins.notify(testNotification('pass', 'phpunit')))
    ;

});

gulp.task('test:postman', 'integration tests the api', [], function(callback){ //@todo fix postman not connecting with travis ci, or not returning exitcodes

    var fs = require('fs');

    var collectionJson = plugins.json5.parse(fs.readFileSync("./api/postman/nglume.json.postman_collection", 'utf8'));

    var envFile = "./api/postman/nglume-local.postman_environment";

    if (process.env.TRAVIS){
        envFile = "./api/postman/nglume-travisci.postman_environment";
    }

    var environment = plugins.json5.parse(fs.readFileSync(envFile, "utf-8")); // environment file (in parsed json format)

    if (!!process.env.NGINX_PORT_8080_TCP){ //if we are executing from a docker container

        var hostEntry = _.find(environment.values, {'key':'host'}); //find the host key entry
        hostEntry.value = process.env.NGINX_PORT_8080_TCP_ADDR + ':8080'; //rewrite it to the nginx container tcp address

    }

    if (!!process.env.MAILCATCHER_PORT_1080_TCP){ //if we are executing from a docker container with mailcatcher connection

        var mcHostEntry = _.find(environment.values, {'key':'mailcatcherHost'}); //find the host key entry
        mcHostEntry.value = process.env.MAILCATCHER_PORT_1080_TCP_ADDR + ':1080'; //rewrite it to the mailcatcher container tcp address

    }

    var newmanOptions = {
        envJson: environment,
        asLibrary: true,
        stopOnError: false,
        exitCode: true
    };

    plugins.newman.execute(collectionJson, newmanOptions, function(exitCode){

        console.log('exit code', exitCode);

        if (exitCode !== 0){
            throw new Error("Postman tests failed!");
        }

        callback();
    });

});

gulp.task('test', 'executes all unit and integration tests', ['test:app', 'test:api', 'test:postman']);

gulp.task('coveralls', 'generates code coverage for the frontend', [], function(){
    gulp.src(paths.dest.coverage)
        .pipe(plugins.coveralls());
});

function testNotification(status, pluginName, override) {
    var options = {
        title:   ( status == 'pass' ) ? 'Tests Passed' : 'Tests Failed',
        message: ( status == 'pass' ) ? '\n\nAll tests have passed!\n\n' : '\n\nOne or more tests failed...\n\n',
        icon:    __dirname + '/node_modules/gulp-' + pluginName +'/assets/test-' + status + '.png'
    };
    options = _.merge(options, override);
    return options;
}
<|endoftext|>


<commit_before>// Usage:
//
// var obj = {
//   a: {
//     b: {
//       c: {
//         d: ['e', 'f', 'g']
//       }
//     }
//   }
// };
//
// Get deep value
// _.deep(obj, 'a.b.c.d[2]'); // 'g'
//
// Set deep value
// _.deep(obj, 'a.b.c.d[2]', 'george');
//
// _.deep(obj, 'a.b.c.d[2]'); // 'george'
_.mixin({
    // Get/set the value of a nested property
    deep: function(obj, key, value) {

        var keys = key.replace(/\[(["']?)([^\1]+?)\1?\]/g, '.$2').replace(/^\./, '').split('.'),
            root,
            i = 0,
            n = keys.length;

        // Set deep value
        if (arguments.length > 2) {

            root = obj;
            n--;

            while (i < n) {
                key = keys[i++];
                obj = obj[key] = _.isObject(obj[key]) ? obj[key] : {};
            }

            obj[keys[i]] = value;

            value = root;

            // Get deep value
        } else {
            while ((obj = obj[keys[i++]]) != null && i < n) {
            }
            ;
            value = i < n ? void 0 : obj;
        }

        return value;
    }
});

// Usage:
//
// var arr = [{
//   deeply: {
//     nested: 'foo'
//   }
// }, {
//   deeply: {
//     nested: 'bar'
//   }
// }];
//
// _.pluckDeep(arr, 'deeply.nested'); // ['foo', 'bar']
_.mixin({
    pluckDeep: function(obj, key) {
        return _.map(obj, function(value) { return _.deep(value, key); });
    }
});

_.mixin({

    // Return a copy of an object containing all but the blacklisted properties.
    unpick: function (obj) {
        obj || (obj = {});
        return _.pick(obj, _.difference(_.keys(obj), _.flatten(Array.prototype.slice.call(arguments, 1))));
    }

});

_.mixin({
    resursivePluck: function self(obj, key, childPropertyName) {
        // default values
        childPropertyName = typeof childPropertyName !== 'undefined' ? childPropertyName : 'children';

        var result = [];
        result.push(obj[key]);

        if (obj.hasOwnProperty(childPropertyName)) {
            _.each(obj[childPropertyName], function(item) {
                result.pushArray(self(item, key, childPropertyName));
            });
        }
        return result;
    }
});

// Usage:
// var obj = [{
//     id: 1, children: [
//         { id: 2 },
//         { id: 3 }
//     ]
// }]
//
// _.addHierarchyLevel(obj, 0, 'children');
// Result:
// var obj = [{
//     id: 1, $level: 0, children: [
//         { id: 2, $level: 1 },
//         { id: 3, $level: 1 }
//     ]
// }]

_.mixin({
    addHierarchyLevelOnNested: function self(objAry, level, childPropertyName) {
        // default values
        level = typeof level !== 'undefined' ? level : 0;
        childPropertyName = typeof childPropertyName !== 'undefined' ? childPropertyName : 'children';

        _.forEach(objAry, function(obj) {
            // add level attribute
            obj["$level"] = level;

            // handle children
            if (obj.hasOwnProperty(childPropertyName) && obj[childPropertyName] !== null) {
                // child object(s)
                var children = obj[childPropertyName];
                if (!_.isArray(children))
                    children = [children];

                _.forEach(children, function(child) {
                    self([child], level + 1, childPropertyName);
                });
            }
        });
    }
});

// http://stackoverflow.com/questions/30864656/set-depth-level-properity-in-flattened-object-hierarchy
_.mixin({
    addHierarchyLevelOnFlatAndSort: function(objAry, idPropertyName, parentIdPropertyName) {
        // default values
        idPropertyName = typeof idPropertyName !== 'undefined' ? idPropertyName : 'id';
        parentIdPropertyName = typeof parentIdPropertyName !== 'undefined' ? parentIdPropertyName : 'parentId';

        // clone to avoid changing source
        var clone = _.clone(objAry);
        var sorted = [];

        // TODO rewrite using lodash
        function setLevel(parentId, level) {
            var ids = [];
            clone.filter(function (el) {
                return el[parentIdPropertyName] === parentId;
            }).forEach(function (el) {
                // add depth level to element
                el.$level = level;
                // add to "sorted" result array
                // this is to ensure that children comes directly after their parent,
                // handy when displaying
                sorted.push(el);
                // recursive call to set child levels and also return their ids
                el.childIds = setLevel(el[idPropertyName], level + 1);
                // so we can add child ids for easy lookup, as they're needed for OData filtering
                ids.push(el[idPropertyName]);
                ids.pushArray(el.childIds);
            });

            return ids;
        }

        // starts the recursive call at the parent level
        setLevel(null, 0);

        return sorted;
    }
});
<commit_msg>Remove filter for field grid function. WIP<commit_after>// Usage:
//
// var obj = {
//   a: {
//     b: {
//       c: {
//         d: ['e', 'f', 'g']
//       }
//     }
//   }
// };
//
// Get deep value
// _.deep(obj, 'a.b.c.d[2]'); // 'g'
//
// Set deep value
// _.deep(obj, 'a.b.c.d[2]', 'george');
//
// _.deep(obj, 'a.b.c.d[2]'); // 'george'
_.mixin({
    // Get/set the value of a nested property
    deep: function(obj, key, value) {

        var keys = key.replace(/\[(["']?)([^\1]+?)\1?\]/g, '.$2').replace(/^\./, '').split('.'),
            root,
            i = 0,
            n = keys.length;

        // Set deep value
        if (arguments.length > 2) {

            root = obj;
            n--;

            while (i < n) {
                key = keys[i++];
                obj = obj[key] = _.isObject(obj[key]) ? obj[key] : {};
            }

            obj[keys[i]] = value;

            value = root;

            // Get deep value
        } else {
            while ((obj = obj[keys[i++]]) != null && i < n) {
            }
            ;
            value = i < n ? void 0 : obj;
        }

        return value;
    }
});

// Usage:
//
// var arr = [{
//   deeply: {
//     nested: 'foo'
//   }
// }, {
//   deeply: {
//     nested: 'bar'
//   }
// }];
//
// _.pluckDeep(arr, 'deeply.nested'); // ['foo', 'bar']
_.mixin({
    pluckDeep: function(obj, key) {
        return _.map(obj, function(value) { return _.deep(value, key); });
    }
});

_.mixin({

    // Return a copy of an object containing all but the blacklisted properties.
    unpick: function (obj) {
        obj || (obj = {});
        return _.pick(obj, _.difference(_.keys(obj), _.flatten(Array.prototype.slice.call(arguments, 1))));
    }

});

_.mixin({
    resursivePluck: function self(obj, key, childPropertyName) {
        // default values
        childPropertyName = typeof childPropertyName !== 'undefined' ? childPropertyName : 'children';

        var result = [];
        result.push(obj[key]);

        if (obj.hasOwnProperty(childPropertyName)) {
            _.each(obj[childPropertyName], function(item) {
                result.pushArray(self(item, key, childPropertyName));
            });
        }
        return result;
    }
});

// Usage:
// var obj = [{
//     id: 1, children: [
//         { id: 2 },
//         { id: 3 }
//     ]
// }]
//
// _.addHierarchyLevel(obj, 0, 'children');
// Result:
// var obj = [{
//     id: 1, $level: 0, children: [
//         { id: 2, $level: 1 },
//         { id: 3, $level: 1 }
//     ]
// }]

_.mixin({
    addHierarchyLevelOnNested: function self(objAry, level, childPropertyName) {
        // default values
        level = typeof level !== 'undefined' ? level : 0;
        childPropertyName = typeof childPropertyName !== 'undefined' ? childPropertyName : 'children';

        _.forEach(objAry, function(obj) {
            // add level attribute
            obj["$level"] = level;

            // handle children
            if (obj.hasOwnProperty(childPropertyName) && obj[childPropertyName] !== null) {
                // child object(s)
                var children = obj[childPropertyName];
                if (!_.isArray(children))
                    children = [children];

                _.forEach(children, function(child) {
                    self([child], level + 1, childPropertyName);
                });
            }
        });
    }
});

// http://stackoverflow.com/questions/30864656/set-depth-level-properity-in-flattened-object-hierarchy
_.mixin({
    addHierarchyLevelOnFlatAndSort: function(objAry, idPropertyName, parentIdPropertyName) {
        // default values
        idPropertyName = typeof idPropertyName !== 'undefined' ? idPropertyName : 'id';
        parentIdPropertyName = typeof parentIdPropertyName !== 'undefined' ? parentIdPropertyName : 'parentId';

        // clone to avoid changing source
        var clone = _.clone(objAry);
        var sorted = [];

        // TODO rewrite using lodash
        function setLevel(parentId, level) {
            var ids = [];
            clone.filter(function (el) {
                return el[parentIdPropertyName] === parentId;
            }).forEach(function (el) {
                // add depth level to element
                el.$level = level;
                // add to "sorted" result array
                // this is to ensure that children comes directly after their parent,
                // handy when displaying
                sorted.push(el);
                // recursive call to set child levels and also return their ids
                el.childIds = setLevel(el[idPropertyName], level + 1);
                // so we can add child ids for easy lookup, as they're needed for OData filtering
                ids.push(el[idPropertyName]);
                ids.pushArray(el.childIds);
            });

            return ids;
        }

        // starts the recursive call at the parent level
        setLevel(null, 0);

        return sorted;
    }
});

_.mixin({
    removeFiltersForField: function (filter, field) {
        // clone to avoid changing source
        var clone = _.clone(filter);

        var isNested = !clone.filters[0].hasOwnProperty("field");
        if (isNested) {
            // iterrate backwards so we can remove items along the way
            _.remove(clone.filters, function(n) {
                return n.filters.field === field;
            });

        } else {
            if (clone.filters[0].field === field) {
                clone = {};
            }
        }

        return clone;
    }
});
<|endoftext|>