<commit_before>var Layout;

(function() {
  var layouts = {};

  Layout = {
    _zoomed: false,
    options: {
      layout: 'list',
      margin: 20,
      padding: 6,
      index: 0
    },

    _create: function() {
      this._render();
      this.element.css({
        left: 0,
        position: 'absolute',
        top: 0
      });
      $('html').css({
        overflow: 'hidden'
      });
      var that = this;
      $(window).resize(function() {
        that._render();
      }).keyup(function(event) {
        if (event.which == 27 /* ESC */) {
          if (that._zoomed = !that._zoomed) {
            that.zoomOut();
          }
          else {
            that.zoomIn();
          }
        }
        else if ((event.which == 37 || event.which == 38) && that.options.index > 0) {
          that.options.index--;
          that.findLayout().show.call(that);
        }
        else if ((event.which == 39 || event.which == 40) && that.options.index < that.elements().length - 1) {
          that.options.index++;
          that.findLayout().show.call(that);
        }
        else {
          var number = event.which - 49;
          if (number >= 0 && number <= 8 && number < that.elements().length) {
            that.options.index = number;
            that.findLayout().show.call(that);
          }
        }
      });
    },

    _render: function() {
      this.findLayout().render.call(this);
      this.findLayout().show.call(this);
    },

    elements: function() {
      return this.element.find('> *');
    },

    destroy: function() {
      $.Widget.prototype.destroy.apply(this, arguments);
    },

    addLayout: function(layout, renderer) {
      return layouts[layout] = renderer;
    },

    setLayout: function(layout) {
      if (this._zoomed) {
        this.zoomIn();
      }
      this.options.layout = layout;
      this._render();
    },

    getLayout: function() {
      return this.options.layout;
    },

    findLayout: function() {
      return layouts[this.options.layout];
    },

    zoomOut: function() {
      var windowWidth = $(window).width(),
          windowHeight = $(window).height(),
          width = this.element.width(),
          height = this.element.height(),
          factor = width > windowWidth ? windowWidth / width : windowHeight / height;
      this.element.css({
        WebkitTransform: 'scale(' + factor + ', ' + factor + ') ' +
          (width > windowWidth
            ? 'translateX(' + ((width - windowWidth) / -2 - parseInt(this.element.css('left'))) / factor + 'px)'
            : 'translateY(' + ((height - windowHeight) / -2 - parseInt(this.element.css('top'))) / factor + 'px)')
      });
      this._zoomed = true;
    },

    zoomIn: function() {
      this.element.css({
        WebkitTransform: 'scale(1, 1) translateX(0) translateY(0)'
      });
      this._zoomed = false;
    },

    show: function(index) {
      if (index < this.elements().length) {
        this.options.index = index;
      }
      this._render();
    },

    margins: function() {
      var margin = this.options.margin;
      return {
        margin: margin,
        left:   this.options.marginLeft   || margin,
        top:    this.options.marginTop    || margin,
        bottom: this.options.marginBottom || margin,
        right:  this.options.marginRight  || margin,
      }
    }
  };
})();

$.widget('ui.layout', Layout);

Layout.addLayout('list', {
  render: function() {
    var margins = this.margins(),
        padding = this.options.padding,
        top = margins.top,
        windowWidth = $(window).width();
    this.elements().each(function() {
      var el = $(this),
          height = el.find('.inner').height();
      el.css({
        height: height + 'px',
        left: margins.left + 'px',
        padding: padding + 'px ' + padding + 'px 0',
        position: 'absolute',
        top: top + 'px',
        width: windowWidth - margins.left - margins.right - 2 * padding + 'px'
      });
      top += height + margins.margin + 2 * padding;
    });
    this.element.css({
      height: top + 'px',
      width: windowWidth + 'px'
    });
  },
  show: function(index) {
    this.element.css({
      left: 0,
      top: -parseInt(this.elements().eq(this.options.index).css('top')) + this.margins().top + 'px'
    });
  }
});

Layout.addLayout('spaces', {
  render: function() {
    var margins = this.margins(),
        padding = this.options.padding,
        left = margins.left,
        right,
        windowHeight = $(window).height(),
        windowWidth = $(window).width(),
        that = this;
    this.elements().each(function(i) {
      var el = $(this);
      right = -i * windowWidth - margins.right;
      el.css({
        left: left + 'px',
        height: windowHeight - margins.top - margins.bottom - padding + 'px',
        padding: padding + 'px ' + padding + 'px 0',
        position: 'absolute',
        top: margins.top + 'px',
        width: windowWidth - margins.left - margins.right - 2 * padding + 'px'
      });
      left += windowWidth - margins.left;
    });
    this.element.css({
      height: windowHeight + 'px',
      width: left + 'px'
    });
  },
  show: function() {
    this.element.css({
      left: -this.options.index * ($(window).width() - this.options.margin) + 'px',
      top: 0
    });
  }
});
<commit_msg>fixed paddings<commit_after>var Layout;

(function() {
  var layouts = {};

  Layout = {
    _zoomed: false,
    options: {
      layout: 'list',
      margin: 20,
      padding: 6,
      index: 0
    },

    _create: function() {
      this._render();
      this.element.css({
        left: 0,
        position: 'absolute',
        top: 0
      });
      $('html').css({
        overflow: 'hidden'
      });
      var that = this;
      $(window).resize(function() {
        that._render();
      }).keyup(function(event) {
        if (event.which == 27 /* ESC */) {
          if (that._zoomed = !that._zoomed) {
            that.zoomOut();
          }
          else {
            that.zoomIn();
          }
        }
        else if ((event.which == 37 || event.which == 38) && that.options.index > 0) {
          that.options.index--;
          that.findLayout().show.call(that);
        }
        else if ((event.which == 39 || event.which == 40) && that.options.index < that.elements().length - 1) {
          that.options.index++;
          that.findLayout().show.call(that);
        }
        else {
          var number = event.which - 49;
          if (number >= 0 && number <= 8 && number < that.elements().length) {
            that.options.index = number;
            that.findLayout().show.call(that);
          }
        }
      });
    },

    _render: function() {
      this.findLayout().render.call(this);
      this.findLayout().show.call(this);
    },

    elements: function() {
      return this.element.find('> *');
    },

    destroy: function() {
      $.Widget.prototype.destroy.apply(this, arguments);
    },

    addLayout: function(layout, renderer) {
      return layouts[layout] = renderer;
    },

    setLayout: function(layout) {
      if (this._zoomed) {
        this.zoomIn();
      }
      this.options.layout = layout;
      this._render();
    },

    getLayout: function() {
      return this.options.layout;
    },

    findLayout: function() {
      return layouts[this.options.layout];
    },

    zoomOut: function() {
      var windowWidth = $(window).width(),
          windowHeight = $(window).height(),
          width = this.element.width(),
          height = this.element.height(),
          factor = width > windowWidth ? windowWidth / width : windowHeight / height;
      this.element.css({
        WebkitTransform: 'scale(' + factor + ', ' + factor + ') ' +
          (width > windowWidth
            ? 'translateX(' + ((width - windowWidth) / -2 - parseInt(this.element.css('left'))) / factor + 'px)'
            : 'translateY(' + ((height - windowHeight) / -2 - parseInt(this.element.css('top'))) / factor + 'px)')
      });
      this._zoomed = true;
    },

    zoomIn: function() {
      this.element.css({
        WebkitTransform: 'scale(1, 1) translateX(0) translateY(0)'
      });
      this._zoomed = false;
    },

    show: function(index) {
      if (index < this.elements().length) {
        this.options.index = index;
      }
      this._render();
    },

    margins: function() {
      var margin = this.options.margin;
      return {
        margin: margin,
        left:   this.options.marginLeft   || margin,
        top:    this.options.marginTop    || margin,
        bottom: this.options.marginBottom || margin,
        right:  this.options.marginRight  || margin,
      }
    }
  };
})();

$.widget('ui.layout', Layout);

Layout.addLayout('list', {
  render: function() {
    var margins = this.margins(),
        padding = this.options.padding,
        top = margins.top,
        windowWidth = $(window).width();
    this.elements().each(function() {
      var el = $(this),
          height = el.find('.inner').height();
      el.css({
        height: height + 'px',
        left: margins.left + 'px',
        padding: padding + 'px 0 0 ' + padding + 'px',
        position: 'absolute',
        top: top + 'px',
        width: windowWidth - margins.left - margins.right - 2 * padding + 'px'
      });
      top += height + margins.margin + 2 * padding;
    });
    this.element.css({
      height: top + 'px',
      width: windowWidth + 'px'
    });
  },
  show: function(index) {
    this.element.css({
      left: 0,
      top: -parseInt(this.elements().eq(this.options.index).css('top')) + this.margins().top + 'px'
    });
  }
});

Layout.addLayout('spaces', {
  render: function() {
    var margins = this.margins(),
        padding = this.options.padding,
        left = margins.left,
        right,
        windowHeight = $(window).height(),
        windowWidth = $(window).width(),
        that = this;
    this.elements().each(function(i) {
      var el = $(this);
      right = -i * windowWidth - margins.right;
      el.css({
        left: left + 'px',
        height: windowHeight - margins.top - margins.bottom - padding + 'px',
        padding: padding + 'px 0 0 ' + padding + 'px',
        position: 'absolute',
        top: margins.top + 'px',
        width: windowWidth - margins.left - margins.right - 2 * padding + 'px'
      });
      left += windowWidth - margins.left;
    });
    this.element.css({
      height: windowHeight + 'px',
      width: left + 'px'
    });
  },
  show: function() {
    this.element.css({
      left: -this.options.index * ($(window).width() - this.options.margin) + 'px',
      top: 0
    });
  }
});
<|endoftext|>


<commit_before>require('dotenv').config()

const asyncRetry = require('async-retry')
const buildExtensions = require('./tasks/build-extensions')
const deployExtensions = require('./tasks/deploy-extensions')
const createEnvironment = require('./tasks/create-new-enviromenment')
const deleteEnvironment = require('./tasks/delete-new-environment')
const createConfigurationFiles = require('./tasks/create-configuration-files')
const runCypress = require('./tasks/run-cypress')

const config = {
  managementToken: process.env.CONTENTFUL_CMA_TOKEN,
  spaceId: process.env.CONTENTFUL_SPACE_ID,
  baseUrl: process.env.CONTENTFUL_APP,
  testLocalSdk: process.env.TEST_LOCAL_SDK === 'true'
}

function listAllEnvironmentVariables() {
  ;['CONTENTFUL_SPACE_ID', 'CONTENTFUL_CMA_TOKEN', 'CYPRESS_baseUrl', 'TEST_LOCAL_SDK'].forEach(
    envvar => {
      console.log(`${envvar}=${process.env[envvar]}`)
    }
  )
}

let environmentId

const cleanup = async () => {
  if (environmentId) {
    try {
      await asyncRetry(
        () => {
          return deleteEnvironment(environmentId)
        },
        { retries: 3 }
      )
    } catch (e) {
      console.log(e)
      throw new Error('Failed to remove environment')
    }
  }
}

const run = async () => {
  listAllEnvironmentVariables()

  try {
    environmentId = await asyncRetry(
      () => {
        return createEnvironment()
      },
      { retries: 3 }
    )
  } catch (e) {
    console.log(e)
    throw new Error('Failed to create a new environment')
  }

  await createConfigurationFiles({
    managementToken: config.managementToken,
    spaceId: config.spaceId,
    environmentId
  })

  await buildExtensions({
    testLocalSdk: config.testLocalSdk
  })

  await deployExtensions()

  await runCypress()
}

;(async function main() {
  try {
    await run()
    await cleanup()
    process.exit(0)
  } catch (err) {
    console.log(err)
    await cleanup()
    process.exit(1)
  }
})()
<commit_msg>Remove pat from logs (#241)<commit_after>require('dotenv').config()

const asyncRetry = require('async-retry')
const buildExtensions = require('./tasks/build-extensions')
const deployExtensions = require('./tasks/deploy-extensions')
const createEnvironment = require('./tasks/create-new-enviromenment')
const deleteEnvironment = require('./tasks/delete-new-environment')
const createConfigurationFiles = require('./tasks/create-configuration-files')
const runCypress = require('./tasks/run-cypress')

const config = {
  managementToken: process.env.CONTENTFUL_CMA_TOKEN,
  spaceId: process.env.CONTENTFUL_SPACE_ID,
  baseUrl: process.env.CONTENTFUL_APP,
  testLocalSdk: process.env.TEST_LOCAL_SDK === 'true'
}

function listAllEnvironmentVariables() {
  ;['CONTENTFUL_SPACE_ID', 'CYPRESS_baseUrl', 'TEST_LOCAL_SDK'].forEach(envvar => {
    console.log(`${envvar}=${process.env[envvar]}`)
  })
  ;['CONTENTFUL_CMA_TOKEN'].forEach(envvar => {
    console.log(`${envvar}=${process.env[envvar].slice(0, 5)}...`)
  })
}

let environmentId

const cleanup = async () => {
  if (environmentId) {
    try {
      await asyncRetry(
        () => {
          return deleteEnvironment(environmentId)
        },
        { retries: 3 }
      )
    } catch (e) {
      console.log(e)
      throw new Error('Failed to remove environment')
    }
  }
}

const run = async () => {
  listAllEnvironmentVariables()

  try {
    environmentId = await asyncRetry(
      () => {
        return createEnvironment()
      },
      { retries: 3 }
    )
  } catch (e) {
    console.log(e)
    throw new Error('Failed to create a new environment')
  }

  await createConfigurationFiles({
    managementToken: config.managementToken,
    spaceId: config.spaceId,
    environmentId
  })

  await buildExtensions({
    testLocalSdk: config.testLocalSdk
  })

  await deployExtensions()

  await runCypress()
}

;(async function main() {
  try {
    await run()
    await cleanup()
    process.exit(0)
  } catch (err) {
    console.log(err)
    await cleanup()
    process.exit(1)
  }
})()
<|endoftext|>


<commit_before>
// 初期化
// 監視を開始
// 新しい処理が登録されると、カウントアップ
// 処理が終われば、カレントのCOMPLETEをTrueにする
// 定期的にカレントの処理が終わってるか確認する
// カレントのCOMPLETEがTrueならカレントアップと同時に、次の処理を実行

// 登録する処理の第１引数は、コールバック関数が自動で入る
// 必ず登録する処理の最後に、第１引数のコールバック関数を実行すること

class ProcessStack {
  constructor(repeatMs = 100) {
    this.count = 0;
    this.current = 0;
    this.REPEAT_MS = repeatMs;
    this.stack = [];

    Log.log();
    Log.log('ProcessStack', Log.ALIGN_CENTER);

    // 初期化
    this.push();
    this.stack[this.current].COMPLETE = true;

    // 監視を開始
    Log.logClass('ProcessStack', 'Monitoring');
    this.check();
  }

  // カレントの監視
  check() {
    setTimeout(() => {
      // Log.logClass('ProcessStack', 'Check');
      // カレントの存在確認
      if (this.stack[this.current] != null) {
        // Log.logClass('ProcessStack', 'Current is exists');
        // カレントが存在する
        // カレントの終了確認
        if (this.stack[this.current].COMPLETE) {
          // Log.logClassKey('ProcessStack', this.stack[this.current].NAME, `ID:${this.current} / Check Complete`);
          // カレントが終了している
          // 次の処理が登録されているか確認
          if (this.stack[this.current + 1] != null) {
            // カレントアップ
            this.current ++;
            // 次の処理を実行する
            Log.logClassKey('ProcessStack', this.stack[this.current].NAME, `ID:${this.current} / Run`);
            this.stack[this.current].FUNCTION(() => {
              // 次の処理の第１引数に処理終了のコールバック関数を入れる
              Log.logClassKey('ProcessStack', this.stack[this.current].NAME, `ID:${this.current} / Complete`);
              this.stack[this.current].COMPLETE = true;
            });
          } else {
            // Log.logClass('ProcessStack', 'Next is not exists');
          }
        }
      }
      // カレントの監視を再実行
      this.check();
    }, this.REPEAT_MS);
  }

  // 新しい処理の登録
  push({
    name = `Stack ${this.count}`,
    func = (callback) => {callback();}
  } = {}) {

    this.stack[this.count] = {};
    this.stack[this.count].NAME = name;
    this.stack[this.count].FUNCTION = func;
    this.stack[this.count].COMPLETE = false;

    if (this.count == 0) {
      Log.logClass('ProcessStack', 'Initialize');
    } else {
      Log.logClassKey('ProcessStack', this.stack[this.count].NAME, `ID:${this.count} / Set`);
    }

    // カウントアップ
    this.count ++;
  }
}
<commit_msg>Upgrade ProcessStack<commit_after>
// 初期化
// 監視を開始
// 新しい処理が登録されると、カウントアップ
// 処理が終われば、カレントのCOMPLETEをTrueにする
// 定期的にカレントの処理が終わってるか確認する
// カレントのCOMPLETEがTrueならカレントアップと同時に、次の処理を実行

// 登録する処理の第１引数は、コールバック関数が自動で入る
// 必ず登録する処理の最後に、第１引数のコールバック関数を実行すること

class ProcessStack {
  constructor() {
    this.NAME = 'ProcessStack';
    this.REPEAT_MS_INIT = 100;
    this.REPEAT_MS_DIFF = 1.5;
    this.REPEAT_MS_MIN = 1000 / 60;
    this.REPEAT_MS_MAX = 5000;

    this.count = 0;
    this.current = 0;
    this.stack = [];

    this.initializeSpeed();

    Log.log();
    Log.log(this.NAME, Log.ALIGN_CENTER);

    // 初期化
    this.push();
    this.stack[this.current].COMPLETE = true;

    // 監視を開始
    Log.logClass(this.NAME, 'Monitoring');
    this.check();
  }

  // カレントの監視
  check() {
    setTimeout(() => {
      // Log.logClass(this.NAME, 'Check');
      // カレントの存在確認
      if (this.stack[this.current] != null) {
        // Log.logClass(this.NAME, 'Current is exists');
        // Log.logClassKey(this.NAME, 'this.repeatMs', this.repeatMs);
        // カレントが存在する
        // カレントの終了確認
        if (this.stack[this.current].COMPLETE) {
          // Log.logClassKey(this.NAME, this.stack[this.current].NAME, `ID:${this.current} / Check Complete`);
          // カレントが終了している
          // 次の処理が登録されているか確認
          if (this.stack[this.current + 1] != null) {
            // 処理速度を早くする
            this.changeSpeed(true);
            // カレントアップ
            this.current ++;
            // 次の処理を実行する
            // Log.logClassKey(this.NAME, this.stack[this.current].NAME, `ID:${this.current} / Run`);
            this.stack[this.current].FUNCTION(() => {
              // 次の処理の第１引数に処理終了のコールバック関数を入れる
              // Log.logClassKey(this.NAME, this.stack[this.current].NAME, `ID:${this.current} / Complete`);
              this.stack[this.current].COMPLETE = true;
            });
          } else {
            // Log.logClass(this.NAME, 'Next is not exists');
            // 処理速度を遅くする
            this.changeSpeed(false);
          }
        } else {
          // 処理速度を遅くする
          this.changeSpeed(false);
        }
      }
      // カレントの監視を再実行
      this.check();
    }, this.repeatMs);
  }

  // 新しい処理の登録
  push({
    name = `Stack ${this.count}`,
    func = (callback) => {callback();}
  } = {}) {

    this.stack[this.count] = {};
    this.stack[this.count].NAME = name;
    this.stack[this.count].FUNCTION = func;
    this.stack[this.count].COMPLETE = false;

    this.initializeSpeed();

    if (this.count == 0) {
      Log.logClass(this.NAME, 'Initialize');
    } else {
      Log.logClassKey(this.NAME, this.stack[this.count].NAME, `ID:${this.count} / Set`);
    }

    // カウントアップ
    this.count ++;
  }

  initializeSpeed() {
    this.repeatMs = this.REPEAT_MS_INIT;
  }

  changeSpeed(_type) {
    if (_type) {
      if (this.repeatMs > this.REPEAT_MS_MIN) {
        this.repeatMs /= this.REPEAT_MS_DIFF;
        if (this.repeatMs < this.REPEAT_MS_MIN) {
          this.repeatMs = this.REPEAT_MS_MIN;
        }
      }
    } else {
      if (this.repeatMs < this.REPEAT_MS_MAX) {
        this.repeatMs *= this.REPEAT_MS_DIFF;
        if (this.repeatMs > this.REPEAT_MS_MAX) {
          this.repeatMs = this.REPEAT_MS_MAX;
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');
const assert = require('assert');
const isPlainObject = require('lodash/isPlainObject');
const eslint = require('eslint');

function runEslint ( file, config ) {
	const linter = new eslint.CLIEngine({
		useEslintrc: false,
		baseConfig: config
	});
	return linter.executeOnText(fs.readFileSync(path.join(__dirname, file), 'utf8')).results[0].messages.map(( err ) => {
		if ( err.ruleId === null && err.fatal === true ) {
			return 'parsing error';
		}
		return err.ruleId;
	});
}

describe('Dependencies', function () {

	it('should have all "dependencies" defined in "peerDependencies"', function () {
		const pkg = require('../package.json');
		assert.deepStrictEqual(pkg.dependencies, pkg.peerDependencies);
	});

});

describe('Config format', function () {

	const config = require('../');

	it('should have config objects which are plain objects', function () {
		assert.ok(isPlainObject(config));
		assert.ok(isPlainObject(config.env));
		assert.ok(isPlainObject(config.rules));
	});

});

describe('Default config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/default.config.js', {
			'extends': require.resolve('../')
		});
		const errorsNonStrict = runEslint('./fixtures/default-non-strict.config.js', {
			'extends': require.resolve('../')
		});
		assert.notEqual(errors.indexOf('quotes'), -1);
		assert.notEqual(errors.indexOf('semi'), -1);
		assert.notEqual(errors.indexOf('promise/param-names'), -1);
		assert.notEqual(errors.indexOf('extend/no-unsafe-extend-inside-call'), -1);
		assert.notEqual(errors.indexOf('extend/no-unsafe-extend-inside-assignment'), -1);
		assert.notEqual(errors.indexOf('unicorn/throw-new-error'), -1);
		assert.notEqual(errors.indexOf('no-const-assign'), -1);
		assert.notEqual(errors.indexOf('prefer-template'), -1);
		assert.notEqual(errors.indexOf('node/no-unsupported-features'), -1);
		assert.notEqual(errorsNonStrict.indexOf('parsing error'), -1);
	});

});

describe('Browser config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/browser.config.js', {
			'extends': [
				'../',
				'../browser'
			].map(require.resolve)
		});
		assert.notEqual(errors.indexOf('no-console'), -1);
		assert.notEqual(errors.indexOf('quotes'), -1);
		assert.notEqual(errors.indexOf('semi'), -1);
	});

});

describe('Next config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/next.config.js', {
			'extends': [
				'../',
				'../next'
			].map(require.resolve)
		});
		assert.notEqual(errors.indexOf('no-unused-vars'), -1);
		assert.notEqual(errors.indexOf('arrow-parens'), -1);
		assert.notEqual(errors.indexOf('quotes'), -1);
		assert.notEqual(errors.indexOf('semi'), -1);
	});

});

describe('Tests config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/tests.config.js', {
			'extends': [
				'../',
				'../tests'
			].map(require.resolve)
		});
		assert.notEqual(errors.indexOf('max-nested-callbacks'), -1);
		assert.notEqual(errors.indexOf('mocha/no-mocha-arrows'), -1);
		assert.equal(errors.indexOf('promise/always-return'), -1);
	});

});

describe('React config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/react.config.js', {
			'extends': [
				'../',
				'../react'
			].map(require.resolve)
		});
		assert.equal(errors.length, 0);
	});

});

describe('Vue config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/vue.config.js', {
			'extends': [
				'../',
				'../vue'
			].map(require.resolve)
		});
		assert.equal(errors.length, 0);
	});

});
<commit_msg>Adjust configuration details<commit_after>'use strict';

const fs = require('fs');
const path = require('path');
const assert = require('assert');
const isPlainObject = require('lodash/isPlainObject');
const eslint = require('eslint');

function runEslint ( file, config ) {
	const linter = new eslint.CLIEngine({
		useEslintrc: false,
		baseConfig: config
	});
	return linter.executeOnText(fs.readFileSync(path.join(__dirname, file), 'utf8')).results[0].messages.map(( err ) => {
		if ( err.ruleId === null && err.fatal === true ) {
			return 'parsing error';
		}
		return err.ruleId;
	});
}

describe('Dependencies', function () {

	it('should have all "dependencies" defined in "peerDependencies"', function () {
		const pkg = require('../package.json');
		assert.deepStrictEqual(pkg.dependencies, pkg.peerDependencies);
	});

});

describe('Config format', function () {

	const config = require('../');

	it('should have config objects which are plain objects', function () {
		assert.ok(isPlainObject(config));
		assert.ok(isPlainObject(config.env));
		assert.ok(isPlainObject(config.rules));
	});

});

describe('Default config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/default.config.js', {
			'extends': require.resolve('../')
		});
		const errorsNonStrict = runEslint('./fixtures/default-non-strict.config.js', {
			'extends': require.resolve('../')
		});
		assert.notEqual(errors.indexOf('quotes'), -1);
		assert.notEqual(errors.indexOf('semi'), -1);
		assert.notEqual(errors.indexOf('promise/param-names'), -1);
		assert.notEqual(errors.indexOf('extend/no-unsafe-extend-inside-call'), -1);
		assert.notEqual(errors.indexOf('extend/no-unsafe-extend-inside-assignment'), -1);
		assert.notEqual(errors.indexOf('unicorn/throw-new-error'), -1);
		assert.notEqual(errors.indexOf('no-const-assign'), -1);
		assert.notEqual(errors.indexOf('prefer-template'), -1);
		assert.notEqual(errors.indexOf('node/no-unsupported-features'), -1);
		assert.notEqual(errorsNonStrict.indexOf('parsing error'), -1);
	});

});

describe('Browser config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/browser.config.js', {
			'extends': [
				'../',
				'../browser'
			].map(require.resolve)
		});
		assert.notEqual(errors.indexOf('no-console'), -1);
	});

});

describe('Next config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/next.config.js', {
			'extends': [
				'../',
				'../next'
			].map(require.resolve)
		});
		assert.notEqual(errors.indexOf('no-unused-vars'), -1);
		assert.notEqual(errors.indexOf('arrow-parens'), -1);
		assert.notEqual(errors.indexOf('quotes'), -1);
		assert.notEqual(errors.indexOf('semi'), -1);
	});

});

describe('Tests config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/tests.config.js', {
			'extends': [
				'../',
				'../tests'
			].map(require.resolve)
		});
		assert.notEqual(errors.indexOf('max-nested-callbacks'), -1);
		assert.notEqual(errors.indexOf('mocha/no-mocha-arrows'), -1);
		assert.equal(errors.indexOf('promise/always-return'), -1);
	});

});

describe('React config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/react.config.js', {
			'extends': [
				'../',
				'../react'
			].map(require.resolve)
		});
		assert.equal(errors.length, 0);
	});

});

describe('Vue config', function () {

	it('should return proper validation errors for linted code', function () {
		const errors = runEslint('./fixtures/vue.config.js', {
			'extends': [
				'../',
				'../vue'
			].map(require.resolve)
		});
		assert.equal(errors.length, 0);
	});

});
<|endoftext|>


<commit_before>window.cls = window.cls || {};

/**
 * Base class for views that show details about a resource
 */
cls.ResourceDetailBase = function()
{
  this.resourcedata = null;
  this.container = null;
  this.drawer = null;
  this.title = null

  // interface:

  /**
   * Override this method in subclasses to to the type specific rendering.
   * The method is called from the main createView function. If it returns
   * something, that is treated as a template and inserted.
   * If it returns something falsy, then the assumption is that the method
   * has inserted the approprate content into the container itself.
   */
  this.render_type_details = function(container, resource, resourcedata) {}

  this.createView = function(container)
  {
    container.clearAndRender(this.drawer.render());
    if (!this.resourcedata)
    {
      var resptype = cls.ResourceUtil.mime_to_content_mode(this.resource.mime);
      this.service.fetch_resource_data(this.on_resource_data.bind(this),
                                       this.resource.id, resptype);
    }
    else
    {
      var tpl = this.render_type_details(container, this.resource, this.resourcedata);
      if (tpl)
      {
        container.render(tpl);
        cls.ResourceDetailBase.sync_dimensions(container);
      }
    }

  }

  this.render_type_details = function(container, resource, resourcedata)
  {
    return ["h1", "No resource details"];
  }

  this.on_resource_data = function(type, data)
  {
    const CONTENT = 5, TEXTCONTENT = 3;
    this.resourcedata = data[CONTENT] ? data[CONTENT][TEXTCONTENT] : null;
    this.update();
  }

  this.init = function(res, service)
  {
    this.service = service;
    this.resource = res;
    this.resourcedata = null;
    this.filename = cls.ResourceUtil.url_filename(res.url) || "<no name>";
    this.drawer = new MetadataDrawer(res);
    this.drawer.expanded = false;
    cls.ResourceDetailBase.prototype.init.call(this, this.filename);
  }
}
cls.ResourceDetailBase.prototype = new TempView();

cls.ResourceDetailBase.sync_dimensions = function(container)
{
    var metadata_drawer = container.getElementsByClassName('metadata-drawer')[0];
    var resource_details = container.getElementsByClassName('resource-detail-container')[0];
    if (metadata_drawer && resource_details)
    {
        resource_details.style.borderTopWidth = metadata_drawer.offsetHeight + 'px';
    }
}

cls.GenericResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return ["h1", "Don't know what this resource is"];
  }

  this.init(res, service);
}
cls.GenericResourceDetail.prototype = new cls.ResourceDetailBase();

// any textual resource, like html, js and css
cls.TextResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.text_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.TextResourceDetail.prototype = new cls.ResourceDetailBase();

cls.JSResourceDetail = function(res, service, options)
{
  options = options || {};
  this.line = options.line;

  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.js_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.JSResourceDetail.prototype = new cls.ResourceDetailBase();

cls.ImageResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.image_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.ImageResourceDetail.prototype = new cls.ResourceDetailBase();

cls.FontResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.font_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.FontResourceDetail.prototype = new cls.ResourceDetailBase();

cls.MarkupResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.markup_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.MarkupResourceDetail.prototype = new cls.ResourceDetailBase();

cls.CSSResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.css_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.CSSResourceDetail.prototype = new cls.ResourceDetailBase();

window.templates = window.templates || {};

window.templates.text_resource_view = function(resource, resourcedata)
{
  return [
    ['div',
        ["code", ["pre", resourcedata]],
        'class', 'resource-detail-container'
    ]
  ]
}

window.templates.js_resource_view = function(resource, resourcedata)
{
  var line_count = 1;
  var lines = [line_count++];
  var source = this.highlight_js_source(resourcedata, function()
  {
    lines.push(line_count++);
  });
  return (
  ['div',
    source,
    ['div', lines.join('\n'), 'class', 'resource-line-numbers', 'unselectable', 'on'],
    'class', 'resource-detail-container mono line-numbered-resource js-resource-content'
  ]);
}

window.templates.markup_resource_view = function(resource, resourcedata)
{
  var line_count = 1;
  var lines = [line_count++];
  var source = this.highlight_markup(resourcedata, function()
  {
    lines.push(line_count++);
  });
  return (
    ['div',
      source,
      ['div', lines.join('\n'), 'class', 'resource-line-numbers', 'unselectable', 'on'],
      'class', 'resource-detail-container mono line-numbered-resource markup-resource-content'
    ])
}
window.templates.css_resource_view = function(resource, resourcedata)
{
  var line_count = 1;
  var lines = [line_count++];
  var source = this.highlight_css(resourcedata, function()
  {
    lines.push(line_count++);
  });
  return (
    ['div',
      source,
      ['div', lines.join('\n'), 'class', 'resource-line-numbers', 'unselectable', 'on'],
      'class', 'resource-detail-container mono line-numbered-resource css-resource-content'
    ])
}

window.templates.image_resource_view = function(resource, resourcedata)
{
  return [
      ['div',
       ["img", "src", resourcedata,
        'class', 'resource-image'
       ],
       'class', 'resource-detail-container resource-image-container'
      ]
  ]
}

window.templates.font_resource_view = function(resource, data)
{
  return ['div',
    templates.font_style(resource, data),
    ["div", "The quick brown fox jumped over the lazy dog", ["br"], "1234567890",
     "style", "font-family: fontresource-" + resource.id,
     "class", "font-preview",
     "contenteditable", "true"],
    'class', 'resource-detail-container'
  ]
}

window.templates.font_style = function(resource, data)
{
  var rule = [
    "@font-face {",
      'font-family: "fontresource-' + resource.id + '";',
      "src: url(" + data + ");",
    "}"
  ].join("\n\n");
  return ["style", rule];
};
<commit_msg>Fixed neverending loop bug. Closes DFL-1985<commit_after>window.cls = window.cls || {};

/**
 * Base class for views that show details about a resource
 */
cls.ResourceDetailBase = function()
{
  this.resourcedata = null;
  this.container = null;
  this.drawer = null;
  this.title = null

  // interface:

  /**
   * Override this method in subclasses to to the type specific rendering.
   * The method is called from the main createView function. If it returns
   * something, that is treated as a template and inserted.
   * If it returns something falsy, then the assumption is that the method
   * has inserted the approprate content into the container itself.
   */
  this.render_type_details = function(container, resource, resourcedata) {}

  this.createView = function(container)
  {
    container.clearAndRender(this.drawer.render());
    if (this.resourcedata === null)
    {
      var resptype = cls.ResourceUtil.mime_to_content_mode(this.resource.mime);
      this.service.fetch_resource_data(this.on_resource_data.bind(this),
                                       this.resource.id, resptype);
    }
    else
    {
      var tpl = this.render_type_details(container, this.resource, this.resourcedata);
      if (tpl)
      {
        container.render(tpl);
        cls.ResourceDetailBase.sync_dimensions(container);
      }
    }

  }

  this.render_type_details = function(container, resource, resourcedata)
  {
    return ["h1", "No resource details"];
  }

  this.on_resource_data = function(type, data)
  {
    const CONTENT = 5, TEXTCONTENT = 3;
    this.resourcedata = data[CONTENT] ? data[CONTENT][TEXTCONTENT] : "";

    this.update();
  }

  this.init = function(res, service)
  {
    this.service = service;
    this.resource = res;
    this.resourcedata = null;
    this.filename = cls.ResourceUtil.url_filename(res.url) || "<no name>";
    this.drawer = new MetadataDrawer(res);
    this.drawer.expanded = false;
    cls.ResourceDetailBase.prototype.init.call(this, this.filename);
  }
}
cls.ResourceDetailBase.prototype = new TempView();

cls.ResourceDetailBase.sync_dimensions = function(container)
{
    var metadata_drawer = container.getElementsByClassName('metadata-drawer')[0];
    var resource_details = container.getElementsByClassName('resource-detail-container')[0];
    if (metadata_drawer && resource_details)
    {
        resource_details.style.borderTopWidth = metadata_drawer.offsetHeight + 'px';
    }
}

cls.GenericResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return ["h1", "Don't know what this resource is"];
  }

  this.init(res, service);
}
cls.GenericResourceDetail.prototype = new cls.ResourceDetailBase();

// any textual resource, like html, js and css
cls.TextResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.text_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.TextResourceDetail.prototype = new cls.ResourceDetailBase();

cls.JSResourceDetail = function(res, service, options)
{
  options = options || {};
  this.line = options.line;

  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.js_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.JSResourceDetail.prototype = new cls.ResourceDetailBase();

cls.ImageResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.image_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.ImageResourceDetail.prototype = new cls.ResourceDetailBase();

cls.FontResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.font_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.FontResourceDetail.prototype = new cls.ResourceDetailBase();

cls.MarkupResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.markup_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.MarkupResourceDetail.prototype = new cls.ResourceDetailBase();

cls.CSSResourceDetail = function(res, service)
{
  this.render_type_details = function(container, resource, resourcedata)
  {
    return window.templates.css_resource_view(resource, resourcedata);
  }

  this.init(res, service);
}
cls.CSSResourceDetail.prototype = new cls.ResourceDetailBase();

window.templates = window.templates || {};

window.templates.text_resource_view = function(resource, resourcedata)
{
  return [
    ['div',
        ["code", ["pre", resourcedata]],
        'class', 'resource-detail-container'
    ]
  ]
}

window.templates.js_resource_view = function(resource, resourcedata)
{
  var line_count = 1;
  var lines = [line_count++];
  var source = this.highlight_js_source(resourcedata, function()
  {
    lines.push(line_count++);
  });
  return (
  ['div',
    source,
    ['div', lines.join('\n'), 'class', 'resource-line-numbers', 'unselectable', 'on'],
    'class', 'resource-detail-container mono line-numbered-resource js-resource-content'
  ]);
}

window.templates.markup_resource_view = function(resource, resourcedata)
{
  var line_count = 1;
  var lines = [line_count++];
  var source = this.highlight_markup(resourcedata, function()
  {
    lines.push(line_count++);
  });
  return (
    ['div',
      source,
      ['div', lines.join('\n'), 'class', 'resource-line-numbers', 'unselectable', 'on'],
      'class', 'resource-detail-container mono line-numbered-resource markup-resource-content'
    ])
}
window.templates.css_resource_view = function(resource, resourcedata)
{
  var line_count = 1;
  var lines = [line_count++];
  var source = this.highlight_css(resourcedata, function()
  {
    lines.push(line_count++);
  });
  return (
    ['div',
      source,
      ['div', lines.join('\n'), 'class', 'resource-line-numbers', 'unselectable', 'on'],
      'class', 'resource-detail-container mono line-numbered-resource css-resource-content'
    ])
}

window.templates.image_resource_view = function(resource, resourcedata)
{
  return [
      ['div',
       ["img", "src", resourcedata,
        'class', 'resource-image'
       ],
       'class', 'resource-detail-container resource-image-container'
      ]
  ]
}

window.templates.font_resource_view = function(resource, data)
{
  return ['div',
    templates.font_style(resource, data),
    ["div", "The quick brown fox jumped over the lazy dog", ["br"], "1234567890",
     "style", "font-family: fontresource-" + resource.id,
     "class", "font-preview",
     "contenteditable", "true"],
    'class', 'resource-detail-container'
  ]
}

window.templates.font_style = function(resource, data)
{
  var rule = [
    "@font-face {",
      'font-family: "fontresource-' + resource.id + '";',
      "src: url(" + data + ");",
    "}"
  ].join("\n\n");
  return ["style", rule];
};
<|endoftext|>


<commit_before>//  Copyright 2002-2014, University of Colorado Boulder

/**
 * This grunt task creates a simulation based on the simula-rasa template.
 * Run from any repository directory that is a sibling of simula-rasa.
 *
 * Example usage:
 * grunt create-sim --name=cannon-blaster --author="Sam Reid (PhET Interactive Simulations)"
 *
 * This task will attempt to coerce a sim title from the repository name. For example,
 * 'cannon-blaster' becomes 'Cannon Blaster'.  If this is not suitable, then use --title
 * to specify a title.  For example:
 * grunt create-sim --name=fractions-basics --title="Fractions: Basics" --author="Sam Reid (PhET Interactive Simulations)"
 *
 * For development and debugging, add --clean=true to delete the repository directory.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chris Malley (PixelZoom, Inc.)
 */

var fs = require( 'fs' );

/**
 * @param grunt the grunt instance
 * @param {string} repositoryName the repository name.  All lower case and hyphenated, like circuit-construction-kit
 * @param {string} author the new author for the project
 * @param {string} [title] optional title. If not provide, will attempt to coerce the repository name to a title.
 * @param {boolean} [clean] whether to delete the repository directory if it already exists, useful for development and debugging
 */
module.exports = function( grunt, repositoryName, author, title, clean ) {
  'use strict';

  // Check for required parameters
  if ( typeof( repositoryName ) === 'undefined' ) {
    throw new Error( 'repositoryName unspecified, use --name=...' );
  }
  if ( typeof( author ) === 'undefined' ) {
    throw new Error( 'Author unspecified, use --author=...' );
  }

  grunt.log.writeln( 'Greetings ' + author + '!' );
  grunt.log.writeln( 'creating sim with repository name ' + repositoryName );

  var destinationPath = '../' + repositoryName;
  if ( clean && fs.existsSync( destinationPath ) ) {
    grunt.log.writeln( 'Cleaning ' + destinationPath );
    grunt.file.delete( destinationPath, { force: true } ); // delete won't operate outside of current working dir unless forced
  }

  // Create the directory, if it didn't exist
  if ( fs.existsSync( destinationPath ) ) {
    throw new Error( destinationPath + ' already exists. Run with --clean if you want to do over.' );
  }
  grunt.file.mkdir( destinationPath );

  // Replace a single occurrence in a string (if any) with another.
  var replaceOneString = function( str, substring, replacement ) {
    var idx = str.indexOf( substring );
    if ( str.indexOf( substring ) !== -1 ) {
      return str.slice( 0, idx ) + replacement + str.slice( idx + substring.length );
    }
    else {
      return str;
    }
  };

  // Replace all occurrences of a string recursively
  var replaceAllString = function( str, substring, replacement ) {
    var replaced = replaceOneString( str, substring, replacement );
    if ( replaced === str ) {
      return replaced;
    }
    else {
      return replaceAllString( replaced, substring, replacement );
    }
  };

  // See http://stackoverflow.com/questions/10425287/convert-string-to-camelcase-with-regular-expression
  // Eg: 'simula-rasa' -> 'simulaRasa'
  function toCamelCase( input ) {
    return input.toLowerCase().replace( /-(.)/g, function( match, group1 ) {
      return group1.toUpperCase();
    } );
  }

  // Coerces a repository name to a sim title. Eg, 'simula-rasa' -> 'Simula Rasa'
  function toTitle( input ) {
    var tmpString = input.replace( /-(.)/g, function( match, group1 ) {
      return ' ' + group1.toUpperCase();
    } );
    return tmpString.substring( 0, 1 ).toUpperCase() + tmpString.substring( 1 );
  }

  // Create variations of the repository name
  var configPath = replaceAllString( repositoryName.toUpperCase(), '-', '_' ); // eg, 'simula-rasa' -> 'SIMULA_RASA'
  var lowerCamelCase = toCamelCase( repositoryName ); // eg, 'simula-rasa' -> 'simulaRasa'
  var upperCamelCase = lowerCamelCase.substring( 0, 1 ).toUpperCase() + lowerCamelCase.substring( 1 ); // eg, 'simula-rasa' -> 'SimulaRasa'
  title = title || toTitle( repositoryName ); // eg, 'simula-rasa' -> 'Simula Rasa'

  // Iterate over the file system and copy files, changing filenames and contents as we go.
  grunt.file.recurse( '../simula-rasa', function( abspath, rootdir, subdir, filename ) {

      // skip these files
      if ( abspath.indexOf( '../simula-rasa/README.md' ) === 0 ||
           abspath.indexOf( '../simula-rasa/node_modules/' ) === 0 ||
           abspath.indexOf( '../simula-rasa/.git/' ) === 0 ||
           abspath.indexOf( '../simula-rasa/build/' ) === 0 ) {
      }
      else {
        var contents = grunt.file.read( abspath );

        // Replace variations of the repository name
        contents = replaceAllString( contents, 'simula-rasa', repositoryName );
        contents = replaceAllString( contents, 'SIMULA_RASA', configPath );
        contents = replaceAllString( contents, 'simulaRasa', lowerCamelCase );
        contents = replaceAllString( contents, 'SimulaRasa', upperCamelCase );
        contents = replaceAllString( contents, 'Simula Rasa', title );

        // Replace author
        contents = replaceAllString( contents, 'Your Name (Your Affiliation)', author );

        // Replace names in the path where the contents will be written
        var contentsPath = subdir ? ( destinationPath + '/' + subdir + '/' + filename ) : ( destinationPath + '/' + filename );
        contentsPath = replaceOneString( contentsPath, 'simula-rasa', repositoryName );
        contentsPath = replaceOneString( contentsPath, 'SimulaRasa', upperCamelCase );

        // Write the file
        grunt.file.write( contentsPath, contents );
        grunt.log.writeln( 'wrote', contentsPath );
      }
    }
  );

  grunt.log.writeln( 'Please generate README.md for your new repository using "grunt generate-unpublished-repo"' );
};<commit_msg>#120 fix typo in message<commit_after>//  Copyright 2002-2014, University of Colorado Boulder

/**
 * This grunt task creates a simulation based on the simula-rasa template.
 * Run from any repository directory that is a sibling of simula-rasa.
 *
 * Example usage:
 * grunt create-sim --name=cannon-blaster --author="Sam Reid (PhET Interactive Simulations)"
 *
 * This task will attempt to coerce a sim title from the repository name. For example,
 * 'cannon-blaster' becomes 'Cannon Blaster'.  If this is not suitable, then use --title
 * to specify a title.  For example:
 * grunt create-sim --name=fractions-basics --title="Fractions: Basics" --author="Sam Reid (PhET Interactive Simulations)"
 *
 * For development and debugging, add --clean=true to delete the repository directory.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chris Malley (PixelZoom, Inc.)
 */

var fs = require( 'fs' );

/**
 * @param grunt the grunt instance
 * @param {string} repositoryName the repository name.  All lower case and hyphenated, like circuit-construction-kit
 * @param {string} author the new author for the project
 * @param {string} [title] optional title. If not provide, will attempt to coerce the repository name to a title.
 * @param {boolean} [clean] whether to delete the repository directory if it already exists, useful for development and debugging
 */
module.exports = function( grunt, repositoryName, author, title, clean ) {
  'use strict';

  // Check for required parameters
  if ( typeof( repositoryName ) === 'undefined' ) {
    throw new Error( 'repositoryName unspecified, use --name=...' );
  }
  if ( typeof( author ) === 'undefined' ) {
    throw new Error( 'Author unspecified, use --author=...' );
  }

  grunt.log.writeln( 'Greetings ' + author + '!' );
  grunt.log.writeln( 'creating sim with repository name ' + repositoryName );

  var destinationPath = '../' + repositoryName;
  if ( clean && fs.existsSync( destinationPath ) ) {
    grunt.log.writeln( 'Cleaning ' + destinationPath );
    grunt.file.delete( destinationPath, { force: true } ); // delete won't operate outside of current working dir unless forced
  }

  // Create the directory, if it didn't exist
  if ( fs.existsSync( destinationPath ) ) {
    throw new Error( destinationPath + ' already exists. Run with --clean if you want to do over.' );
  }
  grunt.file.mkdir( destinationPath );

  // Replace a single occurrence in a string (if any) with another.
  var replaceOneString = function( str, substring, replacement ) {
    var idx = str.indexOf( substring );
    if ( str.indexOf( substring ) !== -1 ) {
      return str.slice( 0, idx ) + replacement + str.slice( idx + substring.length );
    }
    else {
      return str;
    }
  };

  // Replace all occurrences of a string recursively
  var replaceAllString = function( str, substring, replacement ) {
    var replaced = replaceOneString( str, substring, replacement );
    if ( replaced === str ) {
      return replaced;
    }
    else {
      return replaceAllString( replaced, substring, replacement );
    }
  };

  // See http://stackoverflow.com/questions/10425287/convert-string-to-camelcase-with-regular-expression
  // Eg: 'simula-rasa' -> 'simulaRasa'
  function toCamelCase( input ) {
    return input.toLowerCase().replace( /-(.)/g, function( match, group1 ) {
      return group1.toUpperCase();
    } );
  }

  // Coerces a repository name to a sim title. Eg, 'simula-rasa' -> 'Simula Rasa'
  function toTitle( input ) {
    var tmpString = input.replace( /-(.)/g, function( match, group1 ) {
      return ' ' + group1.toUpperCase();
    } );
    return tmpString.substring( 0, 1 ).toUpperCase() + tmpString.substring( 1 );
  }

  // Create variations of the repository name
  var configPath = replaceAllString( repositoryName.toUpperCase(), '-', '_' ); // eg, 'simula-rasa' -> 'SIMULA_RASA'
  var lowerCamelCase = toCamelCase( repositoryName ); // eg, 'simula-rasa' -> 'simulaRasa'
  var upperCamelCase = lowerCamelCase.substring( 0, 1 ).toUpperCase() + lowerCamelCase.substring( 1 ); // eg, 'simula-rasa' -> 'SimulaRasa'
  title = title || toTitle( repositoryName ); // eg, 'simula-rasa' -> 'Simula Rasa'

  // Iterate over the file system and copy files, changing filenames and contents as we go.
  grunt.file.recurse( '../simula-rasa', function( abspath, rootdir, subdir, filename ) {

      // skip these files
      if ( abspath.indexOf( '../simula-rasa/README.md' ) === 0 ||
           abspath.indexOf( '../simula-rasa/node_modules/' ) === 0 ||
           abspath.indexOf( '../simula-rasa/.git/' ) === 0 ||
           abspath.indexOf( '../simula-rasa/build/' ) === 0 ) {
      }
      else {
        var contents = grunt.file.read( abspath );

        // Replace variations of the repository name
        contents = replaceAllString( contents, 'simula-rasa', repositoryName );
        contents = replaceAllString( contents, 'SIMULA_RASA', configPath );
        contents = replaceAllString( contents, 'simulaRasa', lowerCamelCase );
        contents = replaceAllString( contents, 'SimulaRasa', upperCamelCase );
        contents = replaceAllString( contents, 'Simula Rasa', title );

        // Replace author
        contents = replaceAllString( contents, 'Your Name (Your Affiliation)', author );

        // Replace names in the path where the contents will be written
        var contentsPath = subdir ? ( destinationPath + '/' + subdir + '/' + filename ) : ( destinationPath + '/' + filename );
        contentsPath = replaceOneString( contentsPath, 'simula-rasa', repositoryName );
        contentsPath = replaceOneString( contentsPath, 'SimulaRasa', upperCamelCase );

        // Write the file
        grunt.file.write( contentsPath, contents );
        grunt.log.writeln( 'wrote', contentsPath );
      }
    }
  );

  grunt.log.writeln( 'Please generate README.md for your new repository by running "grunt generate-unpublished-README"' );
};<|endoftext|>


<commit_before>var express = require('express'),
      https = require('https'),
   sessions = require('client-sessions'),
      redis = require("redis");

// create a connection to the redis datastore
var db = redis.createClient();

db.on("error", function (err) {
  console.log("Redis Error " + err);
  process.exit(1);
});

var app = express.createServer(
  express.logger(),
  express.bodyParser(),
  sessions({
    cookieName: '123done',
    secret: process.env['COOKIE_SECRET'] || 'define a real secret, please',
    cookie: {
      path: '/api',
      httpOnly: true
    }
  })
);

// a function to verify that the current user is authenticated
function checkAuth(req, res, next) {
  if (!req.session.user) {
    res.send("authentication required\n", 401);
  } else {
    next();
  }
}

app.post('/api/verify', function(req, res) {
  var body = JSON.stringify({
    assertion: req.body.assertion,
    audience: process.env['PUBLIC_URL'] || 'http://127.0.0.1:8080'
  });

  var vreq = https.request({
    host: 'dev.diresworb.org',
    path: '/verify',
    method: 'POST',
    headers: {
      'Content-Length': body.length,
      'Content-Type': 'application/json'
    }
  }, function (vres) {
    var body = "";
    vres.on('data', function(chunk) { body += chunk; });
    vres.on('end', function() {
      try {
        // if response is successful, indicate the user is logged in
        req.session.user = JSON.parse(body).email;
      } catch(e) {
      }
      res.send(body);
    });
  });
  vreq.write(body);
  vreq.end();
});

// auth status reports who the currently logged in user is on this
// session
app.get('/api/auth_status', function(req, res) {
  res.send(JSON.stringify({
    logged_in_email: req.session.user || null,
  }));
});

// logout clears the current authenticated user
app.post('/api/logout', checkAuth, function(req, res) {
  req.session.user = null;
  res.send(200);
});

// the 'todo/save' api saves a todo list
app.post('/api/todos/save', checkAuth, function(req, res) {
  db.set(req.session.user, JSON.stringify(req.body));
  res.send(200);
});

// the 'todo/get' api gets the current version of the todo list
// from the server
app.get('/api/todos/get', checkAuth, function(req, res) {
  db.get(req.session.user, function(err, reply) {
    if (err) {
      res.send(err.toString(), { 'Content-Type': 'text/plain' }, 500);
    } else {
      res.send(reply, { 'Content-Type': 'application/json' }, 200);
    }
  });
});

app.use(express.static(__dirname + "/static"));

app.listen(process.env['PORT'] || 8080, '0.0.0.0');
<commit_msg>don't exit hard if redis isn't available, for local dev<commit_after>var express = require('express'),
      https = require('https'),
   sessions = require('client-sessions'),
      redis = require("redis");

// create a connection to the redis datastore
var db = redis.createClient();

db.on("error", function (err) {
  db = null;
  console.log("redis error!  the server won't actually store anything!  this is just fine for local dev");
});

var app = express.createServer(
  express.logger(),
  express.bodyParser(),
  sessions({
    cookieName: '123done',
    secret: process.env['COOKIE_SECRET'] || 'define a real secret, please',
    cookie: {
      path: '/api',
      httpOnly: true
    }
  })
);

// a function to verify that the current user is authenticated
function checkAuth(req, res, next) {
  if (!req.session.user) {
    res.send("authentication required\n", 401);
  } else {
    next();
  }
}

app.post('/api/verify', function(req, res) {
  var body = JSON.stringify({
    assertion: req.body.assertion,
    audience: process.env['PUBLIC_URL'] || 'http://127.0.0.1:8080'
  });

  var vreq = https.request({
    host: 'dev.diresworb.org',
    path: '/verify',
    method: 'POST',
    headers: {
      'Content-Length': body.length,
      'Content-Type': 'application/json'
    }
  }, function (vres) {
    var body = "";
    vres.on('data', function(chunk) { body += chunk; });
    vres.on('end', function() {
      try {
        // if response is successful, indicate the user is logged in
        req.session.user = JSON.parse(body).email;
      } catch(e) {
      }
      res.send(body);
    });
  });
  vreq.write(body);
  vreq.end();
});

// auth status reports who the currently logged in user is on this
// session
app.get('/api/auth_status', function(req, res) {
  res.send(JSON.stringify({
    logged_in_email: req.session.user || null,
  }));
});

// logout clears the current authenticated user
app.post('/api/logout', checkAuth, function(req, res) {
  req.session.user = null;
  res.send(200);
});

// the 'todo/save' api saves a todo list
app.post('/api/todos/save', checkAuth, function(req, res) {
  if (db) db.set(req.session.user, JSON.stringify(req.body));
  res.send(200);
});

// the 'todo/get' api gets the current version of the todo list
// from the server
app.get('/api/todos/get', checkAuth, function(req, res) {
  if (db) {
    db.get(req.session.user, function(err, reply) {
      if (err) {
        res.send(err.toString(), { 'Content-Type': 'text/plain' }, 500);
      } else {
        res.send(reply, { 'Content-Type': 'application/json' }, 200);
      }
    });
  } else {
    res.send('[{"v": "Install redis locally for persistent storage, if I want to"}]',
             { 'Content-Type': 'application/json' }, 200);
  }
});

app.use(express.static(__dirname + "/static"));

app.listen(process.env['PORT'] || 8080, '0.0.0.0');
<|endoftext|>


<commit_before>game.SpendExp = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage("exp-screen")), -10); // TODO

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [10, 10, 300, 50]);
				this.font = new me.Font("Arial", 46, "white");
			},

			draw: function(renderer){
				this.font.draw(renderer.getContext(), "PRESS F1-F4 TO BUY, F5 TO SKIP", this.pos.x, this.pos.y);
				this.font.draw(renderer.getContext(), "CURRENT EXP: " + this.game.exp. toString(), this.pos.x + 100, this.pos.y + 50);
				this.font.draw(renderer.getContext(), "F1: INCREASE GOLD PRODUCTION" + this.game.exp. toString(), this.pos.x + 100, this.pos.y + 100);
				this.font.draw(renderer.getContext(), "F2: ADD STARTING GOLD" + this.game.exp. toString(), this.pos.x + 100, this.pos.y + 150);
				this.font.draw(renderer.getContext(), "F3: INCREASE ATTACK DAMAGE" + this.game.exp. toString(), this.pos.x + 100, this.pos.y + 200);
				this.font.draw(renderer.getContext(), "F4: INCRERASE STARTING HEALTH" + this.game.exp. toString(), this.pos.x + 100, this.pos.y + 250);

			},
		})));
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {

	}
});
y<commit_msg>Video 44. Added the buttons for the F functions<commit_after>game.SpendExp = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage("exp-screen")), -10); // TODO

		me.input.bindKey(me.input.KEY.F1, "F1");
		me.input.bindKey(me.input.KEY.F2, "F2");
		me.input.bindKey(me.input.KEY.F3, "F3");
		me.input.bindKey(me.input.KEY.F4, "F4");
		me.input.bindKey(me.input.KEY.F5, "F5");

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [10, 10, 300, 50]);
				this.font = new me.Font("Arial", 26, "white");
			},

			draw: function(renderer){
				this.font.draw(renderer.getContext(), "PRESS F1-F4 TO BUY, F5 TO SKIP", this.pos.x, this.pos.y);
				this.font.draw(renderer.getContext(), "CURRENT EXP: " + this.game.exp. toString(), this.pos.x + 100, this.pos.y + 50);
				this.font.draw(renderer.getContext(), "F1: INCREASE GOLD PRODUCTION CURRENT LEVEL: " + this.game.exp1.toString() + " COST: " + ((game.data.exp1 + 1) * 10), this.pos.x, this.pos.y + 100);
				this.font.draw(renderer.getContext(), "F2: ADD STARTING GOLD" + this.game.exp. toString(), this.pos.x, this.pos.y + 150);
				this.font.draw(renderer.getContext(), "F3: INCREASE ATTACK DAMAGE" + this.game.exp. toString(), this.pos.x, this.pos.y + 200);
				this.font.draw(renderer.getContext(), "F4: INCRERASE STARTING HEALTH" + this.game.exp. toString(), this.pos.x, this.pos.y + 250);

			},
		})));

		this.handler = me.event.subscribe(me.event. KEYDOWN, function(action, keyCode, edge){
			if(action === "F1"){

			}
			else if(action === "F2"){

			}
			else if(action === "F3"){

			}
			else if(action === "F4"){

			}
			else if(action === "F5"){
				me.state.change(me.state.PLAY);
			}
		});
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		//makes the keys lose its function.
		me.input.unbindKey(me.input.KEY.F1, "F1");
		me.input.unbindKey(me.input.KEY.F2, "F2");
		me.input.unbindKey(me.input.KEY.F3, "F3");
		me.input.unbindKey(me.input.KEY.F4, "F4");
		me.input.unbindKey(me.input.KEY.F5, "F5");
		me.event.unsubscribe(this.handler);
	}
});
y<|endoftext|>


<commit_before>//Lightweight JSONP fetcher - www.nonobtrusive.com
// The remote server is getting sensed below now, including port number, by the including webpage's script location.
//OPT_REMOTE = 'http://192.168.5.132:3000';

var scriptSource = (function(scripts) {
    var scripts = document.getElementsByTagName('script'),
    script = scripts[scripts.length - 1];

    return (script.getAttribute.length !== undefined) ?
           //FF/Chrome/Safari
           script.src : //(only FYI, this would work also in IE8)
           //IE 6/7/8
           script.getAttribute('src', 4); //using 4 (and not -1) see MSDN http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx
}());
var temp_element = document.createElement("a");
temp_element.href = scriptSource;
optemo_french = (window.location.pathname.match(/fr-ca/i));
OPT_REMOTE = 'http://' + ((optemo_french) ? "fr." : "") + temp_element.host;

var JSONP=(function(){var a=0,c,f,b,d=this;function e(j){var i=document.createElement("script"),h=false;i.src=j;i.async=true;i.onload=i.onreadystatechange=function(){if(!h&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){h=true;i.onload=i.onreadystatechange=null;if(i&&i.parentNode){i.parentNode.removeChild(i)}}};if(!c){c=document.getElementsByTagName("head")[0]}c.appendChild(i)}function g(h,j,k){f="?";j=j||{};for(b in j){if(j.hasOwnProperty(b)){f+=encodeURIComponent(b)+"="+encodeURIComponent(j[b])+"&"}}var i="json"+(++a);d[i]=function(l){k(opt_parse_data_by_pattern(l, "<img[^>]+>", (function(mystring){return mystring.replace(/(\/images\/[^?]+)/, OPT_REMOTE + "$1");})));d[i]=null;try{delete d[i]}catch(m){}};e(h+f+"callback="+i);return i}return{get:g}}());
//Function for executing code at DOMReady
//function opt_s(f){/in/.test(document.readyState)?setTimeout('opt_s('+f+')',9):f()}
function opt_insert(d) {
    var opt_t = document.getElementById("optemo_embedder");
    if (opt_t) {
        var se = document.createElement("div");
        se.id = "opt_new";
        se.innerHTML = d;
        opt_t.appendChild(se);
        if (typeof optemo_module != "undefined") {
            optemo_module.domready();
        }
    } else
        setTimeout(function(){opt_insert(d);d=null;},10);
}
//Load the correct history on reload
var opt_history = location.hash.replace(/^#/, '');
// To get the category id that gets passed in, check the URL:
// http://www.bestbuy.ca/en-CA/digital-cameras.aspx maps to the category id 20218.
// This is ascertained by looking at the database, in the category_id_product_type_maps table.
// The regular expressions for all but the first entry (digital cameras) are assumed (as of July 6, 2011)

var category_id_hash = {'digital-cameras' : 20218,
                        'digital-tvs' : 21344, // The URL is probably not quite correct yet; this is a placeholder
                        'harddrives' : 20243};

var rails_category_id = 0;
for (var i in category_id_hash) {
    if (window.location.pathname.match(new RegExp(i))) {
        rails_category_id = category_id_hash[i];
        break;
    }
}
// Failsafe just in case nothing seems to match
if (rails_category_id == 0) rails_category_id = 20218;

if (opt_history.length > 0)
    var opt_options = {embedding:'true', hist: opt_history, category_id: rails_category_id};
else
    var opt_options = {embedding:'true', category_id: rails_category_id, landing: true};
JSONP.get(OPT_REMOTE, opt_options, function (data) {
    if (scriptSource.match(/localhost/) || scriptSource.match(/192.168/)) { // We need to do some additional work
        var regexp_pattern, data_to_add, data_to_append, scripts, headID = document.getElementsByTagName("head")[0], script_nodes_to_append, i, images;
        // Take out all the scripts, load them on the client (consumer) page in the HEAD tag, and put the data back together
        regexp_pattern = (/<script[^>]+>/g);
        scripts = data.match(regexp_pattern);
        if (scripts != null) {
            // It's odd that we have to do this check: The difference between loader and loader_local used to be
            // the loading of javascript files, as below. However, in the current Best Buy embedding frame,
            // they have been putting bb_loader_packaged.js as a separate line, and so in order to match our local embedded
            // testing environment with the sandbox site, we do not currently have separate scripts to load.
            // Since this could easily change back, I've kept the below code so that we can switch back as necessary. ZAT July 20, 2011
            data_to_add = data.split(regexp_pattern);
            script_nodes_to_append = Array();
            for (i = 0; i < scripts.length; i++)
            {
                srcs = scripts[i].match(/javascripts[^"]+/); // We might want to make a check for src instead.
                if (srcs == null) {
                    scripts[i] = '<script type="text/javascript">';
                } else if (typeof(srcs) == "object" && srcs[0] && srcs[0].match(/easyXDM/)){
        			 scripts[i] = ''; // so it will get taken out completely later
        		} else {
                    script_nodes_to_append.push(OPT_REMOTE + "/" + srcs);
                    scripts[i] = '';
                }
            // When zipping stuff back up, we want to take out the /script tag *unless* there was a null response.
            }

        	//Zipping data back up
            data_to_append = new Array();
            // This is basically a do-while loop in disguise. Put the zeroth element on first, go from there.
            data_to_append.push(data_to_add[0])
            for (i = 0; i < scripts.length; i++) {
                // Either put back the <script> tag that is required for inline scripts, or else take out the < /script> part from the start of data_to_add[i+1].
                // Each time, look at scripts[i]. If empty, we need to take out the /script part that starts the next block.
                if (scripts[i] == '') { // If empty, take out the "/script" part and push the next piece. Also, if it's the XDM script itself
                    data_to_append.push(data_to_add[i+1].replace(/<\/script>/,''));
                } else { // If not empty, we need to put the <script> back in
        			data_to_append.push(scripts[i]);
                    data_to_append.push(data_to_add[i+1]);
                }
            }
            // Now, we want to join all the data
            data_to_append = data_to_append.join("\n");
        } else {
            data_to_append = data;
        }
        opt_insert(data_to_append);

    	// We have to load all scripts in order, but using labJS is too heavy. So, we do a recursive serial loader function.
    	// Although serial should == slow, the javascript we're loading should only be one file in production.
    	// The purpose of having this multiple-script functionality is for development mode.
        if (scripts != null) {
        	(function lazyloader(i) {
        	    // attach current script, using closure-scoped variable
        		var script = document.createElement("script");
                script.setAttribute("type", "text/javascript");
        	    // when finished loading, call lazyloader again on next script, if there is one.
                if ((i + 1) < script_nodes_to_append.length) {
                    if (script.readyState){  //IE
                        script.onreadystatechange = function(){
                            if (script.readyState == "loaded" ||
                                    script.readyState == "complete"){
                                script.onreadystatechange = null;
                                lazyloader(i + 1);
                            }
                        };
                    } else {  //Others
                        script.onload = function(){
                            lazyloader(i + 1);
                        };
                    }
                } else {
               		if (script.readyState){  //IE
                        script.onreadystatechange = function(){
                            if (script.readyState == "loaded" ||
                                    script.readyState == "complete"){
                                script.onreadystatechange = null;
                            }
                        };
                    }
                }
                script.setAttribute("src", script_nodes_to_append[i]);
                document.getElementsByTagName("head")[0].appendChild(script);
            })(0);
        }
    } else {
        opt_insert(data);
    }
});
// Private function for the register_remote socket. Takes data, splits according to rules, does replace() according to rules.
function opt_parse_data_by_pattern(mydata, split_pattern_string, replacement_function) {
	var data_to_add, data_to_append, split_regexp = new RegExp(split_pattern_string, "gi");
    images = mydata.match(split_regexp);
    data_to_add = mydata.split(split_regexp);
    data_to_append = new Array();
    data_to_append.push(data_to_add[0]);
    for (i = 0; i < images.length; i++) {
        if (images[i].match(new RegExp("http:\/\/")))
            data_to_append.push(images[i]);
        else
            data_to_append.push(replacement_function(images[i]));
        data_to_append.push(data_to_add[i+1]);
    }
    return data_to_append.join("\n");
}<commit_msg>Minor change for IE6 phantom french bug<commit_after>//Lightweight JSONP fetcher - www.nonobtrusive.com
// The remote server is getting sensed below now, including port number, by the including webpage's script location.
//OPT_REMOTE = 'http://192.168.5.132:3000';

var scriptSource = (function(scripts) {
    var scripts = document.getElementsByTagName('script'),
    script = scripts[scripts.length - 1];

    return (script.getAttribute.length !== undefined) ?
           //FF/Chrome/Safari
           script.src : //(only FYI, this would work also in IE8)
           //IE 6/7/8
           script.getAttribute('src', 4); //using 4 (and not -1) see MSDN http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx
}());
var temp_element = document.createElement("a");
temp_element.href = scriptSource;
optemo_french = (window.location.href.match(/fr-ca/i));
OPT_REMOTE = 'http://' + ((optemo_french) ? "fr." : "") + temp_element.host;

var JSONP=(function(){var a=0,c,f,b,d=this;function e(j){var i=document.createElement("script"),h=false;i.src=j;i.async=true;i.onload=i.onreadystatechange=function(){if(!h&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){h=true;i.onload=i.onreadystatechange=null;if(i&&i.parentNode){i.parentNode.removeChild(i)}}};if(!c){c=document.getElementsByTagName("head")[0]}c.appendChild(i)}function g(h,j,k){f="?";j=j||{};for(b in j){if(j.hasOwnProperty(b)){f+=encodeURIComponent(b)+"="+encodeURIComponent(j[b])+"&"}}var i="json"+(++a);d[i]=function(l){k(opt_parse_data_by_pattern(l, "<img[^>]+>", (function(mystring){return mystring.replace(/(\/images\/[^?]+)/, OPT_REMOTE + "$1");})));d[i]=null;try{delete d[i]}catch(m){}};e(h+f+"callback="+i);return i}return{get:g}}());
//Function for executing code at DOMReady
//function opt_s(f){/in/.test(document.readyState)?setTimeout('opt_s('+f+')',9):f()}
function opt_insert(d) {
    var opt_t = document.getElementById("optemo_embedder");
    if (opt_t) {
        var se = document.createElement("div");
        se.id = "opt_new";
        se.innerHTML = d;
        opt_t.appendChild(se);
        if (typeof optemo_module != "undefined") {
            optemo_module.domready();
        }
    } else
        setTimeout(function(){opt_insert(d);d=null;},10);
}
//Load the correct history on reload
var opt_history = location.hash.replace(/^#/, '');
// To get the category id that gets passed in, check the URL:
// http://www.bestbuy.ca/en-CA/digital-cameras.aspx maps to the category id 20218.
// This is ascertained by looking at the database, in the category_id_product_type_maps table.
// The regular expressions for all but the first entry (digital cameras) are assumed (as of July 6, 2011)

var category_id_hash = {'digital-cameras' : 20218,
                        'digital-tvs' : 21344, // The URL is probably not quite correct yet; this is a placeholder
                        'harddrives' : 20243};

var rails_category_id = 0;
for (var i in category_id_hash) {
    if (window.location.pathname.match(new RegExp(i))) {
        rails_category_id = category_id_hash[i];
        break;
    }
}
// Failsafe just in case nothing seems to match
if (rails_category_id == 0) rails_category_id = 20218;

if (opt_history.length > 0)
    var opt_options = {embedding:'true', hist: opt_history, category_id: rails_category_id};
else
    var opt_options = {embedding:'true', category_id: rails_category_id, landing: true};
JSONP.get(OPT_REMOTE, opt_options, function (data) {
    if (scriptSource.match(/localhost/) || scriptSource.match(/192.168/)) { // We need to do some additional work
        var regexp_pattern, data_to_add, data_to_append, scripts, headID = document.getElementsByTagName("head")[0], script_nodes_to_append, i, images;
        // Take out all the scripts, load them on the client (consumer) page in the HEAD tag, and put the data back together
        regexp_pattern = (/<script[^>]+>/g);
        scripts = data.match(regexp_pattern);
        if (scripts != null) {
            // It's odd that we have to do this check: The difference between loader and loader_local used to be
            // the loading of javascript files, as below. However, in the current Best Buy embedding frame,
            // they have been putting bb_loader_packaged.js as a separate line, and so in order to match our local embedded
            // testing environment with the sandbox site, we do not currently have separate scripts to load.
            // Since this could easily change back, I've kept the below code so that we can switch back as necessary. ZAT July 20, 2011
            data_to_add = data.split(regexp_pattern);
            script_nodes_to_append = Array();
            for (i = 0; i < scripts.length; i++)
            {
                srcs = scripts[i].match(/javascripts[^"]+/); // We might want to make a check for src instead.
                if (srcs == null) {
                    scripts[i] = '<script type="text/javascript">';
                } else if (typeof(srcs) == "object" && srcs[0] && srcs[0].match(/easyXDM/)){
        			 scripts[i] = ''; // so it will get taken out completely later
        		} else {
                    script_nodes_to_append.push(OPT_REMOTE + "/" + srcs);
                    scripts[i] = '';
                }
            // When zipping stuff back up, we want to take out the /script tag *unless* there was a null response.
            }

        	//Zipping data back up
            data_to_append = new Array();
            // This is basically a do-while loop in disguise. Put the zeroth element on first, go from there.
            data_to_append.push(data_to_add[0])
            for (i = 0; i < scripts.length; i++) {
                // Either put back the <script> tag that is required for inline scripts, or else take out the < /script> part from the start of data_to_add[i+1].
                // Each time, look at scripts[i]. If empty, we need to take out the /script part that starts the next block.
                if (scripts[i] == '') { // If empty, take out the "/script" part and push the next piece. Also, if it's the XDM script itself
                    data_to_append.push(data_to_add[i+1].replace(/<\/script>/,''));
                } else { // If not empty, we need to put the <script> back in
        			data_to_append.push(scripts[i]);
                    data_to_append.push(data_to_add[i+1]);
                }
            }
            // Now, we want to join all the data
            data_to_append = data_to_append.join("\n");
        } else {
            data_to_append = data;
        }
        opt_insert(data_to_append);

    	// We have to load all scripts in order, but using labJS is too heavy. So, we do a recursive serial loader function.
    	// Although serial should == slow, the javascript we're loading should only be one file in production.
    	// The purpose of having this multiple-script functionality is for development mode.
        if (scripts != null) {
        	(function lazyloader(i) {
        	    // attach current script, using closure-scoped variable
        		var script = document.createElement("script");
                script.setAttribute("type", "text/javascript");
        	    // when finished loading, call lazyloader again on next script, if there is one.
                if ((i + 1) < script_nodes_to_append.length) {
                    if (script.readyState){  //IE
                        script.onreadystatechange = function(){
                            if (script.readyState == "loaded" ||
                                    script.readyState == "complete"){
                                script.onreadystatechange = null;
                                lazyloader(i + 1);
                            }
                        };
                    } else {  //Others
                        script.onload = function(){
                            lazyloader(i + 1);
                        };
                    }
                } else {
               		if (script.readyState){  //IE
                        script.onreadystatechange = function(){
                            if (script.readyState == "loaded" ||
                                    script.readyState == "complete"){
                                script.onreadystatechange = null;
                            }
                        };
                    }
                }
                script.setAttribute("src", script_nodes_to_append[i]);
                document.getElementsByTagName("head")[0].appendChild(script);
            })(0);
        }
    } else {
        opt_insert(data);
    }
});
// Private function for the register_remote socket. Takes data, splits according to rules, does replace() according to rules.
function opt_parse_data_by_pattern(mydata, split_pattern_string, replacement_function) {
	var data_to_add, data_to_append, split_regexp = new RegExp(split_pattern_string, "gi");
    images = mydata.match(split_regexp);
    data_to_add = mydata.split(split_regexp);
    data_to_append = new Array();
    data_to_append.push(data_to_add[0]);
    for (i = 0; i < images.length; i++) {
        if (images[i].match(new RegExp("http:\/\/")))
            data_to_append.push(images[i]);
        else
            data_to_append.push(replacement_function(images[i]));
        data_to_append.push(data_to_add[i+1]);
    }
    return data_to_append.join("\n");
}<|endoftext|>


<commit_before>/*jslint browser: true*/
/*global queue, L, d3*/

queue()
    .defer(d3.json, "files/map.geojson")
    .await(ready);

function loadGeoJson(mapJson) {
    "use strict";
    var map, gj;
    map = L.map('map', {
        center: [1.30009, 103.85],
        zoom: 15
    });

    L.tileLayer('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap © CartoDB',
        subdomains: 'abcd',
        maxZoom: 15
    }).addTo(map);

    gj = L.geoJson(mapJson, {
        color: "#ff7800",
        weight: 2,
        opacity: 0
    }).addTo(map);

    gj.eachLayer(function(layer) {
        new Path(layer);
    });
}

function Path(layer) {
    "use strict";
    // I'll place everything into a class
    // this would make everything easier later on
    this.layer = layer;
    this.setId();
    this.addMarker();
    Path.paths[this.getElement().id] = this;
}

Path.prototype.getElement = function() {
    "use strict";
    return this.layer.getElement();
};

Path.prototype.setId = function() {
    "use strict";
    // layer.feature is the geojson data
    // since my sample geojson doesn't contain an id
    // I'll just generate a random id
    var id = Math.floor(Math.random() * 100000);
    this.getElement().id = "feature-" + id; // this.layer.feature.id;
};

Path.prototype.getSvg = function() {
    "use strict";
    return this.getElement().parentNode.parentNode;
};

Path.prototype.getStartPoint = function() {
    "use strict";
    var p = this.getElement().getPointAtLength(0);
    return p.x + "," + p.y;
};

Path.prototype.addMarker = function() {
    "use strict";
    var path = d3.select(this.getElement());
    var svg = d3.select(this.getSvg());

    var startPoint = this.getStartPoint();

    var marker = svg.append("circle");
    marker.attr("r", 2)
        .attr("id", "marker-" + path.attr("id"))
        .attr("fill", "yellow")
        .attr("transform", "translate(" + startPoint + ")");

    this.marker = marker;
};

Path.prototype.tweenDash = function() {
    "use strict";
    var path = d3.select(this);
    var l = path.node().getTotalLength();
    var i = d3.interpolateString("0," + l, l + "," + l);
    var marker = d3.select("#marker-" + path.attr("id"));

    path.attr("stroke-dasharray", i(0));
    path.attr("stroke-opacity", 0.45);
    return function(t) {
        var p = path.node().getPointAtLength(t * l);
        marker.attr("transform", "translate(" + p.x + "," + p.y + ")");
        return i(t);
    };
};

Path.prototype.transition = function(endCallback) {
    "use strict";
    var path = d3.select(this.getElement());
    path.transition()
        .duration(3500)
        .attrTween("stroke-dasharray", this.tweenDash)
        .each("end", endCallback || this.noop);
};

Path.prototype.noop = function() {
    "use strict";
    return;
};

Path.paths = {};

function ready(error, mapJson) { // jshint ignore:line
    "use strict";
    loadGeoJson(mapJson);

    function runParallel() {
        for (var k in Path.paths) {
            if (!Path.paths.hasOwnProperty(k)) {
                continue;
            }

            Path.paths[k].transition();
        }
    }

    function runSequential() {
        // load sequentially, in no particular order
        var pathOrder = [];
        for (var k in Path.paths) {
            if (!Path.paths.hasOwnProperty(k)) {
                continue;
            }

            pathOrder.push(k);
        }

        var ctr = 0;

        function runNext() {
            if (pathOrder[ctr]) {
                Path.paths[pathOrder[ctr]].transition(runNext);
                ++ctr;
            } else {
                runParallel();
            }
        }

        runNext();
    }

    runSequential();

}
<commit_msg>Add license header<commit_after>/*
 * Copyright (c) 2016 Eduardo David Jr.
 * Licensed under the MIT License. See LICENSE file in the project root for full license information.
 */

/*jslint browser: true*/
/*global queue, L, d3*/

queue()
    .defer(d3.json, "files/map.geojson")
    .await(ready);

function loadGeoJson(mapJson) {
    "use strict";
    var map, gj;
    map = L.map('map', {
        center: [1.30009, 103.85],
        zoom: 15
    });

    L.tileLayer('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap © CartoDB',
        subdomains: 'abcd',
        maxZoom: 15
    }).addTo(map);

    gj = L.geoJson(mapJson, {
        color: "#ff7800",
        weight: 2,
        opacity: 0
    }).addTo(map);

    gj.eachLayer(function(layer) {
        new Path(layer);
    });
}

function Path(layer) {
    "use strict";
    // I'll place everything into a class
    // this would make everything easier later on
    this.layer = layer;
    this.setId();
    this.addMarker();
    Path.paths[this.getElement().id] = this;
}

Path.prototype.getElement = function() {
    "use strict";
    return this.layer.getElement();
};

Path.prototype.setId = function() {
    "use strict";
    // layer.feature is the geojson data
    // since my sample geojson doesn't contain an id
    // I'll just generate a random id
    var id = Math.floor(Math.random() * 100000);
    this.getElement().id = "feature-" + id; // this.layer.feature.id;
};

Path.prototype.getSvg = function() {
    "use strict";
    return this.getElement().parentNode.parentNode;
};

Path.prototype.getStartPoint = function() {
    "use strict";
    var p = this.getElement().getPointAtLength(0);
    return p.x + "," + p.y;
};

Path.prototype.addMarker = function() {
    "use strict";
    // ToDo This marker doesn't scale properly on leaflet zoom
    var path = d3.select(this.getElement());
    var svg = d3.select(this.getSvg());

    var startPoint = this.getStartPoint();

    var marker = svg.append("circle");
    marker.attr("r", 2)
        .attr("id", "marker-" + path.attr("id"))
        .attr("fill", "yellow")
        .attr("transform", "translate(" + startPoint + ")");

    this.marker = marker;
};

Path.prototype.tweenDash = function() {
    "use strict";
    var path = d3.select(this);
    var l = path.node().getTotalLength();
    var i = d3.interpolateString("0," + l, l + "," + l);
    var marker = d3.select("#marker-" + path.attr("id"));

    path.attr("stroke-dasharray", i(0));
    path.attr("stroke-opacity", 0.45);
    return function(t) {
        var p = path.node().getPointAtLength(t * l);
        marker.attr("transform", "translate(" + p.x + "," + p.y + ")");
        return i(t);
    };
};

Path.prototype.transition = function(endCallback) {
    "use strict";
    var path = d3.select(this.getElement());
    path.transition()
        .duration(3500)
        .attrTween("stroke-dasharray", this.tweenDash)
        .each("end", endCallback || this.noop);
};

Path.prototype.noop = function() {
    "use strict";
    return;
};

Path.paths = {};

function ready(error, mapJson) { // jshint ignore:line
    "use strict";
    loadGeoJson(mapJson);

    function runParallel() {
        for (var k in Path.paths) {
            if (!Path.paths.hasOwnProperty(k)) {
                continue;
            }

            Path.paths[k].transition();
        }
    }

    function runSequential() {
        // load sequentially, in no particular order
        var pathOrder = [];
        for (var k in Path.paths) {
            if (!Path.paths.hasOwnProperty(k)) {
                continue;
            }

            pathOrder.push(k);
        }

        var ctr = 0;

        function runNext() {
            if (pathOrder[ctr]) {
                Path.paths[pathOrder[ctr]].transition(runNext);
                ++ctr;
            } else {
                runParallel();
            }
        }

        runNext();
    }

    runSequential();

}
<|endoftext|>