<commit_before>import {asyncReplace, isArray, isString, md5} from 'stc-helper';
import {isMaster} from 'cluster';
import PluginInvoke from 'stc-plugin-invoke';
import path from 'path';
import url from 'url';
import ConcurrentLimit from './concurrent_limit.js';
import {
  getAst,
  checkInMaster,
  checkRunIsExecute
} from './helper.js';

/**
 * concurrent limit task instances
 */
const concurrentLimitInstances = {};

/**
 * stc plugin abstract class
 */
export default class StcPlugin {
  /**
   * constructor
   */
  constructor(file, opts = {}){
    this.file = file;
    this.options = opts.options || {};
    this.stc = opts.stc;
    this.config = this.stc.config;
    this.TokenType = this.stc.flkit.TokenType;
    this.include = opts.include;
    //can not use ext in sub plugins
    this._ext = opts.ext || {};
    //store other properties
    this._prop = {};
  }
  /**
   * get matches
   */
  get matches(){
    return this.stc.resource.match(this.file, this.include);
  }
  /**
   * get or set properties
   */
  prop(name, value){
    if(value === undefined){
      return this._prop[name];
    }
    this._prop[name] = value;
    return this;
  }
  /**
   * is template file
   */
  isTpl(){
    return !!this.file.prop('tpl');
  }
  /**
   * get md5 value of plugin & options
   */
  getMd5(){
    if(this.prop('md5')){
      return this.prop('md5');
    }
    let value = md5(this.constructor.toString() + JSON.stringify(this.options));
    this.prop('md5', value);
    return value;
  }
  /**
   * get file content
   */
  async getContent(encoding = null){
    if(isMaster){
      return this.file.getContent(encoding);
    }
    let content = await this.stc.cluster.workerInvoke({
      method: 'getContent',
      encoding: encoding,
      file: this.file.path
    });
    if(encoding !== null){
      return content;
    }
    return new Buffer(content, 'base64');
  }
  /**
   * set file content
   */
  setContent(content){
    checkInMaster('setContent');
    checkRunIsExecute(this, 'setContent');
    this.file.setContent(content);
    return this;
  }
  /**
   * get file ast
   */
  async getAst(){
    let content = await this.getContent('utf8');

    if(isMaster){
      if(this.file.hasAst()){
        return this.file.getAst();
      }
      return getAst(this, content, async () => {
        // turn off cluster
        if(this.config.cluster === false){
          return this.file.getAst();
        }
        //get ast in worker parsed
        let ret = await this.stc.cluster.masterInvoke({
          type: 'getAst',
          content,
          file: this.file.path
        });
        this.file.setAst(ret);
        return ret;
      });
    }

    return getAst(this, content, async () => {
      // if have ast in master, return directory
      let ast = await this.stc.cluster.workerInvoke({
        method: 'getAstIfExist',
        file: this.file.path
      });
      if(ast){
        return ast;
      }
      this.file.setContent(content);
      let ret = await this.file.getAst();
      // update ast in master
      await this.stc.cluster.workerInvoke({
        method: 'updateAst',
        file: this.file.path,
        ast: ret
      });
      return ret;
    });
  }
  /**
   * set ast
   */
  setAst(ast){
    checkInMaster('setAst');
    checkRunIsExecute(this, 'setAst');
    this.file.setAst(ast);
    return this;
  }
  /**
   * add file dependence
   */
  addDependence(dependencies){
    if(!isMaster){
      throw new Error('addDependence must be invoked in master');
    }
    if(!isArray(dependencies)){
      dependencies = [dependencies];
    }
    dependencies = dependencies.map(item => {
      if(!isString(item)){
        return item;
      }
      let filepath = this.getResolvePath(item);
      let file = this.stc.resource.getFileByPath(filepath, this.file.path);
      if(!file){
        throw new Error(`file ${item} is not exist in ${this.file.path}`);
      }
      return file;
    });
    this.file.dependence.add(dependencies);
    return dependencies;
  }
  /**
   * get file dependence
   */
  getDependence(file = this.file){
    return file.dependence.get();
  }

  /**
   * add file
   */
  async addFile(filepath, content, virtual){
    if(!virtual){
      checkRunIsExecute(this, 'addFile');
    }
    let resolvePath = this.getResolvePath(filepath);
    if(isMaster){
      return this.stc.resource.addFile(resolvePath, content, virtual);
    }
    await this.stc.cluster.workerInvoke({
      method: 'addFile',
      file: resolvePath,
      virtual,
      content
    });
    return this.stc.resource.createFile(resolvePath, content, virtual);
  }
  /**
   * get resolve path
   */
  getResolvePath(filepath){
    // parse filepath, remove query & hash in filepath
    filepath = decodeURIComponent(url.parse(filepath).pathname);
    let currentFilePath = path.dirname(this.file.path);
    let resolvePath = path.resolve(currentFilePath, filepath);
    let currentPath = process.cwd() + path.sep;
    if(resolvePath.indexOf(currentPath) === 0){
      resolvePath = resolvePath.slice(currentPath.length);
    }
    return resolvePath;
  }
  /**
   * get file by path
   */
  getFileByPath(filepath){
    filepath = this.getResolvePath(filepath);
    if(isMaster){
      return this.stc.resource.getFileByPath(filepath, this.file.path);
    }
    return this.stc.resource.createFile(filepath);
  }

  /**
   * invoke self plugin
   */
  async invokeSelf(file = this.file){
    if(isString(file)){
      file = this.getFileByPath(file);
    }
    return this.invokePlugin(this.constructor, file);
  }

  /**
   * invoke plugin
   */
  async invokePlugin(plugin, file = this.file){
    if(isString(file)){
      file = this.getFileByPath(file);
    }
    let instance = new PluginInvoke(plugin, file, {
      stc: this.stc,
      options: this.options,
      ext: plugin === this.constructor ? this._ext : {}
    });
    return instance.run();
  }

  /**
   * async content replace
   * must be use RegExp
   */
  asyncReplace(content = '', replace, callback){
    return asyncReplace(content, replace, callback);
  }
  /**
   * get or set cache
   */
  async cache(name, value){
    if(isMaster){
      let md5Value = this.getMd5();
      if(!this.stc.cacheInstances[md5Value]){
        this.stc.cacheInstances[md5Value] = new this.stc.cache({
          onlyMemory: true
        });
      }
      let instance = this.stc.cacheInstances[md5Value];
      if(value === undefined){
        return instance.get(name);
      }
      instance.set(name, value);
      return this;
    }
    //get or set cache from master
    return this.stc.cluster.workerInvoke({
      method: 'cache',
      key: this.getMd5(),
      name,
      value
    });
  }
  /**
   * create token
   */
  createToken(type, value, referToken){
    return this.stc.flkit.createToken(type, value, referToken);
  }
  /**
   * concurrent limit task
   */
  concurrentLimit(fn, ignoreErrorFn, limit, key = this.constructor.name){
    if(!(key in concurrentLimitInstances)){
     concurrentLimitInstances[key] = new ConcurrentLimit(limit, ignoreErrorFn);
    }
    let instance = concurrentLimitInstances[key];
    return instance.run(fn);
  }
  /**
   * throw fatal error
   */
  fatal(message, line, column, file = this.file.path){
    let msg = {
      message,
      className: this.constructor.name,
      file,
      line,
      column
    }
    throw new Error(JSON.stringify(msg));
  }

  /**
   * show error log
   */
  error(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'error');
    this.stc.log.error({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

   /**
   * show warning log
   */
  warning(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'warning')
    this.stc.log.warning({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

   /**
   * show notice log
   */
  notice(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'notice');
    this.stc.log.notice({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

  /**
   * run
   */
  run(){

  }
  /**
   * update
   */
  update(){

  }
}<commit_msg>Add createRawToken method<commit_after>import {asyncReplace, isArray, isString, md5} from 'stc-helper';
import {isMaster} from 'cluster';
import PluginInvoke from 'stc-plugin-invoke';
import path from 'path';
import url from 'url';
import ConcurrentLimit from './concurrent_limit.js';
import {
  getAst,
  checkInMaster,
  checkRunIsExecute
} from './helper.js';

/**
 * concurrent limit task instances
 */
const concurrentLimitInstances = {};

/**
 * stc plugin abstract class
 */
export default class StcPlugin {
  /**
   * constructor
   */
  constructor(file, opts = {}){
    this.file = file;
    this.options = opts.options || {};
    this.stc = opts.stc;
    this.config = this.stc.config;
    this.TokenType = this.stc.flkit.TokenType;
    this.include = opts.include;
    //can not use ext in sub plugins
    this._ext = opts.ext || {};
    //store other properties
    this._prop = {};
  }
  /**
   * get matches
   */
  get matches(){
    return this.stc.resource.match(this.file, this.include);
  }
  /**
   * get or set properties
   */
  prop(name, value){
    if(value === undefined){
      return this._prop[name];
    }
    this._prop[name] = value;
    return this;
  }
  /**
   * is template file
   */
  isTpl(){
    return !!this.file.prop('tpl');
  }
  /**
   * get md5 value of plugin & options
   */
  getMd5(){
    if(this.prop('md5')){
      return this.prop('md5');
    }
    let value = md5(this.constructor.toString() + JSON.stringify(this.options));
    this.prop('md5', value);
    return value;
  }
  /**
   * get file content
   */
  async getContent(encoding = null){
    if(isMaster){
      return this.file.getContent(encoding);
    }
    let content = await this.stc.cluster.workerInvoke({
      method: 'getContent',
      encoding: encoding,
      file: this.file.path
    });
    if(encoding !== null){
      return content;
    }
    return new Buffer(content, 'base64');
  }
  /**
   * set file content
   */
  setContent(content){
    checkInMaster('setContent');
    checkRunIsExecute(this, 'setContent');
    this.file.setContent(content);
    return this;
  }
  /**
   * get file ast
   */
  async getAst(){
    let content = await this.getContent('utf8');

    if(isMaster){
      if(this.file.hasAst()){
        return this.file.getAst();
      }
      return getAst(this, content, async () => {
        // turn off cluster
        if(this.config.cluster === false){
          return this.file.getAst();
        }
        //get ast in worker parsed
        let ret = await this.stc.cluster.masterInvoke({
          type: 'getAst',
          content,
          file: this.file.path
        });
        this.file.setAst(ret);
        return ret;
      });
    }

    return getAst(this, content, async () => {
      // if have ast in master, return directory
      let ast = await this.stc.cluster.workerInvoke({
        method: 'getAstIfExist',
        file: this.file.path
      });
      if(ast){
        return ast;
      }
      this.file.setContent(content);
      let ret = await this.file.getAst();
      // update ast in master
      await this.stc.cluster.workerInvoke({
        method: 'updateAst',
        file: this.file.path,
        ast: ret
      });
      return ret;
    });
  }
  /**
   * set ast
   */
  setAst(ast){
    checkInMaster('setAst');
    checkRunIsExecute(this, 'setAst');
    this.file.setAst(ast);
    return this;
  }
  /**
   * add file dependence
   */
  addDependence(dependencies){
    if(!isMaster){
      throw new Error('addDependence must be invoked in master');
    }
    if(!isArray(dependencies)){
      dependencies = [dependencies];
    }
    dependencies = dependencies.map(item => {
      if(!isString(item)){
        return item;
      }
      let filepath = this.getResolvePath(item);
      let file = this.stc.resource.getFileByPath(filepath, this.file.path);
      if(!file){
        throw new Error(`file ${item} is not exist in ${this.file.path}`);
      }
      return file;
    });
    this.file.dependence.add(dependencies);
    return dependencies;
  }
  /**
   * get file dependence
   */
  getDependence(file = this.file){
    return file.dependence.get();
  }

  /**
   * add file
   */
  async addFile(filepath, content, virtual){
    if(!virtual){
      checkRunIsExecute(this, 'addFile');
    }
    let resolvePath = this.getResolvePath(filepath);
    if(isMaster){
      return this.stc.resource.addFile(resolvePath, content, virtual);
    }
    await this.stc.cluster.workerInvoke({
      method: 'addFile',
      file: resolvePath,
      virtual,
      content
    });
    return this.stc.resource.createFile(resolvePath, content, virtual);
  }
  /**
   * get resolve path
   */
  getResolvePath(filepath){
    // parse filepath, remove query & hash in filepath
    filepath = decodeURIComponent(url.parse(filepath).pathname);
    let currentFilePath = path.dirname(this.file.path);
    let resolvePath = path.resolve(currentFilePath, filepath);
    let currentPath = process.cwd() + path.sep;
    if(resolvePath.indexOf(currentPath) === 0){
      resolvePath = resolvePath.slice(currentPath.length);
    }
    return resolvePath;
  }
  /**
   * get file by path
   */
  getFileByPath(filepath){
    filepath = this.getResolvePath(filepath);
    if(isMaster){
      return this.stc.resource.getFileByPath(filepath, this.file.path);
    }
    return this.stc.resource.createFile(filepath);
  }

  /**
   * invoke self plugin
   */
  async invokeSelf(file = this.file){
    if(isString(file)){
      file = this.getFileByPath(file);
    }
    return this.invokePlugin(this.constructor, file);
  }

  /**
   * invoke plugin
   */
  async invokePlugin(plugin, file = this.file){
    if(isString(file)){
      file = this.getFileByPath(file);
    }
    let instance = new PluginInvoke(plugin, file, {
      stc: this.stc,
      options: this.options,
      ext: plugin === this.constructor ? this._ext : {}
    });
    return instance.run();
  }

  /**
   * async content replace
   * must be use RegExp
   */
  asyncReplace(content = '', replace, callback){
    return asyncReplace(content, replace, callback);
  }
  /**
   * get or set cache
   */
  async cache(name, value){
    if(isMaster){
      let md5Value = this.getMd5();
      if(!this.stc.cacheInstances[md5Value]){
        this.stc.cacheInstances[md5Value] = new this.stc.cache({
          onlyMemory: true
        });
      }
      let instance = this.stc.cacheInstances[md5Value];
      if(value === undefined){
        return instance.get(name);
      }
      instance.set(name, value);
      return this;
    }
    //get or set cache from master
    return this.stc.cluster.workerInvoke({
      method: 'cache',
      key: this.getMd5(),
      name,
      value
    });
  }
  /**
   * create token
   */
  createToken(type, value, referToken){
    return this.stc.flkit.createToken(type, value, referToken);
  }
  /**
   * create raw token in html
   */
  createRawToken(type, value, referToken){
    return this.stc.flkit.createRawToken(type, value, referToken);
  }
  /**
   * concurrent limit task
   */
  concurrentLimit(fn, ignoreErrorFn, limit, key = this.constructor.name){
    if(!(key in concurrentLimitInstances)){
     concurrentLimitInstances[key] = new ConcurrentLimit(limit, ignoreErrorFn);
    }
    let instance = concurrentLimitInstances[key];
    return instance.run(fn);
  }
  /**
   * throw fatal error
   */
  fatal(message, line, column, file = this.file.path){
    let msg = {
      message,
      className: this.constructor.name,
      file,
      line,
      column
    }
    throw new Error(JSON.stringify(msg));
  }

  /**
   * show error log
   */
  error(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'error');
    this.stc.log.error({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

   /**
   * show warning log
   */
  warning(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'warning')
    this.stc.log.warning({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

   /**
   * show notice log
   */
  notice(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'notice');
    this.stc.log.notice({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

  /**
   * run
   */
  run(){

  }
  /**
   * update
   */
  update(){

  }
}<|endoftext|>


<commit_before>var demo = (function () {
    var fileInput = document.getElementById('upload'),
        widthInput = document.getElementById('section-width'),
        heightInput = document.getElementById('section-height'),
        pixelateBtn = document.getElementById('pixelate-btn'),

        outputContainer = document.getElementById('output-container'),
            beforeImg = document.getElementById('before'),
            afterImg = document.getElementById('after'),
            downloadLink = document.getElementById('download'),

        errorContainer = document.getElementById('error-container');

    pixelateBtn.addEventListener('click', function () {
        var file = fileInput.files[0];

        hide(errorContainer);

        if (file instanceof File && /\.(jpe?g|png|gif)$/i.test(file.name)) {
            var reader = new FileReader(),
                canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d');

            reader.addEventListener('load', function () {
                var dataURL = this.result,

                    width,
                    height,

                    pixelator;

                beforeImg.src = dataURL;

                width = beforeImg.width;
                height = beforeImg.height;

                canvas.width = width;
                canvas.height = height;

                ctx.drawImage(beforeImg, 0, 0, width, height);

                pixelator = new Pixelator(ctx.getImageData(0, 0, width, height));

                afterImg.src = pixelator.pixelate((widthInput.value | 0) || 10, (heightInput.value | 0) || 10).canvas.toDataURL();

                show(outputContainer);
            });

            reader.readAsDataURL(file);
        } else {
            error('As of now, this tool only supports jpg, jpeg, png, and gif files.');
        }
    });

    function error(msg) {
        show(errorContainer);
        hide(outputContainer);

        errorContainer.innerHTML = msg;
    }

    function show(elem) {
        elem.style.display = 'inherit';
    }

    function hide(elem) {
        elem.style.display = 'none';
    }

    return {
        error: error,
        show: show,
        hide: hide
    }; // Nothing to export so far.
})();
<commit_msg>Update demo.js<commit_after>var demo = (function () {
    var fileInput = document.getElementById('upload'),
        widthInput = document.getElementById('section-width'),
        heightInput = document.getElementById('section-height'),
        pixelateBtn = document.getElementById('pixelate-btn'),

        outputContainer = document.getElementById('output-container'),
            beforeImg = document.getElementById('before'),
            afterImg = document.getElementById('after'),
            downloadLink = document.getElementById('download'),

        errorContainer = document.getElementById('error-container');

    pixelateBtn.addEventListener('click', function () {
        var file = fileInput.files[0];

        hide(errorContainer);

        if (file instanceof File && /\.(jpe?g|png|gif)$/i.test(file.name)) {
            var reader = new FileReader(),
                canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d');

            reader.addEventListener('load', function () {
                var dataURL = this.result,

                    width,
                    height,

                    pixelator;

                beforeImg.src = dataURL;

                width = beforeImg.width;
                height = beforeImg.height;

                canvas.width = width;
                canvas.height = height;

                ctx.drawImage(beforeImg, 0, 0, width, height);

                pixelator = new Pixelator(ctx.getImageData(0, 0, width, height));

                afterImg.src = pixelator.pixelate((widthInput.value | 0) || 10, (heightInput.value | 0) || 10).canvas.toDataURL('image/png', 1);

                show(outputContainer);
            });

            reader.readAsDataURL(file);
        } else {
            error('As of now, this tool only supports jpg, jpeg, png, and gif files.');
        }
    });

    function error(msg) {
        show(errorContainer);
        hide(outputContainer);

        errorContainer.innerHTML = msg;
    }

    function show(elem) {
        elem.style.display = 'inherit';
    }

    function hide(elem) {
        elem.style.display = 'none';
    }

    return {
        error: error,
        show: show,
        hide: hide
    }; // Nothing to export so far.
})();
<|endoftext|>


<commit_before>//
// Please update "commments" to "submit point"
//

'use strict';

var assertionUrl = 'https://3pp.io:4343/persona';
var postPointUrl = 'https://3pp.io:4343/post/point';
var serviceListUrl = 'https://tosdr.org/index/services.json';

$(document).ready(function(){
	var loggedInUser = null;

	function logout(){
		loggedInUser = null;
		var response = $.post(assertionUrl + '/logout');
		response.always(showPersona);
	}

	function verify(assertion){
		var response = $.ajax(assertionUrl + '/verify', {data: {assertion: assertion}, type: 'POST', xhrFields: {withCredentials: true}});
		response.done(login);
		response.fail(function(){
			navigator.id.logout();
		});
	}

	function login(data){
		showSubmitForm(data.email);
	}

	navigator.id.watch({
		loggedInUser: loggedInUser,
		onlogin: verify,
		onlogout: logout
	});

	function showPersona(){
		$('#form').html('

To submit a point, please sign in — you can use an existing email address.

');
		$('.signinButton').click(function(){ navigator.id.request(); }).css('cursor', 'pointer');
	}

        // This is ugly, too much html here
        //
        //

	function showSubmitForm(email){
		$('#form').html('
Submitting as ' + email + ' (Not your email address? Log out!)
' +
                        '<form class="submitForm">' +
                            '' +
                            '<fieldset>' +
                                '<legend>Submit a point about a clause</legend>' +
                                'Title<input type="text" id="titleField" name="title" required />' +

                                'Service(s)<input id="servicesField" name="services" required class="input-large" />' +

'					Service(s) to which the point applies' +
'					<input type="text" placeholder="facebook">' +
'					<input type="text" placeholder="twitter">' +
'					<button class="btn btn-inline" type="button">Add one</button>' +
'' +

                                '<input type="radio" name="point" id="pointGood" value="good" />Good<input type="radio" name="point" id="pointNeutral" value="neutral" />Neutral<input type="radio" required name="point" id="pointBad" value="bad" />Bad<input type="radio" name="point" id="pointBlocker" value="blocker" />Blocker' +

                                'Topic<input id="topicsField" name="topics" required class="input-large" />' +

'					<select id="topics">' +
'						<option>Select a topic</option>' +
'						<option>Scope of the copyright license</option>' +
'						<option>Changes</option>' +
'					</select>' +

                                'Can you summarise this clause? Parsed as Markdown<textarea name="summary" id="summaryField" required class="input-xxlarge" placeholder="This is the summary, the recap of what the clause in the terms do. It is usually a very difficult exercise. Try not to make more than 5 sentences, but sometimes more is needed. Be creative. Feel free to include some quotes from the terms directly. It is very important that it is easy to understand and written in plain English."></textarea>' +

                            '</fieldset>' +
                            '
' +
                                '<button class="btn btn-primary" id="postPoint">Send</button>' +
                            '
' +
                        '</form>');

        var response = $.get(serviceListUrl, 'json');
        response.done(function(services){
            services = $.map(services, function(value, key){
                return key;
            });
            // Note: the width should be 'element', but for some reason it receives a different width than other input elements
            $('#servicesField').select2({tags: services, width: '220px', containerCss: {'border-radius': '4px'}});
        });

		$('.submitForm').submit(function(e){
			var response = $.ajax(postPointUrl, {data: {title: $('#titleField').val(), point: $('input[name=point]:checked', '.submitForm').val(), services: $('#servicesField').val(), summary: $('#summaryField').val()}, type: 'POST', xhrFields: {withCredentials: true}});
			response.done(showConfirmation);
			response.fail(showError);
			e.preventDefault();
		});
		$('.signoutButton').click(function(){ navigator.id.logout(); });
	}

	function showConfirmation(){
		$('#form').html('Your point has been submitted. Thank you! '
                   +'submit another one or '
                   +'see the list.');
	}

	function showError(){
		$('#form').prepend('
<button type="button" class="close" data-dismiss="alert">×</button>Something went wrong saving your point, did you fill in all the fields?
');
	}

	showPersona();
});
<commit_msg>form help moved<commit_after>//
// Please update "commments" to "submit point"
//

'use strict';

var assertionUrl = 'https://3pp.io:4343/persona';
var postPointUrl = 'https://3pp.io:4343/post/point';
var serviceListUrl = 'https://tosdr.org/index/services.json';

$(document).ready(function(){
	var loggedInUser = null;

	function logout(){
		loggedInUser = null;
		var response = $.post(assertionUrl + '/logout');
		response.always(showPersona);
	}

	function verify(assertion){
		var response = $.ajax(assertionUrl + '/verify', {data: {assertion: assertion}, type: 'POST', xhrFields: {withCredentials: true}});
		response.done(login);
		response.fail(function(){
			navigator.id.logout();
		});
	}

	function login(data){
		showSubmitForm(data.email);
	}

	navigator.id.watch({
		loggedInUser: loggedInUser,
		onlogin: verify,
		onlogout: logout
	});

	function showPersona(){
		$('#form').html('

To submit a point, please sign in — you can use an existing email address.

');
		$('.signinButton').click(function(){ navigator.id.request(); }).css('cursor', 'pointer');
	}

        // This is ugly, too much html here
        //
        //

	function showSubmitForm(email){
		$('#form').html('<form class="submitForm">' +
                            '' +
                            '<fieldset>' +
                                '<legend>Submit a point about a clause</legend>' +

                                '
Submitting as ' + email + ' (Not your email address? Log out!)
' +

                                'Title<input type="text" id="titleField" name="title" required />' +

                                'Service(s)<input id="servicesField" name="services" required class="input-large" />' +

'					Service(s) to which the point applies' +
'					<input type="text" placeholder="facebook">' +
'					<input type="text" placeholder="twitter">' +
'					<button class="btn btn-inline" type="button">Add one</button>' +
'' +

                                '<input type="radio" name="point" id="pointGood" value="good" />Good<input type="radio" name="point" id="pointNeutral" value="neutral" />Neutral<input type="radio" required name="point" id="pointBad" value="bad" />Bad<input type="radio" name="point" id="pointBlocker" value="blocker" />Blocker' +

                                'Topic<input id="topicsField" name="topics" required class="input-large" />' +

'					<select id="topics">' +
'						<option>Select a topic</option>' +
'						<option>Scope of the copyright license</option>' +
'						<option>Changes</option>' +
'					</select>' +

                                'Can you summarise this clause? Parsed as Markdown<textarea name="summary" id="summaryField" required class="input-xxlarge" placeholder="This is the summary, the recap of what the clause in the terms do. It is usually a very difficult exercise. Try not to make more than 5 sentences, but sometimes more is needed. Be creative. Feel free to include some quotes from the terms directly. It is very important that it is easy to understand and written in plain English."></textarea>' +

                            '</fieldset>' +
                            '
' +
                                '<button class="btn btn-primary" id="postPoint">Send</button>' +
                            '
' +
                        '</form>');

        var response = $.get(serviceListUrl, 'json');
        response.done(function(services){
            services = $.map(services, function(value, key){
                return key;
            });
            // Note: the width should be 'element', but for some reason it receives a different width than other input elements
            $('#servicesField').select2({tags: services, width: '220px', containerCss: {'border-radius': '4px'}});
        });

		$('.submitForm').submit(function(e){
			var response = $.ajax(postPointUrl, {data: {title: $('#titleField').val(), point: $('input[name=point]:checked', '.submitForm').val(), services: $('#servicesField').val(), summary: $('#summaryField').val()}, type: 'POST', xhrFields: {withCredentials: true}});
			response.done(showConfirmation);
			response.fail(showError);
			e.preventDefault();
		});
		$('.signoutButton').click(function(){ navigator.id.logout(); });
	}

	function showConfirmation(){
		$('#form').html('Your point has been submitted. Thank you! '
                   +'submit another one or '
                   +'see the list.');
	}

	function showError(){
		$('#form').prepend('
<button type="button" class="close" data-dismiss="alert">×</button>Something went wrong saving your point, did you fill in all the fields?
');
	}

	showPersona();
});
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const json5 = require('json5');
const EtcdClient = require('node-etcd');

function parse(value){
  try {
    return json5.parse(value);
  } catch(err){
    return value;
  }
}

function listing(result){
  const nodes = _.get(result, 'node.nodes');
  const items = _.pluck(nodes, 'value');
  const value = _.map(items, parse);
  return value;
}

function shortstopEtcd(...args){
  const etcd = new EtcdClient(...args);

  function etcdHandler(key, cb){
    etcd.get(key, (err, result) => {
      if(err){
        cb(err);
        return;
      }

      if(result.dir === true){
        const value = listing(result);
        cb(null, value);
        return;
      }

      const value = parse(result.node.value);

      cb(null, value);
    });
  }

  return etcdHandler;
}

module.exports = shortstopEtcd;
<commit_msg>dir flag is on the node<commit_after>'use strict';

const _ = require('lodash');
const json5 = require('json5');
const EtcdClient = require('node-etcd');

function parse(value){
  try {
    return json5.parse(value);
  } catch(err){
    return value;
  }
}

function listing(node){
  const nodes = _.get(node, 'nodes');
  const items = _.pluck(nodes, 'value');
  const value = _.map(items, parse);
  return value;
}

function shortstopEtcd(...args){
  const etcd = new EtcdClient(...args);

  function etcdHandler(key, cb){
    etcd.get(key, (err, result) => {
      if(err){
        cb(err);
        return;
      }

      const node = result.node;

      if(node.dir === true){
        cb(null, listing(node));
        return;
      }

      const value = parse(node.value);

      cb(null, value);
    });
  }

  return etcdHandler;
}

module.exports = shortstopEtcd;
<|endoftext|>


<commit_before>var R    = require('ramda');

export class CliController {
  constructor(opts = {}) {
    Object.keys(opts).forEach((key) => {
      if (opts.hasOwnProperty(key)) {
        this[key] = opts[key];
      }
    });
  }

  index() {
    throw new Error("Don't use CliController directly, implemente the index action.");
  }

  run_action(action_name, ...args) {
    if (R.isNil(action_name) || !R.is(Function, this[action_name])) {
      action_name = 'index';
    }
    this.before_action(action_name, ...args);
    var result = this[action_name].apply(this, args);
    this.after_action(action_name, ...args);
    return result;
  }
  before_action(/* action_name, ...args */) {}
  after_action(/* action_name, ...args */) {}
}
<commit_msg>[CliController] Changing before, action, and after for sequential calls.<commit_after>var R    = require('ramda');

export class CliController {
  constructor(opts = {}) {
    Object.keys(opts).forEach((key) => {
      if (opts.hasOwnProperty(key)) {
        this[key] = opts[key];
      }
    });
  }

  index() {
    throw new Error("Don't use CliController directly, implemente the index action.");
  }

  run_action(action_name, ...args) {
    if (R.isNil(action_name) || !R.is(Function, this[action_name])) {
      action_name = 'index';
    }
    return this.before_action(action_name, ...args);
  }

  before_action(action_name, ...args) {
    var action_result = this[action_name].apply(this, args);
    this.after_action(action_name, ...args);
    return action_result;
  }

  after_action(action_name, action_result) {
    return action_result;
  }
}
<|endoftext|>


<commit_before>import AppBaseClient from './core/index';
import fetchRequest from './core/request/fetch';
import indexApi from './core/api/index';
import getApi from './core/api/get';
import updateApi from './core/api/update';
import deleteApi from './core/api/delete';
import bulkApi from './core/api/bulk';
import searchApi from './core/api/search';
import msearchApi from './core/api/msearch';
import reactiveSearchv3Api from './core/api/reactiveSearchv3Api';
import getMappingsApi from './core/api/getMappings';
import { encodeHeaders } from './utils/index';
import getSuggestionsv3Api from './core/api/getSuggestionsv3Api';

function appbasejs(config) {
  const client = new AppBaseClient(config);

  AppBaseClient.prototype.performFetchRequest = fetchRequest;

  AppBaseClient.prototype.index = indexApi;

  AppBaseClient.prototype.get = getApi;

  AppBaseClient.prototype.update = updateApi;

  AppBaseClient.prototype.delete = deleteApi;

  AppBaseClient.prototype.bulk = bulkApi;

  AppBaseClient.prototype.search = searchApi;

  AppBaseClient.prototype.msearch = msearchApi;

  AppBaseClient.prototype.reactiveSearchv3 = reactiveSearchv3Api;

  AppBaseClient.prototype.getQuerySuggestions = getSuggestionsv3Api;

  AppBaseClient.prototype.getMappings = getMappingsApi;

  AppBaseClient.prototype.setHeaders = function setHeaders(
    headers = {},
    shouldEncode = false,
  ) {
    // Encode headers
    if (shouldEncode) {
      this.headers = encodeHeaders(headers);
    } else {
      this.headers = headers;
    }
  };

  if (typeof window !== 'undefined') {
    window.Appbase = client;
  }
  return client;
}
export default appbasejs;
<commit_msg>fix: refactor index.js<commit_after>import AppBaseClient from './core/index';
import fetchRequest from './core/request/fetch';
import indexApi from './core/api/index';
import getApi from './core/api/get';
import updateApi from './core/api/update';
import deleteApi from './core/api/delete';
import bulkApi from './core/api/bulk';
import searchApi from './core/api/search';
import msearchApi from './core/api/msearch';
import reactiveSearchv3Api from './core/api/reactiveSearchv3Api';
import getMappingsApi from './core/api/getMappings';
import { encodeHeaders } from './utils/index';
import getSuggestionsv3Api from './core/api/getSuggestionsv3Api';

export default function (config) {
	const client = new AppBaseClient(config);

	AppBaseClient.prototype.performFetchRequest = fetchRequest;

	AppBaseClient.prototype.index = indexApi;

	AppBaseClient.prototype.get = getApi;

	AppBaseClient.prototype.update = updateApi;

	AppBaseClient.prototype.delete = deleteApi;

	AppBaseClient.prototype.bulk = bulkApi;

	AppBaseClient.prototype.search = searchApi;

	AppBaseClient.prototype.msearch = msearchApi;

	AppBaseClient.prototype.reactiveSearchv3 = reactiveSearchv3Api;

	AppBaseClient.prototype.getQuerySuggestions = getSuggestionsv3Api;

	AppBaseClient.prototype.getMappings = getMappingsApi;

	AppBaseClient.prototype.setHeaders = function setHeaders(headers = {}, shouldEncode = false) {
		// Encode headers
		if (shouldEncode) {
			this.headers = encodeHeaders(headers);
		} else {
			this.headers = headers;
		}
	};

	if (typeof window !== 'undefined') {
		window.Appbase = client;
	}
	return client;
}
<|endoftext|>


<commit_before>main();

function main () {
    "use strict";

    // Get container for elm controled dom.
    var node = document.getElementById('warp');

    // Start up Elm app
    var app  = Elm.Warp.embed(node);

    // Subscrib to messages from elm to draw warp
    app.ports.warpChange.subscribe(function (data) {
        // Wait for the next browser call to do the paint
        requestAnimationFrame(function() {
            drawAll(data[0], data[1]);
        });
    });

    app.ports.colorChange.subscribe(function (data) {
        // Wait for the next browser call to do the paint
        requestAnimationFrame(function() {
            drawColor(data);
        });
    });

    app.ports.setUrl.subscribe(function (data) {
        // Wait for the next browser call to do the paint
        requestAnimationFrame(function() {
            window.location.hash = data;
            document.getElementById("cpysrc").value = window.location;
        });
    });

    // Get canvas element and the drawing context
    var canvas = document.getElementById("canvas");
    var ctx    = canvas.getContext("2d");

    var colorBuffers = [];

    // init clip board button
    new Clipboard('.clipboard-copy');

    function getBounds ( canvas ) {
        return canvas
            .parentElement
            .getBoundingClientRect();
    }

    function getPixelRatio ( ) {
        // set it up so that we draw at the real dpi of the display
        var devicePixelRatio
            = window.devicePixelRatio || 1;

        var backingStoreRatio
            = ctx.backingStorePixelRatio ||
            ctx.webkitBackingStorePixelRatio ||
            ctx.mozBackingStorePixelRatio ||
            ctx.msBackingStorePixelRatio ||
            ctx.oBackingStorePixelRatio ||
            1;

        var ratio = devicePixelRatio / backingStoreRatio;

        return ratio;
    }

    function initBuffers ( warpWidth, warpHeight, colors ) {
        colorBuffers = [];

        for ( var i = 0 ; i < colors.length ; i++ ) {
            var buf = document.createElement("canvas");
            buf.width  = warpWidth;
            buf.height = warpHeight;
            var btx = buf.getContext('2d');

            btx.fillStyle = "rgba(0,0,0,0)";
	    btx.fillRect( 0, 0, warpWidth, warpWidth );

            colorBuffers.push(buf);
        }
    }

    function drawAll ( warp, colors ) {

        var threading   = warp.threading;
        var tieup       = warp.tieup;
        var treadling   = warp.treadling;
        var threads     = warp.warpColors;
        var weftthreads = warp.weftColors;

        var threadWidth = undefined;

        // Make the width of the warp be the
        // width of it's parent element.
        var bounds = getBounds( canvas );
        var WARP_HEIGHT = 200;
        var warpWidth  = bounds.width;
        var warpHeight = WARP_HEIGHT; //bounds.height;

        var ratio = getPixelRatio();

        // upscale the canvas if the two ratios don't match
        if ( ratio !== 1 ) {
            canvas.style.width = warpWidth + 'px';
            canvas.style.height = warpHeight + 'px';

            warpWidth  *= ratio;
            warpHeight *= ratio;
        }

        if ( threads.length != 0 )
            threadWidth = Math.ceil(warpWidth/threads.length);

        warpWidth = threads.length * threadWidth;
        warpHeight = WARP_HEIGHT * warpWidth/bounds.width ;

        canvas.width = warpWidth;
        canvas.height = warpHeight;

        initBuffers( warpWidth, warpHeight, colors );

        var tupleBuffer = document.createElement("canvas");
        tupleBuffer.width  = warpWidth;
        tupleBuffer.height = warpHeight;

        var tupleOffsets = {};
        var nextTuple    = 0;
        var tupleContext = tupleBuffer.getContext('2d');

        tupleContext.fillStyle = "rgba(0,0,0,0)";
	tupleContext.fillRect( 0, 0, warpWidth, warpWidth );
        tupleContext.fillStyle = "#000000";

        var start = 0;

        if ( treadling.length * threadWidth > warpHeight ) {
            start = Math.ceil(treadling.length/2)
                - Math.floor( warpHeight / threadWidth / 2 );
        }

        var trippleWidth = threadWidth * 3;

	for ( var i = 0 ; i < threads.length ; i++ ) { // reading warp left to right
	    var offset     = i * threadWidth;
            var shaft      = threading[i];
            var colorIndex = threads[i];

            var nextShaft     = "E";
            var preivousShaft = "E";

            if ( i < (threads.length - 1) )
                nextShaft = threads[i+1]

            if ( i !== 0 )
                preivousShaft = threading[i-1];

            var tupleKey    = shaft + "-" + nextShaft;
            var cashOffset = tupleOffsets[tupleKey];

            if ( cashOffset === undefined ) {
                cashOffset = nextTuple;
                nextTuple  += trippleWidth;

                tupleOffsets[tupleKey] = cashOffset;

                var wOffset  = undefined;

                for ( var j = 0 ; j < Math.ceil(warpHeight/threadWidth) ; j++ ) {

                    var treadlingIndex = (j + start) % treadling.length;
                    var shafts         = tieup[treadling[treadlingIndex] - 1];

                    // continue if is is weft
                    if (contains( shaft, shafts )) {
                        if ( wOffset !== undefined ) {
                            var end = j * threadWidth;
                            // Draw pixel
                            tupleContext.fillRect(
                                cashOffset + 1, wOffset,
                                threadWidth   , end - wOffset );
                        }

                        wOffset = undefined;
                    }
                    else if ( wOffset === undefined )
                        wOffset = j * threadWidth;

	        }

                if ( wOffset !== undefined ) {
                    var end = j * threadWidth;
                    // Draw pixel
                    tupleContext.fillRect(
                        cashOffset + 1, wOffset,
                        threadWidth   , end - wOffset );
                }

            }

            var buf = colorBuffers[ colorIndex ].getContext('2d');

            buf.drawImage(tupleBuffer,
                          cashOffset , 0, trippleWidth, warpHeight,
                          offset -1  , 0, trippleWidth, warpHeight);

        }

        drawColor( colors );
    }

    function drawColor ( colors ) {

        var width  = canvas.width;
        var height = canvas.height;

        // Fill the canvas with the weft color
        ctx.fillStyle = colors[0].hex;
	ctx.fillRect( 0, 0, width, height );

        for ( var i = 1; i < colors.length ; i++ ) {
            var buf = colorBuffers[i];
            var btx = buf.getContext('2d');

            btx.save();
            btx.fillStyle = colors[i].hex;
            btx.globalCompositeOperation = "source-in";
            btx.fillRect(0, 0, width, height);
            btx.restore();

            ctx.drawImage(buf, 0, 0, width, height, 0, 0, width, height);
        }

    }

    function contains ( value, list ) {

        for ( var i = 0 ; i < list.length ; i++ )
            if ( value === list[i] )
                return true;

        return false;
    }
}
<commit_msg>fix ios bug related to fractional canvas height<commit_after>main();

function main () {
    "use strict";

    // Get container for elm controled dom.
    var node = document.getElementById('warp');

    // Start up Elm app
    var app  = Elm.Warp.embed(node);

    // Subscrib to messages from elm to draw warp
    app.ports.warpChange.subscribe(function (data) {
        // Wait for the next browser call to do the paint
        requestAnimationFrame(function() {
            drawAll(data[0], data[1]);
        });
    });

    app.ports.colorChange.subscribe(function (data) {
        // Wait for the next browser call to do the paint
        requestAnimationFrame(function() {
            drawColor(data);
        });
    });

    app.ports.setUrl.subscribe(function (data) {
        // Wait for the next browser call to do the paint
        requestAnimationFrame(function() {
            window.location.hash = data;
            document.getElementById("cpysrc").value = window.location;
        });
    });

    // Get canvas element and the drawing context
    var canvas = document.getElementById("canvas");
    var ctx    = canvas.getContext("2d");

    var colorBuffers = [];

    // init clip board button
    new Clipboard('.clipboard-copy');

    function getBounds ( canvas ) {
        return canvas
            .parentElement
            .getBoundingClientRect();
    }

    function getPixelRatio ( ) {
        // set it up so that we draw at the real dpi of the display
        var devicePixelRatio
            = window.devicePixelRatio || 1;

        var backingStoreRatio
            = ctx.backingStorePixelRatio ||
            ctx.webkitBackingStorePixelRatio ||
            ctx.mozBackingStorePixelRatio ||
            ctx.msBackingStorePixelRatio ||
            ctx.oBackingStorePixelRatio ||
            1;

        var ratio = devicePixelRatio / backingStoreRatio;

        return ratio;
    }

    function initBuffers ( warpWidth, warpHeight, colors ) {
        colorBuffers = [];

        for ( var i = 0 ; i < colors.length ; i++ ) {
            var buf = document.createElement("canvas");
            buf.width  = warpWidth;
            buf.height = warpHeight;
            var btx = buf.getContext('2d');

            btx.fillStyle = "rgba(0,0,0,0)";
	    btx.fillRect( 0, 0, warpWidth, warpWidth );

            colorBuffers.push(buf);
        }
    }

    function drawAll ( warp, colors ) {

        var threading   = warp.threading;
        var tieup       = warp.tieup;
        var treadling   = warp.treadling;
        var threads     = warp.warpColors;
        var weftthreads = warp.weftColors;

        var threadWidth = undefined;

        // Make the width of the warp be the
        // width of it's parent element.
        var bounds = getBounds( canvas );
        var WARP_HEIGHT = 200;
        var warpWidth  = bounds.width;
        var warpHeight = WARP_HEIGHT; //bounds.height;

        var ratio = getPixelRatio();

        // upscale the canvas if the two ratios don't match
        if ( ratio !== 1 ) {
            canvas.style.width = warpWidth + 'px';
            canvas.style.height = warpHeight + 'px';

            warpWidth  *= ratio;
            warpHeight *= ratio;
        }

        if ( threads.length != 0 )
            threadWidth = Math.ceil(warpWidth/threads.length);

        //BUG: Doing this for now makes things blurry but
        //     also is easer on the GPU memory which is better
        //     for phones.
        threadWidth = 1;

        warpWidth = threads.length * threadWidth;
        warpHeight = Math.ceil(WARP_HEIGHT * warpWidth/bounds.width) ;

        canvas.width = warpWidth;
        canvas.height = warpHeight;

        initBuffers( warpWidth, warpHeight, colors );

        var tupleBuffer = document.createElement("canvas");
        tupleBuffer.width  = warpWidth * 3;
        tupleBuffer.height = warpHeight;

        var tupleOffsets = {};
        var nextTuple    = 0;
        var tupleContext = tupleBuffer.getContext('2d');

        tupleContext.fillStyle = "rgba(0,0,0,0)";
	tupleContext.fillRect( 0, 0, warpWidth, warpWidth * 3 );
        tupleContext.fillStyle = "#000000";

        var start = 0;

        if ( treadling.length * threadWidth > warpHeight ) {
            start = Math.ceil(treadling.length/2)
                - Math.floor( warpHeight / threadWidth / 2 );
        }

        var trippleWidth = threadWidth * 3;

	for ( var i = 0 ; i < threads.length ; i++ ) { // reading warp left to right
	    var offset     = i * threadWidth;
            var shaft      = threading[i];
            var colorIndex = threads[i];

            var nextShaft     = "E";
            var preivousShaft = "E";

            if ( i < (threads.length - 1) )
                nextShaft = threads[i+1]

            if ( i !== 0 )
                preivousShaft = threading[i-1];

            var tupleKey    = shaft + "-" + nextShaft;
            var cashOffset = tupleOffsets[tupleKey];

            if ( cashOffset === undefined ) {
                cashOffset = nextTuple;
                nextTuple  += trippleWidth;

                tupleOffsets[tupleKey] = cashOffset;

                var wOffset  = undefined;

                for ( var j = 0 ; j < Math.ceil(warpHeight/threadWidth) ; j++ ) {

                    var treadlingIndex = (j + start) % treadling.length;
                    var shafts         = tieup[treadling[treadlingIndex] - 1];

                    // continue if is is weft
                    if (contains( shaft, shafts )) {
                        if ( wOffset !== undefined ) {
                            var end = j * threadWidth;
                            // Draw pixel
                            tupleContext.fillRect(
                                cashOffset + 1, wOffset,
                                threadWidth   , end - wOffset );
                        }

                        wOffset = undefined;
                    }
                    else if ( wOffset === undefined )
                        wOffset = j * threadWidth;

	        }

                if ( wOffset !== undefined ) {
                    var end = j * threadWidth;
                    // Draw pixel
                    tupleContext.fillRect(
                        cashOffset + 1, wOffset,
                        threadWidth   , end - wOffset );
                }

            }

            var buf = colorBuffers[ colorIndex ].getContext('2d');

            buf.drawImage(tupleBuffer,
                          cashOffset , 0, trippleWidth, warpHeight,
                          offset -1  , 0, trippleWidth, warpHeight);

        }

        drawColor( colors );
    }

    function drawColor ( colors ) {

        var width  = canvas.width;
        var height = canvas.height;

        // Fill the canvas with the weft color
        ctx.fillStyle = colors[0].hex;
	ctx.fillRect( 0, 0, width, height );

        for ( var i = 1; i < colors.length ; i++ ) {
            var buf = colorBuffers[i];
            var btx = buf.getContext('2d');

            btx.save();
            btx.fillStyle = colors[i].hex;
            btx.globalCompositeOperation = "source-in";
            btx.fillRect(0, 0, width, height);
            btx.restore();

            ctx.drawImage(buf, 0, 0, width, height, 0, 0, width, height);
        }

    }

    function contains ( value, list ) {

        for ( var i = 0 ; i < list.length ; i++ )
            if ( value === list[i] )
                return true;

        return false;
    }
}
<|endoftext|>


<commit_before>/**
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

import { Realm } from './realm';

const PARAMS = [];
let nextPort;

if (typeof AudioWorkletNode !== 'function') {
  window.AudioWorkletNode = function AudioWorkletNode (context, name, options) {
    const processor = getProcessorsForContext(context)[name];
    const scriptProcessor = context.createScriptProcessor();

    scriptProcessor.parameters = new Map();
    if (processor.properties) {
      for (let i = 0; i < processor.properties.length; i++) {
        const prop = processor.properties[i];
        const node = context.createGain().gain;
        node.value = prop.defaultValue;
        // @TODO there's no good way to construct the proxy AudioParam here
        scriptProcessor.parameters.set(prop.name, node);
      }
    }

    const mc = new MessageChannel();
    this.port = mc.port1;
    nextPort = mc.port2;
    const inst = new processor.Processor(options || {});
    nextPort = null;

    scriptProcessor.processor = processor;
    scriptProcessor.instance = inst;
    scriptProcessor.onaudioprocess = onAudioProcess;
    return scriptProcessor;
  };

  Object.defineProperty(AudioContext.prototype, 'audioWorklet', {
    get () {
      return this.$$audioWorklet || (this.$$audioWorklet = new window.AudioWorklet(this));
    }
  });

  window.AudioWorklet = class AudioWorklet {
    constructor (audioContext) {
      this.$$context = audioContext;
    }

    addModule (url, options) {
      return fetch(url).then(r => {
        if (!r.ok) throw Error(r.status);
        return r.text();
      }).then(code => {
        const context = {
          sampleRate: 0,
          currentTime: 0,
          AudioWorkletProcessor () {
            this.port = nextPort;
          },
          registerProcessor: (name, Processor) => {
            const processors = getProcessorsForContext(this.$$context);
            processors[name] = {
              realm,
              context,
              Processor,
              properties: Processor.parameterDescriptors || []
            };
          }
        };
        context.self = context;
        const realm = new Realm(context, document.documentElement);
        realm.exec(((options && options.transpile) || String)(code));
        return null;
      });
    }
  };
}

function onAudioProcess (e) {
  const parameters = {};
  let index = -1;
  this.parameters.forEach((value, key) => {
    const arr = PARAMS[++index] || (PARAMS[index] = new Float32Array(this.bufferSize));
    // @TODO proper values here if possible
    arr.fill(value.value);
    parameters[key] = arr;
  });
  this.processor.realm.exec(
    'self.sampleRate=sampleRate=' + this.context.sampleRate + ';' +
    'self.currentTime=currentTime=' + this.context.currentTime
  );
  const inputs = channelToArray(e.inputBuffer);
  const outputs = channelToArray(e.outputBuffer);
  this.instance.process([inputs], [outputs], parameters);

  // @todo - keepalive
  // let ret = this.instance.process([inputs], [outputs], parameters);
  // if (ret === true) { }
}

function channelToArray (ch) {
  const out = [];
  for (let i = 0; i < ch.numberOfChannels; i++) {
    out[i] = ch.getChannelData(i);
  }
  return out;
}

function getProcessorsForContext (audioContext) {
  return audioContext.$$processors || (audioContext.$$processors = {});
}
<commit_msg>Do not crash if non-prefixed AudioContext isn't available<commit_after>/**
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

import { Realm } from './realm';

const PARAMS = [];
let nextPort;

if (typeof AudioWorkletNode !== 'function') {
  window.AudioWorkletNode = function AudioWorkletNode (context, name, options) {
    const processor = getProcessorsForContext(context)[name];
    const scriptProcessor = context.createScriptProcessor();

    scriptProcessor.parameters = new Map();
    if (processor.properties) {
      for (let i = 0; i < processor.properties.length; i++) {
        const prop = processor.properties[i];
        const node = context.createGain().gain;
        node.value = prop.defaultValue;
        // @TODO there's no good way to construct the proxy AudioParam here
        scriptProcessor.parameters.set(prop.name, node);
      }
    }

    const mc = new MessageChannel();
    this.port = mc.port1;
    nextPort = mc.port2;
    const inst = new processor.Processor(options || {});
    nextPort = null;

    scriptProcessor.processor = processor;
    scriptProcessor.instance = inst;
    scriptProcessor.onaudioprocess = onAudioProcess;
    return scriptProcessor;
  };

  Object.defineProperty((window.AudioContext||webkitAudioContext).prototype, 'audioWorklet', {
    get () {
      return this.$$audioWorklet || (this.$$audioWorklet = new window.AudioWorklet(this));
    }
  });

  window.AudioWorklet = class AudioWorklet {
    constructor (audioContext) {
      this.$$context = audioContext;
    }

    addModule (url, options) {
      return fetch(url).then(r => {
        if (!r.ok) throw Error(r.status);
        return r.text();
      }).then(code => {
        const context = {
          sampleRate: 0,
          currentTime: 0,
          AudioWorkletProcessor () {
            this.port = nextPort;
          },
          registerProcessor: (name, Processor) => {
            const processors = getProcessorsForContext(this.$$context);
            processors[name] = {
              realm,
              context,
              Processor,
              properties: Processor.parameterDescriptors || []
            };
          }
        };
        context.self = context;
        const realm = new Realm(context, document.documentElement);
        realm.exec(((options && options.transpile) || String)(code));
        return null;
      });
    }
  };
}

function onAudioProcess (e) {
  const parameters = {};
  let index = -1;
  this.parameters.forEach((value, key) => {
    const arr = PARAMS[++index] || (PARAMS[index] = new Float32Array(this.bufferSize));
    // @TODO proper values here if possible
    arr.fill(value.value);
    parameters[key] = arr;
  });
  this.processor.realm.exec(
    'self.sampleRate=sampleRate=' + this.context.sampleRate + ';' +
    'self.currentTime=currentTime=' + this.context.currentTime
  );
  const inputs = channelToArray(e.inputBuffer);
  const outputs = channelToArray(e.outputBuffer);
  this.instance.process([inputs], [outputs], parameters);

  // @todo - keepalive
  // let ret = this.instance.process([inputs], [outputs], parameters);
  // if (ret === true) { }
}

function channelToArray (ch) {
  const out = [];
  for (let i = 0; i < ch.numberOfChannels; i++) {
    out[i] = ch.getChannelData(i);
  }
  return out;
}

function getProcessorsForContext (audioContext) {
  return audioContext.$$processors || (audioContext.$$processors = {});
}
<|endoftext|>


<commit_before>// Copyright 2016, University of Colorado Boulder

/**
 * PhET-iO wrapper type for JS's built-in Array type.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var TObject = require( 'PHET_IO/types/TObject' );

  /**
   * Parametric wrapper type constructor.  Given an element type, this function returns an appropriate array wrapper type.
   * @param {TObject} elementType - wrapper type of the individual elements in the array
   * @constructor
   */
  function TArray( elementType ) {

    /**
     * This type constructor is parameterized based on the elementType.
     * @param {Object[]} arrayInstance - the array to be wrapped
     * @param {string} phetioID - the full unique tandem name for the instance
     * @constructor
     */
    var TArrayImpl = function TArrayImpl( arrayInstance, phetioID ) {
      TObject.call( this, arrayInstance, phetioID );
      assert && assert( Array.isArray( arrayInstance ), 'TArray should wrap array instances' );
    };
    return phetioInherit( TObject, 'TArray', TArrayImpl, {

      /**
       * Sets the state of the array by clearing it and adding new elements.
       */
      // setValue: {
      //   returnType: TVoid,
      //   parameterTypes: [],
      //   implementation: function( elements ) {
      //     this.instance.length = 0;
      //     this.instance.push.apply( this.instance, elements );
      //   },
      //   documentation: 'Sets the value of all elements in the array'
      // }
    }, {
      documentation: 'A wrapper for the built-in JS array type, with the element type specified.',
      elementType: elementType,

      /**
       * Deserialize from a serialized state.
       * @param {Object} stateObject - from toStateObject
       * @returns {Object[]}
       */
      fromStateObject: function( stateObject ) {
        var array = [];
        for ( var i = 0; i < stateObject.length; i++ ) {
          array.push( elementType.fromStateObject( stateObject[ i ] ) );
        }
        return array;
      },

      /**
       * Serialize an array by serializing each element
       * @param {Object[]} array
       * @returns {Array}
       */
      toStateObject: function( array ) {
        var json = [];
        for ( var i = 0; i < array.length; i++ ) {
          json.push( elementType.toStateObject( array[ i ] ) );
        }
        return json;
      }
    } );
  }

  phetioNamespace.register( 'TArray', TArray );

  return TArray;
} );<commit_msg>Added TArray.setValue, see https://github.com/phetsims/phet-io/issues/936<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 * PhET-iO wrapper type for JS's built-in Array type.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var TObject = require( 'PHET_IO/types/TObject' );
  var TVoid = require( 'PHET_IO/types/TVoid' );

  /**
   * Parametric wrapper type constructor.  Given an element type, this function returns an appropriate array wrapper type.
   * @param {TObject} elementType - wrapper type of the individual elements in the array
   * @constructor
   */
  function TArray( elementType ) {

    /**
     * This type constructor is parameterized based on the elementType.
     * @param {Object[]} arrayInstance - the array to be wrapped
     * @param {string} phetioID - the full unique tandem name for the instance
     * @constructor
     */
    var TArrayImpl = function TArrayImpl( arrayInstance, phetioID ) {
      TObject.call( this, arrayInstance, phetioID );
      assert && assert( Array.isArray( arrayInstance ), 'TArray should wrap array instances' );
    };
    return phetioInherit( TObject, 'TArray', TArrayImpl, {}, {
      documentation: 'A wrapper for the built-in JS array type, with the element type specified.',
      elementType: elementType,

      /**
       * Deserialize from a serialized state.
       * @param {Object} stateObject - from toStateObject
       * @returns {Object[]}
       */
      fromStateObject: function( stateObject ) {
        var array = [];
        for ( var i = 0; i < stateObject.length; i++ ) {
          array.push( elementType.fromStateObject( stateObject[ i ] ) );
        }
        return array;
      },

      /**
       * Serialize an array by serializing each element
       * @param {Object[]} array
       * @returns {Array}
       */
      toStateObject: function( array ) {
        var json = [];
        for ( var i = 0; i < array.length; i++ ) {
          json.push( elementType.toStateObject( array[ i ] ) );
        }
        return json;
      },

      setValue: function( instance, elements ) {
        instance.length = 0;
        instance.push.apply( instance, elements );
      }
    } );
  }

  phetioNamespace.register( 'TArray', TArray );

  return TArray;
} );<|endoftext|>


<commit_before>var FW = 20, // width between fitch bars
	LH = 30, // height between proof lines
	NW = 30, // width of numbering column
	OS = LH/6, // offset for text (above baseline and right of fitch bar)
	RC = 30; // space between formula and rule

function draw() {
	var SVGW = "100%",
		SVGH = LH;

	if(PROOF.length > 0) {
		var max = d3.max(PROOF, function(d) {return d.rul=="Premise" ? d.cnt : 0;}); // line number of last premise
		SVGH = PROOF.length*LH;
	}
	var proof = d3.select("#drv")
		.attr("width", SVGW)
		.attr("height", SVGH);

	var line = proof.selectAll("g")
		.data(PROOF);

	var l = line.enter()
		.append("g")
		.attr("transform",function(d,i) {return "translate(0," + i*LH + ")";});

	l.each(function(d,i) { // draw fitch lines
		var el = d3.select(this);
		var pflag = (d.rul=="Premise") && (d.cnt == max);
		if(d.rul=="Assumption" || pflag || d.rul=='Flag') { // adds fitch lines for assumption lines
			for(var i=0;i<(d.dth-1);i++) {
				el.append("path")
					.attr("d",function(d) {
						return "M"+((i*FW)+NW)+" 0, V "+LH;
					});
			}
			var x = ((d.dth-1)*FW)+NW;
			el.append("path") // adds last fitch line
				.attr("d",function(d) {
					return "M"+x+" "+(pflag ? 0 : (1.6*OS))+", V "+LH;
				});
			el.append("path") // adds horizontal assumption line
				.attr("d",function(d) {
					return "M"+x+" "+LH+", H "+(x+10);
				});
		} else { // adds fitch lines for non-assumption lines
			for(var i=0;i<=(d.dth-1);i++) {
				el.append("path")
					.attr("d", function(d) {
						return "M"+((i*FW)+NW)+" 0, V "+LH;
					});
			}
		}
	});

	l.append("text") // append line number
		.attr("x","0")
		.attr("y",""+(LH-OS))
		.text(function(d) {return d.cnt;});

	l.append("text") // append formula
		.attr("x", function(d) {return NW+(FW*(d.dth>1 ? d.dth-1 : 0))+(d.dth>0 ? OS : 0);})
		.attr("y", ""+(LH-OS))
		.attr("class","dfrm")
		.attr("id",function(d) {return "frm"+d.cnt;})
		.text(function(d) {return padBCs(richardify(d.frm));});

	l.append("text") // append rule
		.attr("class","drul")
		.text(function(d) {return d.lin.join(',')+" "+gRul(d.rul);});

	line.exit().remove();

	if(PROOF.length) {
		var w = d3.max(d3.selectAll(".dfrm")[0], function(d) {
			var e = d3.select(d);
			var box = e.node().getBBox();
			return box["width"]+box["x"];})
		d3.selectAll('.drul')
			.attr("x",w+RC)
			.attr("y",(LH-OS));
	};

}

function draw_goals() {
	var SVG2W = "100%",
		SVG2H = 0;
	if(GOALS.length) {
		SVG2H = GOALS.length*LH;
	}

	var goals = d3.select("#gls")
 		.attr("width", SVG2W)
 		.attr("height", SVG2H);

	var goal = goals.selectAll("g")
		.data(GOALS);

	goal.select(".glfrm").text(function(d) {return padBCs(richardify(d));});

	var g = goal.enter().append("g");

	g.attr("transform",function(d,i) {return "translate(0,"+(i*LH)+")";});

	g.append("text")
		.attr("x",0)
		.attr("y",""+(LH-OS))
		.attr("class","gllbl")
		.text("Goal:");

	g.append("text")
		.attr("class","glfrm")
		.text(function(d) {return richardify(d);});

	goal.exit().remove();

	if(CONCLUSION.length) {
		var box = d3.select("#conlbl").node().getBBox();
		var w = box["width"];
		d3.selectAll('.glfrm')
			.attr("x",w+10)
			.attr("y",(LH-OS));
	}
}

function draw_conclusion() {
	var el = d3.select("#con")
		.attr("width", "100%")
		.attr("height",LH);

	var con = el.selectAll("g")
		.data(CONCLUSION);

	con.enter()
		.append("g")
		.attr("transform","translate(0,0)")
		.attr("id","g");

	con.append("text")
		.attr("x",0)
		.attr("y",""+(LH-OS))
		.attr("id","conlbl")
		.text("Conclusion:");

	con.append("text")
		.attr("id","confrm")
		.text(function(d) {return padBCs(richardify(d));});

	con.exit().remove();

	if(CONCLUSION.length) {
		var box = d3.select("#conlbl").node().getBBox();
		var w = box["width"];
		console.log(w);
		d3.select("#confrm")
			.attr("x",10+w)
			.attr("y",(LH-OS));
	};

}<commit_msg>fix paths<commit_after>var FW = 20, // width between fitch bars
	LH = 30, // height between proof lines
	NW = 30, // width of numbering column
	OS = LH/6, // offset for text (above baseline and right of fitch bar)
	RC = 30; // space between formula and rule

function draw() {
	var SVGW = "100%",
		SVGH = LH;

	if(PROOF.length > 0) {
		var max = d3.max(PROOF, function(d) {return d.rul=="Premise" ? d.cnt : 0;}); // line number of last premise
		SVGH = PROOF.length*LH;
	}
	var proof = d3.select("#drv")
		.attr("width", SVGW)
		.attr("height", SVGH);

	var line = proof.selectAll("g")
		.data(PROOF);

	var l = line.enter()
		.append("g")
		.attr("transform",function(d,i) {return "translate(0," + i*LH + ")";});

	l.each(function(d,i) { // draw fitch lines
		var el = d3.select(this);
		var pflag = (d.rul=="Premise") && (d.cnt == max);
		if(d.rul=="Assumption" || pflag || d.rul=='Flag') { // adds fitch lines for assumption lines
			for(var i=0;i<(d.dth-1);i++) {
				el.append("path")
					.attr("d",function(d) {
						return "M"+((i*FW)+NW)+" 0 V "+LH;
					});
			}
			var x = ((d.dth-1)*FW)+NW;
			el.append("path") // adds last fitch line
				.attr("d",function(d) {
					return "M"+x+" "+(pflag ? 0 : (1.6*OS))+" V "+LH;
				});
			el.append("path") // adds horizontal assumption line
				.attr("d",function(d) {
					return "M"+x+" "+LH+" H "+(x+10);
				});
		} else { // adds fitch lines for non-assumption lines
			for(var i=0;i<=(d.dth-1);i++) {
				el.append("path")
					.attr("d", function(d) {
						return "M"+((i*FW)+NW)+" 0 V "+LH;
					});
			}
		}
	});

	l.append("text") // append line number
		.attr("x","0")
		.attr("y",""+(LH-OS))
		.text(function(d) {return d.cnt;});

	l.append("text") // append formula
		.attr("x", function(d) {return NW+(FW*(d.dth>1 ? d.dth-1 : 0))+(d.dth>0 ? OS : 0);})
		.attr("y", ""+(LH-OS))
		.attr("class","dfrm")
		.attr("id",function(d) {return "frm"+d.cnt;})
		.text(function(d) {return padBCs(richardify(d.frm));});

	l.append("text") // append rule
		.attr("class","drul")
		.text(function(d) {return d.lin.join(',')+" "+gRul(d.rul);});

	line.exit().remove();

	if(PROOF.length) {
		var w = d3.max(d3.selectAll(".dfrm")[0], function(d) {
			var e = d3.select(d);
			var box = e.node().getBBox();
			return box["width"]+box["x"];})
		d3.selectAll('.drul')
			.attr("x",w+RC)
			.attr("y",(LH-OS));
	};

}

function draw_goals() {
	var SVG2W = "100%",
		SVG2H = 0;
	if(GOALS.length) {
		SVG2H = GOALS.length*LH;
	}

	var goals = d3.select("#gls")
 		.attr("width", SVG2W)
 		.attr("height", SVG2H);

	var goal = goals.selectAll("g")
		.data(GOALS);

	goal.select(".glfrm").text(function(d) {return padBCs(richardify(d));});

	var g = goal.enter().append("g");

	g.attr("transform",function(d,i) {return "translate(0,"+(i*LH)+")";});

	g.append("text")
		.attr("x",0)
		.attr("y",""+(LH-OS))
		.attr("class","gllbl")
		.text("Goal:");

	g.append("text")
		.attr("class","glfrm")
		.text(function(d) {return richardify(d);});

	goal.exit().remove();

	if(CONCLUSION.length) {
		var box = d3.select("#conlbl").node().getBBox();
		var w = box["width"];
		d3.selectAll('.glfrm')
			.attr("x",w+10)
			.attr("y",(LH-OS));
	}
}

function draw_conclusion() {
	var el = d3.select("#con")
		.attr("width", "100%")
		.attr("height",LH);

	var con = el.selectAll("g")
		.data(CONCLUSION);

	con.enter()
		.append("g")
		.attr("transform","translate(0,0)")
		.attr("id","g");

	con.append("text")
		.attr("x",0)
		.attr("y",""+(LH-OS))
		.attr("id","conlbl")
		.text("Conclusion:");

	con.append("text")
		.attr("id","confrm")
		.text(function(d) {return padBCs(richardify(d));});

	con.exit().remove();

	if(CONCLUSION.length) {
		var box = d3.select("#conlbl").node().getBBox();
		var w = box["width"];
		console.log(w);
		d3.select("#confrm")
			.attr("x",10+w)
			.attr("y",(LH-OS));
	};

}<|endoftext|>


<commit_before>module.exports = {

  Container : require('./container'),
  Row : require('./row'),
  Col : require('./col'),
  AutoCols : require('./auto-cols'),

  IconButton : require('./icon-button'),

  AppHeader : require('./layout/app-header'),
  TopNav : require('./layout/top-nav'),
  SideNav : require('./layout/side-nav'),

  Modal : require('./modal'),

  Table : require('./table'),

  Collapsible : require('./collapsible/collapsible'),

  // Forms
  InputWrapper : require('./forms/input-wrapper'),

  // Utilities
  LayeredComponentMixin : require('./mixins/layered-component'),
  TransitionIn : require('./transition-in'),

};
<commit_msg>Add card to component index<commit_after>module.exports = {

  Container : require('./container'),
  Row : require('./row'),
  Col : require('./col'),
  AutoCols : require('./auto-cols'),

  IconButton : require('./icon-button'),

  AppHeader : require('./layout/app-header'),
  TopNav : require('./layout/top-nav'),
  SideNav : require('./layout/side-nav'),

  Modal : require('./modal'),

  Table : require('./table'),

  Collapsible : require('./collapsible/collapsible'),

  Card : require('./card'),

  // Forms
  InputWrapper : require('./forms/input-wrapper'),

  // Utilities
  LayeredComponentMixin : require('./mixins/layered-component'),
  TransitionIn : require('./transition-in'),

};
<|endoftext|>


<commit_before>import $ from "../vendor/jquery-3.3.1.slim.js";
import {createCheckbox} from "../igv-icons.js"

/**
 * Configure item list for track "gear" menu.
 * @param trackView
 */
const MenuUtils = {

    trackMenuItemList: function (trackView) {

        const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'snp']);

        const hasVizWindow = trackView.track.config && trackView.track.config.visibilityWindow !== undefined;

        let menuItems = [];

        if (trackView.track.config.type !== 'sequence') {
            menuItems.push(trackRenameMenuItem(trackView));
            menuItems.push(trackHeightMenuItem(trackView));
        }

        if (this.showColorPicker(trackView.track)) {
            menuItems.push('
');
            menuItems.push(colorPickerMenuItem({trackView, label: "Set track color", option: "color"}));
            menuItems.push(unsetColorMenuItem({trackView, label: "Unset track color"}));
            menuItems.push(colorPickerMenuItem({trackView, label: "Set alt color", option: "altColor"}));
        }

        if (trackView.track.menuItemList) {
            menuItems = menuItems.concat(trackView.track.menuItemList());
        }

        if (hasVizWindow || vizWindowTypes.has(trackView.track.type)) {
            menuItems.push('
');
            menuItems.push(visibilityWindowMenuItem(trackView));
        }

        if (trackView.track.removable !== false) {
            menuItems.push('
');
            menuItems.push(trackRemovalMenuItem(trackView));
        }

        return menuItems;
    },

    numericDataMenuItems: function (trackView) {

        const menuItems = [];

        menuItems.push('
')

        // Data range
        const object = $('
');
        object.text('Set data range');

        const click = () => {
            trackView.browser.dataRangeDialog.configure(trackView);
            trackView.browser.dataRangeDialog.present($(trackView.browser.columnContainer));
        };
        menuItems.push({object, click});

        if (trackView.track.logScale !== undefined) {
            menuItems.push({
                    object: $(createCheckbox("Log scale", trackView.track.logScale)),
                    click: () => {
                        trackView.track.logScale = !trackView.track.logScale;
                        trackView.repaintViews();
                    }
                }
            )
        }

        menuItems.push({
                object: $(createCheckbox("Autoscale", trackView.track.autoscale)),
                click: () => {
                    trackView.track.autoscale = !trackView.track.autoscale;
                    trackView.updateViews();
                }
            }
        )

        return menuItems;
    },

    trackMenuItemListHelper: function (itemList, menuPopup) {

        var list = [];

        if (itemList.length > 0) {

            list = itemList.map(function (item, i) {
                var $e;

                // name and object fields checked for backward compatibility
                if (item.name) {
                    $e = $('
');
                    $e.text(item.name);
                } else if (item.object) {
                    $e = item.object
                } else if (typeof item.label === 'string') {
                    $e = $('
');
                    $e.html(item.label)
                } else if (typeof item === 'string') {

                    if (item.startsWith("<")) {
                        $e = $(item);
                    } else {
                        $e = $("
" + item + "
");
                    }
                }

                if (0 === i) {
                    $e.addClass('igv-track-menu-border-top');
                }

                if (item.click) {
                    $e.on('click', handleClick);
                    $e.on('touchend', function (e) {
                        handleClick(e);
                    });
                    $e.on('mouseup', function (e) {
                        e.preventDefault();
                        e.stopPropagation();
                    })

                    // eslint-disable-next-line no-inner-declarations
                    function handleClick(e) {
                        item.click(e);
                        menuPopup.hide();
                        e.preventDefault();
                        e.stopPropagation()
                    }
                }

                return {object: $e, init: (item.init || undefined)};
            });
        }

        return list;
    },

    showColorPicker(track) {
        return (
            undefined === track.type ||
            "bedtype" === track.type ||
            "alignment" === track.type ||
            "annotation" === track.type ||
            "variant" === track.type ||
            "wig" === track.type);
    },

    createMenuItem(label, action) {
        const object = $('
');
        object.text(label);
        return {object, click: action};
    }
}

function visibilityWindowMenuItem(trackView) {

    const click = e => {

        const callback = () => {

            let value = trackView.browser.inputDialog.input.value
            value = '' === value || undefined === value ? -1 : value.trim()

            trackView.track.visibilityWindow = Number.parseInt(value);
            trackView.track.config.visibilityWindow = Number.parseInt(value);

            trackView.updateViews();
        }

        const config =
            {
                label: 'Visibility Window',
                value: (trackView.track.visibilityWindow),
                callback
            }
        trackView.browser.inputDialog.present(config, e);

    };

    const object = $('
');
    object.text('Set visibility window');
    return {object, click};

}

function trackRemovalMenuItem(trackView) {

    const object = $('
');
    object.text('Remove track');

    return {object, click: () => trackView.browser.removeTrack(trackView.track)};

}

function colorPickerMenuItem({trackView, label, option}) {

    const $e = $('
');
    $e.text(label);

    return {
        object: $e,
        click: () => trackView.presentColorPicker(option)
    }
}

function unsetColorMenuItem({trackView, label}) {

    const $e = $('
');
    $e.text(label);

    return {
        object: $e,
        click: () => {
            trackView.track.color = undefined;
            trackView.repaintViews();
        }
    }
}

function trackRenameMenuItem(trackView) {

    const click = e => {

        const callback = function () {
            let value = trackView.browser.inputDialog.input.value;
            value = ('' === value || undefined === value) ? 'untitled' : value.trim();
            trackView.track.name = value;
        };

        const config =
            {
                label: 'Track Name',
                value: (getTrackLabelText(trackView.track) || 'unnamed'),
                callback
            }

        trackView.browser.inputDialog.present(config, e);

    };

    const object = $('
');
    object.text('Set track name');
    return {object, click};

}

function trackHeightMenuItem(trackView) {

    const click = e => {

        const callback = () => {

            const number = parseFloat(trackView.browser.inputDialog.input.value, 10);

            if (undefined !== number) {

                // If explicitly setting the height adust min or max, if neccessary.
                if (trackView.track.minHeight !== undefined && trackView.track.minHeight > number) {
                    trackView.track.minHeight = number;
                }
                if (trackView.track.maxHeight !== undefined && trackView.track.maxHeight < number) {
                    trackView.track.minHeight = number;
                }
                trackView.setTrackHeight(number, true);

                trackView.checkContentHeight();
                trackView.repaintViews();

                // Explicitly setting track height turns off autoHeight
                trackView.track.autoHeight = false;
            }

        };

        const config =
            {
                label: 'Track Height',
                value: trackView.track.height,
                callback
            }

        trackView.browser.inputDialog.present(config, e);

    };

    const object = $('
');
    object.text('Set track height');
    return {object, click};

}

function getTrackLabelText(track) {
    var vp,
        txt;

    vp = track.trackView.viewports[0];
    txt = vp.$trackLabel.text();

    return txt;
}

export default MenuUtils;
<commit_msg>ColorPicker. Add support for interact track type (#1408)<commit_after>import $ from "../vendor/jquery-3.3.1.slim.js";
import {createCheckbox} from "../igv-icons.js"

/**
 * Configure item list for track "gear" menu.
 * @param trackView
 */
const MenuUtils = {

    trackMenuItemList: function (trackView) {

        const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'snp']);

        const hasVizWindow = trackView.track.config && trackView.track.config.visibilityWindow !== undefined;

        let menuItems = [];

        if (trackView.track.config.type !== 'sequence') {
            menuItems.push(trackRenameMenuItem(trackView));
            menuItems.push(trackHeightMenuItem(trackView));
        }

        if (this.showColorPicker(trackView.track)) {
            menuItems.push('
');
            menuItems.push(colorPickerMenuItem({trackView, label: "Set track color", option: "color"}));
            menuItems.push(unsetColorMenuItem({trackView, label: "Unset track color"}));
            menuItems.push(colorPickerMenuItem({trackView, label: "Set alt color", option: "altColor"}));
        }

        if (trackView.track.menuItemList) {
            menuItems = menuItems.concat(trackView.track.menuItemList());
        }

        if (hasVizWindow || vizWindowTypes.has(trackView.track.type)) {
            menuItems.push('
');
            menuItems.push(visibilityWindowMenuItem(trackView));
        }

        if (trackView.track.removable !== false) {
            menuItems.push('
');
            menuItems.push(trackRemovalMenuItem(trackView));
        }

        return menuItems;
    },

    numericDataMenuItems: function (trackView) {

        const menuItems = [];

        menuItems.push('
')

        // Data range
        const object = $('
');
        object.text('Set data range');

        const click = () => {
            trackView.browser.dataRangeDialog.configure(trackView);
            trackView.browser.dataRangeDialog.present($(trackView.browser.columnContainer));
        };
        menuItems.push({object, click});

        if (trackView.track.logScale !== undefined) {
            menuItems.push({
                    object: $(createCheckbox("Log scale", trackView.track.logScale)),
                    click: () => {
                        trackView.track.logScale = !trackView.track.logScale;
                        trackView.repaintViews();
                    }
                }
            )
        }

        menuItems.push({
                object: $(createCheckbox("Autoscale", trackView.track.autoscale)),
                click: () => {
                    trackView.track.autoscale = !trackView.track.autoscale;
                    trackView.updateViews();
                }
            }
        )

        return menuItems;
    },

    trackMenuItemListHelper: function (itemList, menuPopup) {

        var list = [];

        if (itemList.length > 0) {

            list = itemList.map(function (item, i) {
                var $e;

                // name and object fields checked for backward compatibility
                if (item.name) {
                    $e = $('
');
                    $e.text(item.name);
                } else if (item.object) {
                    $e = item.object
                } else if (typeof item.label === 'string') {
                    $e = $('
');
                    $e.html(item.label)
                } else if (typeof item === 'string') {

                    if (item.startsWith("<")) {
                        $e = $(item);
                    } else {
                        $e = $("
" + item + "
");
                    }
                }

                if (0 === i) {
                    $e.addClass('igv-track-menu-border-top');
                }

                if (item.click) {
                    $e.on('click', handleClick);
                    $e.on('touchend', function (e) {
                        handleClick(e);
                    });
                    $e.on('mouseup', function (e) {
                        e.preventDefault();
                        e.stopPropagation();
                    })

                    // eslint-disable-next-line no-inner-declarations
                    function handleClick(e) {
                        item.click(e);
                        menuPopup.hide();
                        e.preventDefault();
                        e.stopPropagation()
                    }
                }

                return {object: $e, init: (item.init || undefined)};
            });
        }

        return list;
    },

    showColorPicker(track) {
        return (
            undefined === track.type ||
            "bedtype" === track.type ||
            "alignment" === track.type ||
            "annotation" === track.type ||
            "variant" === track.type ||
            "wig" === track.type) ||
            'interact' === track.type
    },

    createMenuItem(label, action) {
        const object = $('
');
        object.text(label);
        return {object, click: action};
    }
}

function visibilityWindowMenuItem(trackView) {

    const click = e => {

        const callback = () => {

            let value = trackView.browser.inputDialog.input.value
            value = '' === value || undefined === value ? -1 : value.trim()

            trackView.track.visibilityWindow = Number.parseInt(value);
            trackView.track.config.visibilityWindow = Number.parseInt(value);

            trackView.updateViews();
        }

        const config =
            {
                label: 'Visibility Window',
                value: (trackView.track.visibilityWindow),
                callback
            }
        trackView.browser.inputDialog.present(config, e);

    };

    const object = $('
');
    object.text('Set visibility window');
    return {object, click};

}

function trackRemovalMenuItem(trackView) {

    const object = $('
');
    object.text('Remove track');

    return {object, click: () => trackView.browser.removeTrack(trackView.track)};

}

function colorPickerMenuItem({trackView, label, option}) {

    const $e = $('
');
    $e.text(label);

    return {
        object: $e,
        click: () => trackView.presentColorPicker(option)
    }
}

function unsetColorMenuItem({trackView, label}) {

    const $e = $('
');
    $e.text(label);

    return {
        object: $e,
        click: () => {
            trackView.track.color = undefined;
            trackView.repaintViews();
        }
    }
}

function trackRenameMenuItem(trackView) {

    const click = e => {

        const callback = function () {
            let value = trackView.browser.inputDialog.input.value;
            value = ('' === value || undefined === value) ? 'untitled' : value.trim();
            trackView.track.name = value;
        };

        const config =
            {
                label: 'Track Name',
                value: (getTrackLabelText(trackView.track) || 'unnamed'),
                callback
            }

        trackView.browser.inputDialog.present(config, e);

    };

    const object = $('
');
    object.text('Set track name');
    return {object, click};

}

function trackHeightMenuItem(trackView) {

    const click = e => {

        const callback = () => {

            const number = parseFloat(trackView.browser.inputDialog.input.value, 10);

            if (undefined !== number) {

                // If explicitly setting the height adust min or max, if neccessary.
                if (trackView.track.minHeight !== undefined && trackView.track.minHeight > number) {
                    trackView.track.minHeight = number;
                }
                if (trackView.track.maxHeight !== undefined && trackView.track.maxHeight < number) {
                    trackView.track.minHeight = number;
                }
                trackView.setTrackHeight(number, true);

                trackView.checkContentHeight();
                trackView.repaintViews();

                // Explicitly setting track height turns off autoHeight
                trackView.track.autoHeight = false;
            }

        };

        const config =
            {
                label: 'Track Height',
                value: trackView.track.height,
                callback
            }

        trackView.browser.inputDialog.present(config, e);

    };

    const object = $('
');
    object.text('Set track height');
    return {object, click};

}

function getTrackLabelText(track) {
    var vp,
        txt;

    vp = track.trackView.viewports[0];
    txt = vp.$trackLabel.text();

    return txt;
}

export default MenuUtils;
<|endoftext|>