<commit_before>/* jshint strict: false */

var gulp    = require('gulp'),
    map     = require('map-stream'),
    del     = require('del'),
    plugins = require('gulp-load-plugins')(),
    server  = require('tiny-lr')(),
    config  = require('./config.json'),
    pkg     = require('./package.json');

// Prepare CSS
// ===========

var processWinPath = function(file) {
    // Fix for bug with paths on Windows
    var path = require('path');
    if (process.platform === 'win32') {
        file.path = path.relative('.', file.path);
        file.path = file.path.replace(/\\/g, '/');
    }
};

// Compile SASS and add prefixes
var fnSass = function (path) {
    return gulp.src(path)
        .on('data', processWinPath)
        .pipe(plugins.plumber())
        .pipe(plugins.sass({
            sourceComments: 'map'
        }))
        .on('error', function (err) {
            console.log(err.message);
            // process.exit(1);
        })
        .pipe(plugins.autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4', {
            map: true,
            from: pkg.name + '-' + pkg.version + '.css',
            to: pkg.name + '-' + pkg.version + '.css'
        }))
        .pipe(plugins.size({ showFiles: true, title: '[CSS]' }))
        .pipe(gulp.dest(config.build + '/assets'))
        .on('end', function () {
            require('fs').unlink(path);
        });
};
gulp.task('styles:sass:imports', function () {
    var files = [config.app + '/+(sass|app|common)/**/*.scss', '!' + config.app + '/sass/includes/*.scss', '!' + config.app + '/+(app|common)/**/_*.scss'];
    return gulp.src(files, { read: false })
        .on('data', processWinPath)
        .pipe(plugins.intercept(function (file) {
            file.contents = new Buffer('@import \'' + file.path + '\';');
            return file;
        }))
        .pipe(plugins.concat(pkg.name + '-' + pkg.version + '.scss'))
        .pipe(gulp.dest(config.build + '/assets'));
});
gulp.task('styles:sass', ['styles:sass:imports'], function () {
    var files = config.build + '/assets/' + pkg.name + '-' + pkg.version + '.scss';
    return fnSass(files);
});

// Minify CSS
gulp.task('styles', ['styles:sass', 'vendor:css'], function () {
    var arr = (config.vendor_files.css).concat(config.build + '/assets/' + pkg.name + '-' + pkg.version + '.css');
    return gulp.src(arr)
        .pipe(plugins.concat(pkg.name + '-' + pkg.version + '.css'))
        .pipe(plugins.minifyCss({ keepSpecialComments: 0 }))
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.size({ showFiles: true, title: '[CSS]' }))
        .pipe(gulp.dest(config.dist + '/assets'));
});

// Prepare vendor files
// ====================

// Copy vendor JS files to /build/
gulp.task('vendor:js', function () {
    if (!config.vendor_files.js.length) {
        return;
    }
    return gulp.src(config.vendor_files.js, { base: '.' })
        .pipe(gulp.dest(config.build));
});

// Copy vendor css to /build/
gulp.task('vendor:css', function () {
    if (!config.vendor_files.css.length) {
        return;
    }
    return gulp.src(config.vendor_files.css, { base: '.' })
        .pipe(gulp.dest(config.build));
});

// Copy vendor assets to /build/
gulp.task('vendor:assets', function () {
    if (!config.vendor_files.assets.length) {
        return;
    }
    return gulp.src(config.vendor_files.assets, { base: '.' })
        .pipe(gulp.dest(config.build + '/assets'));
});

// Prepare JavaScript
// ==================

// Cache AngularJS templates
var fnCacheTpls = function (path) {
    return gulp.src(path)
        .pipe(plugins.minifyHtml({
            empty: true,
            spare: true,
            quotes: true
        }))
        .pipe(plugins.angularTemplatecache({
            module: 'templates.app',
            standalone: true
        }))
        .pipe(plugins.concat('templates.js'))
        .pipe(gulp.dest(config.build + '/app'));
};
gulp.task('scripts:cacheTpls', function () {
    return fnCacheTpls(config.paths.templates);
});

// Check JavaScript code quality with JSHint
var fnLint = function (path, exitOnError) {
    return gulp.src(path, { base: config.app })
        .pipe(plugins.plumber())
        .pipe(plugins.jshint())
        .pipe(plugins.jshint.reporter('jshint-stylish-ex'))
        .pipe(map(function (file, cb) {
            if (!file.jshint.success && exitOnError) {
                process.exit(1);
            }
            cb(null, file);
        }))
        .pipe(gulp.dest(config.build));
};
gulp.task('scripts:lint', function () {
    return fnLint(config.paths.scripts, true);
});

// Concat and minify JavaScript
gulp.task('scripts', ['scripts:lint', 'scripts:cacheTpls', 'vendor:js'], function () {
    var arr = (config.vendor_files.js).concat(config.paths.scripts.concat(config.build + '/app/templates.js'));
    return gulp.src(arr)
        .pipe(plugins.ngAnnotate())
        .pipe(plugins.concat(pkg.name + '-' + pkg.version + '.js'))
        .pipe(plugins.size({ showFiles: true, title: '[JS]' }))
        .pipe(plugins.uglify({
            mangle: false,
            compress: {
                drop_console: true
            }
        }))
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.size({ showFiles: true, title: '[JS]' }))
        .pipe(gulp.dest(config.dist + '/assets'));
});

// Prepare assets
// ==============

// Copy assets
var fnImg = function (path) {
    return gulp.src(path, { base: config.app })
        .pipe(gulp.dest(config.build));
};
gulp.task('assets:img', function () {
    return fnImg(config.paths.assets);
});

// Compress images
gulp.task('assets', ['assets:img', 'vendor:assets'], function () {
    return gulp.src([config.build + '/assets/**', '!' + config.build + '/assets/*.+(css|scss)'])
        .pipe(plugins.plumber())
        // .pipe(plugins.bytediff.start())
        .pipe(plugins.newer(config.dist + '/assets'))
        // .pipe(plugins.imagemin({ optimizationLevel: 7, progressive: true, interlaced: true }))
        // .pipe(plugins.bytediff.stop())
        .pipe(gulp.dest(config.dist + '/assets'));
});

// Prepare HTML
// ============

// Inject CSS & JS to index.html source
var fnInject = function (path) {
    var inject = {
        css : (config.vendor_files.css).concat(config.build + '/assets/*.css'),
        js  : (config.vendor_files.js).concat(config.build + '/+(app|common)/**/*.module.js').concat(config.build + '/+(app|common)/**/*.js')
    };

    return gulp.src(inject.css.concat(inject.js), { read: false })
        .pipe(plugins.inject(path, {
            addRootSlash: false,
            ignorePath: ['/', config.build + '/']
        }))
        .pipe(gulp.dest(config.build));
};
gulp.task('html:inject', ['styles:sass', 'scripts:lint', 'scripts:cacheTpls'], function () {
    return fnInject(config.paths.html);
});

// Replace non-optimized HTML blocks
gulp.task('html:replace', ['html:inject'], function () {
    return gulp.src(config.build + '/index.html')
        .pipe(plugins.htmlReplace({
            css: 'assets/' + pkg.name + '-' + pkg.version + '.min.css',
            js: 'assets/' + pkg.name + '-' + pkg.version + '.min.js'
        }))
        .pipe(gulp.dest(config.dist));
});

// Compile and minify HTML
gulp.task('html', ['html:replace'], function () {
    return gulp.src(config.dist + '/index.html')
        .pipe(plugins.plumber())
        .pipe(plugins.minifyHtml({
            empty: true,
            spare: true,
            quotes: true
        }))
        .pipe(gulp.dest(config.dist));
});

// Karma
// ============
var testFiles = [
    config.build + '/vendor/**/*.js',
    config.build + '/+(app|common)/**/*.module.js',
    config.build + '/+(app|common)/**/*.js',
    config.mocks,
    config.paths.tests
];

gulp.task('test:run', ['scripts:lint', 'scripts:cacheTpls', 'vendor:assets', 'styles:sass', 'html:inject'] , function () {
    // Be sure to return the stream
    return gulp.src(testFiles)
        .pipe(plugins.karma({
            configFile: 'karma.conf.js',
            action: 'run'
        }))
        .on('error', function (err) {
            process.exit(1);
        });
});

gulp.task('test:watch', ['scripts:lint', 'scripts:cacheTpls', 'vendor:assets', 'styles:sass', 'html:inject'], function () {
    gulp.src(testFiles)
        .pipe(plugins.karma({
            configFile: 'karma.conf.js',
            action: 'watch'
        }));
});

// Set up Watch
// ============

// Add files to Watch
gulp.task('watch', ['styles:sass', 'scripts:lint', 'scripts:cacheTpls', 'assets:img', 'vendor:css', 'vendor:js', 'vendor:assets', 'test:watch', 'html:inject'], function () {
    require('./server.js')(server);

    // watch for JS changes
    gulp.watch(config.paths.scripts, function (event) {
        if (event.path.lastIndexOf('.js') === event.path.length - 3) {
            if (event.type === 'deleted') {
                del(event.path.replace(config.app, config.build));
            } else {
                return fnLint(event.path).pipe(plugins.livereload(server));
            }
        }
    });

    // remove deleted JS files from index.html
    gulp.watch(config.build + '/+(app|common)/**/*.js', function (event) {
        if (event.type !== 'changed') {
            return fnInject(config.paths.html).pipe(plugins.livereload(server));
        }
    });

    // watch AngularJS templates to cache
    gulp.watch(config.app + '/+(app|common)/**', function (event) {
        if (event.path.lastIndexOf('.tpl.html') === event.path.length - 9) {
            return fnCacheTpls(config.paths.templates).pipe(plugins.livereload(server));
        }
    });

    // watch for SASS changes
    var runSequence = require('run-sequence');
    gulp.watch(config.paths.sass, function (event) {
        runSequence('styles:sass:imports', function () {
            var files = config.build + '/assets/' + pkg.name + '-' + pkg.version + '.scss';
            return fnSass(files).pipe(plugins.livereload(server));
        });
    });

    gulp.watch(config.paths.assets, function (event) {
        if (event.type === 'deleted') {
            del(event.path.replace(config.app, config.build));
        } else {
            return fnImg(event.path).pipe(plugins.livereload(server));
        }
    });

    gulp.watch(config.paths.html, function (event) {
        return fnInject(event.path).pipe(plugins.livereload(server));
    });
});

// Clean up development & production directories
// =============================================

gulp.task('clean:build', function (cb) {
    del(config.build, cb);
});
gulp.task('clean:compile', function (cb) {
    del(config.dist, { force: true }, cb);
});

// Main gulp tasks
// ===============

gulp.task('build', ['clean:build'], function () {
    gulp.start('styles:sass', 'scripts:lint', 'scripts:cacheTpls', 'vendor:css', 'vendor:js', 'vendor:assets', 'test:run', 'assets:img', 'html:inject');
});

gulp.task('compile', ['clean:compile', 'build'], function () {
    gulp.start('styles', 'scripts', 'assets', 'html');
});

gulp.task('default', function () {
    gulp.start('compile');
});
<commit_msg>chore(build): renamed task clean:compile to clean:dist for convenience<commit_after>/* jshint strict: false */

var gulp    = require('gulp'),
    map     = require('map-stream'),
    del     = require('del'),
    plugins = require('gulp-load-plugins')(),
    server  = require('tiny-lr')(),
    config  = require('./config.json'),
    pkg     = require('./package.json');

// Prepare CSS
// ===========

var processWinPath = function (file) {
    // Fix for bug with paths on Windows
    var path = require('path');
    if (process.platform === 'win32') {
        file.path = path.relative('.', file.path);
        file.path = file.path.replace(/\\/g, '/');
    }
};

// Compile SASS and add prefixes
var fnSass = function (path) {
    return gulp.src(path)
        .on('data', processWinPath)
        .pipe(plugins.plumber())
        .pipe(plugins.sass({
            sourceComments: 'map'
        }))
        .on('error', function (err) {
            console.log(err.message);
            // process.exit(1);
        })
        .pipe(plugins.autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4', {
            map: true,
            from: pkg.name + '-' + pkg.version + '.css',
            to: pkg.name + '-' + pkg.version + '.css'
        }))
        .pipe(plugins.size({ showFiles: true, title: '[CSS]' }))
        .pipe(gulp.dest(config.build + '/assets'))
        .on('end', function () {
            require('fs').unlink(path);
        });
};
gulp.task('styles:sass:imports', function () {
    var files = [config.app + '/+(sass|app|common)/**/*.scss', '!' + config.app + '/sass/includes/*.scss', '!' + config.app + '/+(app|common)/**/_*.scss'];
    return gulp.src(files, { read: false })
        .on('data', processWinPath)
        .pipe(plugins.intercept(function (file) {
            file.contents = new Buffer('@import \'' + file.path + '\';');
            return file;
        }))
        .pipe(plugins.concat(pkg.name + '-' + pkg.version + '.scss'))
        .pipe(gulp.dest(config.build + '/assets'));
});
gulp.task('styles:sass', ['styles:sass:imports'], function () {
    var files = config.build + '/assets/' + pkg.name + '-' + pkg.version + '.scss';
    return fnSass(files);
});

// Minify CSS
gulp.task('styles', ['styles:sass', 'vendor:css'], function () {
    var arr = (config.vendor_files.css).concat(config.build + '/assets/' + pkg.name + '-' + pkg.version + '.css');
    return gulp.src(arr)
        .pipe(plugins.concat(pkg.name + '-' + pkg.version + '.css'))
        .pipe(plugins.minifyCss({ keepSpecialComments: 0 }))
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.size({ showFiles: true, title: '[CSS]' }))
        .pipe(gulp.dest(config.dist + '/assets'));
});

// Prepare vendor files
// ====================

// Copy vendor JS files to /build/
gulp.task('vendor:js', function () {
    if (!config.vendor_files.js.length) {
        return;
    }
    return gulp.src(config.vendor_files.js, { base: '.' })
        .pipe(gulp.dest(config.build));
});

// Copy vendor css to /build/
gulp.task('vendor:css', function () {
    if (!config.vendor_files.css.length) {
        return;
    }
    return gulp.src(config.vendor_files.css, { base: '.' })
        .pipe(gulp.dest(config.build));
});

// Copy vendor assets to /build/
gulp.task('vendor:assets', function () {
    if (!config.vendor_files.assets.length) {
        return;
    }
    return gulp.src(config.vendor_files.assets, { base: '.' })
        .pipe(gulp.dest(config.build + '/assets'));
});

// Prepare JavaScript
// ==================

// Cache AngularJS templates
var fnCacheTpls = function (path) {
    return gulp.src(path)
        .pipe(plugins.minifyHtml({
            empty: true,
            spare: true,
            quotes: true
        }))
        .pipe(plugins.angularTemplatecache({
            module: 'templates.app',
            standalone: true
        }))
        .pipe(plugins.concat('templates.js'))
        .pipe(gulp.dest(config.build + '/app'));
};
gulp.task('scripts:cacheTpls', function () {
    return fnCacheTpls(config.paths.templates);
});

// Check JavaScript code quality with JSHint
var fnLint = function (path, exitOnError) {
    return gulp.src(path, { base: config.app })
        .pipe(plugins.plumber())
        .pipe(plugins.jshint())
        .pipe(plugins.jshint.reporter('jshint-stylish-ex'))
        .pipe(map(function (file, cb) {
            if (!file.jshint.success && exitOnError) {
                process.exit(1);
            }
            cb(null, file);
        }))
        .pipe(gulp.dest(config.build));
};
gulp.task('scripts:lint', function () {
    return fnLint(config.paths.scripts, true);
});

// Concat and minify JavaScript
gulp.task('scripts', ['scripts:lint', 'scripts:cacheTpls', 'vendor:js'], function () {
    var arr = (config.vendor_files.js).concat(config.paths.scripts.concat(config.build + '/app/templates.js'));
    return gulp.src(arr)
        .pipe(plugins.ngAnnotate())
        .pipe(plugins.concat(pkg.name + '-' + pkg.version + '.js'))
        .pipe(plugins.size({ showFiles: true, title: '[JS]' }))
        .pipe(plugins.uglify({
            mangle: false,
            compress: {
                drop_console: true
            }
        }))
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.size({ showFiles: true, title: '[JS]' }))
        .pipe(gulp.dest(config.dist + '/assets'));
});

// Prepare assets
// ==============

// Copy assets
var fnImg = function (path) {
    return gulp.src(path, { base: config.app })
        .pipe(gulp.dest(config.build));
};
gulp.task('assets:img', function () {
    return fnImg(config.paths.assets);
});

// Compress images
gulp.task('assets', ['assets:img', 'vendor:assets'], function () {
    return gulp.src([config.build + '/assets/**', '!' + config.build + '/assets/*.+(css|scss)'])
        .pipe(plugins.plumber())
        // .pipe(plugins.bytediff.start())
        .pipe(plugins.newer(config.dist + '/assets'))
        // .pipe(plugins.imagemin({ optimizationLevel: 7, progressive: true, interlaced: true }))
        // .pipe(plugins.bytediff.stop())
        .pipe(gulp.dest(config.dist + '/assets'));
});

// Prepare HTML
// ============

// Inject CSS & JS to index.html source
var fnInject = function (path) {
    var inject = {
        css : (config.vendor_files.css).concat(config.build + '/assets/*.css'),
        js  : (config.vendor_files.js).concat(config.build + '/+(app|common)/**/*.module.js').concat(config.build + '/+(app|common)/**/*.js')
    };

    return gulp.src(inject.css.concat(inject.js), { read: false })
        .pipe(plugins.inject(path, {
            addRootSlash: false,
            ignorePath: ['/', config.build + '/']
        }))
        .pipe(gulp.dest(config.build));
};
gulp.task('html:inject', ['styles:sass', 'scripts:lint', 'scripts:cacheTpls'], function () {
    return fnInject(config.paths.html);
});

// Replace non-optimized HTML blocks
gulp.task('html:replace', ['html:inject'], function () {
    return gulp.src(config.build + '/index.html')
        .pipe(plugins.htmlReplace({
            css: 'assets/' + pkg.name + '-' + pkg.version + '.min.css',
            js: 'assets/' + pkg.name + '-' + pkg.version + '.min.js'
        }))
        .pipe(gulp.dest(config.dist));
});

// Compile and minify HTML
gulp.task('html', ['html:replace'], function () {
    return gulp.src(config.dist + '/index.html')
        .pipe(plugins.plumber())
        .pipe(plugins.minifyHtml({
            empty: true,
            spare: true,
            quotes: true
        }))
        .pipe(gulp.dest(config.dist));
});

// Karma
// ============
var testFiles = [
    config.build + '/vendor/**/*.js',
    config.build + '/+(app|common)/**/*.module.js',
    config.build + '/+(app|common)/**/*.js',
    config.mocks,
    config.paths.tests
];

gulp.task('test:run', ['scripts:lint', 'scripts:cacheTpls', 'vendor:assets', 'styles:sass', 'html:inject'] , function () {
    // Be sure to return the stream
    return gulp.src(testFiles)
        .pipe(plugins.karma({
            configFile: 'karma.conf.js',
            action: 'run'
        }))
        .on('error', function (err) {
            process.exit(1);
        });
});

gulp.task('test:watch', ['scripts:lint', 'scripts:cacheTpls', 'vendor:assets', 'styles:sass', 'html:inject'], function () {
    gulp.src(testFiles)
        .pipe(plugins.karma({
            configFile: 'karma.conf.js',
            action: 'watch'
        }));
});

// Set up Watch
// ============

// Add files to Watch
gulp.task('watch', ['styles:sass', 'scripts:lint', 'scripts:cacheTpls', 'assets:img', 'vendor:css', 'vendor:js', 'vendor:assets', 'test:watch', 'html:inject'], function () {
    require('./server.js')(server);

    // watch for JS changes
    gulp.watch(config.paths.scripts, function (event) {
        if (event.path.lastIndexOf('.js') === event.path.length - 3) {
            if (event.type === 'deleted') {
                del(event.path.replace(config.app, config.build));
            } else {
                return fnLint(event.path).pipe(plugins.livereload(server));
            }
        }
    });

    // remove deleted JS files from index.html
    gulp.watch(config.build + '/+(app|common)/**/*.js', function (event) {
        if (event.type !== 'changed') {
            return fnInject(config.paths.html).pipe(plugins.livereload(server));
        }
    });

    // watch AngularJS templates to cache
    gulp.watch(config.app + '/+(app|common)/**', function (event) {
        if (event.path.lastIndexOf('.tpl.html') === event.path.length - 9) {
            return fnCacheTpls(config.paths.templates).pipe(plugins.livereload(server));
        }
    });

    // watch for SASS changes
    var runSequence = require('run-sequence');
    gulp.watch(config.paths.sass, function (event) {
        runSequence('styles:sass:imports', function () {
            var files = config.build + '/assets/' + pkg.name + '-' + pkg.version + '.scss';
            return fnSass(files).pipe(plugins.livereload(server));
        });
    });

    gulp.watch(config.paths.assets, function (event) {
        if (event.type === 'deleted') {
            del(event.path.replace(config.app, config.build));
        } else {
            return fnImg(event.path).pipe(plugins.livereload(server));
        }
    });

    gulp.watch(config.paths.html, function (event) {
        return fnInject(event.path).pipe(plugins.livereload(server));
    });
});

// Clean up development & production directories
// =============================================

gulp.task('clean:build', function (cb) {
    del(config.build, cb);
});
gulp.task('clean:dist', function (cb) {
    del(config.dist, { force: true }, cb);
});

// Main gulp tasks
// ===============

gulp.task('build', ['clean:build'], function () {
    gulp.start('styles:sass', 'scripts:lint', 'scripts:cacheTpls', 'vendor:css', 'vendor:js', 'vendor:assets', 'test:run', 'assets:img', 'html:inject');
});

gulp.task('compile', ['clean:dist', 'build'], function () {
    gulp.start('styles', 'scripts', 'assets', 'html');
});

gulp.task('default', function () {
    gulp.start('compile');
});
<|endoftext|>


<commit_before>'use strict';

var install       = exports;
var lang          = require('../util/lang');
var semver_helper = require('../util/semver');
var stable        = require('semver-stable');
var cortex_json   = require('read-cortex-json');
var node_path     = require('path');
var async         = require('async');
var spawn         = require('child_process').spawn;
var shrinkwrap    = require('../util/shrinkwrap');

// Attension: there will no arguments checking
// @param {Object} options:
// - packages: {Array.<string>} packages to install, ['a@1.0.1', 'b@0.0.2'], notice that the version of each module must be specified:
//    'a' should be 'a@latest', or there will be an failure
// - save: {boolean} save cortexDependencies
// - cwd: {string}
// - _desc: {string} private property, which will never called by command-line
// - recursive: {boolean} if false, cortex will not install dependencies

// @param {function()} callback
install.run = function(options, callback) {
  if (!options.packages.length) {
    this.logger.warn('it seems that there\'s no packages to install.');
    return callback(null);
  }

  options.module_root = this.profile.get('cache_root');

  var self = this;
  async.waterfall([
    function (done) {
      self.download_package(options, done);
    },

    function (done) {
      self.build_packages(options, done);
    },

    function (done) {
      self.save_dependencies(options, done);
    },

    function (done) {
      self.update_shrinkwrap(options, done);
    },

    function (done) {
      self.clone_to_workspace(options, done);
    }

  ], callback);
};

install.download_package = function(options, callback) {
  var command_description = options._desc;
  var packages = options.packages;

  this.logger.info('{{cyan ' + command_description + '}}', packages.join(', '));

  // suppose:
  // 1. packages -> ['a@~0.0.1', 'b@0.0.2']
  // 2. dependencies of 'b@0.0.2' -> ['~a@0.1.2']
  this.neuropil.install({
    packages: packages,
    dir: options.module_root,
    recursive: options.recursive,
    dependency_key: 'dependencies',
    force_stable: options._save

  }, function(err, data) {
    if (err) {
      return callback(err);
    }

    options.data = data;
    callback(null);
  });
};

// @type {Object} options.data
// {
//     origins: {
//         'a': ['~0.0.1'],
//         'b': ['0.0.2']
//     },

//     documents: {
//         'a': {
//             '0.0.7': <pkg>,
//             '0.1.3': <pkg>
//         },

//         'b': {
//             '0.0.2': <pkg>
//         }
//     },

//     // according to `options.dependency_key`
//     dependencies: {
//         'a': {
//             '0.0.7': {}, // no deps
//             '0.1.3': {}
//         },

//         'b': {
//             '0.0.2': {
//                 'a': '~0.1.2'
//             }
//         }
//     },

//     ranges: {
//         'a': {
//             '~0.0.1': '0.0.7',
//             '~0.1.2': '0.1.3'
//         }
//     }
// }
install.build_packages = function(options, callback) {
  // build packages
  var tasks = [];
  var commander = this.commander;
  var packages = this.iterate_packages(options.data);

  async.each(packages, build_package, function(err) {
    callback(err);
  });

  function build_package (pkg, done) {
    var cwd = node_path.join(options.module_root, pkg.name, pkg.version, 'package');

    // mock process.argv
    var argv = [
      '', '',
      'build',

      // You need to finish your custom build scripts
      // before publishing into the registry, and cortex will
      // not run `scripts.prebuild` when installing
      '--no-prebuild',

      // run `scripts.preinstall`
      '--preinstall',
      '--no-link',
      '--cwd', cwd
    ];

    commander.run(argv, done);
  }
};

install.save_dependencies = function(options, callback) {
  var self = this;

  // save to package.json
  if (options._save) {
    var data = options.data;
    var logger = this.logger;
    cortex_json.read(options.cwd, function(err, ctx) {
      if (err) {
        return callback(err);
      }

      // if --save --save-async, --save-async will be ignored
      var key = self.key_to_save(options);

      var deps = ctx[key] || (ctx[key] = {});
      // var exact_deps = ctx.exactDependencies || (ctx.exactDependencies = {});

      Object.keys(data.origins).forEach(function(name) {
        var versions = data.origins[name];
        var ranges = data.ranges[name] || {};

        versions.forEach(function(version) {
          var exact_version = ranges[version] || version;
          if (!stable.is(exact_version)) {
            var dep_pkg = name + '@' + exact_version;
            logger.warn(
              'You are trying to install an {{bold UNSTABLE}} package "' + dep_pkg + '".\n' +
              '  Be very sure to remember to publish "' + dep_pkg + '" then.'
            );
          }
          // It's great that `semver` does a awesome job on prerelease versions:
          // '1.0.0-alpha' satisfies '~1.0.0',
          // so we simply remove prerelease version before saving into field `dependencies`
          deps[name] = '~' + semver_helper.remove_prerelease(exact_version);
        });
      });

      cortex_json.save(options.cwd, ctx, callback);

      // use_inherits
    }, true);

  } else {
    callback(null);
  }
};

install.update_shrinkwrap = function (options, callback) {
  if (!options._save) {
    return callback(null);
  }

  shrinkwrap.call(this, options.cwd, callback);
};

var ENUM_SAVE = {
  'save': 'dependencies',
  'save-dev': 'devDependencies',
  'save-async': 'asyncDependencies',
  'save-engine': 'engines'
};

install.key_to_save = function(options) {
  var save_to;

  Object.keys(ENUM_SAVE).some(function(option) {
    if (options[option]) {
      save_to = ENUM_SAVE[option];
      return true;
    }
  });

  return save_to;
};

install.clone_to_workspace = function(options, callback) {
  if (!options.clone) {
    return callback(null);
  }

  var data = options.data;
  var packages = [];
  var mod;

  // get all origin packages from cli
  for (mod in data.origins) {
    data.origins[mod].forEach(function(v) {
      packages.push({
        name: mod,
        version: v
      });
    });
  }

  var repos = {};
  var logger = this.logger;
  var workspace = this.profile.get('workspace') || options.cwd;

  function clone_module (mod, done) {
    var version = data.ranges[mod.name][mod.version];
    var package_json = data.documents[mod.name].versions[version];

    var is_git = lang.object_member_by_namespaces(package_json, "repository.type") == "git";
    var repo_url = lang.object_member_by_namespaces(package_json, "repository.url");

    if (!is_git || !repo_url || repos[repo_url]) {
      return done(null);

    } else {
      repos[repo_url] = true;

      logger.info("\n{{cyan clone}}", mod.name + ':', repo_url);
      var dir = node_path.join(workspace, mod.name);

      var child = spawn("git", ["clone", repo_url, dir], {
        stdio: "inherit"
      });

      child.on("close", function(code, signal) {
        if (code) {
          done({
            code: 'EGITCLONE',
            message: 'fails to git-clone "' + repo_url + '"',
            data: {
              repo: repo_url,
              dir: dir
            }
          });
        } else {
          done(null);
        }
      });
    }
  }

  async.each(packages, clone_module, callback);
};

// @param {Object} packages
// @param {function(name, version)} callback
install.iterate_packages = function(data) {
  var packages = [];

  lang.each(data.dependencies, function(versions, name) {
    var range = data.ranges[name] || {};
    Object.keys(versions).forEach(function(version) {
      packages.push({
        name: name,
        version: range[version] || version
      });
    });
  });

  return packages;
};
<commit_msg>command/install: save ^ ranges by default after installing; fixes #393<commit_after>'use strict';

var install       = exports;
var lang          = require('../util/lang');
var semver_helper = require('../util/semver');
var stable        = require('semver-stable');
var cortex_json   = require('read-cortex-json');
var node_path     = require('path');
var async         = require('async');
var spawn         = require('child_process').spawn;
var shrinkwrap    = require('../util/shrinkwrap');

// Attension: there will no arguments checking
// @param {Object} options:
// - packages: {Array.<string>} packages to install, ['a@1.0.1', 'b@0.0.2'], notice that the version of each module must be specified:
//    'a' should be 'a@latest', or there will be an failure
// - save: {boolean} save cortexDependencies
// - cwd: {string}
// - _desc: {string} private property, which will never called by command-line
// - recursive: {boolean} if false, cortex will not install dependencies

// @param {function()} callback
install.run = function(options, callback) {
  if (!options.packages.length) {
    this.logger.warn('it seems that there\'s no packages to install.');
    return callback(null);
  }

  options.module_root = this.profile.get('cache_root');

  var self = this;
  async.waterfall([
    function (done) {
      self.download_package(options, done);
    },

    function (done) {
      self.build_packages(options, done);
    },

    function (done) {
      self.save_dependencies(options, done);
    },

    function (done) {
      self.update_shrinkwrap(options, done);
    },

    function (done) {
      self.clone_to_workspace(options, done);
    }

  ], callback);
};

install.download_package = function(options, callback) {
  var command_description = options._desc;
  var packages = options.packages;

  this.logger.info('{{cyan ' + command_description + '}}', packages.join(', '));

  // suppose:
  // 1. packages -> ['a@~0.0.1', 'b@0.0.2']
  // 2. dependencies of 'b@0.0.2' -> ['~a@0.1.2']
  this.neuropil.install({
    packages: packages,
    dir: options.module_root,
    recursive: options.recursive,
    dependency_key: 'dependencies',
    force_stable: options._save

  }, function(err, data) {
    if (err) {
      return callback(err);
    }

    options.data = data;
    callback(null);
  });
};

// @type {Object} options.data
// {
//     origins: {
//         'a': ['~0.0.1'],
//         'b': ['0.0.2']
//     },

//     documents: {
//         'a': {
//             '0.0.7': <pkg>,
//             '0.1.3': <pkg>
//         },

//         'b': {
//             '0.0.2': <pkg>
//         }
//     },

//     // according to `options.dependency_key`
//     dependencies: {
//         'a': {
//             '0.0.7': {}, // no deps
//             '0.1.3': {}
//         },

//         'b': {
//             '0.0.2': {
//                 'a': '~0.1.2'
//             }
//         }
//     },

//     ranges: {
//         'a': {
//             '~0.0.1': '0.0.7',
//             '~0.1.2': '0.1.3'
//         }
//     }
// }
install.build_packages = function(options, callback) {
  // build packages
  var tasks = [];
  var commander = this.commander;
  var packages = this.iterate_packages(options.data);

  async.each(packages, build_package, function(err) {
    callback(err);
  });

  function build_package (pkg, done) {
    var cwd = node_path.join(options.module_root, pkg.name, pkg.version, 'package');

    // mock process.argv
    var argv = [
      '', '',
      'build',

      // You need to finish your custom build scripts
      // before publishing into the registry, and cortex will
      // not run `scripts.prebuild` when installing
      '--no-prebuild',

      // run `scripts.preinstall`
      '--preinstall',
      '--no-link',
      '--cwd', cwd
    ];

    commander.run(argv, done);
  }
};

install.save_dependencies = function(options, callback) {
  var self = this;

  // save to package.json
  if (options._save) {
    var data = options.data;
    var logger = this.logger;
    cortex_json.read(options.cwd, function(err, ctx) {
      if (err) {
        return callback(err);
      }

      // if --save --save-async, --save-async will be ignored
      var key = self.key_to_save(options);

      var deps = ctx[key] || (ctx[key] = {});
      // var exact_deps = ctx.exactDependencies || (ctx.exactDependencies = {});

      Object.keys(data.origins).forEach(function(name) {
        var versions = data.origins[name];
        var ranges = data.ranges[name] || {};

        versions.forEach(function(version) {
          var exact_version = ranges[version] || version;
          if (!stable.is(exact_version)) {
            var dep_pkg = name + '@' + exact_version;
            logger.warn(
              'You are trying to install an {{bold UNSTABLE}} package "' + dep_pkg + '".\n' +
              '  Be very sure to remember to publish "' + dep_pkg + '" then.'
            );
          }
          // It's great that `semver` does a awesome job on prerelease versions:
          // '1.0.0-alpha' satisfies '^1.0.0',
          // so we simply remove prerelease version before saving into field `dependencies`
          deps[name] = '^' + semver_helper.remove_prerelease(exact_version);
        });
      });

      cortex_json.save(options.cwd, ctx, callback);

      // use_inherits
    }, true);

  } else {
    callback(null);
  }
};

install.update_shrinkwrap = function (options, callback) {
  if (!options._save) {
    return callback(null);
  }

  shrinkwrap.call(this, options.cwd, callback);
};

var ENUM_SAVE = {
  'save': 'dependencies',
  'save-dev': 'devDependencies',
  'save-async': 'asyncDependencies',
  'save-engine': 'engines'
};

install.key_to_save = function(options) {
  var save_to;

  Object.keys(ENUM_SAVE).some(function(option) {
    if (options[option]) {
      save_to = ENUM_SAVE[option];
      return true;
    }
  });

  return save_to;
};

install.clone_to_workspace = function(options, callback) {
  if (!options.clone) {
    return callback(null);
  }

  var data = options.data;
  var packages = [];
  var mod;

  // get all origin packages from cli
  for (mod in data.origins) {
    data.origins[mod].forEach(function(v) {
      packages.push({
        name: mod,
        version: v
      });
    });
  }

  var repos = {};
  var logger = this.logger;
  var workspace = this.profile.get('workspace') || options.cwd;

  function clone_module (mod, done) {
    var version = data.ranges[mod.name][mod.version];
    var package_json = data.documents[mod.name].versions[version];

    var is_git = lang.object_member_by_namespaces(package_json, "repository.type") == "git";
    var repo_url = lang.object_member_by_namespaces(package_json, "repository.url");

    if (!is_git || !repo_url || repos[repo_url]) {
      return done(null);

    } else {
      repos[repo_url] = true;

      logger.info("\n{{cyan clone}}", mod.name + ':', repo_url);
      var dir = node_path.join(workspace, mod.name);

      var child = spawn("git", ["clone", repo_url, dir], {
        stdio: "inherit"
      });

      child.on("close", function(code, signal) {
        if (code) {
          done({
            code: 'EGITCLONE',
            message: 'fails to git-clone "' + repo_url + '"',
            data: {
              repo: repo_url,
              dir: dir
            }
          });
        } else {
          done(null);
        }
      });
    }
  }

  async.each(packages, clone_module, callback);
};

// @param {Object} packages
// @param {function(name, version)} callback
install.iterate_packages = function(data) {
  var packages = [];

  lang.each(data.dependencies, function(versions, name) {
    var range = data.ranges[name] || {};
    Object.keys(versions).forEach(function(version) {
      packages.push({
        name: name,
        version: range[version] || version
      });
    });
  });

  return packages;
};
<|endoftext|>


<commit_before>//  _____             _____     _
// |  _  |___ ___ ___| __  |___| |
// |   __| . |   | . | __ -| . |  _|
// |__|  |___|_|_|_  |_____|___|_|
//               |___|

'use strict';

var mongoose = require('mongoose');
var mongoUri = 'mongodb://' + process.env.OPENSHIFT_MONGODB_DB_USERNAME
    + ':' + process.env.OPENSHIFT_MONGODB_DB_PASSWORD + '@'
    + process.env.OPENSHIFT_MONGODB_DB_HOST  + ':'
    + process.env.OPENSHIFT_MONGODB_DB_PORT;
mongoose.connect(mongoUri);

var app = require('./lib/app').instance();

var port = process.env.OPENSHIFT_NODEJS_PORT || 3000;
app.listen(port);
console.log('Listening on port', port);
<commit_msg>Add hostname when express starts.<commit_after>//  _____             _____     _
// |  _  |___ ___ ___| __  |___| |
// |   __| . |   | . | __ -| . |  _|
// |__|  |___|_|_|_  |_____|___|_|
//               |___|

'use strict';

var mongoose = require('mongoose');
var mongoUri = 'mongodb://' + process.env.OPENSHIFT_MONGODB_DB_USERNAME
    + ':' + process.env.OPENSHIFT_MONGODB_DB_PASSWORD + '@'
    + process.env.OPENSHIFT_MONGODB_DB_HOST  + ':'
    + process.env.OPENSHIFT_MONGODB_DB_PORT;
mongoose.connect(mongoUri);

var app = require('./lib/app').instance();

var ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.PORT || 3000;
app.listen(port, function() {
  console.log('Listening on port', port);
});
<|endoftext|>


<commit_before>(function(window, angular, undefined) {
'use strict';

var noop     = angular.noop,
	forEach  = angular.forEach,
	extend   = angular.extend,
	copy     = angular.copy,
	isFunc   = angular.isFunction,
	isObject = angular.isObject,
	isArray  = angular.isArray

function underscore(str) {
	var toLower = function($1) { return "_" + $1.toLowerCase(); };
	return str.replace(/([A-Z])/g, toLower).replace(/^_+/, '');
}

function serialize(obj, prefix) {
	var str = [];
	var enc = encodeURIComponent;

	for (var p in obj) {
		var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
		str.push(isObject(v) ? serialize(v, k) : enc(k) + "=" + enc(v));
	}
	return str.join("&");
}

angular.module('ur.model', []).provider('model', function() {

	// Used to evaluate expressions; initialized by the service invokation
	var expr;

	// "Box" an object value in a model instance if it is present.
	// Otherwise, return an empty model object.
	function autoBox(config, object, data) {
		return data ? config.box(object, data) : object;
	}

	// Box an array of JSON objects into a model collection
	function boxArray(object, data) {
		object.length = object.length || 0;

		forEach(data, function(item) {
			object.push(Model.create(item));
		});
		return object;
	}

	// Global registry of settings
	var global = {

		// Base URL prepended to generated URLs
		base: null,

		// Extract URL from object, or use default URL
		url: function(config, object) {
			return object instanceof Model ? expr(object, config.identity) || this.url : this.url;
		}
	};

	// Master registry of application model configurations
	var registry = {};

	// Default configuration for new model classes
	var DEFAULTS = {

		// Default values which should be applied when creating a new model instance
		defaults: {},

		// The name of the key to the URL that identifies the object
		identity: "$links.self",

		// The name of the key to assign an object map of errors
		errors: "$errors",

		// Object boxing function
		box: function(object, data) {
			return isArray(object) ? boxArray(object, data) : copy(data, object);
		}
	};

	var DEFAULT_METHODS = {

		// Methods available on the model class
		$class {
			find: function(data) {
				return $factory.request(config.actions.apply('collection', []), 'GET', data);
			},
			create: function(data) {
				return this.instance(extend({}, defaults, data || {}));
			},
			instance: function(data) {
				return new ModelInstance(data);
			}
		},

		// Methods available on model instances
		$instance: {
			$save: function(data) {
				var method = this.$exists() ? 'PATCH' : 'POST';
				return $factory.request(extend(this, data || {}), method, this);
			},
			$delete: function() {
				return $factory.request(this, 'DELETE');
			},
			$reload: function() {
				return $factory.request(this, 'GET');
			},
			$revert: function() {
				// @todo Reset to previously loaded state
			},
			$exists: function() {
				return !!expr(this, config.identity);
			}
		},

		// Methods available on model collections
		$collection: {
			add: function(object) {
				var self = this;
				return object.$save().success(function() { self.push(object); });
			},
			remove: function(index) {
				index = (typeof index !== 'number') ? index = this.indexOf(index) : index;

				var self = this;
				return self[index].$delete().success(function() { self.splice(index, 1); });
			}
		}
	};

	// Configures a new model, updates an existing model's settings, or updates global settings
	function config(model, options) {
		if (isObject(model)) {
			extend(global, model);
			return;
		}
		if (!options) {
			return registry[model];
		}
		registry[model] = new Model(extend(registry[model] || DEFAULTS, options));

		if (!registry[model].url) {
			registry[model].url = global.base + underscore(model);
		}

		forEach(DEFAULT_METHODS, function(val, key) {
			if (isFunc(val)) {
				return registry[model][key] = options[key] || key;
			}
			registry[model][key] = extend(val, options[key] || {});
		});

		return this;
	}

	extend(this, {

		// Used to add named model configurations, or set global configuration
		config: function(model, options) {
			return config.apply(this, model, options);
		},

		// Returns the model service
		$get: ['$http', '$parse', function($http, $parse) {

			// Extracts a value from an object based on a string expression
			expr = function(obj, path) {
				return $parse(path)(obj);
			};

			return extend(this, {
				config: function(model, options) {
					return config.apply(this, model, options);
				},
				get: function(model) {
					return registry[model];
				}
			});
		}]
	});

	function ModelFactory(name, config) {

		var $factory = {

			request: function(object, method, data, headers) {
				var params = {
					method: method,
					url: this.url(object),
					data: data,
					headers: headers || {}
				};

				if (method === 'PATCH') {
					extend(params.headers, { 'Content-Type': 'application/json;charset=UTF-8' });
				}
				var deferred = $q.defer(), promise = deferred.promise;

				$http(params).then(function(resp) {
					resp.data = (resp.data) ? config.autoBox(object, resp.data) : object;
					deferred.resolve(resp);
				}, function(reason) {
					object[config.errorsKey] = reason.data;
					deferred.reject(reason);
				});

				return extend(object, {
					$success: function(callback) {
						promise.then(function(resp) {
							callback(resp.data, resp.headers);
						});
						return this;
					},

					$error: function(callback) {
						promise.then(null, function(resp) {
							callback(resp);
						});
						return this;
					},

					$then: promise.then
				});
			}
		};

		function Model(data) {
			copy(data || {}, this);
		}

		return Model;
	}

	return ModelFactory;

}).directive('link', ['model', function(model) {

	return {
		restrict: 'E',
		link: function(scope, element, attrs) {
			if (attrs.rel !== "resource" || !attrs.href || !attrs.name) {
				return;
			}
			// model.config(attrs.name, { url: attrs.href });
		}
	};

}]);

})(window, window.angular);<commit_msg>Changing indenting to JS standard.<commit_after>(function(window, angular, undefined) {
'use strict';

var noop     = angular.noop,
  forEach  = angular.forEach,
  extend   = angular.extend,
  copy     = angular.copy,
  isFunc   = angular.isFunction,
  isObject = angular.isObject,
  isArray  = angular.isArray

function underscore(str) {
  var toLower = function($1) { return "_" + $1.toLowerCase(); };
  return str.replace(/([A-Z])/g, toLower).replace(/^_+/, '');
}

function serialize(obj, prefix) {
  var str = [];
  var enc = encodeURIComponent;

  for (var p in obj) {
    var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
    str.push(isObject(v) ? serialize(v, k) : enc(k) + "=" + enc(v));
  }
  return str.join("&");
}

angular.module('ur.model', []).provider('model', function() {

  // Used to evaluate expressions; initialized by the service invokation
  var expr;

  // "Box" an object value in a model instance if it is present.
  // Otherwise, return an empty model object.
  function autoBox(config, object, data) {
    return data ? config.box(object, data) : object;
  }

  // Box an array of JSON objects into a model collection
  function boxArray(object, data) {
    object.length = object.length || 0;

    forEach(data, function(item) {
      object.push(Model.create(item));
    });
    return object;
  }

  // Global registry of settings
  var global = {

    // Base URL prepended to generated URLs
    base: null,

    // Extract URL from object, or use default URL
    url: function(config, object) {
      return object instanceof Model ? expr(object, config.identity) || this.url : this.url;
    }
  };

  // Master registry of application model configurations
  var registry = {};

  // Default configuration for new model classes
  var DEFAULTS = {

    // Default values which should be applied when creating a new model instance
    defaults: {},

    // The name of the key to the URL that identifies the object
    identity: "$links.self",

    // The name of the key to assign an object map of errors
    errors: "$errors",

    // Object boxing function
    box: function(object, data) {
      return isArray(object) ? boxArray(object, data) : copy(data, object);
    }
  };

  var DEFAULT_METHODS = {

    // Methods available on the model class
    $class {
      find: function(data) {
        return $factory.request(config.actions.apply('collection', []), 'GET', data);
      },
      create: function(data) {
        return this.instance(extend({}, defaults, data || {}));
      },
      instance: function(data) {
        return new ModelInstance(data);
      }
    },

    // Methods available on model instances
    $instance: {
      $save: function(data) {
        var method = this.$exists() ? 'PATCH' : 'POST';
        return $factory.request(extend(this, data || {}), method, this);
      },
      $delete: function() {
        return $factory.request(this, 'DELETE');
      },
      $reload: function() {
        return $factory.request(this, 'GET');
      },
      $revert: function() {
        // @todo Reset to previously loaded state
      },
      $exists: function() {
        return !!expr(this, config.identity);
      }
    },

    // Methods available on model collections
    $collection: {
      add: function(object) {
        var self = this;
        return object.$save().success(function() { self.push(object); });
      },
      remove: function(index) {
        index = (typeof index !== 'number') ? index = this.indexOf(index) : index;

        var self = this;
        return self[index].$delete().success(function() { self.splice(index, 1); });
      }
    }
  };

  // Configures a new model, updates an existing model's settings, or updates global settings
  function config(model, options) {
    if (isObject(model)) {
      extend(global, model);
      return;
    }
    if (!options) {
      return registry[model];
    }
    registry[model] = new Model(extend(registry[model] || DEFAULTS, options));

    if (!registry[model].url) {
      registry[model].url = global.base + underscore(model);
    }

    forEach(DEFAULT_METHODS, function(val, key) {
      if (isFunc(val)) {
        return registry[model][key] = options[key] || key;
      }
      registry[model][key] = extend(val, options[key] || {});
    });

    return this;
  }

  extend(this, {

    // Used to add named model configurations, or set global configuration
    config: function(model, options) {
      return config.apply(this, model, options);
    },

    // Returns the model service
    $get: ['$http', '$parse', function($http, $parse) {

      // Extracts a value from an object based on a string expression
      expr = function(obj, path) {
        return $parse(path)(obj);
      };

      return extend(this, {
        config: function(model, options) {
          return config.apply(this, model, options);
        },
        get: function(model) {
          return registry[model];
        }
      });
    }]
  });

  function ModelFactory(name, config) {

    var $factory = {

      request: function(object, method, data, headers) {
        var params = {
          method: method,
          url: this.url(object),
          data: data,
          headers: headers || {}
        };

        if (method === 'PATCH') {
          extend(params.headers, { 'Content-Type': 'application/json;charset=UTF-8' });
        }
        var deferred = $q.defer(), promise = deferred.promise;

        $http(params).then(function(resp) {
          resp.data = (resp.data) ? config.autoBox(object, resp.data) : object;
          deferred.resolve(resp);
        }, function(reason) {
          object[config.errorsKey] = reason.data;
          deferred.reject(reason);
        });

        return extend(object, {
          $success: function(callback) {
            promise.then(function(resp) {
              callback(resp.data, resp.headers);
            });
            return this;
          },

          $error: function(callback) {
            promise.then(null, function(resp) {
              callback(resp);
            });
            return this;
          },

          $then: promise.then
        });
      }
    };

    function Model(data) {
      copy(data || {}, this);
    }

    return Model;
  }

  return ModelFactory;

}).directive('link', ['model', function(model) {

  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      if (attrs.rel !== "resource" || !attrs.href || !attrs.name) {
        return;
      }
      // model.config(attrs.name, { url: attrs.href });
    }
  };

}]);

})(window, window.angular);<|endoftext|>


<commit_before>var fs = require("fs");
var path = require("path");

// https://github.com/octokit/rest.js
// https://octokit.github.io/rest.js/
const Octokit = require('@octokit/rest');

console.log("process.cwd():");
console.log(process.cwd());
console.log("path.resolve(\".\")");
console.log(path.resolve("."));

console.log("__dirname:");
console.log(__dirname);

const args = process.argv.slice(2);
console.log("args:");
console.log(args);

const envCommitSha = process.env.TRAVIS_COMMIT || process.env.APPVEYOR_REPO_COMMIT;

console.log("TRAVIS_COMMIT:");
console.log(envCommitSha);
if (!envCommitSha) {
    console.log("Missing TRAVIS_COMMIT! Abort.");
    process.exit(1);
    return;
}

console.log("TRAVIS_TAG:");
console.log(process.env.TRAVIS_TAG);
if (!process.env.TRAVIS_TAG) {
    console.log("Missing TRAVIS_TAG! Abort.");
    process.exit(1);
    return;
}

if (!process.env.GH_TOKEN) {
    console.log("Missing GH_TOKEN! Abort.");
    process.exit(1);
    return;
}

const octokit = new Octokit({
    auth: `token ${process.env.GH_TOKEN}`
});

// !!!!!!!!!!!!!!!!
// IMPORTANT !!!!
// Make sure DEBUG is *off* in TravisCI,
// as this potentially prints console messages that contain the HTTP header:
// authorization: 'token GH_TOKEN'
// It that happens, revoke the token immediately!
// https://github.com/settings/tokens
// Example: when getReleaseByTag() return 404
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
const DEBUG = false;
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

const owner_appveyor = "danielweck";
const owner = "readium";
const repo = "readium-desktop";
const tag = process.env.TRAVIS_TAG;

(async () => {

console.log("################################################");
console.log("################ getReleaseByTag:");
let getReleaseByTagRES = undefined;
try {
    getReleaseByTagRES = await octokit.repos.getReleaseByTag({owner, repo, tag})
} catch (err) {
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    if (DEBUG) console.log(err);
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    console.log("getReleaseByTag error! Continue.");
    // if (err.status !== 404) {
    //     console.log("getReleaseByTag error! Abort.");
    //     process.exit(1);
    //     return;
    // }
}

if (getReleaseByTagRES) {
    console.log("getReleaseByTagRES:");
    if (DEBUG) console.log(getReleaseByTagRES);

    const release_id = getReleaseByTagRES.data.id;

    console.log("################################################");
    console.log("################ deleteRelease:");
    let deleteReleaseRES = undefined;
    try {
        deleteReleaseRES = await octokit.repos.deleteRelease({owner, repo, release_id})
    } catch (err) {
        console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        if (DEBUG) console.log(err);
        console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        console.log("deleteReleaseRES error! Continue.");
        // console.log("deleteRelease error! Abort.");
        // process.exit(1);
        // return;
    }
    if (deleteReleaseRES) {
        console.log("deleteReleaseRES:");
        if (DEBUG) console.log(deleteReleaseRES);
    }
}

const ref = `tags/${process.env.TRAVIS_TAG}`;

console.log("################################################");
console.log("################ deleteRef:");
let deleteRefRES = undefined;
try {
    deleteRefRES = await octokit.git.deleteRef({owner, repo, ref})
} catch (err) {
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    if (DEBUG) console.log(err);
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    console.log("deleteRefRES error! Continue.");
    // console.log("deleteRef error! Abort.");
    // process.exit(1);
    // return;
}

if (deleteRefRES) {
    console.log("deleteRefRES:");
    if (DEBUG) console.log(deleteRefRES);
}

if (process.env.APPVEYOR_REPO_COMMIT) {
    console.log("Appveyor: skip create tag and release.");
    process.exit(0);
}

const message = process.env.TRAVIS_TAG;
const object = envCommitSha;
const type =  "commit";
const tagger = {
    name: "Daniel Weck",
    email: "daniel.weck@gmail.com",
    date: new Date().toISOString(),
};

console.log("################################################");
console.log("################ createTag:");
let createTagRES = undefined;
try {
    createTagRES = await octokit.git.createTag({owner, repo, tag, message, object, type, tagger, "tagger:name": tagger.name, "tagger:email": tagger.email, "tagger:date": tagger.date});
} catch (err) {
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    if (DEBUG) console.log(err);
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    console.log("createTag error! Continue.");
    // console.log("createTag error! Abort.");
    // process.exit(1);
    // return;
}
if (createTagRES) {
    console.log("createTagRES:");
    if (DEBUG) console.log(createTagRES);

    const ref2 = `refs/tags/${process.env.TRAVIS_TAG}`;
    const sha = createTagRES.data.sha;

    console.log("################################################");
    console.log("################ createRef:");
    let createRefRES = undefined;
    try {
        createRefRES = await octokit.git.createRef({owner, repo, ref: ref2, sha});
    } catch (err) {
        console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        if (DEBUG) console.log(err);
        console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        console.log("createRef error! Continue.");
        // console.log("createRef error! Abort.");
        // process.exit(1);
        // return;
    }

    if (createRefRES) {
        console.log("createRefRES:");
        if (DEBUG) console.log(createRefRES);
    }
}

const travisURL = process.env.TRAVIS_JOB_WEB_URL || process.env.TRAVIS_BUILD_WEB_URL || `${process.env.APPVEYOR_URL}/project/${owner_appveyor}/${repo}/builds/${process.env.APPVEYOR_BUILD_ID}`;

const tag_name = process.env.TRAVIS_TAG;
const target_commitish = envCommitSha;
const name = `[${tag_name}] continuous test build (prerelease)`;
const body = `Travis build job: ${travisURL}`; // gets replaced by Appveyor script anyway
const draft = false;
const prerelease = true;

console.log("################################################");
console.log("################ createRelease:");
let createReleaseRES = undefined;
try {
    createReleaseRES = await octokit.repos.createRelease({owner, repo, tag_name, target_commitish, name, body, draft, prerelease});
} catch (err) {
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    if (DEBUG) console.log(err);
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    console.log("createRelease error! Continue.");
    // console.log("createRelease error! Abort.");
    // process.exit(1);
    // return;
}

if (createReleaseRES) {
    console.log("createReleaseRES:");
    if (DEBUG) console.log(createReleaseRES);
}

})();
<commit_msg>hotfix(CI): Octokit/rest API breaking change for Travis/AppVeyor automated build updates to GitHub (see https://github.com/octokit/rest.js/commit/c1d6c6a37ef4967753515c435f79bcedfcba29bf )<commit_after>var fs = require("fs");
var path = require("path");

// https://github.com/octokit/rest.js
// https://octokit.github.io/rest.js/
const { Octokit } = require('@octokit/rest');

console.log("process.cwd():");
console.log(process.cwd());
console.log("path.resolve(\".\")");
console.log(path.resolve("."));

console.log("__dirname:");
console.log(__dirname);

const args = process.argv.slice(2);
console.log("args:");
console.log(args);

const envCommitSha = process.env.TRAVIS_COMMIT || process.env.APPVEYOR_REPO_COMMIT;

console.log("TRAVIS_COMMIT:");
console.log(envCommitSha);
if (!envCommitSha) {
    console.log("Missing TRAVIS_COMMIT! Abort.");
    process.exit(1);
    return;
}

console.log("TRAVIS_TAG:");
console.log(process.env.TRAVIS_TAG);
if (!process.env.TRAVIS_TAG) {
    console.log("Missing TRAVIS_TAG! Abort.");
    process.exit(1);
    return;
}

if (!process.env.GH_TOKEN) {
    console.log("Missing GH_TOKEN! Abort.");
    process.exit(1);
    return;
}

const octokit = new Octokit({
    auth: `token ${process.env.GH_TOKEN}`
});

// !!!!!!!!!!!!!!!!
// IMPORTANT !!!!
// Make sure DEBUG is *off* in TravisCI,
// as this potentially prints console messages that contain the HTTP header:
// authorization: 'token GH_TOKEN'
// It that happens, revoke the token immediately!
// https://github.com/settings/tokens
// Example: when getReleaseByTag() return 404
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
const DEBUG = false;
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

const owner_appveyor = "danielweck";
const owner = "readium";
const repo = "readium-desktop";
const tag = process.env.TRAVIS_TAG;

(async () => {

console.log("################################################");
console.log("################ getReleaseByTag:");
let getReleaseByTagRES = undefined;
try {
    getReleaseByTagRES = await octokit.repos.getReleaseByTag({owner, repo, tag})
} catch (err) {
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    if (DEBUG) console.log(err);
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    console.log("getReleaseByTag error! Continue.");
    // if (err.status !== 404) {
    //     console.log("getReleaseByTag error! Abort.");
    //     process.exit(1);
    //     return;
    // }
}

if (getReleaseByTagRES) {
    console.log("getReleaseByTagRES:");
    if (DEBUG) console.log(getReleaseByTagRES);

    const release_id = getReleaseByTagRES.data.id;

    console.log("################################################");
    console.log("################ deleteRelease:");
    let deleteReleaseRES = undefined;
    try {
        deleteReleaseRES = await octokit.repos.deleteRelease({owner, repo, release_id})
    } catch (err) {
        console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        if (DEBUG) console.log(err);
        console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        console.log("deleteReleaseRES error! Continue.");
        // console.log("deleteRelease error! Abort.");
        // process.exit(1);
        // return;
    }
    if (deleteReleaseRES) {
        console.log("deleteReleaseRES:");
        if (DEBUG) console.log(deleteReleaseRES);
    }
}

const ref = `tags/${process.env.TRAVIS_TAG}`;

console.log("################################################");
console.log("################ deleteRef:");
let deleteRefRES = undefined;
try {
    deleteRefRES = await octokit.git.deleteRef({owner, repo, ref})
} catch (err) {
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    if (DEBUG) console.log(err);
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    console.log("deleteRefRES error! Continue.");
    // console.log("deleteRef error! Abort.");
    // process.exit(1);
    // return;
}

if (deleteRefRES) {
    console.log("deleteRefRES:");
    if (DEBUG) console.log(deleteRefRES);
}

if (process.env.APPVEYOR_REPO_COMMIT) {
    console.log("Appveyor: skip create tag and release.");
    process.exit(0);
}

const message = process.env.TRAVIS_TAG;
const object = envCommitSha;
const type =  "commit";
const tagger = {
    name: "Daniel Weck",
    email: "daniel.weck@gmail.com",
    date: new Date().toISOString(),
};

console.log("################################################");
console.log("################ createTag:");
let createTagRES = undefined;
try {
    createTagRES = await octokit.git.createTag({owner, repo, tag, message, object, type, tagger, "tagger:name": tagger.name, "tagger:email": tagger.email, "tagger:date": tagger.date});
} catch (err) {
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    if (DEBUG) console.log(err);
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    console.log("createTag error! Continue.");
    // console.log("createTag error! Abort.");
    // process.exit(1);
    // return;
}
if (createTagRES) {
    console.log("createTagRES:");
    if (DEBUG) console.log(createTagRES);

    const ref2 = `refs/tags/${process.env.TRAVIS_TAG}`;
    const sha = createTagRES.data.sha;

    console.log("################################################");
    console.log("################ createRef:");
    let createRefRES = undefined;
    try {
        createRefRES = await octokit.git.createRef({owner, repo, ref: ref2, sha});
    } catch (err) {
        console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        if (DEBUG) console.log(err);
        console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        console.log("createRef error! Continue.");
        // console.log("createRef error! Abort.");
        // process.exit(1);
        // return;
    }

    if (createRefRES) {
        console.log("createRefRES:");
        if (DEBUG) console.log(createRefRES);
    }
}

const travisURL = process.env.TRAVIS_JOB_WEB_URL || process.env.TRAVIS_BUILD_WEB_URL || `${process.env.APPVEYOR_URL}/project/${owner_appveyor}/${repo}/builds/${process.env.APPVEYOR_BUILD_ID}`;

const tag_name = process.env.TRAVIS_TAG;
const target_commitish = envCommitSha;
const name = `[${tag_name}] continuous test build (prerelease)`;
const body = `Travis build job: ${travisURL}`; // gets replaced by Appveyor script anyway
const draft = false;
const prerelease = true;

console.log("################################################");
console.log("################ createRelease:");
let createReleaseRES = undefined;
try {
    createReleaseRES = await octokit.repos.createRelease({owner, repo, tag_name, target_commitish, name, body, draft, prerelease});
} catch (err) {
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    if (DEBUG) console.log(err);
    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    console.log("createRelease error! Continue.");
    // console.log("createRelease error! Abort.");
    // process.exit(1);
    // return;
}

if (createReleaseRES) {
    console.log("createReleaseRES:");
    if (DEBUG) console.log(createReleaseRES);
}

})();
<|endoftext|>


<commit_before>(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as anonymous module.
    define(['jquery'], factory);
  } else if (typeof exports === 'object') {
    // Node / CommonJS
    factory(require('jquery'));
  } else {
    // Browser globals.
    factory(jQuery);
  }
})(function ($) {

  'use strict';

  var NAMESPACE = 'qor.replicator';
  var EVENT_ENABLE = 'enable.' + NAMESPACE;
  var EVENT_DISABLE = 'disable.' + NAMESPACE;
  var EVENT_CLICK = 'click.' + NAMESPACE;
  var IS_TEMPLATE = 'is-template';

  function QorReplicator(element, options) {
    this.$element = $(element);
    this.options = $.extend({}, QorReplicator.DEFAULTS, $.isPlainObject(options) && options);
    this.index = 0;
    this.init();
  }

  QorReplicator.prototype = {
    constructor: QorReplicator,

    init: function () {
      var $this = this.$element;
      var options = this.options;
      var $all = $this.find(options.itemClass);
      var $template;

      if (!$all.length) {
        return;
      }

      $template = $all.filter(options.newClass);

      if (!$template.length) {
        $template = $all.last();
      }

      this.$template = $template;
      this.template = $template.prop('outerHTML');
      $template.data(IS_TEMPLATE, true).hide();

      this.parse();
      this.bind();
    },

    parse: function () {
      var i = 0;

      this.template = this.template.replace(/(\w+)\="(\S*\[\d+\]\S*)"/g, function (attribute, name, value) {
        value = value.replace(/^(\S*)\[(\d+)\]([^\[\]]*)$/, function (input, prefix, index, suffix) {
          if (input === value) {
            if (name === 'name') {
              i = index;
            }

            return (prefix + '[{{index}}]' + suffix);
          }
        });

        return (name + '="' + value + '"');
      });

      this.index = parseFloat(i);
    },

    bind: function () {
      var options = this.options;

      this.$element.
        on(EVENT_CLICK, options.addClass, $.proxy(this.add, this)).
        on(EVENT_CLICK, options.delClass, $.proxy(this.del, this));
    },

    unbind: function () {
      this.$element.
        off(EVENT_CLICK, this.add).
        off(EVENT_CLICK, this.del);
    },

    add: function (e) {
      var $template = this.$template;
      var $item = $template;
      var $target;

      if ($template && $template.is(':hidden')) {
        $template.show();
      } else {
        $target = $(e.target).closest(this.options.addClass);

        if ($target.length) {
          $item = $(this.template.replace(/\{\{index\}\}/g, ++this.index));
          $target.before($item);
        }
      }

      if ($item) {

        // Enable all JavaScript components within the fieldset
        $item.trigger('enable');
      }
    },

    del: function (e) {
      var options = this.options;
      var $item = $(e.target).closest(options.itemClass);
      var $alert;

      if ($item.is(options.newClass)) {
        if ($item.data(IS_TEMPLATE)) {
          this.$template = null;
        }

        // Destroy all JavaScript components within the fieldset
        $item.trigger('disable').remove();
      } else {
        $item.children(':visible').addClass('hidden').hide();
        $alert = $(options.alertTemplate.replace('{{name}}', this.parseName($item)));
        $alert.find(options.undoClass).one(EVENT_CLICK, function () {
          $alert.remove();
          $item.children('.hidden').removeClass('hidden').show();
        });
        $item.append($alert);
      }
    },

    parseName: function ($item) {
      var name = $item.find('input[name]').attr('name');

      if (name) {
        return name.replace(/[^\[\]]+$/, '');
      }
    },

    destroy: function () {
      this.unbind();
      this.$element.removeData(NAMESPACE);
    },
  };

  QorReplicator.DEFAULTS = {
    itemClass: false,
    newClass: false,
    addClass: false,
    delClass: false,
    alertTemplate: '',
  };

  QorReplicator.plugin = function (options) {
    return this.each(function () {
      var $this = $(this);
      var data = $this.data(NAMESPACE);
      var fn;

      if (!data) {
        $this.data(NAMESPACE, (data = new QorReplicator(this, options)));
      }

      if (typeof options === 'string' && $.isFunction(fn = data[options])) {
        fn.call(data);
      }
    });
  };

  $(function () {
    var selector = '.qor-fieldset-container';
    var options = {
          itemClass: '.qor-fieldset',
          newClass: '.qor-fieldset--new',
          addClass: '.qor-fieldset__add',
          delClass: '.qor-fieldset__delete',
          undoClass: '.qor-fieldset__undo',
          alertTemplate: (
            '
' +
              '<input type="hidden" name="{{name}}._destroy" value="1">' +
              '<button class="mdl-button mdl-button--accent mdl-js-button mdl-js-ripple-effect qor-fieldset__undo" type="button">Undo delete</button>' +
            '
'
          ),
        };

    $(document).
      on(EVENT_DISABLE, function (e) {
        QorReplicator.plugin.call($(selector, e.target), 'destroy');
      }).
      on(EVENT_ENABLE, function (e) {
        QorReplicator.plugin.call($(selector, e.target), options);
      }).
      triggerHandler(EVENT_ENABLE);
  });

  return QorReplicator;

});
<commit_msg>Fix material problem<commit_after>(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as anonymous module.
    define(['jquery'], factory);
  } else if (typeof exports === 'object') {
    // Node / CommonJS
    factory(require('jquery'));
  } else {
    // Browser globals.
    factory(jQuery);
  }
})(function ($) {

  'use strict';

  var NAMESPACE = 'qor.replicator';
  var EVENT_ENABLE = 'enable.' + NAMESPACE;
  var EVENT_DISABLE = 'disable.' + NAMESPACE;
  var EVENT_CLICK = 'click.' + NAMESPACE;
  var IS_TEMPLATE = 'is-template';

  function QorReplicator(element, options) {
    this.$element = $(element);
    this.options = $.extend({}, QorReplicator.DEFAULTS, $.isPlainObject(options) && options);
    this.index = 0;
    this.init();
  }

  QorReplicator.prototype = {
    constructor: QorReplicator,

    init: function () {
      var $this = this.$element;
      var options = this.options;
      var $all = $this.find(options.itemClass);
      var $template;

      if (!$all.length) {
        return;
      }

      $template = $all.filter(options.newClass);

      if (!$template.length) {
        $template = $all.last();
      }

      // Should downgrade material components here
      $template.trigger('disable.qor.material');

      this.$template = $template;
      this.template = $template.prop('outerHTML');
      $template.data(IS_TEMPLATE, true).hide();

      this.parse();
      this.bind();
    },

    parse: function () {
      var i = 0;

      this.template = this.template.replace(/(\w+)\="(\S*\[\d+\]\S*)"/g, function (attribute, name, value) {
        value = value.replace(/^(\S*)\[(\d+)\]([^\[\]]*)$/, function (input, prefix, index, suffix) {
          if (input === value) {
            if (name === 'name') {
              i = index;
            }

            return (prefix + '[{{index}}]' + suffix);
          }
        });

        return (name + '="' + value + '"');
      });

      this.index = parseFloat(i);
    },

    bind: function () {
      var options = this.options;

      this.$element.
        on(EVENT_CLICK, options.addClass, $.proxy(this.add, this)).
        on(EVENT_CLICK, options.delClass, $.proxy(this.del, this));
    },

    unbind: function () {
      this.$element.
        off(EVENT_CLICK, this.add).
        off(EVENT_CLICK, this.del);
    },

    add: function (e) {
      var $template = this.$template;
      var $item = $template;
      var $target;

      if ($template && $template.is(':hidden')) {
        $template.show();
      } else {
        $target = $(e.target).closest(this.options.addClass);

        if ($target.length) {
          $item = $(this.template.replace(/\{\{index\}\}/g, ++this.index));
          $target.before($item);
        }
      }

      if ($item) {

        // Enable all JavaScript components within the fieldset
        $item.trigger('enable');
      }
    },

    del: function (e) {
      var options = this.options;
      var $item = $(e.target).closest(options.itemClass);
      var $alert;

      if ($item.is(options.newClass)) {
        if ($item.data(IS_TEMPLATE)) {
          this.$template = null;
        }

        // Destroy all JavaScript components within the fieldset
        $item.trigger('disable').remove();
      } else {
        $item.children(':visible').addClass('hidden').hide();
        $alert = $(options.alertTemplate.replace('{{name}}', this.parseName($item)));
        $alert.find(options.undoClass).one(EVENT_CLICK, function () {
          $alert.remove();
          $item.children('.hidden').removeClass('hidden').show();
        });
        $item.append($alert);
      }
    },

    parseName: function ($item) {
      var name = $item.find('input[name]').attr('name');

      if (name) {
        return name.replace(/[^\[\]]+$/, '');
      }
    },

    destroy: function () {
      this.unbind();
      this.$element.removeData(NAMESPACE);
    },
  };

  QorReplicator.DEFAULTS = {
    itemClass: false,
    newClass: false,
    addClass: false,
    delClass: false,
    alertTemplate: '',
  };

  QorReplicator.plugin = function (options) {
    return this.each(function () {
      var $this = $(this);
      var data = $this.data(NAMESPACE);
      var fn;

      if (!data) {
        $this.data(NAMESPACE, (data = new QorReplicator(this, options)));
      }

      if (typeof options === 'string' && $.isFunction(fn = data[options])) {
        fn.call(data);
      }
    });
  };

  $(function () {
    var selector = '.qor-fieldset-container';
    var options = {
          itemClass: '.qor-fieldset',
          newClass: '.qor-fieldset--new',
          addClass: '.qor-fieldset__add',
          delClass: '.qor-fieldset__delete',
          undoClass: '.qor-fieldset__undo',
          alertTemplate: (
            '
' +
              '<input type="hidden" name="{{name}}._destroy" value="1">' +
              '<button class="mdl-button mdl-button--accent mdl-js-button mdl-js-ripple-effect qor-fieldset__undo" type="button">Undo delete</button>' +
            '
'
          ),
        };

    $(document).
      on(EVENT_DISABLE, function (e) {
        QorReplicator.plugin.call($(selector, e.target), 'destroy');
      }).
      on(EVENT_ENABLE, function (e) {
        QorReplicator.plugin.call($(selector, e.target), options);
      }).
      triggerHandler(EVENT_ENABLE);
  });

  return QorReplicator;

});
<|endoftext|>


<commit_before>function editButton(url, text='Edit') {
    return "<button class='btn btn-success edit-button btn-sm' type='button' url='" + url + "'>" + text + "</button>";
}

function deleteButton(url, text='Delete') {
    return "<button class='btn btn-danger delete-button btn-sm' type='button' url='" + url + "'>" + text + "</button>";
}

function renderLink(text, url) {
    if (text === '' || url === '') {
        return text;
    }

    return '' + text + '';
}

function enableButtons(elements, enabled) {
    for (let item of elements) {
        $(item).prop('disabled', !enabled);
    }
}

function linkButtonsToSelection(table, buttons) {
    /* Link a bootstrap-table object to one or more buttons.
     * The buttons will only be enabled if there is at least one row selected
     */

    // Initially set the enable state of the buttons
    enableButtons(buttons, table.bootstrapTable('getSelections').length > 0);

    // Add a callback
    table.on('check.bs.table uncheck.bs.table check-some.bs.table uncheck-some.bs.table check-all.bs.table uncheck-all.bs.table', function(row) {
        enableButtons(buttons, table.bootstrapTable('getSelections').length > 0);
    });
}

function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

/*
 * Reload a table which has already been made into a bootstrap table.
 * New filters can be optionally provided, to change the query params.
 */
function reloadTable(table, filters) {

    // Simply perform a refresh
    if (filters == null) {
        table.bootstrapTable('refresh');
        return;
    }

    // More complex refresh with new filters supplied
    var options = table.bootstrapTable('getOptions');

    // Construct a new list of filters to use for the query
    var params = {};

    for (var key in filters) {
        params[key] = filters[key];
    }

    // Original query params will override
    if (options.original != null) {
        for (var key in options.original) {
            params[key] = options.original[key];
        }
    }

    options.queryParams = params;

    table.bootstrapTable('refreshOptions', options);
    table.bootstrapTable('refresh');
}

/* Wrapper function for bootstrapTable.
 * Sets some useful defaults, and manage persistent settings.
 */
$.fn.inventreeTable = function(options) {

    var tableName = options.name || 'table';

    var varName = tableName + '-pagesize';

    options.pagination = true;
    options.pageSize = inventreeLoad(varName, 25);
    options.pageList = [25, 50, 100, 250, 'all'];
    options.rememberOrder = true;
    options.sortable = true;
    options.search = true;

    // Callback to save pagination data
    options.onPageChange = function(number, size) {
        inventreeSave(varName, size);
    };

    // Standard options for all tables
    this.bootstrapTable(options);
}

function customGroupSorter(sortName, sortOrder, sortData) {

    var order = sortOrder === 'desc' ? -1 : 1;

    sortData.sort(function(a, b) {

        // Extract default field values
        var aa = a[sortName];
        var bb = b[sortName];

        // Extract parent information
        var aparent = a._data && a._data['parent-index'];
        var bparent = b._data && b._data['parent-index'];

        // If either of the comparisons are in a group
        if (aparent || bparent) {

            // If the parents are different (or one item does not have a parent,
            // then we need to extract the parent value for the selected column.

            if (aparent != bparent) {
                if (aparent) {
                    aa = a._data['table'].options.groupByFormatter(sortName, 0, a._data['group-data']);
                }

                if (bparent) {
                    bb = b._data['table'].options.groupByFormatter(sortName, 0, b._data['group-data']);
                }
            }
        }

        if (aa === undefined || aa === null) {
            aa = '';
        }
        if (bb === undefined || bb === null) {
            bb = '';
        }

        if (isNumeric(aa) && isNumeric(bb)) {
            if (aa < bb) {
                return order * -1;
            } else if (aa > bb) {
                return order;
            } else {
                return 0;
            }
        }

        aa = aa.toString();
        bb = bb.toString();

        var cmp = aa.localeCompare(bb);

        if (cmp === -1) {
            return order * -1;
        } else if (cmp === 1) {
            return order;
        } else {
            return 0;
        }
    });
}<commit_msg>Add function to turn a set of visible columns into a settings string for saving to session<commit_after>function editButton(url, text='Edit') {
    return "<button class='btn btn-success edit-button btn-sm' type='button' url='" + url + "'>" + text + "</button>";
}

function deleteButton(url, text='Delete') {
    return "<button class='btn btn-danger delete-button btn-sm' type='button' url='" + url + "'>" + text + "</button>";
}

function renderLink(text, url) {
    if (text === '' || url === '') {
        return text;
    }

    return '' + text + '';
}

function enableButtons(elements, enabled) {
    for (let item of elements) {
        $(item).prop('disabled', !enabled);
    }
}

function linkButtonsToSelection(table, buttons) {
    /* Link a bootstrap-table object to one or more buttons.
     * The buttons will only be enabled if there is at least one row selected
     */

    // Initially set the enable state of the buttons
    enableButtons(buttons, table.bootstrapTable('getSelections').length > 0);

    // Add a callback
    table.on('check.bs.table uncheck.bs.table check-some.bs.table uncheck-some.bs.table check-all.bs.table uncheck-all.bs.table', function(row) {
        enableButtons(buttons, table.bootstrapTable('getSelections').length > 0);
    });
}

function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

/*
 * Reload a table which has already been made into a bootstrap table.
 * New filters can be optionally provided, to change the query params.
 */
function reloadTable(table, filters) {

    // Simply perform a refresh
    if (filters == null) {
        table.bootstrapTable('refresh');
        return;
    }

    // More complex refresh with new filters supplied
    var options = table.bootstrapTable('getOptions');

    // Construct a new list of filters to use for the query
    var params = {};

    for (var key in filters) {
        params[key] = filters[key];
    }

    // Original query params will override
    if (options.original != null) {
        for (var key in options.original) {
            params[key] = options.original[key];
        }
    }

    options.queryParams = params;

    table.bootstrapTable('refreshOptions', options);
    table.bootstrapTable('refresh');
}

function visibleColumnString(columns) {
    /* Generate a list of "visible" columns to save to file. */

    var fields = [];

    columns.forEach(function(column) {
        if (column.switchable && column.visible) {
            fields.push(column.field);
        }
    });

    return fields.join(',');
}

/* Wrapper function for bootstrapTable.
 * Sets some useful defaults, and manage persistent settings.
 */
$.fn.inventreeTable = function(options) {

    var tableName = options.name || 'table';

    var varName = tableName + '-pagesize';

    options.pagination = true;
    options.pageSize = inventreeLoad(varName, 25);
    options.pageList = [25, 50, 100, 250, 'all'];
    options.rememberOrder = true;
    options.sortable = true;
    options.search = true;

    // Callback to save pagination data
    options.onPageChange = function(number, size) {
        inventreeSave(varName, size);
    };

    // Standard options for all tables
    this.bootstrapTable(options);
}

function customGroupSorter(sortName, sortOrder, sortData) {

    var order = sortOrder === 'desc' ? -1 : 1;

    sortData.sort(function(a, b) {

        // Extract default field values
        var aa = a[sortName];
        var bb = b[sortName];

        // Extract parent information
        var aparent = a._data && a._data['parent-index'];
        var bparent = b._data && b._data['parent-index'];

        // If either of the comparisons are in a group
        if (aparent || bparent) {

            // If the parents are different (or one item does not have a parent,
            // then we need to extract the parent value for the selected column.

            if (aparent != bparent) {
                if (aparent) {
                    aa = a._data['table'].options.groupByFormatter(sortName, 0, a._data['group-data']);
                }

                if (bparent) {
                    bb = b._data['table'].options.groupByFormatter(sortName, 0, b._data['group-data']);
                }
            }
        }

        if (aa === undefined || aa === null) {
            aa = '';
        }
        if (bb === undefined || bb === null) {
            bb = '';
        }

        if (isNumeric(aa) && isNumeric(bb)) {
            if (aa < bb) {
                return order * -1;
            } else if (aa > bb) {
                return order;
            } else {
                return 0;
            }
        }

        aa = aa.toString();
        bb = bb.toString();

        var cmp = aa.localeCompare(bb);

        if (cmp === -1) {
            return order * -1;
        } else if (cmp === 1) {
            return order;
        } else {
            return 0;
        }
    });
}<|endoftext|>


<commit_before>'use strict';
const Config = require('electron-config');

module.exports = new Config({
  defaults: {
    darkMode: true,
    zoomFactor: 1,
    lastWindowState: {
      width: 414,
      height: 700
    }
  }
});
<commit_msg>Light theme as default<commit_after>'use strict';
const Config = require('electron-config');

module.exports = new Config({
  defaults: {
    darkMode: false,
    zoomFactor: 1,
    lastWindowState: {
      width: 414,
      height: 700
    }
  }
});
<|endoftext|>


<commit_before>import api from '../api/NewsApi';
import NewsActionTypes from '../constants/NewsActionTypes';
import NewsDispatcher from '../dispatcher/NewsDispatcher';

const newsAction = {
  getSources() {
    api.getSource((res) => {
      const newsSource = JSON.parse(res.text);
      NewsDispatcher.dispatch({
        eventName: NewsActionTypes.GET_SOURCES,
        sourcesItem: newsSource,
      });
    },
    (error) => {
      throw window.alert(error);
    });
  },
  getNews(source, sortby) {
    api.getNews(source, sortby, (res) => {
      const news = JSON.parse(res.text);
      NewsDispatcher.dispatch({
        eventName: NewsActionTypes.GET_NEWS,
        newsItem: news,
      });
    },
    (error) => {
      throw window.alert(error);
    });
  },
};

export default newsAction;
<commit_msg>documentation<commit_after>import api from '../api/NewsApi';
import NewsActionTypes from '../constants/NewsActionTypes';
import NewsDispatcher from '../dispatcher/NewsDispatcher';

const newsAction = {
  /**
   * @desc initiates call to api to get sources
   * then sends it through the dispatcher
   * to the store
   *
   * @memberof newsAction
   */
  getSources() {
    api.getSource((res) => {
      const newsSource = res.body;
      NewsDispatcher.dispatch({
        eventName: NewsActionTypes.GET_SOURCES,
        sourcesItem: newsSource,
      });
    },
    (error) => {
      throw window.alert(error);
    });
  },
   /**
   * @desc initiates call to api to get news
   * then sends it through the dispatcher
   * to the store
   *@param {string} source and sortby are both pased as string

   * @memberof newsAction
   */
  getNews(source, sortby) {
    api.getNews(source, sortby, (res) => {
      const news = JSON.parse(res.text);
      NewsDispatcher.dispatch({
        eventName: NewsActionTypes.GET_NEWS,
        newsItem: news,
      });
    },
    (error) => {
      throw window.alert(error);
    });
  },
};

export default newsAction;
<|endoftext|>


<commit_before>/*
 * Minio Cloud Storage, (C) 2015 Minio, Inc.
 *
 * Licensed 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.
 */

var gulp = require('gulp');
var del = require('del');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var less = require('gulp-less');
var uglify = require('gulp-uglify');
var streamify = require('gulp-streamify');
var rename = require('gulp-rename');
var minifycss = require('gulp-minify-css');
var concat = require('gulp-concat');
var server = require('gulp-webserver');
var eslint = require('gulp-eslint');

var paths = {
  reactScripts : ['app/scripts/minio/*', 'app/scripts/minio/**/*'],
  otherScripts : ['app/scripts/extern/*'],
  fonts : 'app/fonts/**/*',
  less : ['app/styles/*.less', 'app/styles/**/*.less']
}

gulp.task('clean', function() {
  return del(['dist']);
});

gulp.task('less', function () {
  return gulp.src('./app/styles/app.less') //path to your main less file
    .pipe(less())
    .pipe(minifycss())
    .pipe(rename('app.min.css'))
    .pipe(gulp.dest('dist'))
});

gulp.task('fonts', function() {
  return gulp.src(paths.fonts, {base:"app"})
    .pipe(gulp.dest('dist'))
})

gulp.task('html', function() {
  return gulp.src('app/index.html')
    .pipe(gulp.dest('dist'))
})

gulp.task('react-scripts', function() {
  return browserify({entries: './app/scripts/minio/app.js', extensions: ['.jsx']}).transform('reactify')
    .bundle()
    .pipe(source('app.min.js'))
    .pipe(streamify(uglify()))
    .pipe(gulp.dest('dist'))
})

gulp.task('other-scripts', function() {
  return gulp.src(['app/scripts/extern/*.js'])
    .pipe(concat('extern.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist'))
})

gulp.task('watch', ['build'], function() {
  gulp.watch(paths.reactScripts, ['react-scripts'])
  gulp.watch(paths.otherScripts, ['other-scripts'])
  gulp.watch('app/index.html', ['html'])
  gulp.watch(paths.fonts, ['fonts'])
  gulp.watch(paths.less, ['less'])
})

gulp.task('serve', ['watch'], function() {
  gulp.src('dist')
    .pipe(server({
      livereload: true,
      open: true,
      proxies: [{
        source: '/rpc',
        target: 'http://localhost:9001/rpc'
      }]
    }))
})

gulp.task('lint', function () {
  return gulp.src(paths.reactScripts)
  // eslint() attaches the lint output to the eslint property
  // of the file object so it can be used by other modules.
    .pipe(eslint())
  // eslint.format() outputs the lint results to the console.
  // Alternatively use eslint.formatEach() (see Docs).
    .pipe(eslint.format())
  // To have the process exit with an error code (1) on
  // lint error, return the stream and pipe to failOnError last.
    .pipe(eslint.failOnError());
});

gulp.task('scripts', ['react-scripts', 'other-scripts'])

gulp.task('build', ['less', 'fonts', 'html', 'scripts', 'lint'])

gulp.task('default', ['build'])
<commit_msg>Add jquery before bootstrap to resolve dependency issues<commit_after>/*
 * Minio Cloud Storage, (C) 2015 Minio, Inc.
 *
 * Licensed 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.
 */

var gulp = require('gulp');
var del = require('del');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var less = require('gulp-less');
var uglify = require('gulp-uglify');
var streamify = require('gulp-streamify');
var rename = require('gulp-rename');
var minifycss = require('gulp-minify-css');
var concat = require('gulp-concat');
var server = require('gulp-webserver');
var eslint = require('gulp-eslint');

var paths = {
  reactScripts : ['app/scripts/minio/*', 'app/scripts/minio/**/*'],
  otherScripts : ['app/scripts/extern/*'],
  fonts : 'app/fonts/**/*',
  less : ['app/styles/*.less', 'app/styles/**/*.less']
}

gulp.task('clean', function() {
  return del(['dist']);
});

gulp.task('less', function () {
  return gulp.src('./app/styles/app.less') //path to your main less file
    .pipe(less())
    .pipe(minifycss())
    .pipe(rename('app.min.css'))
    .pipe(gulp.dest('dist'))
});

gulp.task('fonts', function() {
  return gulp.src(paths.fonts, {base:"app"})
    .pipe(gulp.dest('dist'))
})

gulp.task('html', function() {
  return gulp.src('app/index.html')
    .pipe(gulp.dest('dist'))
})

gulp.task('react-scripts', function() {
  return browserify({entries: './app/scripts/minio/app.js', extensions: ['.jsx']}).transform('reactify')
    .bundle()
    .pipe(source('app.min.js'))
    .pipe(streamify(uglify()))
    .pipe(gulp.dest('dist'))
})

gulp.task('other-scripts', function() {
  return gulp.src([
    'app/scripts/extern/jquery.js',
    'app/scripts/extern/bootstrap.js',
    'app/scripts/extern/jsonrpc.js',
  ])
    .pipe(concat('extern.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist'))
})

gulp.task('watch', ['build'], function() {
  gulp.watch(paths.reactScripts, ['react-scripts'])
  gulp.watch(paths.otherScripts, ['other-scripts'])
  gulp.watch('app/index.html', ['html'])
  gulp.watch(paths.fonts, ['fonts'])
  gulp.watch(paths.less, ['less'])
})

gulp.task('serve', ['watch'], function() {
  gulp.src('dist')
    .pipe(server({
      livereload: true,
      open: true,
      proxies: [{
        source: '/rpc',
        target: 'http://localhost:9001/rpc'
      }]
    }))
})

gulp.task('lint', function () {
  return gulp.src(paths.reactScripts)
  // eslint() attaches the lint output to the eslint property
  // of the file object so it can be used by other modules.
    .pipe(eslint())
  // eslint.format() outputs the lint results to the console.
  // Alternatively use eslint.formatEach() (see Docs).
    .pipe(eslint.format())
  // To have the process exit with an error code (1) on
  // lint error, return the stream and pipe to failOnError last.
    .pipe(eslint.failOnError());
});

gulp.task('scripts', ['react-scripts', 'other-scripts'])

gulp.task('build', ['less', 'fonts', 'html', 'scripts', 'lint'])

gulp.task('default', ['build'])
<|endoftext|>