<commit_before>var concat = require('gulp-concat');
var gulp = require('gulp');
var changed = require('gulp-changed');
var glob = require('glob');
var path = require('path');
var browserify  = require('browserify');
var source = require('vinyl-source-stream');
var map = require('vinyl-map');
var exorcist = require('exorcist');
var sourcemaps = require('gulp-sourcemaps');

var typescript = require('gulp-typescript');

gulp.task('compile', function() {
    var tsProject = typescript.createProject({
        declarationFiles: true,
        noExternalResolve: true,
        target: 'ES5',
        module: 'commonjs',
        sourceRoot: './awayjs-stagegl/lib'
    });

    var ambientWrap = map(function(code, filename) {
        code = code.toString();
        code = 'declare module "' + path.relative('../', filename.slice(0,-5)) + '" {\n\t'
        + code.split('declare ').join('').split('\n').join('\n\t') + "\n"
        + '}';
        return code;
    });

    var tsResult = gulp.src(['./lib/**/*.ts', './node_modules/awayjs-**/build/*.d.ts'])
        .pipe(sourcemaps.init())
        .pipe(typescript(tsProject));

    tsResult.dts
        .pipe(ambientWrap)
        .pipe(concat('awayjs-stagegl.d.ts'))
        .pipe(gulp.dest('./build'));

    return tsResult.js
        .pipe(sourcemaps.write({sourceRoot: '../'}))
        .pipe(gulp.dest('./lib'));
});

gulp.task('watch', ['package'], function() {
    gulp.watch('./lib/**/*.ts', ['package']);
});

gulp.task('package', ['compile'], function(callback){
    var b = browserify({
        debug: true,
        paths: ['../']
    });

    glob('./node_modules/awayjs-**/lib/**/*.js', {}, function (error, files) {
        files.forEach(function (file) {
            b.external(file);
        });
    });

    glob('./lib/**/*.js', {}, function (error, files) {

        files.forEach(function (file) {
            b.require(file, {expose:path.relative('../', file.slice(0,-3))});
        });

        b.bundle()
            .pipe(exorcist('./build/awayjs-stagegl.js.map'))
            .pipe(source('awayjs-stagegl.js'))
            .pipe(gulp.dest('./build'))
            .on('end', callback);
    });
});

gulp.task('tests', function () {

    var tsProject = typescript.createProject({
        declarationFiles: true,
        noExternalResolve: true,
        target: 'ES5',
        module: 'commonjs',
        sourceRoot: './'
    });

    var tsResult = gulp.src(['./tests/**/*.ts', './node_modules/awayjs-**/build/*.d.ts', './build/awayjs-stagegl.d.ts'])
        //.pipe(changed('./tests', {extension:'.js', hasChanged: changed.compareLastModifiedTime}))
        .pipe(sourcemaps.init())
        .pipe(typescript(tsProject));

    return tsResult.js
        .pipe(sourcemaps.write({sourceRoot: './tests'}))
        .pipe(gulp.dest('./tests'));
});<commit_msg>updated gulpfile for minified builds<commit_after>var concat = require('gulp-concat');
var gulp = require('gulp');
var changed = require('gulp-changed');
var glob = require('glob');
var path = require('path');
var browserify  = require('browserify');
var source = require('vinyl-source-stream');
var map = require('vinyl-map');
var exorcist = require('exorcist');
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

var typescript = require('gulp-typescript');

gulp.task('compile', function() {
    var tsProject = typescript.createProject({
        declarationFiles: true,
        noExternalResolve: true,
        target: 'ES5',
        module: 'commonjs',
        sourceRoot: './awayjs-stagegl/lib'
    });

    var ambientWrap = map(function(code, filename) {
        code = code.toString();
        code = 'declare module "' + path.relative('../', filename.slice(0,-5)) + '" {\n\t'
        + code.split('declare ').join('').split('\n').join('\n\t') + "\n"
        + '}';
        return code;
    });

    var tsResult = gulp.src(['./lib/**/*.ts', './node_modules/awayjs-**/build/*.d.ts'])
        .pipe(sourcemaps.init())
        .pipe(typescript(tsProject));

    tsResult.dts
        .pipe(ambientWrap)
        .pipe(concat('awayjs-stagegl.d.ts'))
        .pipe(gulp.dest('./build'));

    return tsResult.js
        .pipe(sourcemaps.write({sourceRoot: '../'}))
        .pipe(gulp.dest('./lib'));
});

gulp.task('watch', ['package'], function() {
    gulp.watch('./lib/**/*.ts', ['package']);
});

gulp.task('package', ['compile'], function(callback){
    var b = browserify({
        debug: true,
        paths: ['../']
    });

    glob('./node_modules/awayjs-**/lib/**/*.js', {}, function (error, files) {
        files.forEach(function (file) {
            b.external(file);
        });
    });

    glob('./lib/**/*.js', {}, function (error, files) {

        files.forEach(function (file) {
            b.require(file, {expose:path.relative('../', file.slice(0,-3))});
        });

        b.bundle()
            .pipe(exorcist('./build/awayjs-stagegl.js.map'))
            .pipe(source('awayjs-stagegl.js'))
            .pipe(gulp.dest('./build'))
            .on('end', callback);
    });
});

gulp.task('package-min', ['package'], function(callback){
    return gulp.src('./build/awayjs-stagegl.js')
        .pipe(sourcemaps.init({loadMaps:true}))
        .pipe(uglify())
        .pipe(rename(function (path) {
            path.basename += '.min';
        }))
        .pipe(sourcemaps.write('./', {sourceRoot: './'}))
        .pipe(gulp.dest('./build'));
});

gulp.task('tests', function () {

    var tsProject = typescript.createProject({
        declarationFiles: true,
        noExternalResolve: true,
        target: 'ES5',
        module: 'commonjs',
        sourceRoot: './'
    });

    var tsResult = gulp.src(['./tests/**/*.ts', './node_modules/awayjs-**/build/*.d.ts', './build/awayjs-stagegl.d.ts'])
        //.pipe(changed('./tests', {extension:'.js', hasChanged: changed.compareLastModifiedTime}))
        .pipe(sourcemaps.init())
        .pipe(typescript(tsProject));

    return tsResult.js
        .pipe(sourcemaps.write({sourceRoot: './tests'}))
        .pipe(gulp.dest('./tests'));
});<|endoftext|>


<commit_before>'use strict';

// Note that the SDK (which holds these constants) is a TS lib, so we can't
// require it in this CJS file.
const MERCHANT_PAYMENT_UNIVERSAL_LINK_HOSTNAME = 'ssr-wallet.cardstack.com';
const MERCHANT_PAYMENT_UNIVERSAL_LINK_STAGING_HOSTNAME =
  'ssr-wallet-staging.stack.cards';

const universalLinkHostnamesByTarget = {
  staging: MERCHANT_PAYMENT_UNIVERSAL_LINK_STAGING_HOSTNAME,
  production: MERCHANT_PAYMENT_UNIVERSAL_LINK_HOSTNAME,
};

const pkg = require('../package.json');

// eslint-disable-next-line no-undef
module.exports = function (environment) {
  let ENV = {
    modulePrefix: '@cardstack/ssr-web',
    environment,
    rootURL: '/',
    locationType: 'auto',
    hubURL: process.env.HUB_URL,
    universalLinkDomain:
      universalLinkHostnamesByTarget[process.env.SSR_WEB_ENVIRONMENT] ??
      MERCHANT_PAYMENT_UNIVERSAL_LINK_STAGING_HOSTNAME,
    version: pkg.version,
    sentryDsn: process.env.SENTRY_DSN,
    '@sentry/ember': {
      sentry: {
        dsn: process.env.SENTRY_DSN,
        // debug: true, // uncomment this to get helpful logs about sentry's behavior
        enabled:
          environment === 'production' && process.env.SENTRY_DSN !== undefined,
        environment: process.env.SENTRY_ENVIRONMENT || 'staging',
        release:
          `ssr-web${
            process.env.GITHUB_SHA ? `-${process.env.GITHUB_SHA}` : ''
          }@` + pkg.version,
        // Set tracesSampleRate to 1.0 to capture 100%
        // of transactions for performance monitoring.
        // We recommend adjusting this value in production,
        tracesSampleRate: 1.0,
      },
    },
    pageTitle: {
      separator: ' · ',
    },
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
      },
      EXTEND_PROTOTYPES: {
        // Prevent Ember Data from overriding Date.parse.
        Date: false,
      },
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    },
    urls: {
      about: 'https://cardstack.com/cardpay',
      appStoreLink:
        'https://apps.apple.com/us/app/card-wallet-by-cardstack/id1549183378',
      googlePlayLink:
        'https://play.google.com/store/apps/details?id=com.cardstack.cardpay',
      mailToSupportUrl: 'mailto:support@cardstack.com',
      statusPageBase: 'https://status.cardstack.com',
      statusPageUrl: 'https://status.cardstack.com/api/v2/summary.json',
    },
    'ember-cli-mirage': {
      enabled: false,
    },
  };

  if (environment === 'development') {
    // ENV.APP.LOG_RESOLVER = true;
    // ENV.APP.LOG_ACTIVE_GENERATION = true;
    // ENV.APP.LOG_TRANSITIONS = true;
    // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
    // ENV.APP.LOG_VIEW_LOOKUPS = true;
    ENV.hubURL = ENV.hubURL ?? 'http://localhost:3000';
  }

  if (environment === 'test') {
    // Testem prefers this...
    ENV.locationType = 'none';

    // thread animation interval > 0 means we might have to wait for css animations in tests
    ENV.threadAnimationInterval = 0;

    // keep test console output quieter
    ENV.APP.LOG_ACTIVE_GENERATION = false;
    ENV.APP.LOG_VIEW_LOOKUPS = false;

    ENV.APP.rootElement = '#ember-testing';
    ENV.APP.autoboot = false;

    // mock server during test
    ENV.hubURL = '';
    ENV['ember-cli-mirage'] = {
      enabled: true,
      trackRequests: true,
    };
  }

  if (environment === 'production') {
    // here you can enable a production-specific feature
  }

  return ENV;
};
<commit_msg>ssr: Fix wallet domain config (#2740)<commit_after>'use strict';

// Note that the SDK (which holds these constants) is a TS lib, so we can't
// require it in this CJS file.
const MERCHANT_PAYMENT_UNIVERSAL_LINK_HOSTNAME = 'wallet.cardstack.com';
const MERCHANT_PAYMENT_UNIVERSAL_LINK_STAGING_HOSTNAME =
  'wallet-staging.stack.cards';

const universalLinkHostnamesByTarget = {
  staging: MERCHANT_PAYMENT_UNIVERSAL_LINK_STAGING_HOSTNAME,
  production: MERCHANT_PAYMENT_UNIVERSAL_LINK_HOSTNAME,
};

const pkg = require('../package.json');

// eslint-disable-next-line no-undef
module.exports = function (environment) {
  let ENV = {
    modulePrefix: '@cardstack/ssr-web',
    environment,
    rootURL: '/',
    locationType: 'auto',
    hubURL: process.env.HUB_URL,
    universalLinkDomain:
      universalLinkHostnamesByTarget[process.env.SSR_WEB_ENVIRONMENT] ??
      MERCHANT_PAYMENT_UNIVERSAL_LINK_STAGING_HOSTNAME,
    version: pkg.version,
    sentryDsn: process.env.SENTRY_DSN,
    '@sentry/ember': {
      sentry: {
        dsn: process.env.SENTRY_DSN,
        // debug: true, // uncomment this to get helpful logs about sentry's behavior
        enabled:
          environment === 'production' && process.env.SENTRY_DSN !== undefined,
        environment: process.env.SENTRY_ENVIRONMENT || 'staging',
        release:
          `ssr-web${
            process.env.GITHUB_SHA ? `-${process.env.GITHUB_SHA}` : ''
          }@` + pkg.version,
        // Set tracesSampleRate to 1.0 to capture 100%
        // of transactions for performance monitoring.
        // We recommend adjusting this value in production,
        tracesSampleRate: 1.0,
      },
    },
    pageTitle: {
      separator: ' · ',
    },
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
      },
      EXTEND_PROTOTYPES: {
        // Prevent Ember Data from overriding Date.parse.
        Date: false,
      },
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    },
    urls: {
      about: 'https://cardstack.com/cardpay',
      appStoreLink:
        'https://apps.apple.com/us/app/card-wallet-by-cardstack/id1549183378',
      googlePlayLink:
        'https://play.google.com/store/apps/details?id=com.cardstack.cardpay',
      mailToSupportUrl: 'mailto:support@cardstack.com',
      statusPageBase: 'https://status.cardstack.com',
      statusPageUrl: 'https://status.cardstack.com/api/v2/summary.json',
    },
    'ember-cli-mirage': {
      enabled: false,
    },
  };

  if (environment === 'development') {
    // ENV.APP.LOG_RESOLVER = true;
    // ENV.APP.LOG_ACTIVE_GENERATION = true;
    // ENV.APP.LOG_TRANSITIONS = true;
    // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
    // ENV.APP.LOG_VIEW_LOOKUPS = true;
    ENV.hubURL = ENV.hubURL ?? 'http://localhost:3000';
  }

  if (environment === 'test') {
    // Testem prefers this...
    ENV.locationType = 'none';

    // thread animation interval > 0 means we might have to wait for css animations in tests
    ENV.threadAnimationInterval = 0;

    // keep test console output quieter
    ENV.APP.LOG_ACTIVE_GENERATION = false;
    ENV.APP.LOG_VIEW_LOOKUPS = false;

    ENV.APP.rootElement = '#ember-testing';
    ENV.APP.autoboot = false;

    // mock server during test
    ENV.hubURL = '';
    ENV['ember-cli-mirage'] = {
      enabled: true,
      trackRequests: true,
    };
  }

  if (environment === 'production') {
    // here you can enable a production-specific feature
  }

  return ENV;
};
<|endoftext|>


<commit_before>var gulp = require('gulp');

var less = require('gulp-less');
var cleanCss = require('gulp-clean-css');
var postCss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');

var uglifyjs = require('uglify-es');
var composer = require('gulp-uglify/composer');

var sourcemaps = require('gulp-sourcemaps');
var child = require('child_process');
var gulpUtil = require('gulp-util');

var minify = composer(uglifyjs, console);

let assetsBaseOutput = 'assets';

var minify = composer(uglifyjs, console);

gulp.task('css', function() {
  return gulp.src('_less/[^_]*.less')
    .pipe(less())
    .pipe(postCss([ autoprefixer() ]))
    .pipe(cleanCss({ skipAggressiveMerging: true }))
    .pipe(gulp.dest(assetsBaseOutput + '/style/'));
});

gulp.task('js', function() {
  return gulp.src('_js/**/*.js')
    .pipe(sourcemaps.init())
      .pipe(minify())
      .on('error', err => console.log('uglify error', err))
    .pipe(sourcemaps.write('maps'))
    .pipe(gulp.dest(assetsBaseOutput + '/scripts/'));
});

gulp.task('vega', function() {
  return gulp.src('_vg/**/*.json')
    .pipe(gulp.dest(assetsBaseOutput + '/vega/'));
});

gulp.task('images', function () {
  gulp.src('_images/**/*')
    .pipe(gulp.dest(assetsBaseOutput + '/images/'));
});

gulp.task('jekyll', function (done) {
  const jekyll = child.spawn('jekyll', ['build', '--incremental']);

  const jekyllLogger = (buffer) => {
    buffer.toString()
      .split(/\n/)
      .forEach((message) => gulpUtil.log('Jekyll: ' + message));
  };

  jekyll.stdout.on('data', jekyllLogger);
  jekyll.stderr.on('data', jekyllLogger);

  jekyll.on('close', (code) => {
    done()
  });
});

gulp.task('html-partials', function () {
  gulp.src('_html-partials/**/*.html')
    .pipe(gulp.dest(assetsBaseOutput + '/html-partials/'));
});

gulp.task('default', [ 'css', 'js', 'vega', 'images', 'jekyll', 'html-partials' ]);

gulp.task('watch', function() {
  gulp.watch('_js/**/*.js', ['js']);
  gulp.watch('_less/**/*.less', ['css']);
  gulp.watch('_vg/**/*.json', ['vega']);
  gulp.watch('_html-partials/**/*.html', ['html-partials']);
  gulp.watch('_images/**/*', ['images']);
  gulp.watch(['_config.yml', '_jekyll/**/*'], ['jekyll']);
});
<commit_msg>Move assets inside site<commit_after>var gulp = require('gulp');

var less = require('gulp-less');
var cleanCss = require('gulp-clean-css');
var postCss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');

var uglifyjs = require('uglify-es');
var composer = require('gulp-uglify/composer');

var sourcemaps = require('gulp-sourcemaps');
var child = require('child_process');
var gulpUtil = require('gulp-util');

var minify = composer(uglifyjs, console);

let assetsBaseOutput = 'site/assets';

var minify = composer(uglifyjs, console);

gulp.task('css', function() {
  return gulp.src('_less/[^_]*.less')
    .pipe(less())
    .pipe(postCss([ autoprefixer() ]))
    .pipe(cleanCss({ skipAggressiveMerging: true }))
    .pipe(gulp.dest(assetsBaseOutput + '/style/'));
});

gulp.task('js', function() {
  return gulp.src('_js/**/*.js')
    .pipe(sourcemaps.init())
      .pipe(minify())
      .on('error', err => console.log('uglify error', err))
    .pipe(sourcemaps.write('maps'))
    .pipe(gulp.dest(assetsBaseOutput + '/scripts/'));
});

gulp.task('vega', function() {
  return gulp.src('_vg/**/*.json')
    .pipe(gulp.dest(assetsBaseOutput + '/vega/'));
});

gulp.task('images', function () {
  gulp.src('_images/**/*')
    .pipe(gulp.dest(assetsBaseOutput + '/images/'));
});

gulp.task('jekyll', function (done) {
  const jekyll = child.spawn('jekyll', ['build', '--incremental']);

  const jekyllLogger = (buffer) => {
    buffer.toString()
      .split(/\n/)
      .forEach((message) => gulpUtil.log('Jekyll: ' + message));
  };

  jekyll.stdout.on('data', jekyllLogger);
  jekyll.stderr.on('data', jekyllLogger);

  jekyll.on('close', (code) => {
    done()
  });
});

gulp.task('html-partials', function () {
  gulp.src('_html-partials/**/*.html')
    .pipe(gulp.dest(assetsBaseOutput + '/html-partials/'));
});

gulp.task('default', [ 'css', 'js', 'vega', 'images', 'jekyll', 'html-partials' ]);

gulp.task('watch', function() {
  gulp.watch('_js/**/*.js', ['js']);
  gulp.watch('_less/**/*.less', ['css']);
  gulp.watch('_vg/**/*.json', ['vega']);
  gulp.watch('_html-partials/**/*.html', ['html-partials']);
  gulp.watch('_images/**/*', ['images']);
  gulp.watch(['_config.yml', '_jekyll/**/*'], ['jekyll']);
});
<|endoftext|>


<commit_before>(function (window, $, ch) {
	'use strict';

	if (window.ch === undefined) {
		throw new window.Error('Expected ch namespace defined.');
	}

	/**
	 * Expandable lets you show or hide the container. Expandable needs a pair: the title and the container related to that title.
	 * @constructor
	 * @memberOf ch
	 * @augments ch.Navs
	 * @param {Object} [options] Object with configuration properties.
	 * @param {Boolean} [options.open] Shows the expandable open when component was loaded. By default, the value is false.
	 * @param {Boolean} [options.fx] Enable or disable UI effects. By default, the effects are disable.
	 * @returns {Object}
	 * @exampleDescription Create a new expandable without configuration.
	 * @example
	 * var widget = $('.example').expandable();
	 * @exampleDescription Create a new expandable with configuration.
	 * @example
	 * var widget = $('.example').expandable({
	 *     'open': true,
	 *     'fx': true
	 * });
	 */
	function Expandable($el, options) {

		this.init($el, options);

		/**
		 * Reference to a internal component instance, saves all the information and configuration properties.
		 * @private
		 * @type {Object}
		 */
		var that = this;

		/**
		 * Triggers when the component is ready to use (Since 0.8.0).
		 * @fires ch.Expandable#ready
		 * @since 0.8.0
		 * @exampleDescription Following the first example, using widget as expandable's instance controller:
		 * @example
		 * widget.on('ready',function () {
		 *	this.show();
		 * });
		 */
		window.setTimeout(function () { that.emit('ready'); }, 50);
	}

	/**
	 * Private
	 */
	var $html = $('html'),

		/**
		 * Inheritance
		 */
		parent = ch.util.inherits(Expandable, ch.Widget);

	/**
	 * Prototype
	 */
	Expandable.prototype.name = 'expandable';

	Expandable.prototype.constructor = Expandable;

	Expandable.prototype.defaults = {
		'open': false,
		'fx': false
	};

	Expandable.prototype.init = function ($el, options) {
		parent.init.call(this, $el, options);
<<<<<<>>>>>> chicollinares/v1.0
		this.require('Collapsible', 'Content');

		/**
		 * Private Members
		 */

		/**
		 * Reference to a internal component instance, saves all the information and configuration properties.
		 * @private
		 * @type {Object}
		 */
		var that = this,

			/**
			 * Map that contains the ARIA attributes for the trigger element
			 * @private
			 * @type {Object}
			 */
			triggerAttr = {
				'aria-expanded': that.options.open,
				'aria-controls': 'ch-expandable-' + that.uid
			},

			/**
			 * Map that contains the ARIA attributes for the container element
			 * @private
			 * @type {Object}
			 */
			containerAttr = {
				'id': triggerAttr['aria-controls'],
				'aria-hidden': !triggerAttr['aria-expanded']
			};

		/**
		 * Protected Members
		 */

		 /**
		  * Status of component
		  * @protected
		  * @type {Boolean}
		  * @ignore
		  */
		 that.active = this.options.open;

		/**
		 * The component's trigger.
		 * @protected
		 * @type {Selector}
		 * @ignore
		 */
		that.$trigger = that.$el.children(':first-child');

		/**
		 * The component's container.
		 * @protected
		 * @type {Selector}
		 * @ignore
		 */
		that.$container = that.$el.children(':last-child').wrapInner('
');

		/**
		 * The component's content.
		 * @protected
		 * @type {Selector}
		 * @ignore
		 */
		that.$content = that.$container.children(':last-child');

		/**
		 * Default behavior
		 */
		that.$el.addClass('ch-expandable');

		that.$trigger
			.attr(triggerAttr)
			.addClass('ch-expandable-trigger')
			.on('click.expandable', function (event) {
				event.preventDefault();
				that.show();
			})
			.children()
				.attr('role', 'presentation');

		that.$container
			.attr(containerAttr)
			.addClass('ch-expandable-container ch-hide');

		that.content.onmessage = function (data) {
			that.$content.html(data);
		};

		// Icon configuration
		if ($html.hasClass('lt-ie8')) {
			$('Drop').appendTo(this.$trigger);
		} else {
			this.$trigger.addClass('ch-expandable-ico');
		}

		if (this.options.open) {
			this.show();
		}

		ch.util.avoidTextSelection(that.$trigger);

	};

	Expandable.prototype.show = function () {
		if (this.active) {
			return this.hide();
		}

		this.collapsible.show();

		return this;
	};

	Expandable.prototype.hide = function () {
		if (!this.active) {
			return;
		}

		this.collapsible.hide();

		return this;
	};

	/**
	 * Returns a Boolean if the component's core behavior is active. That means it will return 'true' if the component is on and it will return false otherwise.
	 * @name isActive
	 * @methodOf ch.Expandable#isActive
	 * @returns {boolean}
	 * @exampleDescription
	 * @example
	 * if (widget.isActive()) {
	 *     fn();
	 * }
	 */
	Expandable.prototype.isActive = function () {
		return this.active;
	};

	ch.factory(Expandable);

	$.fn.expando = $.fn.expandable;

}(this, this.jQuery, this.ch));<commit_msg>Fix merge<commit_after>(function (window, $, ch) {
	'use strict';

	if (window.ch === undefined) {
		throw new window.Error('Expected ch namespace defined.');
	}

	/**
	 * Expandable lets you show or hide the container. Expandable needs a pair: the title and the container related to that title.
	 * @constructor
	 * @memberOf ch
	 * @augments ch.Navs
	 * @param {Object} [options] Object with configuration properties.
	 * @param {Boolean} [options.open] Shows the expandable open when component was loaded. By default, the value is false.
	 * @param {Boolean} [options.fx] Enable or disable UI effects. By default, the effects are disable.
	 * @returns {Object}
	 * @exampleDescription Create a new expandable without configuration.
	 * @example
	 * var widget = $('.example').expandable();
	 * @exampleDescription Create a new expandable with configuration.
	 * @example
	 * var widget = $('.example').expandable({
	 *     'open': true,
	 *     'fx': true
	 * });
	 */
	function Expandable($el, options) {

		this.init($el, options);

		/**
		 * Reference to a internal component instance, saves all the information and configuration properties.
		 * @private
		 * @type {Object}
		 */
		var that = this;

		/**
		 * Triggers when the component is ready to use (Since 0.8.0).
		 * @fires ch.Expandable#ready
		 * @since 0.8.0
		 * @exampleDescription Following the first example, using widget as expandable's instance controller:
		 * @example
		 * widget.on('ready',function () {
		 *	this.show();
		 * });
		 */
		window.setTimeout(function () { that.emit('ready'); }, 50);
	}

	/**
	 * Private
	 */
	var $html = $('html'),

		/**
		 * Inheritance
		 */
		parent = ch.util.inherits(Expandable, ch.Widget);

	/**
	 * Prototype
	 */
	Expandable.prototype.name = 'expandable';

	Expandable.prototype.constructor = Expandable;

	Expandable.prototype.defaults = {
		'open': false,
		'fx': false
	};

	Expandable.prototype.init = function ($el, options) {
		parent.init.call(this, $el, options);

		this.require('Collapsible', 'Content');

		/**
		 * Private Members
		 */

		/**
		 * Reference to a internal component instance, saves all the information and configuration properties.
		 * @private
		 * @type {Object}
		 */
		var that = this,

			/**
			 * Map that contains the ARIA attributes for the trigger element
			 * @private
			 * @type {Object}
			 */
			triggerAttr = {
				'aria-expanded': that.options.open,
				'aria-controls': 'ch-expandable-' + that.uid
			},

			/**
			 * Map that contains the ARIA attributes for the container element
			 * @private
			 * @type {Object}
			 */
			containerAttr = {
				'id': triggerAttr['aria-controls'],
				'aria-hidden': !triggerAttr['aria-expanded']
			};

		/**
		 * Protected Members
		 */

		 /**
		  * Status of component
		  * @protected
		  * @type {Boolean}
		  * @ignore
		  */
		 that.active = this.options.open;

		/**
		 * The component's trigger.
		 * @protected
		 * @type {Selector}
		 * @ignore
		 */
		that.$trigger = that.$el.children(':first-child');

		/**
		 * The component's container.
		 * @protected
		 * @type {Selector}
		 * @ignore
		 */
		that.$container = that.$el.children(':last-child').wrapInner('
');

		/**
		 * The component's content.
		 * @protected
		 * @type {Selector}
		 * @ignore
		 */
		that.$content = that.$container.children(':last-child');

		/**
		 * Default behavior
		 */
		that.$el.addClass('ch-expandable');

		that.$trigger
			.attr(triggerAttr)
			.addClass('ch-expandable-trigger')
			.on('click.expandable', function (event) {
				event.preventDefault();
				that.show();
			})
			.children()
				.attr('role', 'presentation');

		that.$container
			.attr(containerAttr)
			.addClass('ch-expandable-container ch-hide');

		that.content.onmessage = function (data) {
			that.$content.html(data);
		};

		// Icon configuration
		if ($html.hasClass('lt-ie8')) {
			$('Drop').appendTo(this.$trigger);
		} else {
			this.$trigger.addClass('ch-expandable-ico');
		}

		if (this.options.open) {
			this.show();
		}

		ch.util.avoidTextSelection(that.$trigger);

	};

	Expandable.prototype.show = function () {
		if (this.active) {
			return this.hide();
		}

		this.collapsible.show();

		return this;
	};

	Expandable.prototype.hide = function () {
		if (!this.active) {
			return;
		}

		this.collapsible.hide();

		return this;
	};

	/**
	 * Returns a Boolean if the component's core behavior is active. That means it will return 'true' if the component is on and it will return false otherwise.
	 * @name isActive
	 * @methodOf ch.Expandable#isActive
	 * @returns {boolean}
	 * @exampleDescription
	 * @example
	 * if (widget.isActive()) {
	 *     fn();
	 * }
	 */
	Expandable.prototype.isActive = function () {
		return this.active;
	};

	ch.factory(Expandable);

	$.fn.expando = $.fn.expandable;

}(this, this.jQuery, this.ch));<|endoftext|>


<commit_before>import cx from 'classnames';
import { ScreenEdge, useDockWindow, useOptions } from 'openfin-react-hooks';
import React, { useEffect, useState } from 'react';
import Components from 'stockflux-components';
import { OpenfinApiHelpers } from 'stockflux-core';
import './App.css';
import FreeTextSearch from './free-text-search/FreeTextSearch';
import getUndockedPosition from './helpers/getUndockedPosition';
import { ReactComponent as LeftIcon } from './icons/left.svg';
import { ReactComponent as RightIcon } from './icons/right.svg';
import { ReactComponent as TopIcon } from './icons/top.svg';
import Watchlist from './app-shortcuts/Watchlist';
import ToolBar from './toolbar/ToolBar';

export default () => {
  const [options] = useOptions();
  const defaultHeight = options ? options.defaultHeight : 75;
  const defaultWidth = options ? options.defaultWidth : 50;
  const isDockable = options ? options.customData.isDockable : false;
  const [undockPosition, setUndockPosition] = useState({ left: 0, top: 0 });
  const [isHorizontal, setHorizontal] = useState(true);
  const [edge, windowActions] = useDockWindow(
    ScreenEdge.TOP,
    OpenfinApiHelpers.getCurrentWindowSync(),
    true,
    {
      dockedWidth: isHorizontal ? defaultWidth : 80,
      dockedHeight: defaultHeight
    },
    {
      undockPosition: { left: undockPosition.left, top: undockPosition.top },
      undockSize: { width: 724, height: 88 }
    }
  );

  const iconStyle = `icon ${isHorizontal ? 'horizontal' : 'vertical'}`;
  const toolbarStyle = isHorizontal ? 'toolbar' : 'toolbar t-vertical';
  const title = isHorizontal ? (

      Stock
      Flux

  ) : (
    ''
  );

  /* Hook undock if initialDocked is false on start */
  useEffect(() => {
    if (
      options &&
      options.customData &&
      options.customData.initialDocked === false
    ) {
      windowActions.dockNone();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [options]);

  /* Make sure window shrinks when dragged from top */
  useEffect(() => {
    if (edge === ScreenEdge.NONE) {
      getUndockedPosition().then(position => {
        setUndockPosition({ left: position.left, top: position.top });

        windowActions.dockNone();
      });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [edge]);

  useEffect(() => {
    setHorizontal([ScreenEdge.TOP, ScreenEdge.NONE].includes(edge));
  }, [edge]);

  return (

        <Components.Titlebar title={title} dockedTo={edge} />

        {!isHorizontal && (

            S
            F

        )}

          <Watchlist symbol="TSLA" name="Tesla" />

        <FreeTextSearch dockedTo={edge} />

        <ToolBar
          style={toolbarStyle}
          tools={[
            {
              className: 'icon',
              label: <LeftIcon />,
              onClick: windowActions.dockLeft,
              disabled: edge === ScreenEdge.LEFT,
              visible: isDockable
            },
            {
              className: 'icon',
              label: <TopIcon />,
              onClick: windowActions.dockTop,
              disabled: edge === ScreenEdge.TOP,
              visible: isDockable
            },
            {
              className: 'icon',
              label: <RightIcon />,
              onClick: windowActions.dockRight,
              disabled: edge === ScreenEdge.RIGHT,
              visible: isDockable
            }
          ]}
        />

  );
};
<commit_msg>Add confirmClose prop to titlebar to make sure message shows<commit_after>import cx from 'classnames';
import { ScreenEdge, useDockWindow, useOptions } from 'openfin-react-hooks';
import React, { useEffect, useState } from 'react';
import Components from 'stockflux-components';
import { OpenfinApiHelpers } from 'stockflux-core';
import './App.css';
import FreeTextSearch from './free-text-search/FreeTextSearch';
import getUndockedPosition from './helpers/getUndockedPosition';
import { ReactComponent as LeftIcon } from './icons/left.svg';
import { ReactComponent as RightIcon } from './icons/right.svg';
import { ReactComponent as TopIcon } from './icons/top.svg';
import Watchlist from './app-shortcuts/Watchlist';
import ToolBar from './toolbar/ToolBar';

export default () => {
  const [options] = useOptions();
  const defaultHeight = options ? options.defaultHeight : 75;
  const defaultWidth = options ? options.defaultWidth : 50;
  const isDockable = options ? options.customData.isDockable : false;
  const [undockPosition, setUndockPosition] = useState({ left: 0, top: 0 });
  const [isHorizontal, setHorizontal] = useState(true);
  const [edge, windowActions] = useDockWindow(
    ScreenEdge.TOP,
    OpenfinApiHelpers.getCurrentWindowSync(),
    true,
    {
      dockedWidth: isHorizontal ? defaultWidth : 80,
      dockedHeight: defaultHeight
    },
    {
      undockPosition: { left: undockPosition.left, top: undockPosition.top },
      undockSize: { width: 724, height: 88 }
    }
  );

  const iconStyle = `icon ${isHorizontal ? 'horizontal' : 'vertical'}`;
  const toolbarStyle = isHorizontal ? 'toolbar' : 'toolbar t-vertical';
  const title = isHorizontal ? (

      Stock
      Flux

  ) : (
    ''
  );

  /* Hook undock if initialDocked is false on start */
  useEffect(() => {
    if (
      options &&
      options.customData &&
      options.customData.initialDocked === false
    ) {
      windowActions.dockNone();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [options]);

  /* Make sure window shrinks when dragged from top */
  useEffect(() => {
    if (edge === ScreenEdge.NONE) {
      getUndockedPosition().then(position => {
        setUndockPosition({ left: position.left, top: position.top });

        windowActions.dockNone();
      });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [edge]);

  useEffect(() => {
    setHorizontal([ScreenEdge.TOP, ScreenEdge.NONE].includes(edge));
  }, [edge]);

  return (

        <Components.Titlebar title={title} confirmClose={true} />

        {!isHorizontal && (

            S
            F

        )}

          <Watchlist symbol="TSLA" name="Tesla" />

        <FreeTextSearch dockedTo={edge} />

        <ToolBar
          style={toolbarStyle}
          tools={[
            {
              className: 'icon',
              label: <LeftIcon />,
              onClick: windowActions.dockLeft,
              disabled: edge === ScreenEdge.LEFT,
              visible: isDockable
            },
            {
              className: 'icon',
              label: <TopIcon />,
              onClick: windowActions.dockTop,
              disabled: edge === ScreenEdge.TOP,
              visible: isDockable
            },
            {
              className: 'icon',
              label: <RightIcon />,
              onClick: windowActions.dockRight,
              disabled: edge === ScreenEdge.RIGHT,
              visible: isDockable
            }
          ]}
        />

  );
};
<|endoftext|>


<commit_before>// Use '[[' and ']]' tags since Django using Mustache's default template tags.
Mustache.tags = ['[[', ']]'];

$(function(){
  var swiper = new Swiper('.swiper-container', {
    loop : true,
    pagination: '.swiper-pagination',
    nextButton: '.swiper-button-next',
    prevButton: '.swiper-button-prev',
    slidesPerView: 'auto',
    centeredSlides: true,
    paginationClickable: true,
    spaceBetween: 30
  });
  $('#top-tabs').tabs({
    selected: 0
  });
});

(function (window) {
  var $ = window.jQuery;
  var moment = window.moment;

  $('.dropdown-toggle').dropdown();

  $(function () {
    webshim.activeLang('ja');
    $.webshims.setOptions('extendNative', true);
    $.webshims.polyfill('forms');
  });

  moment.locale('ja', {week: {dow: 1}});

  var DateFormat = 'YYYY-MM-DD';
  $(function () {
    $('#searchform-date').datetimepicker({
      inline: true,
      locale: moment.locale('ja'),
      format: DateFormat
    });

    $('#result-number').change(function() {
      var url = window.location.href;
      var num = this.value;
      var regex = /\b(numperpage=)[^&]*/;
      var newUrl;
      if (regex.test(url)) {
        newUrl = url.replace(regex, '$1' + num);
      } else {
        newUrl = url + "&numperpage=" + num;
      }
      window.location.replace(newUrl);
    });
  });
})(this);

/**
 * bootstrap-confirmation2
 */
(function (global) {
  global.jQuery(function ($) {
    $('[data-toggle=confirmation]').confirmation({
      rootSelector: '[data-toggle=confirmation]',
      title: '本当によろしいですか？',
      btnOkLabel: 'はい',
      btnCancelLabel: 'いいえ'
    });
  });
})(this);

/**
 * croppie-upload - use croppie.js to crop uploaded images
 */
(function (global) {
  var $ = global.jQuery;
  var Blob = global.Blob;
  var alert = global.alert;
  var FileReader = global.FileReader;
  var FormData = global.FormData;

  var base64ToBlob = function (src) {
    var chunkSize = 1024;

    var srcList = src.split(/[:;,]/);
    var mime = srcList[1];
    var byteChars = global.atob(srcList[3]);
    var byteArrays = [];

    for (var c = 0, len = byteChars.length; c < len; c += chunkSize) {
      var slice = byteChars.slice(c, c + chunkSize);
      var byteNumbers = new Array(slice.length);
      for (var i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      var byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }

    return new Blob(byteArrays, {type: mime});
  };

  $.fn.extend({
    croppieUpload: function (opt) {
      var self = this;
      var div;

      // read file
      self.on('change', function () {
        $('.croppie-upload-ready').remove();

        div = $('<div>')
          .addClass('croppie-upload-ready')
          .croppie(
            $.extend({
              enableExif: true,
              viewport: {
                width: 200,
                height: 200,
                type: 'square'
              },
              boundary: {
                width: 300,
                height: 300
              }
            }, opt)
          );

        if (!this.files || !this.files[0]) {
          alert("Sorry - your browser doesn't support the FileReader API");
          return false;
        }

        var reader = new FileReader();
        reader.onload = function (e) {
          div.croppie('bind', {
            url: e.target.result
          });
        };
        reader.readAsDataURL(this.files[0]);
        self.after(div);
      });

      self.closest('form').submit(function () {
        var form = $(this);
        var formData = new FormData(form.get(0));
        var name = self.attr('name');

        div
          .croppie('result', {
            type: 'canvas',
            size: 'viewport'
          })
          .then(function (resp) {
            formData.append(name, base64ToBlob(resp), 'cropped');
            $.ajax({
              cache: true,
              async: false,
              url: form.attr('action'),
              type: form.attr('method'),
              cache: false,
              processData: false,
              contentType: false,
              data: formData
            })
            .done(function () {
              global.location.reload();
            });
          });

        return false;
      });
    }
  });
})(this);
<commit_msg>hide swiper if events count is 0<commit_after>// Use '[[' and ']]' tags since Django using Mustache's default template tags.
Mustache.tags = ['[[', ']]'];

$(function(){
  var count = $('.swiper-container .swiper-slide').length;
  if (count > 0) {
    var swiper = new Swiper('.swiper-container', {
      loop : true,
      pagination: '.swiper-pagination',
      nextButton: '.swiper-button-next',
      prevButton: '.swiper-button-prev',
      slidesPerView: 'auto',
      centeredSlides: true,
      paginationClickable: true,
      spaceBetween: 30
    });
  } else {
    $('.swiper-container').hide();
  }
  $('#top-tabs').tabs({
    selected: 0
  });
});

(function (window) {
  var $ = window.jQuery;
  var moment = window.moment;

  $('.dropdown-toggle').dropdown();

  $(function () {
    webshim.activeLang('ja');
    $.webshims.setOptions('extendNative', true);
    $.webshims.polyfill('forms');
  });

  moment.locale('ja', {week: {dow: 1}});

  var DateFormat = 'YYYY-MM-DD';
  $(function () {
    $('#searchform-date').datetimepicker({
      inline: true,
      locale: moment.locale('ja'),
      format: DateFormat
    });

    $('#result-number').change(function() {
      var url = window.location.href;
      var num = this.value;
      var regex = /\b(numperpage=)[^&]*/;
      var newUrl;
      if (regex.test(url)) {
        newUrl = url.replace(regex, '$1' + num);
      } else {
        newUrl = url + "&numperpage=" + num;
      }
      window.location.replace(newUrl);
    });
  });
})(this);

/**
 * bootstrap-confirmation2
 */
(function (global) {
  global.jQuery(function ($) {
    $('[data-toggle=confirmation]').confirmation({
      rootSelector: '[data-toggle=confirmation]',
      title: '本当によろしいですか？',
      btnOkLabel: 'はい',
      btnCancelLabel: 'いいえ'
    });
  });
})(this);

/**
 * croppie-upload - use croppie.js to crop uploaded images
 */
(function (global) {
  var $ = global.jQuery;
  var Blob = global.Blob;
  var alert = global.alert;
  var FileReader = global.FileReader;
  var FormData = global.FormData;

  var base64ToBlob = function (src) {
    var chunkSize = 1024;

    var srcList = src.split(/[:;,]/);
    var mime = srcList[1];
    var byteChars = global.atob(srcList[3]);
    var byteArrays = [];

    for (var c = 0, len = byteChars.length; c < len; c += chunkSize) {
      var slice = byteChars.slice(c, c + chunkSize);
      var byteNumbers = new Array(slice.length);
      for (var i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      var byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }

    return new Blob(byteArrays, {type: mime});
  };

  $.fn.extend({
    croppieUpload: function (opt) {
      var self = this;
      var div;

      // read file
      self.on('change', function () {
        $('.croppie-upload-ready').remove();

        div = $('<div>')
          .addClass('croppie-upload-ready')
          .croppie(
            $.extend({
              enableExif: true,
              viewport: {
                width: 200,
                height: 200,
                type: 'square'
              },
              boundary: {
                width: 300,
                height: 300
              }
            }, opt)
          );

        if (!this.files || !this.files[0]) {
          alert("Sorry - your browser doesn't support the FileReader API");
          return false;
        }

        var reader = new FileReader();
        reader.onload = function (e) {
          div.croppie('bind', {
            url: e.target.result
          });
        };
        reader.readAsDataURL(this.files[0]);
        self.after(div);
      });

      self.closest('form').submit(function () {
        var form = $(this);
        var formData = new FormData(form.get(0));
        var name = self.attr('name');

        div
          .croppie('result', {
            type: 'canvas',
            size: 'viewport'
          })
          .then(function (resp) {
            formData.append(name, base64ToBlob(resp), 'cropped');
            $.ajax({
              cache: true,
              async: false,
              url: form.attr('action'),
              type: form.attr('method'),
              cache: false,
              processData: false,
              contentType: false,
              data: formData
            })
            .done(function () {
              global.location.reload();
            });
          });

        return false;
      });
    }
  });
})(this);
<|endoftext|>


<commit_before>var gulp = require('gulp');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var nodemon = require('gulp-nodemon');
var watch = require('gulp-watch');
var rename = require('gulp-rename');
var karma = require('gulp-karma');
var mocha = require('gulp-mocha');
var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant');
var shell = require('gulp-shell');

var publicDir = 'public/**/*.js';

//Backbone requires specific order for its dependencies
gulp.task('scripts', function(){
  return gulp.src(['./bower_components/jquery/dist/jquery.js',
                   './bower_components/underscore/underscore.js',
                   './bower_components/backbone/backbone.js',
                   './node_modules/socket.io-client/socket.io.js',
                   './public/client/**/*.js',
                   './public/client/app.js'])
          .pipe(concat('scripts.js'))
          .pipe(gulp.dest('./public/dist/'))
          .pipe(rename('scripts.min.js'))
          .pipe(uglify())
          .pipe(gulp.dest('./public/dist/'));
});

gulp.task('images', function () {
    return gulp.src('./public/client/img/**/*')
        .pipe(imagemin({
            progressive: true,
            svgoPlugins: [{removeViewBox: false}],
            use: [pngquant()]
        }))
        .pipe(gulp.dest('./public/client/images'));
});

gulp.task('watch-public', function(){
  gulp.watch([publicDir, '!public/dist/*.js'], ['scripts']);
});

gulp.task('develop', function(){
  gulp.start('images');
  gulp.start('scripts');
  nodemon({
    script: './server.js',
    env: { 'NODE_ENV': 'development' },
    ignore: ['public/dist/']
  }).on('start', ['watch-public']);
});

gulp.task('default', ['develop']);

gulp.task('test-server', function(){
  return gulp.src(['./test/server/server.js','./test/server/integration.js' ], {read: false})
    .pipe(mocha({reporter: 'nyan'}));
});

var testFiles = ['./test/client/unit.js', './test/client/integration.js'];

gulp.task('test-client', function() {
  return gulp.src(testFiles)
    .pipe(karma({
      configFile: 'karma.conf.js',
      reporters: ['progress', 'coverage'],
      action: 'run'
    })).on('error', function(err){ throw err; });
});

gulp.task('emojis:fetch', function(){
  return gulp.src('./server/workers/emojis/emojiWorkerSeedData.js', {read: false})
    .pipe(shell(['node <%=  file.path %>']));
});

gulp.task('emojis:download', ['emojis:fetch'], function(){
  return gulp.src('./server/workers/emojis/emojiWorkerStoreEmojisLocal.js', {read: false})
    .pipe(shell(['node <%=  file.path %>']));
});

gulp.task('seed:emojis', ['emojis:fetch', 'emojis:download']);
<commit_msg>Update gulpfile to ignore files on nodemon start<commit_after>var gulp = require('gulp');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var nodemon = require('gulp-nodemon');
var rename = require('gulp-rename');
var karma = require('gulp-karma');
var mocha = require('gulp-mocha');
var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant');
var shell = require('gulp-shell');

var publicDir = 'public/**/*.js';
var testFiles = ['./test/client/unit.js', './test/client/integration.js'];

//Backbone requires specific order for its dependencies
gulp.task('scripts', function(){
  return gulp.src(['./bower_components/jquery/dist/jquery.js',
                   './bower_components/underscore/underscore.js',
                   './bower_components/backbone/backbone.js',
                   './node_modules/socket.io-client/socket.io.js',
                   './public/client/**/*.js',
                   './public/client/app.js'])
    .pipe(concat('scripts.js'))
    .pipe(gulp.dest('./public/dist/'))
    .pipe(rename('scripts.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./public/dist/'));
});

gulp.task('images', function () {
  return gulp.src('./public/client/img/**/*')
    .pipe(imagemin({
      progressive: true,
      svgoPlugins: [{removeViewBox: false}],
      use: [pngquant()]
    }))
    .pipe(gulp.dest('./public/client/images'));
});

gulp.task('watch-public', function(){
  gulp.watch([publicDir, '!public/dist/*.js'], ['scripts']);
});

gulp.task('develop', function(){
  gulp.start('images');
  gulp.start('scripts');
  nodemon({
    script: './server.js',
    env: { 'NODE_ENV': 'development' },
    ignore: ['public/dist/', '.git', 'node_modules/**/node_modules']
  }).on('start', ['watch-public']);
});

gulp.task('default', ['develop']);

gulp.task('test-server', function(){
  return gulp.src(['./test/server/server.js','./test/server/integration.js' ], {read: false})
    .pipe(mocha({reporter: 'nyan'}));
});

gulp.task('test-client', function() {
  return gulp.src(testFiles)
    .pipe(karma({
      configFile: 'karma.conf.js',
      reporters: ['progress', 'coverage'],
      action: 'run'
    })).on('error', function(err){ throw err; });
});

gulp.task('emojis:fetch', function(){
  return gulp.src('./server/workers/emojis/emojiWorkerSeedData.js', {read: false})
    .pipe(shell(['node <%=  file.path %>']));
});

gulp.task('emojis:download', ['emojis:fetch'], function(){
  return gulp.src('./server/workers/emojis/emojiWorkerStoreEmojisLocal.js', {read: false})
    .pipe(shell(['node <%=  file.path %>']));
});

gulp.task('seed:emojis', ['emojis:fetch', 'emojis:download']);
<|endoftext|>


<commit_before>/**
 * app.js
 *
 * This is the entry file for the application, only setup and boilerplate
 * code.
 */

/* eslint-disable */
import './public-path';
import 'babel-polyfill';
/* eslint-disable no-console */
// Import all the third party stuff
import { Provider } from 'react-redux';
import React from 'react';
import ReactDOM from 'react-dom';
import { ConnectedRouter } from 'react-router-redux';
import createHistory from 'history/createBrowserHistory';
import { merge, isFunction } from 'lodash';
import 'sanitize.css/sanitize.css';
import 'whatwg-fetch';

import LanguageProvider from 'containers/LanguageProvider';

import App from 'containers/App';
import { showNotification } from 'containers/NotificationProvider/actions';
import {
  freezeApp,
  pluginLoaded,
  unfreezeApp,
  unsetHasUserPlugin,
  updatePlugin,
} from 'containers/App/actions';

import auth from 'utils/auth';
import configureStore from './store';
import { translationMessages, languages } from './i18n';
import { findIndex } from 'lodash';

const plugins = (() => {
  try {
    return require('./config/plugins.json');
  } catch (e) {
    return [];
  }
})();
/* eslint-enable */

// Create redux store with history
const basename = strapi.remoteURL.replace(window.location.origin, '');
const history = createHistory({
  basename,
});
const store = configureStore({}, history);

const render = (translatedMessages) => {
  ReactDOM.render(
    <Provider store={store}>
      <LanguageProvider messages={translatedMessages}>
        <ConnectedRouter history={history}>
          <App />
        </ConnectedRouter>
      </LanguageProvider>
    </Provider>,
    document.getElementById('app')
  );
};

// Hot reloadable translation json files
if (module.hot) {
  // modules.hot.accept does not accept dynamic dependencies,
  // have to be constants at compile-time
  module.hot.accept('./i18n', () => {
    render(translationMessages);
  });
}

// Chunked polyfill for browsers without Intl support
window.onload = function onLoad() {
  if (!window.Intl) {
    Promise.all([
      System.import('intl'),
      System.import('intl/locale-data/jsonp/en.js'),
      System.import('intl/locale-data/jsonp/fr.js'),
    ]).then(() => render(translationMessages));
  } else {
    render(translationMessages);
  }
};

// Don't inject plugins in development mode.
if (window.location.port !== '4000') {
  fetch(`${strapi.remoteURL}/config/plugins.json`)
    .then(response => {
      return response.json();
    })
    .then(plugins => {
      if (findIndex(plugins, ['id', 'users-permissions']) === -1) {
        store.dispatch(unsetHasUserPlugin());
      }

      const $body = document.getElementsByTagName('body')[0];

      (plugins || []).forEach(plugin => {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.onerror = function (oError) {
          const source = new URL(oError.target.src);
          const url = new URL(`${strapi.remoteURL}`);

          if (!source || !url) {
            throw new Error(`Impossible to load: ${oError.target.src}`);
          }

          // Remove tag.
          $body.removeChild(script);

          // New attempt with new src.
          const newScript = document.createElement('script');
          newScript.type = 'text/javascript';
          newScript.src = `${url.origin}${source.pathname}`;
          $body.appendChild(newScript);
        };

        script.src = plugin.source[process.env.NODE_ENV].indexOf('://') === -1 ?
          `${basename}${plugin.source[process.env.NODE_ENV]}`.replace('//', '/'): // relative
          plugin.source[process.env.NODE_ENV]; // absolute

        $body.appendChild(script);
      });
    })
    .catch(err => {
      console.log(err);
    });
} else if (findIndex(plugins, ['id', 'users-permissions']) === -1) {
  store.dispatch(unsetHasUserPlugin());
}

// const isPluginAllowedToRegister = (plugin) => true;
const isPluginAllowedToRegister = (plugin) => plugin.id === 'users-permissions' || plugin.id === 'email' || auth.getToken();

/**
 * Register a plugin
 *
 * @param params
 */
const registerPlugin = (plugin) => {
  // Merge admin translation messages
  merge(translationMessages, plugin.translationMessages);

  plugin.leftMenuSections = plugin.leftMenuSections || [];
  const shouldAllowRegister = isPluginAllowedToRegister(plugin) !== null;

  switch (true) {
    // Execute bootstrap function and check if plugin can be rendered
    case isFunction(plugin.bootstrap) && isFunction(plugin.pluginRequirements) && shouldAllowRegister:
      plugin.pluginRequirements(plugin)
        .then(plugin => {
          return plugin.bootstrap(plugin);
        })
        .then(plugin => {
          store.dispatch(pluginLoaded(plugin));
        });
      break;
    // Check if plugin can be rendered
    case isFunction(plugin.pluginRequirements):
      plugin.pluginRequirements(plugin).then(plugin => {
        store.dispatch(pluginLoaded(plugin));
      });
      break;
    // Execute bootstrap function
    case isFunction(plugin.bootstrap) && shouldAllowRegister:
      plugin.bootstrap(plugin).then(plugin => {
        store.dispatch(pluginLoaded(plugin));
      });
      break;
    default:
      store.dispatch(pluginLoaded(plugin));
  }
};

const displayNotification = (message, status) => {
  store.dispatch(showNotification(message, status));
};

const lockApp = () => {
  store.dispatch(freezeApp());
};

const unlockApp = () => {
  store.dispatch(unfreezeApp());
};

/**
 * Public Strapi object exposed to the `window` object
 */

window.strapi = Object.assign(window.strapi || {}, {
  mode: process.env.MODE || 'host',
  registerPlugin,
  notification: {
    success: (message) => {
      displayNotification(message, 'success');
    },
    warning: (message) => {
      displayNotification(message, 'warning');
    },
    error: (message) => {
      displayNotification(message, 'error');
    },
    info: (message) => {
      displayNotification(message, 'info');
    },
  },
  refresh: (pluginId) => ({
    translationMessages: (translationMessagesUpdated) => {
      render(merge({}, translationMessages, translationMessagesUpdated));
    },
    leftMenuSections: (leftMenuSectionsUpdated) => {
      store.dispatch(updatePlugin(pluginId, 'leftMenuSections', leftMenuSectionsUpdated));
    },
  }),
  router: history,
  languages,
  currentLanguage: window.localStorage.getItem('strapi-admin-language') ||  window.navigator.language ||  window.navigator.userLanguage || 'en',
  lockApp,
  unlockApp,
});

const dispatch = store.dispatch;
export {
  dispatch,
};
<commit_msg>Disable eslint for app.js log<commit_after>/**
 * app.js
 *
 * This is the entry file for the application, only setup and boilerplate
 * code.
 */

/* eslint-disable */
import './public-path';
import 'babel-polyfill';
/* eslint-disable no-console */
// Import all the third party stuff
import { Provider } from 'react-redux';
import React from 'react';
import ReactDOM from 'react-dom';
import { ConnectedRouter } from 'react-router-redux';
import createHistory from 'history/createBrowserHistory';
import { merge, isFunction } from 'lodash';
import 'sanitize.css/sanitize.css';
import 'whatwg-fetch';

import LanguageProvider from 'containers/LanguageProvider';

import App from 'containers/App';
import { showNotification } from 'containers/NotificationProvider/actions';
import {
  freezeApp,
  pluginLoaded,
  unfreezeApp,
  unsetHasUserPlugin,
  updatePlugin,
} from 'containers/App/actions';

import auth from 'utils/auth';
import configureStore from './store';
import { translationMessages, languages } from './i18n';
import { findIndex } from 'lodash';

const plugins = (() => {
  try {
    return require('./config/plugins.json');
  } catch (e) {
    return [];
  }
})();
/* eslint-enable */

// Create redux store with history
const basename = strapi.remoteURL.replace(window.location.origin, '');
const history = createHistory({
  basename,
});
const store = configureStore({}, history);

const render = (translatedMessages) => {
  ReactDOM.render(
    <Provider store={store}>
      <LanguageProvider messages={translatedMessages}>
        <ConnectedRouter history={history}>
          <App />
        </ConnectedRouter>
      </LanguageProvider>
    </Provider>,
    document.getElementById('app')
  );
};

// Hot reloadable translation json files
if (module.hot) {
  // modules.hot.accept does not accept dynamic dependencies,
  // have to be constants at compile-time
  module.hot.accept('./i18n', () => {
    render(translationMessages);
  });
}

// Chunked polyfill for browsers without Intl support
window.onload = function onLoad() {
  if (!window.Intl) {
    Promise.all([
      System.import('intl'),
      System.import('intl/locale-data/jsonp/en.js'),
      System.import('intl/locale-data/jsonp/fr.js'),
    ]).then(() => render(translationMessages));
  } else {
    render(translationMessages);
  }
};

// Don't inject plugins in development mode.
if (window.location.port !== '4000') {
  fetch(`${strapi.remoteURL}/config/plugins.json`)
    .then(response => {
      return response.json();
    })
    .then(plugins => {
      if (findIndex(plugins, ['id', 'users-permissions']) === -1) {
        store.dispatch(unsetHasUserPlugin());
      }

      const $body = document.getElementsByTagName('body')[0];

      (plugins || []).forEach(plugin => {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.onerror = function (oError) {
          const source = new URL(oError.target.src);
          const url = new URL(`${strapi.remoteURL}`);

          if (!source || !url) {
            throw new Error(`Impossible to load: ${oError.target.src}`);
          }

          // Remove tag.
          $body.removeChild(script);

          // New attempt with new src.
          const newScript = document.createElement('script');
          newScript.type = 'text/javascript';
          newScript.src = `${url.origin}${source.pathname}`;
          $body.appendChild(newScript);
        };

        script.src = plugin.source[process.env.NODE_ENV].indexOf('://') === -1 ?
          `${basename}${plugin.source[process.env.NODE_ENV]}`.replace('//', '/'): // relative
          plugin.source[process.env.NODE_ENV]; // absolute

        $body.appendChild(script);
      });
    })
    .catch(err => {
      console.log(err); // eslint-disable-line no-console
    });
} else if (findIndex(plugins, ['id', 'users-permissions']) === -1) {
  store.dispatch(unsetHasUserPlugin());
}

// const isPluginAllowedToRegister = (plugin) => true;
const isPluginAllowedToRegister = (plugin) => plugin.id === 'users-permissions' || plugin.id === 'email' || auth.getToken();

/**
 * Register a plugin
 *
 * @param params
 */
const registerPlugin = (plugin) => {
  // Merge admin translation messages
  merge(translationMessages, plugin.translationMessages);

  plugin.leftMenuSections = plugin.leftMenuSections || [];
  const shouldAllowRegister = isPluginAllowedToRegister(plugin) !== null;

  switch (true) {
    // Execute bootstrap function and check if plugin can be rendered
    case isFunction(plugin.bootstrap) && isFunction(plugin.pluginRequirements) && shouldAllowRegister:
      plugin.pluginRequirements(plugin)
        .then(plugin => {
          return plugin.bootstrap(plugin);
        })
        .then(plugin => {
          store.dispatch(pluginLoaded(plugin));
        });
      break;
    // Check if plugin can be rendered
    case isFunction(plugin.pluginRequirements):
      plugin.pluginRequirements(plugin).then(plugin => {
        store.dispatch(pluginLoaded(plugin));
      });
      break;
    // Execute bootstrap function
    case isFunction(plugin.bootstrap) && shouldAllowRegister:
      plugin.bootstrap(plugin).then(plugin => {
        store.dispatch(pluginLoaded(plugin));
      });
      break;
    default:
      store.dispatch(pluginLoaded(plugin));
  }
};

const displayNotification = (message, status) => {
  store.dispatch(showNotification(message, status));
};

const lockApp = () => {
  store.dispatch(freezeApp());
};

const unlockApp = () => {
  store.dispatch(unfreezeApp());
};

/**
 * Public Strapi object exposed to the `window` object
 */

window.strapi = Object.assign(window.strapi || {}, {
  mode: process.env.MODE || 'host',
  registerPlugin,
  notification: {
    success: (message) => {
      displayNotification(message, 'success');
    },
    warning: (message) => {
      displayNotification(message, 'warning');
    },
    error: (message) => {
      displayNotification(message, 'error');
    },
    info: (message) => {
      displayNotification(message, 'info');
    },
  },
  refresh: (pluginId) => ({
    translationMessages: (translationMessagesUpdated) => {
      render(merge({}, translationMessages, translationMessagesUpdated));
    },
    leftMenuSections: (leftMenuSectionsUpdated) => {
      store.dispatch(updatePlugin(pluginId, 'leftMenuSections', leftMenuSectionsUpdated));
    },
  }),
  router: history,
  languages,
  currentLanguage: window.localStorage.getItem('strapi-admin-language') ||  window.navigator.language ||  window.navigator.userLanguage || 'en',
  lockApp,
  unlockApp,
});

const dispatch = store.dispatch;
export {
  dispatch,
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) Région Hauts-de-France, Département 77, CGI, 2016.
 *
 * This file is part of OPEN ENT NG. OPEN ENT NG is a versatile ENT Project based on the JVM and ENT Core Project.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation (version 3 of the License).
 * For the sake of explanation, any module that communicate over native
 * Web protocols, such as HTTP, with OPEN ENT NG is outside the scope of this
 * license and could be license under its own terms. This is merely considered
 * normal use of OPEN ENT NG, and does not fall under the heading of "covered work".
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

var gulp = require('gulp');
var ts = require('gulp-typescript');
var webpack = require('webpack-stream');
var bower = require('gulp-bower');
var merge = require('merge2');
var watch = require('gulp-watch');
var rev = require('gulp-rev');
var revReplace = require("gulp-rev-replace");
var clean = require('gulp-clean');
var sourcemaps = require('gulp-sourcemaps');
var typescript = require('typescript');
var glob = require('glob');
var colors = require('colors');

var paths = {
    infra: '../infra-front',
    toolkit: '../toolkit'
};

function compileTs(){
    var tsProject = ts.createProject('./tsconfig.json', {
        typescript: typescript
    });
    var tsResult = tsProject.src()
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject));

    return tsResult.js
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/main/resources/public/temp'));
}

function startWebpackEntcore(isLocal) {
    return gulp.src('./src/main/resources/public/module/entcore')
        .pipe(webpack(require('./webpack-entcore.config.js')))
        .pipe(gulp.dest('./src/main/resources/public/dist/entcore'))
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(rev())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/main/resources/public/dist/entcore'))
        .pipe(rev.manifest({ merge: true, path : './manifests/entcore.json' }))
        .pipe(gulp.dest('./'));
}

function startWebpack(isLocal) {
    gulp.src("./manifests/*").pipe(clean());
    var absc = gulp.src('./src/main/resources/public/modules/absences/')
        .pipe(webpack(require('./src/main/resources/public/modules/absences/webpack.config.absc.js')))
        .pipe(gulp.dest('./src/main/resources/public/dist/absences'))
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(rev())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/main/resources/public/dist/absences'))
        .pipe(rev.manifest({path : './manifests/absc.json' }))
        .pipe(gulp.dest('./'));

    var vsco = gulp.src('./src/main/resources/public/modules/viescolaire/')
        .pipe(webpack(require('./src/main/resources/public/modules/viescolaire/webpack.config.vsco.js')))
        .pipe(gulp.dest('./src/main/resources/public/dist/viescolaire'))
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(rev())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/main/resources/public/dist/viescolaire'))
        .pipe(rev.manifest({path : './manifests/vsco.json' }))
        .pipe(gulp.dest('./'));

    return merge([absc, vsco]);
}

function updateRefs() {
    var absc = gulp.src(glob.sync("./src/main/resources/view-src/absences/*.html"))
        .pipe(revReplace({manifest: gulp.src(["./manifests/absc.json", "./manifests/entcore.json"]) }))
        .pipe(gulp.dest("./src/main/resources/view/absences"));
    var vsco = gulp.src(glob.sync("./src/main/resources/view-src/viescolaire/*.html"))
        .pipe(revReplace({manifest: gulp.src(["./manifests/vscos.json", "./manifests/entcore.json"]) }))
        .pipe(gulp.dest("./src/main/resources/view/viescolaire"));
    return merge([absc, vsco]);
}

gulp.task('ts-local', ['copy-files'], function () { return compileTs() });
gulp.task('webpack-local', ['ts-local'], function(){ return startWebpack() });
gulp.task('webpack-entcore-local', ['webpack-local'], function(){ return startWebpackEntcore() });

gulp.task('ts', ['copy-files'], function () { return compileTs() });
gulp.task('webpack', ['ts'], function(){ return startWebpack() });
gulp.task('webpack-entcore', ['webpack'], function(){ return startWebpackEntcore() });

gulp.task('copy-files', () => {
    var html = gulp.src('./node_modules/entcore/src/template/**/*.html')
        .pipe(gulp.dest('./src/main/resources/public/template/entcore'));
var bundle = gulp.src('./node_modules/entcore/bundle/*')
    .pipe(gulp.dest('./src/main/resources/public/temp/entcore'));

    return merge(html, bundle);
})

gulp.task('drop-temp', ['webpack-entcore'], function() {
    return gulp.src([
        './src/main/resources/public/**/*.map.map',
        './src/main/resources/public/temp',
        './src/main/resources/public/dist/entcore/ng-app.js',
        './src/main/resources/public/dist/entcore/ng-app.js.map',
        './src/main/resources/public/dist/application.js',
        './src/main/resources/public/dist/application.js.map'
    ], { read: false })
        .pipe(clean());
});

gulp.task('build', ['drop-temp'], function () {
    var refs = updateRefs();
    var copyBehaviours = gulp.src('./src/main/resources/public/dist/behaviours.js')
        .pipe(gulp.dest('./src/main/resources/public/js'));
    return merge[refs, copyBehaviours];
});

gulp.task('build-local', ['webpack-entcore-local'], function () {
    var refs = updateRefs();
    var copyBehaviours = gulp.src('./src/main/resources/public/dist/behaviours.js')
        .pipe(gulp.dest('./src/main/resources/public/js'));
    return merge[refs, copyBehaviours];
});

gulp.task('removeTemp', function () {
    return gulp.src(['./src/main/resources/public/temp'], { read: false })
        .pipe(clean());
});

gulp.task('updateRefs', function () {
    updateRefs();
});<commit_msg>MN-522 : Removing local tasks<commit_after>/*
 * Copyright (c) Région Hauts-de-France, Département 77, CGI, 2016.
 *
 * This file is part of OPEN ENT NG. OPEN ENT NG is a versatile ENT Project based on the JVM and ENT Core Project.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation (version 3 of the License).
 * For the sake of explanation, any module that communicate over native
 * Web protocols, such as HTTP, with OPEN ENT NG is outside the scope of this
 * license and could be license under its own terms. This is merely considered
 * normal use of OPEN ENT NG, and does not fall under the heading of "covered work".
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

var gulp = require('gulp');
var ts = require('gulp-typescript');
var webpack = require('webpack-stream');
var bower = require('gulp-bower');
var merge = require('merge2');
var watch = require('gulp-watch');
var rev = require('gulp-rev');
var revReplace = require("gulp-rev-replace");
var clean = require('gulp-clean');
var sourcemaps = require('gulp-sourcemaps');
var typescript = require('typescript');
var glob = require('glob');
var colors = require('colors');

var paths = {
    infra: '../infra-front',
    toolkit: '../toolkit'
};

function compileTs(){
    var tsProject = ts.createProject('./tsconfig.json', {
        typescript: typescript
    });
    var tsResult = tsProject.src()
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject));

    return tsResult.js
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/main/resources/public/temp'));
}

function startWebpackEntcore(isLocal) {
    return gulp.src('./src/main/resources/public/module/entcore')
        .pipe(webpack(require('./webpack-entcore.config.js')))
        .pipe(gulp.dest('./src/main/resources/public/dist/entcore'))
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(rev())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/main/resources/public/dist/entcore'))
        .pipe(rev.manifest({ merge: true, path : './manifests/entcore.json' }))
        .pipe(gulp.dest('./'));
}

function startWebpack(isLocal) {
    gulp.src("./manifests/*").pipe(clean());
    var absc = gulp.src('./src/main/resources/public/modules/absences/')
        .pipe(webpack(require('./src/main/resources/public/modules/absences/webpack.config.absc.js')))
        .pipe(gulp.dest('./src/main/resources/public/dist/absences'))
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(rev())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/main/resources/public/dist/absences'))
        .pipe(rev.manifest({path : './manifests/absc.json' }))
        .pipe(gulp.dest('./'));

    var vsco = gulp.src('./src/main/resources/public/modules/viescolaire/')
        .pipe(webpack(require('./src/main/resources/public/modules/viescolaire/webpack.config.vsco.js')))
        .pipe(gulp.dest('./src/main/resources/public/dist/viescolaire'))
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(rev())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./src/main/resources/public/dist/viescolaire'))
        .pipe(rev.manifest({path : './manifests/vsco.json' }))
        .pipe(gulp.dest('./'));

    return merge([absc, vsco]);
}

function updateRefs() {
    var absc = gulp.src(glob.sync("./src/main/resources/view-src/absences/*.html"))
        .pipe(revReplace({manifest: gulp.src(["./manifests/absc.json", "./manifests/entcore.json"]) }))
        .pipe(gulp.dest("./src/main/resources/view/absences"));
    var vsco = gulp.src(glob.sync("./src/main/resources/view-src/viescolaire/*.html"))
        .pipe(revReplace({manifest: gulp.src(["./manifests/vscos.json", "./manifests/entcore.json"]) }))
        .pipe(gulp.dest("./src/main/resources/view/viescolaire"));
    return merge([absc, vsco]);
}

gulp.task('ts', ['copy-files'], function () { return compileTs() });
gulp.task('webpack', ['ts'], function(){ return startWebpack() });
gulp.task('webpack-entcore', ['webpack'], function(){ return startWebpackEntcore() });

gulp.task('copy-files', () => {
    var html = gulp.src('./node_modules/entcore/src/template/**/*.html')
        .pipe(gulp.dest('./src/main/resources/public/template/entcore'));
var bundle = gulp.src('./node_modules/entcore/bundle/*')
    .pipe(gulp.dest('./src/main/resources/public/temp/entcore'));

    return merge(html, bundle);
})

gulp.task('drop-temp', ['webpack-entcore'], function() {
    return gulp.src([
        './src/main/resources/public/**/*.map.map',
        './src/main/resources/public/temp',
        './src/main/resources/public/dist/entcore/ng-app.js',
        './src/main/resources/public/dist/entcore/ng-app.js.map',
        './src/main/resources/public/dist/application.js',
        './src/main/resources/public/dist/application.js.map'
    ], { read: false })
        .pipe(clean());
});

gulp.task('build', ['drop-temp'], function () {
    var refs = updateRefs();
    var copyBehaviours = gulp.src('./src/main/resources/public/dist/behaviours.js')
        .pipe(gulp.dest('./src/main/resources/public/js'));
    return merge[refs, copyBehaviours];
});

gulp.task('removeTemp', function () {
    return gulp.src(['./src/main/resources/public/temp'], { read: false })
        .pipe(clean());
});

gulp.task('updateRefs', function () {
    updateRefs();
});<|endoftext|>


<commit_before>#!/usr/bin/env node

// @ts-check
'use strict';

const fs = require('fs');
const path = require('path');
const util = require('util');
const readfiles = require('node-readfiles');
const yaml = require('js-yaml');

const validator = require('oas-validator');
const common = require('oas-kit-common');
const clone = require('reftools/lib/clone.js').clone;

const swagger2openapi = require('./index.js');

let globalExpectFailure = false;

const baseName = path.basename(process.argv[1]);

const yargs = require('yargs');
let argv = yargs
    .usage(baseName+' [options] {path-to-specs}...')
    .string('encoding')
    .alias('e', 'encoding')
    .default('encoding', 'utf8')
    .describe('encoding', 'encoding for input/output files')
    .string('fail')
    .describe('fail', 'path to specs expected to fail')
    .alias('f', 'fail')
    .string('jsonschema')
    .alias('j', 'jsonschema')
    .describe('jsonschema', 'path to alternative JSON schema')
    .boolean('laxurls')
    .alias('l', 'laxurls')
    .describe('laxurls', 'lax checking of empty urls')
    .boolean('lint')
    .describe('lint','lint the definition')
    .boolean('nopatch')
    .alias('n', 'nopatch')
    .describe('nopatch', 'do not patch minor errors in the source definition')
    .string('output')
    .alias('o', 'output')
    .describe('output', 'output conversion result')
    .boolean('quiet')
    .alias('q', 'quiet')
    .describe('quiet', 'do not show test passes on console, for CI')
    .boolean('resolve')
    .alias('r', 'resolve')
    .describe('resolve', 'resolve external references')
    .boolean('stop')
    .alias('s', 'stop')
    .describe('stop', 'stop on first error')
    .string('validateSchema')
    .describe('validateSchema','Run schema validation step: first, last* or never')
    .count('verbose')
    .alias('v', 'verbose')
    .describe('verbose', 'increase verbosity')
    .boolean('warnOnly')
    .describe('warnOnly','Do not throw on non-patchable errors')
    .boolean('whatwg')
    .alias('w', 'whatwg')
    .describe('whatwg', 'enable WHATWG URL parsing')
    .boolean('yaml')
    .alias('y', 'yaml')
    .describe('yaml', 'skip YAML-safe test')
    .help('h')
    .alias('h', 'help')
    .strict()
    .demand(1)
    .version()
    .argv;

let pass = 0;
let fail = 0;
let failures = [];
let warnings = [];

let genStack = [];

let options = argv;
options.patch = !argv.nopatch;
options.fatal = true;

function finalise(err, options) {
    if (!argv.quiet || err) {
        console.log(common.colour.normal + options.file);
    }
    if (err) {
        console.log(common.colour.red + options.context.pop() + '\n' + err.message);
        if (err.name.indexOf('ERR_INVALID_URL')>=0) {
            // nop
        }
        else if (err.message.indexOf('schema validation')>=0) {
            if (options.validateSchema !== 'first') {
                warnings.push('Schema fallback '+options.file);
            }
        }
        else if (err.stack && err.name !== 'AssertionError') {
            console.log(err.stack);
            warnings.push(err.name+' '+options.file);
        }
        if (options.lintRule && options.lintRule.description !== err.message) {
            console.warn(options.lintRule.description);
        }
        options.valid = !!options.expectFailure;
    }
    if (options.warnings) {
        for (let warning of options.warnings) {
            warnings.push(options.file + ' ' + warning);
        }
    }

    let src = options.original;
    let result = options.valid;

    if (!argv.quiet) {
        let colour = ((options.expectFailure ? !result : result) ? common.colour.green : common.colour.red);
        if (src && src.info) {
            console.log(colour + '  %s %s', src.info.title, src.info.version);
            if (src["x-testcase"]) console.log(' ',src["x-testcase"]);
            console.log('  %s', src.swagger ? (src.host ? src.host : 'relative') : (src.servers && src.servers.length ? src.servers[0].url : 'relative'),common.colour.normal);
        }
    }
    if (result) {
        pass++;
        if ((options.file.indexOf('swagger.yaml') >= 0) && argv.output) {
            let outFile = options.file.replace('swagger.yaml', argv.output);
            let resultStr = yaml.safeDump(options.openapi, {lineWidth: -1});
            fs.writeFile(outFile, resultStr, argv.encoding);
        }
    }
    else {
        fail++;
        if (options.file != 'unknown') failures.push(options.file);
        if (argv.stop) process.exit(1);
    }
    genStackNext();
}

function handleResult(err, options) {
    let result = false;
    if (err) {
        options = err.options || { file: 'unknown', src: { info: { version: '', title: '' } } }; // src is just enough to provide dummy outputs
        options.context = [];
        options.warnings = [];
        options.expectFailure = globalExpectFailure;
        finalise(err,options);
    }
    else {
        result = options.openapi;
    }
    let resultStr = JSON.stringify(result);

    if (typeof result !== 'boolean') try {
        if (!options.yaml) {
            resultStr = yaml.safeDump(result, { lineWidth: -1 }); // should be representable safely in yaml
            let resultStr2 = yaml.safeDump(result, { lineWidth: -1, noRefs: true });
            resultStr.should.not.be.exactly('{}','Result should not be empty');
            resultStr.should.equal(resultStr2,'Result should have no object identity ref_s');
        }

        validator.validate(result, options, finalise);
    }
    catch (ex) {
        console.log(common.colour.normal + options.file);
        console.log(common.colour.red + options.context.pop() + '\n' + ex.message);
        if (ex.stack && ex.name !== 'AssertionError') {
            console.log(ex.stack);
        }
        options.valid = !options.expectFailure;
        finalise(ex, options);
    }
}

function genStackNext() {
    if (!genStack.length) return false;
    let gen = genStack.shift();
    gen.next();
    return true;
}

function* check(file, force, expectFailure) {
    let result = false;
    options.context = [];
    options.expectFailure = expectFailure;
    options.file = file;
    let components = file.split(path.sep);
    let name = components[components.length - 1];
    let src;

    if ((name.indexOf('.yaml') >= 0) || (name.indexOf('.yml') >= 0) || (name.indexOf('.json') >= 0) || force) {

        if (!file.startsWith('http')) {
            let srcStr = fs.readFileSync(path.resolve(file), options.encoding);
            try {
                src = JSON.parse(srcStr);
            }
            catch (ex) {
                try {
                    src = yaml.safeLoad(srcStr, { schema: yaml.JSON_SCHEMA, json: true });
                }
                catch (ex) {
                    let warning = 'Could not parse file ' + file + '\n' + ex.message;
                    console.log(common.colour.red + warning);
                    if (ex.stack && ex.message.indexOf('stack')>=0) {
                        console.warn(ex.stack);
                    }
                    warnings.push(warning);
                }
            }

            if (!src || ((!src.swagger && !src.openapi))) {
                genStackNext();
                return true;
            }
        }

        options.original = src;
        options.source = path.resolve(file);

        if ((options.source.indexOf('!')>=0) && (options.source.indexOf('swagger.')>=0)) {
            expectFailure = true;
        }

        if (file.startsWith('http')) {
            swagger2openapi.convertUrl(file, clone(options))
            .then(function(options){
                handleResult(null,options);
            })
            .catch(function(ex){
                console.warn(common.colour.red+ex,common.colour.normal);
                if (expectFailure) {
                    warnings.push('Converter failed ' + options.source);
                }
                else {
                    failures.push('Converter failed ' + options.source);
                    fail++;
                }
                genStackNext();
                result = false;
            });
        }
        else {
            swagger2openapi.convertObj(src, clone(options))
            .then(function(options){
                handleResult(null,options);
            })
            .catch(function(ex){
                console.warn(common.colour.red+ex,common.colour.normal);
                if (expectFailure) {
                    warnings.push('Converter failed ' + options.source);
                }
                else {
                    failures.push('Converter failed ' + options.source);
                    fail++;
                }
                genStackNext();
                result = false;
            });
        }
    }
    else {
        genStackNext();
        result = true;
    }
    return result;
}

function processPathSpec(pathspec, expectFailure) {
    globalExpectFailure = expectFailure;
    if (pathspec.startsWith('@')) {
        pathspec = pathspec.substr(1, pathspec.length - 1);
        let list = fs.readFileSync(pathspec, 'utf8').split('\r').join('').split('\n');
        for (let file of list) {
            genStack.push(check(file, false, expectFailure));
        }
        genStackNext();
    }
    else if (pathspec.startsWith('http')) {
        genStack.push(check(pathspec, true, expectFailure));
        genStackNext();
    }
    else if (fs.statSync(path.resolve(pathspec)).isFile()) {
        genStack.push(check(pathspec, true, expectFailure));
        genStackNext();
    }
    else {
        readfiles(pathspec, { readContents: false, filenameFormat: readfiles.FULL_PATH }, function (err) {
            if (err) console.log(util.inspect(err));
        })
        .then(files => {
            files = files.sort();
            for (let file of files) {
                genStack.push(check(file, false, expectFailure));
            }
            genStackNext();
        })
        .catch(err => {
            console.log(util.inspect(err));
        });
    }
}

process.exitCode = 1;
console.log('Gathering...');
for (let pathspec of argv._) {
    processPathSpec(pathspec, false);
}
if (argv.fail) {
    if (!Array.isArray(argv.fail)) argv.fail = [argv.fail];
    for (let pathspec of argv.fail) {
        processPathSpec(pathspec, true);
    }
}

process.on('unhandledRejection', r => console.warn(r));

process.on('exit', function () {
    if (warnings.length) {
        warnings.sort();
        console.log(common.colour.normal + '\nWarnings:' + common.colour.yellow);
        for (let w in warnings) {
            console.log(warnings[w]);
        }
    }
    if (failures.length) {
        failures.sort();
        console.log(common.colour.normal + '\nFailures:' + common.colour.red);
        for (let f in failures) {
            console.log(failures[f]);
        }
    }
    console.log(common.colour.normal);
    console.log('Tests: %s passing, %s failing, %s warnings', pass, fail, warnings.length);
    process.exitCode = ((fail === 0) && (pass > 0)) ? 0 : 1;
});
<commit_msg>testRunner; missing sync on writeFile<commit_after>#!/usr/bin/env node

// @ts-check
'use strict';

const fs = require('fs');
const path = require('path');
const util = require('util');
const readfiles = require('node-readfiles');
const yaml = require('js-yaml');

const validator = require('oas-validator');
const common = require('oas-kit-common');
const clone = require('reftools/lib/clone.js').clone;

const swagger2openapi = require('./index.js');

let globalExpectFailure = false;

const baseName = path.basename(process.argv[1]);

const yargs = require('yargs');
let argv = yargs
    .usage(baseName+' [options] {path-to-specs}...')
    .string('encoding')
    .alias('e', 'encoding')
    .default('encoding', 'utf8')
    .describe('encoding', 'encoding for input/output files')
    .string('fail')
    .describe('fail', 'path to specs expected to fail')
    .alias('f', 'fail')
    .string('jsonschema')
    .alias('j', 'jsonschema')
    .describe('jsonschema', 'path to alternative JSON schema')
    .boolean('laxurls')
    .alias('l', 'laxurls')
    .describe('laxurls', 'lax checking of empty urls')
    .boolean('lint')
    .describe('lint','lint the definition')
    .boolean('nopatch')
    .alias('n', 'nopatch')
    .describe('nopatch', 'do not patch minor errors in the source definition')
    .string('output')
    .alias('o', 'output')
    .describe('output', 'output conversion result')
    .boolean('quiet')
    .alias('q', 'quiet')
    .describe('quiet', 'do not show test passes on console, for CI')
    .boolean('resolve')
    .alias('r', 'resolve')
    .describe('resolve', 'resolve external references')
    .boolean('stop')
    .alias('s', 'stop')
    .describe('stop', 'stop on first error')
    .string('validateSchema')
    .describe('validateSchema','Run schema validation step: first, last* or never')
    .count('verbose')
    .alias('v', 'verbose')
    .describe('verbose', 'increase verbosity')
    .boolean('warnOnly')
    .describe('warnOnly','Do not throw on non-patchable errors')
    .boolean('whatwg')
    .alias('w', 'whatwg')
    .describe('whatwg', 'enable WHATWG URL parsing')
    .boolean('yaml')
    .alias('y', 'yaml')
    .describe('yaml', 'skip YAML-safe test')
    .help('h')
    .alias('h', 'help')
    .strict()
    .demand(1)
    .version()
    .argv;

let pass = 0;
let fail = 0;
let failures = [];
let warnings = [];

let genStack = [];

let options = argv;
options.patch = !argv.nopatch;
options.fatal = true;

function finalise(err, options) {
    if (!argv.quiet || err) {
        console.log(common.colour.normal + options.file);
    }
    if (err) {
        console.log(common.colour.red + options.context.pop() + '\n' + err.message);
        if (err.name.indexOf('ERR_INVALID_URL')>=0) {
            // nop
        }
        else if (err.message.indexOf('schema validation')>=0) {
            if (options.validateSchema !== 'first') {
                warnings.push('Schema fallback '+options.file);
            }
        }
        else if (err.stack && err.name !== 'AssertionError') {
            console.log(err.stack);
            warnings.push(err.name+' '+options.file);
        }
        if (options.lintRule && options.lintRule.description !== err.message) {
            console.warn(options.lintRule.description);
        }
        options.valid = !!options.expectFailure;
    }
    if (options.warnings) {
        for (let warning of options.warnings) {
            warnings.push(options.file + ' ' + warning);
        }
    }

    let src = options.original;
    let result = options.valid;

    if (!argv.quiet) {
        let colour = ((options.expectFailure ? !result : result) ? common.colour.green : common.colour.red);
        if (src && src.info) {
            console.log(colour + '  %s %s', src.info.title, src.info.version);
            if (src["x-testcase"]) console.log(' ',src["x-testcase"]);
            console.log('  %s', src.swagger ? (src.host ? src.host : 'relative') : (src.servers && src.servers.length ? src.servers[0].url : 'relative'),common.colour.normal);
        }
    }
    if (result) {
        pass++;
        if ((options.file.indexOf('swagger.yaml') >= 0) && argv.output) {
            let outFile = options.file.replace('swagger.yaml', argv.output);
            let resultStr = yaml.safeDump(options.openapi, {lineWidth: -1});
            fs.writeFileSync(outFile, resultStr, argv.encoding);
        }
    }
    else {
        fail++;
        if (options.file != 'unknown') failures.push(options.file);
        if (argv.stop) process.exit(1);
    }
    genStackNext();
}

function handleResult(err, options) {
    let result = false;
    if (err) {
        options = err.options || { file: 'unknown', src: { info: { version: '', title: '' } } }; // src is just enough to provide dummy outputs
        options.context = [];
        options.warnings = [];
        options.expectFailure = globalExpectFailure;
        finalise(err,options);
    }
    else {
        result = options.openapi;
    }
    let resultStr = JSON.stringify(result);

    if (typeof result !== 'boolean') try {
        if (!options.yaml) {
            resultStr = yaml.safeDump(result, { lineWidth: -1 }); // should be representable safely in yaml
            let resultStr2 = yaml.safeDump(result, { lineWidth: -1, noRefs: true });
            resultStr.should.not.be.exactly('{}','Result should not be empty');
            resultStr.should.equal(resultStr2,'Result should have no object identity ref_s');
        }

        validator.validate(result, options, finalise);
    }
    catch (ex) {
        console.log(common.colour.normal + options.file);
        console.log(common.colour.red + options.context.pop() + '\n' + ex.message);
        if (ex.stack && ex.name !== 'AssertionError') {
            console.log(ex.stack);
        }
        options.valid = !options.expectFailure;
        finalise(ex, options);
    }
}

function genStackNext() {
    if (!genStack.length) return false;
    let gen = genStack.shift();
    gen.next();
    return true;
}

function* check(file, force, expectFailure) {
    let result = false;
    options.context = [];
    options.expectFailure = expectFailure;
    options.file = file;
    let components = file.split(path.sep);
    let name = components[components.length - 1];
    let src;

    if ((name.indexOf('.yaml') >= 0) || (name.indexOf('.yml') >= 0) || (name.indexOf('.json') >= 0) || force) {

        if (!file.startsWith('http')) {
            let srcStr = fs.readFileSync(path.resolve(file), options.encoding);
            try {
                src = JSON.parse(srcStr);
            }
            catch (ex) {
                try {
                    src = yaml.safeLoad(srcStr, { schema: yaml.JSON_SCHEMA, json: true });
                }
                catch (ex) {
                    let warning = 'Could not parse file ' + file + '\n' + ex.message;
                    console.log(common.colour.red + warning);
                    if (ex.stack && ex.message.indexOf('stack')>=0) {
                        console.warn(ex.stack);
                    }
                    warnings.push(warning);
                }
            }

            if (!src || ((!src.swagger && !src.openapi))) {
                genStackNext();
                return true;
            }
        }

        options.original = src;
        options.source = path.resolve(file);

        if ((options.source.indexOf('!')>=0) && (options.source.indexOf('swagger.')>=0)) {
            expectFailure = true;
        }

        if (file.startsWith('http')) {
            swagger2openapi.convertUrl(file, clone(options))
            .then(function(options){
                handleResult(null,options);
            })
            .catch(function(ex){
                console.warn(common.colour.red+ex,common.colour.normal);
                if (expectFailure) {
                    warnings.push('Converter failed ' + options.source);
                }
                else {
                    failures.push('Converter failed ' + options.source);
                    fail++;
                }
                genStackNext();
                result = false;
            });
        }
        else {
            swagger2openapi.convertObj(src, clone(options))
            .then(function(options){
                handleResult(null,options);
            })
            .catch(function(ex){
                console.warn(common.colour.red+ex,common.colour.normal);
                if (expectFailure) {
                    warnings.push('Converter failed ' + options.source);
                }
                else {
                    failures.push('Converter failed ' + options.source);
                    fail++;
                }
                genStackNext();
                result = false;
            });
        }
    }
    else {
        genStackNext();
        result = true;
    }
    return result;
}

function processPathSpec(pathspec, expectFailure) {
    globalExpectFailure = expectFailure;
    if (pathspec.startsWith('@')) {
        pathspec = pathspec.substr(1, pathspec.length - 1);
        let list = fs.readFileSync(pathspec, 'utf8').split('\r').join('').split('\n');
        for (let file of list) {
            genStack.push(check(file, false, expectFailure));
        }
        genStackNext();
    }
    else if (pathspec.startsWith('http')) {
        genStack.push(check(pathspec, true, expectFailure));
        genStackNext();
    }
    else if (fs.statSync(path.resolve(pathspec)).isFile()) {
        genStack.push(check(pathspec, true, expectFailure));
        genStackNext();
    }
    else {
        readfiles(pathspec, { readContents: false, filenameFormat: readfiles.FULL_PATH }, function (err) {
            if (err) console.log(util.inspect(err));
        })
        .then(files => {
            files = files.sort();
            for (let file of files) {
                genStack.push(check(file, false, expectFailure));
            }
            genStackNext();
        })
        .catch(err => {
            console.log(util.inspect(err));
        });
    }
}

process.exitCode = 1;
console.log('Gathering...');
for (let pathspec of argv._) {
    processPathSpec(pathspec, false);
}
if (argv.fail) {
    if (!Array.isArray(argv.fail)) argv.fail = [argv.fail];
    for (let pathspec of argv.fail) {
        processPathSpec(pathspec, true);
    }
}

process.on('unhandledRejection', r => console.warn(r));

process.on('exit', function () {
    if (warnings.length) {
        warnings.sort();
        console.log(common.colour.normal + '\nWarnings:' + common.colour.yellow);
        for (let w in warnings) {
            console.log(warnings[w]);
        }
    }
    if (failures.length) {
        failures.sort();
        console.log(common.colour.normal + '\nFailures:' + common.colour.red);
        for (let f in failures) {
            console.log(failures[f]);
        }
    }
    console.log(common.colour.normal);
    console.log('Tests: %s passing, %s failing, %s warnings', pass, fail, warnings.length);
    process.exitCode = ((fail === 0) && (pass > 0)) ? 0 : 1;
});
<|endoftext|>