<commit_before>/* global Dropzone*/
import Ember from 'ember';

export default Ember.Component.extend({
  classNames: ['dropzone'],

  myDropzone: document.body || undefined,

  dropzoneOptions: null,
  // Configuration Options
  dzOptionsList: [
    'url', 'withCredentials', 'method', 'parallelUploads', 'maxFilesize', 'filesizeBase',
    'paramName', 'uploadMultiple', 'headers', 'addRemoveLinks', 'previewsContainer',
    'clickable', 'maxThumbnailFilesize', 'thumbnailWidth', 'thumbnailHeight', 'maxFiles',
    'createImageThumbnails', 'params', 'acceptedFiles', 'autoProcessQueue', 'forceFallback',
    'previewTemplate', 'dictDefaultMessage', 'dictFallbackMessage', 'dictInvalidFileType',
    'dictFallbackText', 'dictFileTooBig', 'dictResponseError', 'dictCancelUpload',
    'dictCancelUploadConfirmation', 'dictRemoveFile', 'dictMaxFilesExceeded', 'maxDropRegion'
  ],

  dzConfigHash: {},

  // Need to preserve null default values
  thumbnailHeight: null,
  thumbnailWidth: null,

  // Events
  // All of these receive the event as first parameter:
  drop: null,
  dragstart: null,
  dragend: null,
  dragleave: null,

  //noops
  dragenter() {},
  dragover() {},

  // All of these receive the file as first parameter:
  addedfile: null,
  removedfile: null,
  thumbnail: null,
  error: null,
  processing: null,
  uploadprogress: null,
  sending: null,
  success: null,
  complete: null,
  canceled: null,
  maxfilesreached: null,
  maxfilesexceeded: null,

  // All of these receive a list of files as first parameter and are only called if the uploadMultiple option is true:
  processingmultiple: null,
  sendingmultiple: null,
  successmultiple: null,
  completemultiple: null,
  canceledmultiple: null,

  // Special events:
  totaluploadprogress: null,
  reset: null,
  queuecomplete: null,
  files: null,

  // Callback functions
  accept: null,

  setEvents() {
    let myDropzone = this.get('myDropzone');
    let events = {
      drop: this.drop,
      dragstart: this.dragstart,
      dragend: this.dragend,
      dragenter: this.dragenter,
      dragover: this.dragover,
      dragleave: this.dragleave,
      addedfile: this.addedfile,
      removedfile: this.removedfile,
      thumbnail: this.thumbnail,
      error: this.error,
      processing: this.processing,
      uploadprogress: this.uploadprogress,
      sending: this.sending,
      success: this.success,
      complete: this.complete,
      canceled: this.canceled,
      maxfilesreached: this.maxfilesreached,
      maxfilesexceeded: this.maxfilesexceeded,
      processingmultiple: this.processingmultiple,
      sendingmultiple: this.sendingmultiple,
      successmultiple: this.successmultiple,
      completemultiple: this.completemultiple,
      canceledmultiple: this.canceledmultiple,
      totaluploadprogress: this.totaluploadprogress,
      reset: this.reset,
      queuecomplete: this.queuecomplete,
      files: this.files,
      accept: this.accept,
    };

    for (let e in events) {
      if (events[e] !== null) {
        myDropzone.on(e, events[e]);
      }
    }
  },

  config: Ember.computed(function(){
    let config = this.get('dzConfigHash'),
        optList = this.get('dzOptionsList'),
        output = {};

    optList.forEach((e) => {
      // use dynamic hash first
      if (config.hasOwnProperty(e)) {
        output[e] = config[e];
      }

      // if property is set specifically, override
      if (this.get(e) != null) {
        output[e] = this.get(e);
      }

      // need to set null versions of thumbnail width / height
      if (e === 'thumbnailHeight' || e === 'thumbnailWidth') {
        output[e] = this.get(e)
      }
    });

    Ember.assert('Url is required for dropzone', output.url);
    // Preserve defaults for existing apps/tests
    if (!output.url) {
      output.url = '#';
    }
    return output;
  }),

  getDropzoneOptions() {
    const onDragEnterLeaveHandler = function(dropzoneInstance) {
      const onDrag = ( element => {
        let dragCounter = 0;

        return {
          enter(event) {
            event.preventDefault();
            dragCounter++;
            element.classList.add('dz-drag-hover');
          },
          leave() {
            dragCounter--;

            if (dragCounter === 0) {
              element.classList.remove('dz-drag-hover');
            }
          }
        };
      }).call(this, dropzoneInstance.element);

      dropzoneInstance.on('dragenter', onDrag.enter);
      dropzoneInstance.on('dragleave', onDrag.leave);
    };

    let config = this.get('config');
    config.init = function () { onDragEnterLeaveHandler(this); }

    this.set('dropzoneOptions', config);
  },

  createDropzone(element) {
    let region = this.get('maxDropRegion') ? document.body : element;
    this.set('myDropzone', new Dropzone(region, this.dropzoneOptions));
  },

  destroyDropzone: Ember.on('willDestroyElement', function() {
    this.get('myDropzone').destroy();
  }),

  insertDropzone: Ember.on('didInsertElement', function() {
    let _this = this;
    this.getDropzoneOptions();
    Dropzone.autoDiscover = false;
    this.createDropzone(this.element);
    //make sure events are set before any files are added
    this.setEvents();

    //this condition requires a fully resolved array to work
    //will not work with model.get('files') as it returns promise not array hence length condition is failed
    if (this.files && this.files.length > 0) {
      this.files.map(function(file) {
        let dropfile = {
          name: file.get('name'),
          type: file.get('type'),
          size: file.get('size'),
          status: Dropzone.ADDED,
          //add support for id  in files object so that it can be access in addedFile,removedFile callbacks for files identified by id
          id: file.get('id')
        };
        let thumbnail = file.get('thumbnail');

        if (typeof (thumbnail) === 'string') {
          dropfile.thumbnail = thumbnail;
        }

        _this.myDropzone.emit('addedfile', dropfile);

        if (typeof (thumbnail) === 'string') {

          _this.myDropzone.emit('thumbnail', dropfile, thumbnail);
        }

        _this.myDropzone.emit('complete', dropfile);
        _this.myDropzone.files.push(file);
      });
    }

    return this.myDropzone;
  }),
});
<commit_msg>better documentation<commit_after>/* global Dropzone*/
import Ember from 'ember';

export default Ember.Component.extend({
  classNames: ['dropzone'],

  /**
   * Dropzone dom element
   * @private
   * @type {[type]}
   */
  myDropzone: document.body || undefined,

  /**
   * internal configurtion for Dropzone method
   * @private
   * @type {[type]}
   */
  dropzoneOptions: null,

  /**
   * list of available properties
   * @type {Array}
   */
  dzOptionsList: [
    'url', 'withCredentials', 'method', 'parallelUploads', 'maxFilesize', 'filesizeBase',
    'paramName', 'uploadMultiple', 'headers', 'addRemoveLinks', 'previewsContainer',
    'clickable', 'maxThumbnailFilesize', 'thumbnailWidth', 'thumbnailHeight', 'maxFiles',
    'createImageThumbnails', 'params', 'acceptedFiles', 'autoProcessQueue', 'forceFallback',
    'previewTemplate', 'dictDefaultMessage', 'dictFallbackMessage', 'dictInvalidFileType',
    'dictFallbackText', 'dictFileTooBig', 'dictResponseError', 'dictCancelUpload',
    'dictCancelUploadConfirmation', 'dictRemoveFile', 'dictMaxFilesExceeded', 'maxDropRegion'
  ],

  /**
   * Configuration Hash to set dynamic properties
   * @public
   * @type {Object}
   */
  config: {},

  // Need to preserve null default values
  thumbnailHeight: null,
  thumbnailWidth: null,

  // Events
  // All of these receive the event as first parameter:
  drop: null,
  dragstart: null,
  dragend: null,
  dragleave: null,

  //noops
  dragenter() {},
  dragover() {},

  // All of these receive the file as first parameter:
  addedfile: null,
  removedfile: null,
  thumbnail: null,
  error: null,
  processing: null,
  uploadprogress: null,
  sending: null,
  success: null,
  complete: null,
  canceled: null,
  maxfilesreached: null,
  maxfilesexceeded: null,

  // All of these receive a list of files as first parameter and are only called if the uploadMultiple option is true:
  processingmultiple: null,
  sendingmultiple: null,
  successmultiple: null,
  completemultiple: null,
  canceledmultiple: null,

  // Special events:
  totaluploadprogress: null,
  reset: null,
  queuecomplete: null,
  files: null,

  // Callback functions
  accept: null,

  /**
   * @private
   * event management
   */
  setEvents() {
    let myDropzone = this.get('myDropzone');
    let events = {
      drop: this.drop,
      dragstart: this.dragstart,
      dragend: this.dragend,
      dragenter: this.dragenter,
      dragover: this.dragover,
      dragleave: this.dragleave,
      addedfile: this.addedfile,
      removedfile: this.removedfile,
      thumbnail: this.thumbnail,
      error: this.error,
      processing: this.processing,
      uploadprogress: this.uploadprogress,
      sending: this.sending,
      success: this.success,
      complete: this.complete,
      canceled: this.canceled,
      maxfilesreached: this.maxfilesreached,
      maxfilesexceeded: this.maxfilesexceeded,
      processingmultiple: this.processingmultiple,
      sendingmultiple: this.sendingmultiple,
      successmultiple: this.successmultiple,
      completemultiple: this.completemultiple,
      canceledmultiple: this.canceledmultiple,
      totaluploadprogress: this.totaluploadprogress,
      reset: this.reset,
      queuecomplete: this.queuecomplete,
      files: this.files,
      accept: this.accept,
    };

    for (let e in events) {
      if (events[e] !== null) {
        myDropzone.on(e, events[e]);
      }
    }
  },
  /**
   * internal config cp
   * @private
   * @return {[type]} [description]
   */
  _dzConfig: Ember.computed(function(){
    let config = this.get('confi'),
        optList = this.get('dzOptionsList'),
        output = {};

    optList.forEach((e) => {
      // use dynamic hash first
      if (config.hasOwnProperty(e)) {
        output[e] = config[e];
      }

      // if property is set specifically, override
      if (this.get(e) != null) {
        output[e] = this.get(e);
      }

      // need to set null versions of thumbnail width / height
      if (e === 'thumbnailHeight' || e === 'thumbnailWidth') {
        output[e] = this.get(e)
      }
    });

    Ember.assert('Url is required for dropzone', output.url);
    // Preserve defaults for existing apps/tests
    if (!output.url) {
      output.url = '#';
    }
    return output;
  }),

  getDropzoneOptions() {
    const onDragEnterLeaveHandler = function(dropzoneInstance) {
      const onDrag = ( element => {
        let dragCounter = 0;

        return {
          enter(event) {
            event.preventDefault();
            dragCounter++;
            element.classList.add('dz-drag-hover');
          },
          leave() {
            dragCounter--;

            if (dragCounter === 0) {
              element.classList.remove('dz-drag-hover');
            }
          }
        };
      }).call(this, dropzoneInstance.element);

      dropzoneInstance.on('dragenter', onDrag.enter);
      dropzoneInstance.on('dragleave', onDrag.leave);
    };

    let config = this.get('_dzConfig');
    config.init = function () { onDragEnterLeaveHandler(this); }

    this.set('dropzoneOptions', config);
  },

  createDropzone(element) {
    let region = this.get('maxDropRegion') ? document.body : element;
    this.set('myDropzone', new Dropzone(region, this.dropzoneOptions));
  },

  destroyDropzone: Ember.on('willDestroyElement', function() {
    this.get('myDropzone').destroy();
  }),

  insertDropzone: Ember.on('didInsertElement', function() {
    let _this = this;
    this.getDropzoneOptions();
    Dropzone.autoDiscover = false;
    this.createDropzone(this.element);
    //make sure events are set before any files are added
    this.setEvents();

    //this condition requires a fully resolved array to work
    //will not work with model.get('files') as it returns promise not array hence length condition is failed
    if (this.files && this.files.length > 0) {
      this.files.map(function(file) {
        let dropfile = {
          name: file.get('name'),
          type: file.get('type'),
          size: file.get('size'),
          status: Dropzone.ADDED,
          //add support for id  in files object so that it can be access in addedFile,removedFile callbacks for files identified by id
          id: file.get('id')
        };
        let thumbnail = file.get('thumbnail');

        if (typeof (thumbnail) === 'string') {
          dropfile.thumbnail = thumbnail;
        }

        _this.myDropzone.emit('addedfile', dropfile);

        if (typeof (thumbnail) === 'string') {

          _this.myDropzone.emit('thumbnail', dropfile, thumbnail);
        }

        _this.myDropzone.emit('complete', dropfile);
        _this.myDropzone.files.push(file);
      });
    }

    return this.myDropzone;
  }),
});
<|endoftext|>


<commit_before>xinha_editors = null;
xinha_init    = null;
xinha_config  = null;
xinha_plugins = null;

// This contains the names of textareas we will make into Xinha editors
xinha_init = xinha_init ? xinha_init : function()
{
   /** STEP 1 ***************************************************************
   * First, specify the textareas that shall be turned into Xinhas.
   * For each one add the respective id to the xinha_editors array.
   * I you want add more than on textarea, keep in mind that these
   * values are comma seperated BUT there is no comma after the last value.
   * If you are going to use this configuration on several pages with different
   * textarea ids, you can add them all. The ones that are not found on the
   * current page will just be skipped.
   ************************************************************************/

  xinha_editors = xinha_editors ? xinha_editors :
  [
    'myTextArea', 'anotherOne'
  ];

  /** STEP 2 ***************************************************************
   * Now, what are the plugins you will be using in the editors on this
   * page.  List all the plugins you will need, even if not all the editors
   * will use all the plugins.
   *
   * The list of plugins below is a good starting point, but if you prefer
   * a simpler editor to start with then you can use the following
   *
   * xinha_plugins = xinha_plugins ? xinha_plugins : [ ];
   *
   * which will load no extra plugins at all.
   ************************************************************************/

  xinha_plugins = xinha_plugins ? xinha_plugins :
  [
   'CharacterMap',
   'ContextMenu',
   'SmartReplace',
   'Stylist',
   'PersistentStorage',
   'PSLocal',
   'Linker',
   'SuperClean',
   'TableOperations','GetHtml'
  ];

         // THIS BIT OF JAVASCRIPT LOADS THE PLUGINS, NO TOUCHING  :)
         if(!Xinha.loadPlugins(xinha_plugins, xinha_init)) return;

  /** STEP 3 ***************************************************************
   * We create a default configuration to be used by all the editors.
   * If you wish to configure some of the editors differently this will be
   * done in step 5.
   *
   * If you want to modify the default config you might do something like this.
   *
   *   xinha_config = new Xinha.Config();
   *   xinha_config.width  = '640px';
   *   xinha_config.height = '420px';
   *
   *
   * For a list of the available configuration options, see:
   * http://trac.xinha.org/wiki/Documentation/ConfigVariablesList
   *
   *************************************************************************/

   xinha_config = xinha_config ? xinha_config() : new Xinha.Config();

  //this is the standard toolbar, feel free to remove buttons as you like
  xinha_config.toolbar =
  [
    ["popupeditor"],
    ["separator","formatblock","fontname","fontsize","bold","italic","underline","strikethrough"],
    ["separator","forecolor","hilitecolor","textindicator"],
    ["separator","subscript","superscript"],
    ["linebreak","separator","justifyleft","justifycenter","justifyright","justifyfull"],
    ["separator","insertorderedlist","insertunorderedlist","outdent","indent"],
    ["separator","inserthorizontalrule","createlink","insertimage","inserttable"],
    ["linebreak","separator","undo","redo","selectall","print"], (Xinha.is_gecko ? [] : ["cut","copy","paste","overwrite","saveas"]),
    ["separator","killword","clearfonts","removeformat","toggleborders","splitblock","lefttoright", "righttoleft"],
    ["separator","htmlmode","showhelp","about"]
  ];

   // To adjust the styling inside the editor, we can load an external stylesheet like this
   // NOTE : YOU MUST GIVE AN ABSOLUTE URL
   xinha_config.pageStyleSheets = [ _editor_url + "examples/files/full_example.css" ];
   //if you're using Stylist, import a stylesheet like this
   xinha_config.stylistLoadStylesheet(_editor_url + "examples/files/stylist.css");

  /** STEP 4 ***************************************************************
   * We first create editors for the textareas.
   *
   * You can do this in two ways, either
   *
   *   xinha_editors   = Xinha.makeEditors(xinha_editors, xinha_config, xinha_plugins);
   *
   * if you want all the editor objects to use the same set of plugins, OR;
   *
   *   xinha_editors = Xinha.makeEditors(xinha_editors, xinha_config);
   *   xinha_editors.myTextArea.registerPlugins(['Stylist']);
   *   xinha_editors.anotherOne.registerPlugins(['CSS','SuperClean']);
   *
   * if you want to use a different set of plugins for one or more of the
   * editors.
   ************************************************************************/

  xinha_editors   = Xinha.makeEditors(xinha_editors, xinha_config, xinha_plugins);

  /** STEP 5 ***************************************************************
   * If you want to change the configuration variables of any of the
   * editors,  this is the place to do that, for example you might want to
   * change the width and height of one of the editors, like this...
   *
   *   xinha_editors.myTextArea.config.width  = '640px';
   *   xinha_editors.myTextArea.config.height = '480px';
   *
   ************************************************************************/

  /** STEP 6 ***************************************************************
   * Finally we "start" the editors, this turns the textareas into
   * Xinha editors.
   ************************************************************************/

  Xinha.startEditors(xinha_editors);
}

Xinha.addOnloadHandler(xinha_init); // this executes the xinha_init function on page load
                                     // and does not interfere with window.onload properties set by other scripts

<commit_msg>mistake<commit_after>xinha_editors = null;
xinha_init    = null;
xinha_config  = null;
xinha_plugins = null;

// This contains the names of textareas we will make into Xinha editors
xinha_init = xinha_init ? xinha_init : function()
{
   /** STEP 1 ***************************************************************
   * First, specify the textareas that shall be turned into Xinhas.
   * For each one add the respective id to the xinha_editors array.
   * I you want add more than on textarea, keep in mind that these
   * values are comma seperated BUT there is no comma after the last value.
   * If you are going to use this configuration on several pages with different
   * textarea ids, you can add them all. The ones that are not found on the
   * current page will just be skipped.
   ************************************************************************/

  xinha_editors = xinha_editors ? xinha_editors :
  [
    'myTextArea', 'anotherOne'
  ];

  /** STEP 2 ***************************************************************
   * Now, what are the plugins you will be using in the editors on this
   * page.  List all the plugins you will need, even if not all the editors
   * will use all the plugins.
   *
   * The list of plugins below is a good starting point, but if you prefer
   * a simpler editor to start with then you can use the following
   *
   * xinha_plugins = xinha_plugins ? xinha_plugins : [ ];
   *
   * which will load no extra plugins at all.
   ************************************************************************/

  xinha_plugins = xinha_plugins ? xinha_plugins :
  [
   'CharacterMap',
   'ContextMenu',
   'SmartReplace',
   'Stylist',
   'PersistentStorage',
   'PSLocal',
   'Linker',
   'SuperClean',
   'TableOperations'
  ];

         // THIS BIT OF JAVASCRIPT LOADS THE PLUGINS, NO TOUCHING  :)
         if(!Xinha.loadPlugins(xinha_plugins, xinha_init)) return;

  /** STEP 3 ***************************************************************
   * We create a default configuration to be used by all the editors.
   * If you wish to configure some of the editors differently this will be
   * done in step 5.
   *
   * If you want to modify the default config you might do something like this.
   *
   *   xinha_config = new Xinha.Config();
   *   xinha_config.width  = '640px';
   *   xinha_config.height = '420px';
   *
   *
   * For a list of the available configuration options, see:
   * http://trac.xinha.org/wiki/Documentation/ConfigVariablesList
   *
   *************************************************************************/

   xinha_config = xinha_config ? xinha_config() : new Xinha.Config();

  //this is the standard toolbar, feel free to remove buttons as you like
  xinha_config.toolbar =
  [
    ["popupeditor"],
    ["separator","formatblock","fontname","fontsize","bold","italic","underline","strikethrough"],
    ["separator","forecolor","hilitecolor","textindicator"],
    ["separator","subscript","superscript"],
    ["linebreak","separator","justifyleft","justifycenter","justifyright","justifyfull"],
    ["separator","insertorderedlist","insertunorderedlist","outdent","indent"],
    ["separator","inserthorizontalrule","createlink","insertimage","inserttable"],
    ["linebreak","separator","undo","redo","selectall","print"], (Xinha.is_gecko ? [] : ["cut","copy","paste","overwrite","saveas"]),
    ["separator","killword","clearfonts","removeformat","toggleborders","splitblock","lefttoright", "righttoleft"],
    ["separator","htmlmode","showhelp","about"]
  ];

   // To adjust the styling inside the editor, we can load an external stylesheet like this
   // NOTE : YOU MUST GIVE AN ABSOLUTE URL
   xinha_config.pageStyleSheets = [ _editor_url + "examples/files/full_example.css" ];
   //if you're using Stylist, import a stylesheet like this
   xinha_config.stylistLoadStylesheet(_editor_url + "examples/files/stylist.css");

  /** STEP 4 ***************************************************************
   * We first create editors for the textareas.
   *
   * You can do this in two ways, either
   *
   *   xinha_editors   = Xinha.makeEditors(xinha_editors, xinha_config, xinha_plugins);
   *
   * if you want all the editor objects to use the same set of plugins, OR;
   *
   *   xinha_editors = Xinha.makeEditors(xinha_editors, xinha_config);
   *   xinha_editors.myTextArea.registerPlugins(['Stylist']);
   *   xinha_editors.anotherOne.registerPlugins(['CSS','SuperClean']);
   *
   * if you want to use a different set of plugins for one or more of the
   * editors.
   ************************************************************************/

  xinha_editors   = Xinha.makeEditors(xinha_editors, xinha_config, xinha_plugins);

  /** STEP 5 ***************************************************************
   * If you want to change the configuration variables of any of the
   * editors,  this is the place to do that, for example you might want to
   * change the width and height of one of the editors, like this...
   *
   *   xinha_editors.myTextArea.config.width  = '640px';
   *   xinha_editors.myTextArea.config.height = '480px';
   *
   ************************************************************************/

  /** STEP 6 ***************************************************************
   * Finally we "start" the editors, this turns the textareas into
   * Xinha editors.
   ************************************************************************/

  Xinha.startEditors(xinha_editors);
}

Xinha.addOnloadHandler(xinha_init); // this executes the xinha_init function on page load
                                     // and does not interfere with window.onload properties set by other scripts

<|endoftext|>


<commit_before>'use strict'
var path = require('path')
var Flume = require('flumedb')
var OffsetLog = require('flumelog-offset')
//var codec = require('flumecodec/json')
var AsyncWrite = require('async-write')
var V = require('ssb-validate')
var timestamp = require('monotonic-timestamp')
var Obv       = require('obv')
var ssbKeys   = require('ssb-keys')
var box       = ssbKeys.box
var pull      = require('pull-stream')
var rebox     = require('./util').rebox
var isFeed = require('ssb-ref').isFeed

var isArray = Array.isArray
function isFunction (f) { return 'function' === typeof f }

function unbox(data, unboxers, key) {
  var plaintext
  if(data && isString(data.value.content)) {
    for(var i = 0;i < unboxers.length;i++) {
        var unbox = unboxers[i], value
        if(isFunction(unbox)) {
          plaintext = unbox(data.value.content, data.value)
        }
        else if(!key && unbox.key) {
          key = unbox.key(data.value.content, data.value)
        }

        if(key)
          plaintext = unbox.value(data.value.content, key)

        if(plaintext) {
            var msg = {}
            for(var k in data.value)
              msg[k] = data.value[k]

            msg.cyphertext = data.value.content
            msg.content = plaintext
            msg.unbox = key.toString('base64')
            msg.private = true
            return {key: data.key, value: msg, timestamp: data.timestamp}
        }
    }
  }
  return data
}

/*
## queue (msg, cb)

add a message to the log, buffering the write to make it as fast as
possible, cb when the message is queued.

## append (msg, cb)

write a message, callback once it's definitely written.
*/

function toKeyValueTimestamp(msg) {
  return {
    key: V.id(msg),
    value: msg,
    timestamp: timestamp()
  }
}

function isString (s) {
  return 'string' === typeof s
}

module.exports = function (dirname, keys, opts) {
  var hmac_key = opts && opts.caps && opts.caps.sign

  var main_unboxer = {
    key: function (content) { return ssbKeys.unboxKey(content, keys) },
    value: function (content, key) { return ssbKeys.unboxBody(content, key) }
  }

  var unboxers = [ main_unboxer ]

  var codec = {
    encode: function (obj) {
      return JSON.stringify(obj, null, 2)
    },
    decode: function (str) {
      return unbox(JSON.parse(str.toString()), unboxers)
    },
    buffer: false,
    type: 'ssb'
  }

  var log = OffsetLog(path.join(dirname, 'log.offset'), {blockSize:1024*16, codec:codec})

  //NOTE: must use db.ready.set(true) at when migration is complete

  var db = Flume(log, false) //false says the database is not ready yet!
  .use('last', require('./indexes/last')())

  var state = V.initial(), ready = false
  var waiting = [], flush = []

  var append = db.rawAppend = db.append
  db.post = Obv()
  var queue = AsyncWrite(function (_, cb) {
    var batch = state.queue//.map(toKeyValueTimestamp)
    state.queue = []
    append(batch, function (err, v) {
      batch.forEach(function (data) {
        db.post.set(rebox(data))
      })
      cb(err, v)
    })
  }, function reduce(_, msg) {
    state = V.append(state, hmac_key, msg)
    state.queue[state.queue.length-1] = toKeyValueTimestamp(state.queue[state.queue.length-1])
    return state
  }, function (_state) {
    return state.queue.length > 1000
  }, function isEmpty (_state) {
    return !state.queue.length
  }, 10)

  queue.onDrain = function () {
    if(state.queue.length == 0) {
      var l = flush.length;
      for (var i = 0; i < l; ++i)
        flush[i]()
      flush = flush.slice(l)
    }
  }

  db.last.get(function (err, last) {
    //copy to so we avoid weirdness, because this object
    //tracks the state coming in to the database.
    for(var k in last) {
      state.feeds[k] = {
        id: last[k].id,
        timestamp: last[k].ts||last[k].timestamp,
        sequence: last[k].sequence,
        queue: []
      }
    }
    ready = true

    var l = waiting.length;
    for (var i = 0; i < l; ++i)
      waiting[i]()
    waiting = waiting.slice(l)
  })

  function wait(fn) {
    return function (value, cb) {
      if(ready) fn(value, cb)
      else waiting.push(function () {
        fn(value, cb)
      })
    }
  }

  db.queue = wait(function (msg, cb) {
    queue(msg, function (err) {
      if(err) cb(err)
      else cb(null, toKeyValueTimestamp(msg))
    })
  })
  db.append = wait(function (opts, cb) {
    try {
      var content = opts.content, recps = opts.content.recps
      if(recps) {
        if(isFeed(recps) || isArray(recps) && recps.every(isFeed) && recps.length > 0) {
          recps = opts.content.recps = [].concat(recps) //force to array
          content = opts.content = box(opts.content, recps)
        }
        else throw new Error('private message must have all valid recipients, was:'+JSON.stringify(recps))
      }

      var msg = V.create(
        state.feeds[opts.keys.id],
        opts.keys, opts.hmacKey || hmac_key,
        content,
        timestamp()
      )
    }
    catch (err) {
      cb(err)
      return
    }

    queue(msg, function (err) {
      if(err) return cb(err)
      var data = state.queue[state.queue.length-1]
      flush.push(function () {
        cb(null, data)
      })
    })
  })
  db.buffer = function () {
    return queue.buffer
  }
  db.flush = function (cb) {
    //maybe need to check if there is anything currently writing?
    if(!queue.buffer || !queue.buffer.queue.length && !queue.writing) cb()
    else flush.push(cb)
  }
  db.addUnboxer = function(unboxer) {
    unboxers.push(unboxer);
  }

  db.unbox = function (data, key) {
    return unbox(data, unboxers, key)
  }

  return db
}

<commit_msg>Reuse hash of message instead of recomputing it<commit_after>'use strict'
var path = require('path')
var Flume = require('flumedb')
var OffsetLog = require('flumelog-offset')
//var codec = require('flumecodec/json')
var AsyncWrite = require('async-write')
var V = require('ssb-validate')
var timestamp = require('monotonic-timestamp')
var Obv       = require('obv')
var ssbKeys   = require('ssb-keys')
var box       = ssbKeys.box
var pull      = require('pull-stream')
var rebox     = require('./util').rebox
var isFeed = require('ssb-ref').isFeed

var isArray = Array.isArray
function isFunction (f) { return 'function' === typeof f }

function unbox(data, unboxers, key) {
  var plaintext
  if(data && isString(data.value.content)) {
    for(var i = 0;i < unboxers.length;i++) {
      var unbox = unboxers[i], value
      if(isFunction(unbox)) {
        plaintext = unbox(data.value.content, data.value)
      }
      else if(!key && unbox.key) {
        key = unbox.key(data.value.content, data.value)
      }

      if(key)
        plaintext = unbox.value(data.value.content, key)

      if(plaintext) {
        var msg = {}
        for(var k in data.value)
          msg[k] = data.value[k]

        msg.cyphertext = data.value.content
        msg.content = plaintext
        msg.unbox = key.toString('base64')
        msg.private = true
        return {key: data.key, value: msg, timestamp: data.timestamp}
      }
    }
  }
  return data
}

/*
## queue (msg, cb)

add a message to the log, buffering the write to make it as fast as
possible, cb when the message is queued.

## append (msg, cb)

write a message, callback once it's definitely written.
*/

function toKeyValueTimestamp(msg, id) {
  return {
    key: id ? id : V.id(msg),
    value: msg,
    timestamp: timestamp()
  }
}

function isString (s) {
  return 'string' === typeof s
}

module.exports = function (dirname, keys, opts) {
  var hmac_key = opts && opts.caps && opts.caps.sign

  var main_unboxer = {
    key: function (content) { return ssbKeys.unboxKey(content, keys) },
    value: function (content, key) { return ssbKeys.unboxBody(content, key) }
  }

  var unboxers = [ main_unboxer ]

  var codec = {
    encode: function (obj) {
      return JSON.stringify(obj, null, 2)
    },
    decode: function (str) {
      return unbox(JSON.parse(str.toString()), unboxers)
    },
    buffer: false,
    type: 'ssb'
  }

  var log = OffsetLog(path.join(dirname, 'log.offset'), {blockSize:1024*16, codec:codec})

  //NOTE: must use db.ready.set(true) at when migration is complete

  var db = Flume(log, false) //false says the database is not ready yet!
  .use('last', require('./indexes/last')())

  var state = V.initial(), ready = false
  var waiting = [], flush = []

  var append = db.rawAppend = db.append
  db.post = Obv()
  var queue = AsyncWrite(function (_, cb) {
    var batch = state.queue//.map(toKeyValueTimestamp)
    state.queue = []
    append(batch, function (err, v) {
      batch.forEach(function (data) {
        db.post.set(rebox(data))
      })
      cb(err, v)
    })
  }, function reduce(_, msg) {
    state = V.append(state, hmac_key, msg)
    state.queue[state.queue.length-1] = toKeyValueTimestamp(state.queue[state.queue.length-1], state.feeds[msg.author].id)
    return state
  }, function (_state) {
    return state.queue.length > 1000
  }, function isEmpty (_state) {
    return !state.queue.length
  }, 10)

  queue.onDrain = function () {
    if(state.queue.length == 0) {
      var l = flush.length;
      for (var i = 0; i < l; ++i)
        flush[i]()
      flush = flush.slice(l)
    }
  }

  db.last.get(function (err, last) {
    //copy to so we avoid weirdness, because this object
    //tracks the state coming in to the database.
    for(var k in last) {
      state.feeds[k] = {
        id: last[k].id,
        timestamp: last[k].ts||last[k].timestamp,
        sequence: last[k].sequence,
        queue: []
      }
    }
    ready = true

    var l = waiting.length;
    for (var i = 0; i < l; ++i)
      waiting[i]()
    waiting = waiting.slice(l)
  })

  function wait(fn) {
    return function (value, cb) {
      if(ready) fn(value, cb)
      else waiting.push(function () {
        fn(value, cb)
      })
    }
  }

  db.queue = wait(function (msg, cb) {
    queue(msg, function (err) {
      if(err) cb(err)
      else cb(null, toKeyValueTimestamp(msg))
    })
  })

  db.append = wait(function (opts, cb) {
    try {
      var content = opts.content, recps = opts.content.recps
      if(recps) {
        if(isFeed(recps) || isArray(recps) && recps.every(isFeed) && recps.length > 0) {
          recps = opts.content.recps = [].concat(recps) //force to array
          content = opts.content = box(opts.content, recps)
        }
        else throw new Error('private message must have all valid recipients, was:'+JSON.stringify(recps))
      }

      var msg = V.create(
        state.feeds[opts.keys.id],
        opts.keys, opts.hmacKey || hmac_key,
        content,
        timestamp()
      )
    }
    catch (err) {
      cb(err)
      return
    }

    queue(msg, function (err) {
      if(err) return cb(err)
      var data = state.queue[state.queue.length-1]
      flush.push(function () {
        cb(null, data)
      })
    })
  })

  db.buffer = function () {
    return queue.buffer
  }

  db.flush = function (cb) {
    //maybe need to check if there is anything currently writing?
    if(!queue.buffer || !queue.buffer.queue.length && !queue.writing) cb()
    else flush.push(cb)
  }

  db.addUnboxer = function(unboxer) {
    unboxers.push(unboxer);
  }

  db.unbox = function (data, key) {
    return unbox(data, unboxers, key)
  }

  return db
}

<|endoftext|>


<commit_before>/**
 * grunt-angular-configurator
 * @author vitre
 * @contributor Thomas Timmers
 * @licence MIT
 * @version 1.1.22
 * @url https://github.com/TimmersThomas/grunt-angular-configurator
 */

'use strict';

var _ = require('lodash'),
    path = require('path'),
    fs = require('fs');

function generateTemplateSimple() {
  var content = "'use strict';\n" +
                "angular.module('<%= module %>')\n" +
                "    .constant('<%= variable %>', <%= config %>);";

  return content;
};

function generateTemplateBrowserified() {
  var content = "'use strict';\n\n" +
                "exports.inject = function (appModule) {\n" +
                "   appModule.constant('<%= variable %>', exports.constant);\n" +
                "   return exports.constant;\n" +
                "};\n\n" +
                "exports.constant = <%= config %>";

  return content;
};

function generateConfiguration(grunt, options){
  var files = grunt.file.expand({ filter: 'isDirectory'}, options.search_base + '*');

  var config = {},
      states = {};

  grunt.log.debug("Reading files: " + JSON.stringify(files));
  _.forEach(files, function(dir) {
      var module = path.basename(dir),
          configFile = path.resolve(dir, options.config_folder, options.config_file_config),
          stateFile = path.resolve(dir, options.config_folder, options.config_file_state);

      if (fs.existsSync(configFile)) {
          grunt.log.debug("File exists: " + configFile);
          _.merge(config, grunt.file.readJSON(configFile));
      }

      if (fs.existsSync(stateFile)) {
          grunt.log.debug("File exists: " + stateFile);

          _.merge(states, {states: _.mapValues(grunt.file.readJSON(stateFile), function(state) {
              return _.extend({
                  'module': module
              }, state);
          })});
      }
  });

  config = _.merge(
              {},
              states,
              config,
              grunt.file.readJSON( path.resolve(options.general_config_folder, 'config.json') ),
              grunt.file.readJSON( path.resolve(options.general_config_folder, 'config_' + env + '.json') )
            );

  grunt.log.debug("Generated Config: " + JSON.stringify(config));
  return config;
}

module.exports = function(grunt) {

  grunt.registerTask('ng_config_configurator', 'Generate a configuration based on the current ENVIRONMENT', function(envTarget) {
    var environment = envTarget || grunt.config('env');

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      "env": environment,
      "general_config_folder": "app/scripts/_config/",
      "search_base": "app/scripts/",
      "config_folder": "config",
      "config_file_config": "config.json",
      "config_file_state": "states.json",
      "export_module": "app.common",
      "export_variable": "config",
      "export_dest": "app/scripts/common/config/config.js",
      "browserify": true
    });

    grunt.log.debug("Using options: " + JSON.stringify(options));

    var template = generateTemplateSimple(),
        configuraton = generateConfiguration(grunt, options);

    if(options.browserify){
      template = generateTemplateBrowserified();
    }

    grunt.log.debug("Used template: " + template);

    var generatedContent = grunt.template.process(template, {
                                                              data: {
                                                                "module": options.export_module,
                                                                "variable": options.export_variable,
                                                                "config": generateConfiguration()
                                                              }
                                                            }
                                                          );

        grunt.file.write(options.export_dest, generatedContent);
        grunt.log.ok('Generated ' + options.export_dest);
  });
};<commit_msg>[Hotfix] env problem<commit_after>/**
 * grunt-angular-configurator
 * @author vitre
 * @contributor Thomas Timmers
 * @licence MIT
 * @version 1.1.22
 * @url https://github.com/TimmersThomas/grunt-angular-configurator
 */

'use strict';

var _ = require('lodash'),
    path = require('path'),
    fs = require('fs');

function generateTemplateSimple() {
  var content = "'use strict';\n" +
                "angular.module('<%= module %>')\n" +
                "    .constant('<%= variable %>', <%= config %>);";

  return content;
};

function generateTemplateBrowserified() {
  var content = "'use strict';\n\n" +
                "exports.inject = function (appModule) {\n" +
                "   appModule.constant('<%= variable %>', exports.constant);\n" +
                "   return exports.constant;\n" +
                "};\n\n" +
                "exports.constant = <%= config %>";

  return content;
};

function generateConfiguration(grunt, options){
  var files = grunt.file.expand({ filter: 'isDirectory'}, options.search_base + '*');

  var config = {},
      states = {};

  grunt.log.debug("Reading files: " + JSON.stringify(files));
  _.forEach(files, function(dir) {
      var module = path.basename(dir),
          configFile = path.resolve(dir, options.config_folder, options.config_file_config),
          stateFile = path.resolve(dir, options.config_folder, options.config_file_state);

      if (fs.existsSync(configFile)) {
          grunt.log.debug("File exists: " + configFile);
          _.merge(config, grunt.file.readJSON(configFile));
      }

      if (fs.existsSync(stateFile)) {
          grunt.log.debug("File exists: " + stateFile);

          _.merge(states, {states: _.mapValues(grunt.file.readJSON(stateFile), function(state) {
              return _.extend({
                  'module': module
              }, state);
          })});
      }
  });

  config = _.merge(
              {},
              states,
              config,
              grunt.file.readJSON( path.resolve(options.general_config_folder, 'config.json') ),
              grunt.file.readJSON( path.resolve(options.general_config_folder, 'config_' + options.env + '.json') )
            );

  grunt.log.debug("Generated Config: " + JSON.stringify(config));
  return config;
}

module.exports = function(grunt) {

  grunt.registerTask('ng_config_configurator', 'Generate a configuration based on the current ENVIRONMENT', function(envTarget) {
    var environment = envTarget || grunt.config('env');

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      "env": environment,
      "general_config_folder": "app/scripts/_config/",
      "search_base": "app/scripts/",
      "config_folder": "config",
      "config_file_config": "config.json",
      "config_file_state": "states.json",
      "export_module": "app.common",
      "export_variable": "config",
      "export_dest": "app/scripts/common/config/config.js",
      "browserify": true
    });

    grunt.log.debug("Using options: " + JSON.stringify(options));

    var template = generateTemplateSimple(),
        configuraton = generateConfiguration(grunt, options);

    if(options.browserify){
      template = generateTemplateBrowserified();
    }

    grunt.log.debug("Used template: " + template);

    var generatedContent = grunt.template.process(template, {
                                                              data: {
                                                                "module": options.export_module,
                                                                "variable": options.export_variable,
                                                                "config": generateConfiguration()
                                                              }
                                                            }
                                                          );

        grunt.file.write(options.export_dest, generatedContent);
        grunt.log.ok('Generated ' + options.export_dest);
  });
};<|endoftext|>


<commit_before>console.log("WTF");
var MIN_CONFIDENCE = .5;
VMX.config.useMagicCanvas = true;
VMX.storage.ledger = {}
console.log("RE STARTING COUNTER");

VMX.callback = function(detections){
  console.log("eh..?");
  if (! ( mc = VMX.getMagicCanvas() ) ){
    return; //canvas not open
  };
  var modelName = detections[0].cls;
  console.log("ok...");
/*
  var mcc = mc.getContext('2d');
  console.log("VMX..",VMX);

  for(var x in detections){
    if(detections[x].score > MIN_CONFIDENCE){
//      VMX.storage.ledger[modelName] = (x+1);
    } else {
      break;
    }
  }

  console.log(VMX.storage.ledger);
  */
}

<commit_msg>fast commit<commit_after>console.log("WTF");
var MIN_CONFIDENCE = .5;
VMX.config.useMagicCanvas = true;
console.log("RE STARTING COUNTER");

VMX.callback = function(detections){
  console.log("eh..?");
  if (! ( mc = VMX.getMagicCanvas() ) ){
    return; //canvas not open
  };
  var modelName = detections[0].cls;
  console.log("ok...");
/*
  var mcc = mc.getContext('2d');
  console.log("VMX..",VMX);

  for(var x in detections){
    if(detections[x].score > MIN_CONFIDENCE){
//      VMX.storage.ledger[modelName] = (x+1);
    } else {
      break;
    }
  }

  console.log(VMX.storage.ledger);
  */
}

<|endoftext|>


<commit_before>var tabs = new Object();

function initTabs() {
    var container = document.getElementById('tabs');
    tabs.tabs = findTabs(container);
    tabs.titles = findTitles(tabs.tabs);
    tabs.headers = findHeaders(container);
    tabs.select = select;
    tabs.deselectAll = deselectAll;
    tabs.select(0);
    return true;
}

window.onload = initTabs;

function switchTab() {
    var id = this.id.substr(1);
    for (var i = 0; i < tabs.tabs.length; i++) {
        if (tabs.tabs[i].id == id) {
            tabs.select(i);
            return false;
        }
    }
    return false;
}

function select(i) {
    this.deselectAll();
    this.tabs[i].setAttribute('class', 'tab selected');
    this.headers[i].setAttribute('class', 'selected');
    while (this.headers[i].firstChild) {
        this.headers[i].removeChild(this.headers[i].firstChild);
    }
    var h2 = document.createElement('H2');
    h2.appendChild(document.createTextNode(this.titles[i]));
    this.headers[i].appendChild(h2);
}

function deselectAll() {
    for (var i = 0; i < this.tabs.length; i++) {
        this.tabs[i].setAttribute('class', 'tab deselected');
        this.headers[i].setAttribute('class', 'deselected');
        while (this.headers[i].firstChild) {
            this.headers[i].removeChild(this.headers[i].firstChild);
        }
        var a = document.createElement('A');
        a.setAttribute('id', 'ltab' + i);
        a.setAttribute('href', '#tab' + i);
        a.onclick = switchTab;
        a.appendChild(document.createTextNode(this.titles[i]));
        this.headers[i].appendChild(a);
    }
}

function findTabs(container) {
    return findChildElements(container, 'DIV', 'tab');
}

function findHeaders(container) {
    var owner = findChildElements(container, 'UL', 'tabLinks');
    return findChildElements(owner[0], 'LI', null);
}

function findTitles(tabs) {
    var titles = new Array();
    for (var i = 0; i < tabs.length; i++) {
        var tab = tabs[i];
        var header = findChildElements(tab, 'H2', null)[0];
        header.parentNode.removeChild(header);
        titles.push(header.textContent)
    }
    return titles;
}

function findChildElements(container, name, targetClass) {
    var elements = new Array();
    var children = container.childNodes;
    for (var i = 0; i < children.length; i++) {
        var child = children.item(i);
        if (child.nodeType == 1 && child.nodeName == name) {
            if (targetClass && child.getAttribute('class').indexOf(targetClass) < 0) {
                continue;
            }
            elements.push(child);
        }
    }
    return elements;
}
<commit_msg>Some ie fixes for test report.<commit_after>var tabs = new Object();

function initTabs() {
    var container = document.getElementById('tabs');
    tabs.tabs = findTabs(container);
    tabs.titles = findTitles(tabs.tabs);
    tabs.headers = findHeaders(container);
    tabs.select = select;
    tabs.deselectAll = deselectAll;
    tabs.select(0);
    return true;
}

window.onload = initTabs;

function switchTab() {
    var id = this.id.substr(1);
    for (var i = 0; i < tabs.tabs.length; i++) {
        if (tabs.tabs[i].id == id) {
            tabs.select(i);
            return false;
        }
    }
    return false;
}

function select(i) {
    this.deselectAll();
    this.tabs[i].setAttribute('class', 'tab selected');
    this.headers[i].setAttribute('class', 'selected');
    while (this.headers[i].firstChild) {
        this.headers[i].removeChild(this.headers[i].firstChild);
    }
    var h2 = document.createElement('H2');
    h2.appendChild(document.createTextNode(this.titles[i]));
    this.headers[i].appendChild(h2);
}

function deselectAll() {
    for (var i = 0; i < this.tabs.length; i++) {
        this.tabs[i].setAttribute('class', 'tab deselected');
        this.headers[i].setAttribute('class', 'deselected');
        while (this.headers[i].firstChild) {
            this.headers[i].removeChild(this.headers[i].firstChild);
        }
        var a = document.createElement('A');
        a.setAttribute('id', 'ltab' + i);
        a.setAttribute('href', '#tab' + i);
        a.onclick = switchTab;
        a.appendChild(document.createTextNode(this.titles[i]));
        this.headers[i].appendChild(a);
    }
}

function findTabs(container) {
    return findChildElements(container, 'DIV', 'tab');
}

function findHeaders(container) {
    var owner = findChildElements(container, 'UL', 'tabLinks');
    return findChildElements(owner[0], 'LI', null);
}

function findTitles(tabs) {
    var titles = new Array();
    for (var i = 0; i < tabs.length; i++) {
        var tab = tabs[i];
        var header = findChildElements(tab, 'H2', null)[0];
        header.parentNode.removeChild(header);
        if (header.innerText) {
            titles.push(header.innerText)
        } else {
            titles.push(header.textContent)
        }
    }
    return titles;
}

function findChildElements(container, name, targetClass) {
    var elements = new Array();
    var children = container.childNodes;
    for (var i = 0; i < children.length; i++) {
        var child = children.item(i);
        if (child.nodeType == 1 && child.nodeName == name) {
            if (targetClass && child.getAttribute('class').indexOf(targetClass) < 0) {
                continue;
            }
            elements.push(child);
        }
    }
    return elements;
}
<|endoftext|>


<commit_before>Ext.namespace('Gemma');

Gemma.DIFF_THRESHOLD = 0.01;
Gemma.MAX_DIFF_RESULTS = 125;
/**
 *
 * Top level container for all sections of gene info
 *
 * To open the page at a specific tab, include ?tab=[tabName] suffix in the URL. Tab names are each tab's itemId.
 *
 * @class Gemma.GenePage
 * @extends Ext.TabPanel
 *
 */

Gemma.GenePage = Ext.extend(Ext.TabPanel, {

      autoScroll : true,
      defaults : {
         autoScroll : true,
         width : 850
      },
      deferredRender : true,
      listeners : {
         'tabchange' : function(tabPanel, newTab) {
            newTab.fireEvent('tabChanged');
         },
         'beforetabchange' : function(tabPanel, newTab, currTab) {
            // if false is returned, tab isn't changed
            if (currTab) {
               return currTab.fireEvent('leavingTab');
            }
            return true;
         }
      },
      initComponent : function() {

         var geneId = this.geneId;
         Gemma.GenePage.superclass.initComponent.call(this);

         // DETAILS TAB
         var details = new Gemma.GeneDetails({
               title : 'Details',
               itemId : 'details',
               geneId : geneId
            });
         details.on('changeTab', function(tabName) {
               this.setActiveTab(tabName);
            }, this);
         this.add(details);

         this.add(this.initDiffExTab(geneId));

         this.add(this.initCoexTab(geneId));

         this.add(this.initPhenotypeTab(geneId));

         this.add({
               title : 'Gene Ontology Terms',
               xtype : 'genegogrid',
               border : true,
               geneid : this.geneId,
               minHeight : 150,
               deferLoadToRender : true,
               itemId : 'goGrid'
            });

         // ALLEN BRAIN ATLAS IMAGES
         this.add({
               xtype : 'geneallenbrainatlasimages',
               geneId : geneId,
               title : 'Expression Images',
               itemId : 'expression'
            });

         var initialTab = 'details';
         this.loadSpecificTab = (document.URL.indexOf("?") > -1 && (document.URL.indexOf("tab=") > -1));
         if (this.loadSpecificTab) {
            var param = Ext.urlDecode(document.URL.substr(document.URL.indexOf("?") + 1));
            if (param.tab) {
               if (this.getComponent(param.tab) != undefined) {
                  initialTab = param.tab;
               }
            }
         }

         this.on('render', function() {
               this.setActiveTab(initialTab);
            });
      },
      initCoexTab : function(geneId) {
         var coexpressedGeneGrid = new Gemma.CoexpressionGridLight({
               title : 'Coexpression',
               colspan : 2,
               noSmallGemma : true,
               itemId : 'coex'
            });
         coexpressedGeneGrid.on('render', function() {
               coexpressedGeneGrid.doSearch({
                     geneIds : [geneId],
                     quick : true,
                     stringency : 2,
                     forceProbeLevelSearch : false
                  });
            });
         return coexpressedGeneGrid;

      },
      initDiffExTab : function(geneId) {
         var diffExGrid = new Gemma.ProbeLevelDiffExGrid({
               title : 'Differential Expression',
               itemId : 'diffEx'
            });
         diffExGrid.on('render', function() {
               var visColumnIndex = diffExGrid.getColumnModel().getIndexById('visualize');
               diffExGrid.getColumnModel().setHidden(visColumnIndex, false);
               // this should go in grid itself, but it wasn't working properly (or at all)
               if (!this.loadMask && this.getEl()) {
                  this.loadMask = new Ext.LoadMask(this.getEl(), {
                        msg : Gemma.StatusText.Loading.generic,
                        msgCls : 'absolute-position-loading-mask ext-el-mask-msg x-mask-loading'
                     });
               }
               this.loadMask.show();
               diffExGrid.getStore().load({
                     params : [geneId, Gemma.DIFF_THRESHOLD, Gemma.MAX_DIFF_RESULTS]
                  });
            });
         return diffExGrid;
      },
      initPhenotypeTab : function(geneId) {
         var phenotypeEvidenceGridPanel = new Gemma.PhenotypeEvidenceGridPanel({
               title : 'Phenotypes',
               iconCls : 'icon-neurocarta',
               itemId : 'phenotypes',
               hasRelevanceColumn : false,
               displayPhenotypeAsLink : true,
               displayEvidenceCodeFullName : true,
               deferLoadToRender : true,
               currentGene : {
                  id : this.geneId,
                  ncbiId : this.geneNcbiId,
                  officialSymbol : this.geneSymbol,
                  officialName : this.geneName,
                  taxonCommonName : this.geneTaxonName,
                  taxonId : this.geneTaxonId
               },
               listeners : {
                  phenotypeAssociationChanged : function(phenotypes, gene) {
                     this.getStore().reload();
                  }
               }
            });
         phenotypeEvidenceGridPanel.getView().emptyText = Gemma.HelpText.WidgetDefaults.PhenotypePanel.noRecordEmptyText;

         // In PhenotypePanel, when a user logs in, PhenotypeGridPanel will be reloaded first, followed by
         // PhenotypeGeneGridPanel and then PhenotypeEvidenceGridPanel. So, the following code should not
         // be done in PhenotypeEvidenceGridPanel. Otherwise, PhenotypeEvidenceGridPanel would be reloaded twice.
         Gemma.Application.currentUser.on("logIn", function(userName, isAdmin) {
               phenotypeEvidenceGridPanel.getStore().reload();
            }, this);

         return phenotypeEvidenceGridPanel;
      }
   });
<commit_msg>bug 3872: removing confusing double scroll bars on gene page<commit_after>Ext.namespace('Gemma');

Gemma.DIFF_THRESHOLD = 0.01;
Gemma.MAX_DIFF_RESULTS = 125;
/**
 *
 * Top level container for all sections of gene info
 *
 * To open the page at a specific tab, include ?tab=[tabName] suffix in the URL. Tab names are each tab's itemId.
 *
 * @class Gemma.GenePage
 * @extends Ext.TabPanel
 *
 */

Gemma.GenePage = Ext.extend(Ext.TabPanel, {

      defaults : {
         width : 850
      },
      deferredRender : true,
      listeners : {
         'tabchange' : function(tabPanel, newTab) {
            newTab.fireEvent('tabChanged');
         },
         'beforetabchange' : function(tabPanel, newTab, currTab) {
            // if false is returned, tab isn't changed
            if (currTab) {
               return currTab.fireEvent('leavingTab');
            }
            return true;
         }
      },
      initComponent : function() {

         var geneId = this.geneId;
         Gemma.GenePage.superclass.initComponent.call(this);

         // DETAILS TAB
         var details = new Gemma.GeneDetails({
               title : 'Details',
               itemId : 'details',
               geneId : geneId
            });
         details.on('changeTab', function(tabName) {
               this.setActiveTab(tabName);
            }, this);
         this.add(details);

         this.add(this.initDiffExTab(geneId));

         this.add(this.initCoexTab(geneId));

         this.add(this.initPhenotypeTab(geneId));

         this.add({
               title : 'Gene Ontology Terms',
               xtype : 'genegogrid',
               border : true,
               geneid : this.geneId,
               minHeight : 150,
               deferLoadToRender : true,
               itemId : 'goGrid'
            });

         // ALLEN BRAIN ATLAS IMAGES
         this.add({
               xtype : 'geneallenbrainatlasimages',
               geneId : geneId,
               title : 'Expression Images',
               itemId : 'expression'
            });

         var initialTab = 'details';
         this.loadSpecificTab = (document.URL.indexOf("?") > -1 && (document.URL.indexOf("tab=") > -1));
         if (this.loadSpecificTab) {
            var param = Ext.urlDecode(document.URL.substr(document.URL.indexOf("?") + 1));
            if (param.tab) {
               if (this.getComponent(param.tab) != undefined) {
                  initialTab = param.tab;
               }
            }
         }

         this.on('render', function() {
               this.setActiveTab(initialTab);
            });
      },
      initCoexTab : function(geneId) {
         var coexpressedGeneGrid = new Gemma.CoexpressionGridLight({
               title : 'Coexpression',
               colspan : 2,
               noSmallGemma : true,
               itemId : 'coex'
            });
         coexpressedGeneGrid.on('render', function() {
               coexpressedGeneGrid.doSearch({
                     geneIds : [geneId],
                     quick : true,
                     stringency : 2,
                     forceProbeLevelSearch : false
                  });
            });
         return coexpressedGeneGrid;

      },
      initDiffExTab : function(geneId) {
         var diffExGrid = new Gemma.ProbeLevelDiffExGrid({
               title : 'Differential Expression',
               itemId : 'diffEx'
            });
         diffExGrid.on('render', function() {
               var visColumnIndex = diffExGrid.getColumnModel().getIndexById('visualize');
               diffExGrid.getColumnModel().setHidden(visColumnIndex, false);
               // this should go in grid itself, but it wasn't working properly (or at all)
               if (!this.loadMask && this.getEl()) {
                  this.loadMask = new Ext.LoadMask(this.getEl(), {
                        msg : Gemma.StatusText.Loading.generic,
                        msgCls : 'absolute-position-loading-mask ext-el-mask-msg x-mask-loading'
                     });
               }
               this.loadMask.show();
               diffExGrid.getStore().load({
                     params : [geneId, Gemma.DIFF_THRESHOLD, Gemma.MAX_DIFF_RESULTS]
                  });
            });
         return diffExGrid;
      },
      initPhenotypeTab : function(geneId) {
         var phenotypeEvidenceGridPanel = new Gemma.PhenotypeEvidenceGridPanel({
               title : 'Phenotypes',
               iconCls : 'icon-neurocarta',
               itemId : 'phenotypes',
               hasRelevanceColumn : false,
               displayPhenotypeAsLink : true,
               displayEvidenceCodeFullName : true,
               deferLoadToRender : true,
               currentGene : {
                  id : this.geneId,
                  ncbiId : this.geneNcbiId,
                  officialSymbol : this.geneSymbol,
                  officialName : this.geneName,
                  taxonCommonName : this.geneTaxonName,
                  taxonId : this.geneTaxonId
               },
               listeners : {
                  phenotypeAssociationChanged : function(phenotypes, gene) {
                     this.getStore().reload();
                  }
               }
            });
         phenotypeEvidenceGridPanel.getView().emptyText = Gemma.HelpText.WidgetDefaults.PhenotypePanel.noRecordEmptyText;

         // In PhenotypePanel, when a user logs in, PhenotypeGridPanel will be reloaded first, followed by
         // PhenotypeGeneGridPanel and then PhenotypeEvidenceGridPanel. So, the following code should not
         // be done in PhenotypeEvidenceGridPanel. Otherwise, PhenotypeEvidenceGridPanel would be reloaded twice.
         Gemma.Application.currentUser.on("logIn", function(userName, isAdmin) {
               phenotypeEvidenceGridPanel.getStore().reload();
            }, this);

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


<commit_before>var reloadTabOnDblclick = {
  reload: function (e) {
    var t = e.originalTarget;

    if (t.localName === 'tab' || t.parentNode.localName === 'tab') {
      if (e.shiftKey) {
        BrowserReloadSkipCache();
      } else {
        BrowserReload();
      }
    }
  }
};

window.addEventListener("dblclick", reloadTabOnDblclick.reload, false);
<commit_msg>use XPath to check double-clicked node (Thanks to Piro)<commit_after>var reloadTabOnDblclick = {
  reload: function (e) {
    var t = e.originalTarget;

    if (t.ownerDocument.evaluate("ancestor-or-self::*[local-name()='tab']", t, null, XPathResult.BOOLEAN_TYPE, null).booleanValue) {
      if (e.shiftKey) {
        BrowserReloadSkipCache();
      } else {
        BrowserReload();
      }
    }
  }
};

window.addEventListener("dblclick", reloadTabOnDblclick.reload, false);
<|endoftext|>


<commit_before>'use strict';

import React from 'react';
import Tab from 'components/atoms/tab/Tab';
_ = require('lodash');
require('./stylesheets/issues_tabs.scss');

class IssuesTabs extends React.Component {
  constructor(props) {
    super(props);
    this.state = {activeTab: 'hot'};
  }
  changeTab(tab) {
    this.setState({activeTab: tab});
  }
  render() {
    return (

{_.capitalize(this.state.activeTab)} Issues

          <Tab name='hot' onClick={this.changeTab.bind(this)} activeTab={this.state.activeTab}/>
          <Tab name='trending' onClick={this.changeTab.bind(this)} activeTab={this.state.activeTab} />
          <Tab name='fresh' onClick={this.changeTab.bind(this)} activeTab={this.state.activeTab} />

    );
  }
}

IssuesTabs.displayName = 'MoleculeIssuesTabs';

// Uncomment properties you need
// IssuesTabs.propTypes = {};
IssuesTabs.defaultProps = {activeTab: 'hot'};

export default IssuesTabs;
<commit_msg>fix lint errors<commit_after>'use strict'

import React from 'react'
import Tab from 'components/atoms/tab/Tab'
_ = require('lodash')
require('./stylesheets/issues_tabs.scss')

class IssuesTabs extends React.Component {
  constructor(props) {
    super(props)
    this.state = {activeTab: 'hot'}
  }
  changeTab(tab) {
    this.setState({activeTab: tab})
  }
  render() {
    return (

{_.capitalize(this.state.activeTab)} Issues

          <Tab name='hot' onClick={this.changeTab.bind(this)}
               activeTab={this.state.activeTab}/>
          <Tab name='trending'
               onClick={this.changeTab.bind(this)}
               activeTab={this.state.activeTab} />
          <Tab name='fresh' onClick={this.changeTab.bind(this)}
               activeTab={this.state.activeTab} />

    )
  }
}

IssuesTabs.displayName = 'MoleculeIssuesTabs'

// Uncomment properties you need
// IssuesTabs.propTypes = {};
IssuesTabs.defaultProps = {activeTab: 'hot'}

export default IssuesTabs
<|endoftext|>


<commit_before>(function(global, undef)
{
  var json = global.JSON;
  if (!json) {
    return;
  }

  // Fix Safari issue throwing errors when "undefined" is passed in
  try
  {
    json.stringify();
  }
  catch(ex)
  {
    var stringifyOrig = json.stringify;
    json.stringify = function(value) {
      return value === undef ? value : stringifyOrig.apply(json, arguments);
    };
  }
})(core.Main.getGlobal());
<commit_msg>Enabled strict<commit_after>

"use strict";

(function(global, undef)
{
  var json = global.JSON;
  if (!json) {
    return;
  }

  // Fix Safari issue throwing errors when "undefined" is passed in
  try
  {
    json.stringify();
  }
  catch(ex)
  {
    var stringifyOrig = json.stringify;
    json.stringify = function(value) {
      return value === undef ? value : stringifyOrig.apply(json, arguments);
    };
  }

})(core.Main.getGlobal());
<|endoftext|>


<commit_before>"use strict";

class Player {
    constructor({$container, videoSrc, videoId, videoStart, videoEnd}) {
        this.$container = $container;

        this.videoId = videoId;

        this.selectedAnnotation = null;

        this.annotations = null;

        this.annotationRectBindings = [];

        this.videoSrc = videoSrc;

        this.view = null;

        this.videoStart = videoStart;

        this.videoEnd = videoEnd;

        this.metrics = {
            playerStartTimes: Date.now(),
            annotationsStartTime: null,
            annotationsEndTime: null,
        };

        // Promises
        this.annotationsDataReady = Misc.CustomPromise();
        this.annotationsReady = Misc.CustomPromise();
        this.viewReady = Misc.CustomPromise();

        // We're ready when all the components are ready.
        this.ready = Misc.CustomPromiseAll(
            this.annotationsReady(),
            this.viewReady()
        );

        // Prevent adding new properties
        Misc.preventExtensions(this, Player);

        this.initAnnotations();
        this.initView();
        this.initHandlers();
    }

    // Init ALL the annotations!

    initView() {
        var {$container, videoSrc, videoStart, videoEnd} = this;

        this.view = new PlayerView({$container, videoSrc, videoStart, videoEnd});

        this.view.ready().then(this.viewReady.resolve);
    }

    initAnnotations() {
        DataSources.annotations.load(this.videoId).then((annotations) => {
            this.annotations = annotations;
            this.annotationsDataReady.resolve();
        });

        // When this.annotations is loaded AND view is ready for drawing...
        Promise.all([this.annotationsDataReady(), this.viewReady()]).then(() => {
            for (let annotation of this.annotations) {
                let rect = this.view.addRect();
                rect.fill = annotation.fill;
                this.initBindAnnotationAndRect(annotation, rect);
            }

            $(this).triggerHandler('change-onscreen-annotations');
            $(this).triggerHandler('change-keyframes');

            this.annotationsReady.resolve();
        });
    }

    initBindAnnotationAndRect(annotation, rect) {
        // On PlayerView...

        this.annotationRectBindings.push({annotation, rect});

        // On Rect...

        $(rect).on('discrete-change', (e, bounds) => {
            annotation.updateKeyframe({
                time: this.view.video.currentTime,
                bounds: bounds,
            });
            $(this).triggerHandler('change-onscreen-annotations');
            $(this).triggerHandler('change-keyframes');
        });

        $(rect).on('select', () => {
            this.selectedAnnotation = annotation;
            $(this).triggerHandler('change-keyframes');
        });

        $(rect).on('drag-start', () => {
            this.view.video.pause();
        });

        $(rect).on('focus', () => {
            this.selectedAnnotation = annotation;
            $(this).triggerHandler('change-onscreen-annotations');
            $(this).triggerHandler('change-keyframes');
        });

        // On Annotation...

        $(annotation).on('change delete', () => {
            rect.appear({singlekeyframe: annotation.keyframes.length === 1});
        });
        $(annotation).triggerHandler('change');

        $(annotation).on('delete', () => {
            $(annotation).off();
            $(rect).off();
            this.view.deleteRect(rect);
        });
    }

    initHandlers() {
        // Drawing annotations
        $(this).on('change-onscreen-annotations', () => {
            this.drawOnscreenAnnotations();
        });

        $(this).on('change-keyframes', () => {
            this.drawKeyframes();
        });

        // Submitting
        // TODO doesn't respect scope
        $('#submit-btn').click(this.submitAnnotations.bind(this));
        $('#submit-survey-btn').click(this.submitSurvey.bind(this));

        $(this).on('change-verification', this.updateVerifiedButton.bind(this));
        $(this).triggerHandler('change-verification');

        $('#verified-btn').click(this.submitVerified.bind(this));

        // On drawing changed
        this.viewReady().then(() => {
            $(this.view.creationRect).on('drag-start', () => {
                this.view.video.pause();
            });

            $(this.view.creationRect).on('focus', () => {
               this.selectedAnnotation = null;
                $(this).triggerHandler('change-onscreen-annotations');
                $(this).triggerHandler('change-keyframes');
            });

            $(this.view.video).on('', () => {
                $(this).triggerHandler('change-onscreen-annotations');
            });

            $(this.view).on('create-rect', (e, rect) => {
                this.addAnnotationAtCurrentTimeFromRect(rect);
                rect.focus();
                $(this).triggerHandler('change-keyframes');
            });

            $(this.view).on('delete-keyframe', () => {
                this.view.video.pause();
                this.deleteSelectedKeyframe();
                $(this).triggerHandler('change-onscreen-annotations');
                $(this).triggerHandler('change-keyframes');
            });

            $(this.view).on('step-forward-keyframe', () => {
                var time = this.view.video.currentTime;
                for (let [i, kf] of this.selectedAnnotation.keyframes.entries()) {
                    if (time == kf.time) {
                        if (i != this.selectedAnnotation.keyframes.length - 1) {
                            var nf = this.selectedAnnotation.keyframes[i + 1];
                            this.view.video.currentTime = nf.time;
                            break;
                        }
                    }
                }
            });

            $(this.view).on('step-backward-keyframe', () => {
                var time = this.view.video.currentTime;
                for (let [i, kf] of this.selectedAnnotation.keyframes.entries()) {
                    if (time == kf.time) {
                        if (i !== 0) {
                            var nf = this.selectedAnnotation.keyframes[i - 1];
                            this.view.video.currentTime = nf.time;
                            break;
                        }
                    }
                }
            });

        });
    }

    // Draw something

    drawOnscreenAnnotations() {
        for (let {annotation, rect} of this.annotationRectBindings) {
            this.drawAnnotationOnRect(annotation, rect);
        }
    }

    drawKeyframes() {
        this.view.keyframebar.resetWithDuration(this.view.video.duration);
        for (let annotation of this.annotations) {
            for (let keyframe of annotation.keyframes) {
                let selected = (annotation == this.selectedAnnotation);
                this.view.keyframebar.addKeyframeAt(keyframe.time, {selected});
            }
        }
    }

    drawAnnotationOnRect(annotation, rect) {
        if (this.metrics.annotationsStartTime == null) {
            this.metrics.annotationsStartTime = Date.now();
        }
        var time = this.view.video.currentTime;
        var {bounds, prevIndex, nextIndex, closestIndex} = annotation.getFrameAtTime(time);

        rect.appear({
            real: closestIndex != null || (prevIndex != null && nextIndex != null),
            selected: this.selectedAnnotation === annotation,
        });

        // Don't mess up our drag
        if (rect.isBeingDragged()) return;

        rect.bounds = bounds;
    }

    // Actions

    submitAnnotations(e) {
        e.preventDefault();
        this.metrics.annotationsEndTime = Date.now();
        if (this.metrics.annotationsStartTime == null) {
            this.metrics.annotationsStartTime = this.metrics.annotationsEndTime;
        }
        if (this.annotations.length === 0 && !confirm('Confirm that there are no objects in the video?')) {
            return;
        }
        DataSources.annotations.save(this.videoId, this.annotations, this.metrics, window.mturk).then((response) => {
            $('.submit-result').html(response + (numberOfSurveyQuestions ? "
Optional feedback on your experience: " : ''));
        });
        $('#myModal').modal();
    }

    submitSurvey() {
        var results = [];
        for (let i = 1; i <= numberOfSurveyQuestions; i++) {
            results.push($(`input[name='survey-q${i}']:checked`).val());
        }
        console.log(results);
        //TODO: Store results in datasources
    }

    updateVerifiedButton() {
        if (window.video.verified) {
            $('#verified-btn').text('Verified').addClass('btn btn-success').removeClass('btn-danger');
        }
        else {
            $('#verified-btn').text('Not Verified').addClass('btn btn-danger').removeClass('btn-success');
        }
    }

    submitVerified() {
        return fetch(`/video/${this.videoId}/verify/`, {
            headers: {
                'X-CSRFToken': window.CSRFToken,
                'Content-Type': 'application/json',
            },
            credentials: 'same-origin',
            method: 'post',
            body: (!window.video.verified).toString(),
        }).then((response) => {
            if (response.ok) {
                window.video.verified = !window.video.verified;
                $(this).triggerHandler('change-verification');
            }
            return response.text();
        }).then((text) => console.log(text));
    }

    addAnnotationAtCurrentTimeFromRect(rect) {
        var annotation = Annotation.newFromCreationRect();
        annotation.updateKeyframe({
            time: this.view.video.currentTime,
            bounds: rect.bounds
        });
        this.annotations.push(annotation);
        rect.fill = annotation.fill;
        this.initBindAnnotationAndRect(annotation, rect);
    }

    deleteAnnotation(annotation) {
        if (annotation == null) return false;

        if (annotation == this.selectedAnnotation) {
            this.selectedAnnotation = null;
        }

        for (let i = 0; i < this.annotations.length; i++) {
            if (this.annotations[i] === annotation) {
                annotation.delete();
                this.annotations.splice(i, 1);
                this.annotationRectBindings.splice(i, 1);
                return true;
            }
        }

        throw new Error("Player.deleteAnnotation: annotation not found");
    }

    deleteSelectedKeyframe() {
        if (this.selectedAnnotation == null) return false;

        this.selectedAnnotation.deleteKeyframeAtTime(this.view.video.currentTime);

        if (this.selectedAnnotation.keyframes.length === 0) {
            this.deleteAnnotation(this.selectedAnnotation);
        }

        return true;
    }
}

void Player;
<commit_msg>put in the on time update handler<commit_after>"use strict";

class Player {
    constructor({$container, videoSrc, videoId, videoStart, videoEnd}) {
        this.$container = $container;

        this.videoId = videoId;

        this.selectedAnnotation = null;

        this.annotations = null;

        this.annotationRectBindings = [];

        this.videoSrc = videoSrc;

        this.view = null;

        this.videoStart = videoStart;

        this.videoEnd = videoEnd;

        this.metrics = {
            playerStartTimes: Date.now(),
            annotationsStartTime: null,
            annotationsEndTime: null,
        };

        // Promises
        this.annotationsDataReady = Misc.CustomPromise();
        this.annotationsReady = Misc.CustomPromise();
        this.viewReady = Misc.CustomPromise();

        // We're ready when all the components are ready.
        this.ready = Misc.CustomPromiseAll(
            this.annotationsReady(),
            this.viewReady()
        );

        // Prevent adding new properties
        Misc.preventExtensions(this, Player);

        this.initAnnotations();
        this.initView();
        this.initHandlers();
    }

    // Init ALL the annotations!

    initView() {
        var {$container, videoSrc, videoStart, videoEnd} = this;

        this.view = new PlayerView({$container, videoSrc, videoStart, videoEnd});

        this.view.ready().then(this.viewReady.resolve);
    }

    initAnnotations() {
        DataSources.annotations.load(this.videoId).then((annotations) => {
            this.annotations = annotations;
            this.annotationsDataReady.resolve();
        });

        // When this.annotations is loaded AND view is ready for drawing...
        Promise.all([this.annotationsDataReady(), this.viewReady()]).then(() => {
            for (let annotation of this.annotations) {
                let rect = this.view.addRect();
                rect.fill = annotation.fill;
                this.initBindAnnotationAndRect(annotation, rect);
            }

            $(this).triggerHandler('change-onscreen-annotations');
            $(this).triggerHandler('change-keyframes');

            this.annotationsReady.resolve();
        });
    }

    initBindAnnotationAndRect(annotation, rect) {
        // On PlayerView...

        this.annotationRectBindings.push({annotation, rect});

        // On Rect...

        $(rect).on('discrete-change', (e, bounds) => {
            annotation.updateKeyframe({
                time: this.view.video.currentTime,
                bounds: bounds,
            });
            $(this).triggerHandler('change-onscreen-annotations');
            $(this).triggerHandler('change-keyframes');
        });

        $(rect).on('select', () => {
            this.selectedAnnotation = annotation;
            $(this).triggerHandler('change-keyframes');
        });

        $(rect).on('drag-start', () => {
            this.view.video.pause();
        });

        $(rect).on('focus', () => {
            this.selectedAnnotation = annotation;
            $(this).triggerHandler('change-onscreen-annotations');
            $(this).triggerHandler('change-keyframes');
        });

        // On Annotation...

        $(annotation).on('change delete', () => {
            rect.appear({singlekeyframe: annotation.keyframes.length === 1});
        });
        $(annotation).triggerHandler('change');

        $(annotation).on('delete', () => {
            $(annotation).off();
            $(rect).off();
            this.view.deleteRect(rect);
        });
    }

    initHandlers() {
        // Drawing annotations
        $(this).on('change-onscreen-annotations', () => {
            this.drawOnscreenAnnotations();
        });

        $(this).on('change-keyframes', () => {
            this.drawKeyframes();
        });

        // Submitting
        // TODO doesn't respect scope
        $('#submit-btn').click(this.submitAnnotations.bind(this));
        $('#submit-survey-btn').click(this.submitSurvey.bind(this));

        $(this).on('change-verification', this.updateVerifiedButton.bind(this));
        $(this).triggerHandler('change-verification');

        $('#verified-btn').click(this.submitVerified.bind(this));

        // On drawing changed
        this.viewReady().then(() => {
            $(this.view.creationRect).on('drag-start', () => {
                this.view.video.pause();
            });

            $(this.view.creationRect).on('focus', () => {
               this.selectedAnnotation = null;
                $(this).triggerHandler('change-onscreen-annotations');
                $(this).triggerHandler('change-keyframes');
            });

            this.view.video.onTimeUpdate(() => {
                $(this).triggerHandler('change-onscreen-annotations');
            });

            $(this.view).on('create-rect', (e, rect) => {
                this.addAnnotationAtCurrentTimeFromRect(rect);
                rect.focus();
                $(this).triggerHandler('change-keyframes');
            });

            $(this.view).on('delete-keyframe', () => {
                this.view.video.pause();
                this.deleteSelectedKeyframe();
                $(this).triggerHandler('change-onscreen-annotations');
                $(this).triggerHandler('change-keyframes');
            });

            $(this.view).on('step-forward-keyframe', () => {
                var time = this.view.video.currentTime;
                for (let [i, kf] of this.selectedAnnotation.keyframes.entries()) {
                    if (time == kf.time) {
                        if (i != this.selectedAnnotation.keyframes.length - 1) {
                            var nf = this.selectedAnnotation.keyframes[i + 1];
                            this.view.video.currentTime = nf.time;
                            break;
                        }
                    }
                }
            });

            $(this.view).on('step-backward-keyframe', () => {
                var time = this.view.video.currentTime;
                for (let [i, kf] of this.selectedAnnotation.keyframes.entries()) {
                    if (time == kf.time) {
                        if (i !== 0) {
                            var nf = this.selectedAnnotation.keyframes[i - 1];
                            this.view.video.currentTime = nf.time;
                            break;
                        }
                    }
                }
            });

        });
    }

    // Draw something

    drawOnscreenAnnotations() {
        for (let {annotation, rect} of this.annotationRectBindings) {
            this.drawAnnotationOnRect(annotation, rect);
        }
    }

    drawKeyframes() {
        this.view.keyframebar.resetWithDuration(this.view.video.duration);
        for (let annotation of this.annotations) {
            for (let keyframe of annotation.keyframes) {
                let selected = (annotation == this.selectedAnnotation);
                this.view.keyframebar.addKeyframeAt(keyframe.time, {selected});
            }
        }
    }

    drawAnnotationOnRect(annotation, rect) {
        if (this.metrics.annotationsStartTime == null) {
            this.metrics.annotationsStartTime = Date.now();
        }
        var time = this.view.video.currentTime;
        var {bounds, prevIndex, nextIndex, closestIndex} = annotation.getFrameAtTime(time);

        rect.appear({
            real: closestIndex != null || (prevIndex != null && nextIndex != null),
            selected: this.selectedAnnotation === annotation,
        });

        // Don't mess up our drag
        if (rect.isBeingDragged()) return;

        rect.bounds = bounds;
    }

    // Actions

    submitAnnotations(e) {
        e.preventDefault();
        this.metrics.annotationsEndTime = Date.now();
        if (this.metrics.annotationsStartTime == null) {
            this.metrics.annotationsStartTime = this.metrics.annotationsEndTime;
        }
        if (this.annotations.length === 0 && !confirm('Confirm that there are no objects in the video?')) {
            return;
        }
        DataSources.annotations.save(this.videoId, this.annotations, this.metrics, window.mturk).then((response) => {
            $('.submit-result').html(response + (numberOfSurveyQuestions ? "
Optional feedback on your experience: " : ''));
        });
        $('#myModal').modal();
    }

    submitSurvey() {
        var results = [];
        for (let i = 1; i <= numberOfSurveyQuestions; i++) {
            results.push($(`input[name='survey-q${i}']:checked`).val());
        }
        console.log(results);
        //TODO: Store results in datasources
    }

    updateVerifiedButton() {
        if (window.video.verified) {
            $('#verified-btn').text('Verified').addClass('btn btn-success').removeClass('btn-danger');
        }
        else {
            $('#verified-btn').text('Not Verified').addClass('btn btn-danger').removeClass('btn-success');
        }
    }

    submitVerified() {
        return fetch(`/video/${this.videoId}/verify/`, {
            headers: {
                'X-CSRFToken': window.CSRFToken,
                'Content-Type': 'application/json',
            },
            credentials: 'same-origin',
            method: 'post',
            body: (!window.video.verified).toString(),
        }).then((response) => {
            if (response.ok) {
                window.video.verified = !window.video.verified;
                $(this).triggerHandler('change-verification');
            }
            return response.text();
        }).then((text) => console.log(text));
    }

    addAnnotationAtCurrentTimeFromRect(rect) {
        var annotation = Annotation.newFromCreationRect();
        annotation.updateKeyframe({
            time: this.view.video.currentTime,
            bounds: rect.bounds
        });
        this.annotations.push(annotation);
        rect.fill = annotation.fill;
        this.initBindAnnotationAndRect(annotation, rect);
    }

    deleteAnnotation(annotation) {
        if (annotation == null) return false;

        if (annotation == this.selectedAnnotation) {
            this.selectedAnnotation = null;
        }

        for (let i = 0; i < this.annotations.length; i++) {
            if (this.annotations[i] === annotation) {
                annotation.delete();
                this.annotations.splice(i, 1);
                this.annotationRectBindings.splice(i, 1);
                return true;
            }
        }

        throw new Error("Player.deleteAnnotation: annotation not found");
    }

    deleteSelectedKeyframe() {
        if (this.selectedAnnotation == null) return false;

        this.selectedAnnotation.deleteKeyframeAtTime(this.view.video.currentTime);

        if (this.selectedAnnotation.keyframes.length === 0) {
            this.deleteAnnotation(this.selectedAnnotation);
        }

        return true;
    }
}

void Player;
<|endoftext|>


<commit_before>define(["dojo/_base/declare"], function (declare) {
	return function (name, store) {

		angular.module("ng" + name, [])
			.factory(name, function ($q) {

				var promise = function(method){
					return function(){
						var d = $q.defer();
						var res = this.inherited(arguments);
						res.then(function () {             // success
							d.resolve.apply(d, arguments);
						}, function(){                     // error
							d.reject.apply(d, arguments);
						}, function () {                   // update
							d.notify.apply(d, arguments);
						});

						// TODO: no access is provided to dojo's promise methods
						// (isRejected, isCancelled, etc.) It may be necessary.
						return d.promise;
					}
				}

				var _store = declare(store, {
					get    : promise(),
					//save   : promise(),
					//add    : promise(),
					//put    : promise(),
					//remove : promise()
				});

				return _store;
			});
	};
});
<commit_msg>Wrapped all store methods into angular promises<commit_after>define(["dojo/_base/declare"], function (declare) {
	return function (name, store) {

		angular.module("ng" + name, [])
			.factory(name, function ($q) {

				var promise = function(method){
					return function(){
						var d = $q.defer();
						var res = this.inherited(arguments);
						res.then(function () {             // success
							d.resolve.apply(d, arguments);
						}, function(){                     // error
							d.reject.apply(d, arguments);
						}, function () {                   // update
							d.notify.apply(d, arguments);
						});

						// TODO: no access is provided to dojo's promise methods
						// (isRejected, isCancelled, etc.) It may be necessary.
						return d.promise;
					};
				};

				var _store = declare(store, {
					get    : promise(),
					save   : promise(),
					add    : promise(),
					put    : promise(),
					remove : promise()
				});

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


<commit_before>/* global Reference, SqlService, Promise, Group */
'use strict';

/**
 * Group.js
 *
 * @description :: TODO: You might write a short summary of how this model works and what it represents here.
 * @docs        :: http://sailsjs.org/#!documentation/models
 */

var _ = require('lodash');
var researchEntity = require('./ResearchEntity');

module.exports = _.merge({}, researchEntity, {
    attributes: {
        name: 'STRING',
        slug: 'STRING',
        shortname: 'TEXT',
        description: 'TEXT',
        publicationsAcronym: 'TEXT',
        memberships: {
            collection: 'membership',
            via: 'group'
        },
        collaborations: {
            collection: 'collaboration',
            via: 'group'
        },
        administrators: {
            collection: 'user',
            via: 'admininstratedGroups'
        },
        drafts: {
            collection: 'Reference',
            via: 'draftGroupCreator'
        },
        documents: {
            collection: 'reference',
            via: 'groups',
            through: 'authorshipgroup'
        },
        authorships: {
            collection: 'authorshipGroup',
            via: 'researchEntity',
        },
        discardedReferences: {
            collection: 'Reference',
            via: 'discardedGroups'
        },
        suggestedReferences: {
            collection: 'reference',
            via: 'suggestedGroups'
        },
        suggestedDocuments: {
            collection: 'reference',
            via: 'groups',
            through: 'documentsuggestiongroup'
        },
        getType: function () {
            return 'group';
        },
        scopusId: {
            type: 'STRING'
        },
        institute: {
            model: 'institute'
        }
    },
    getAuthorshipsData: function (document) {
        return Promise.resolve({
            isVerifiable: true,
            document: document
        });
    },
    doVerifyDocument: function (document, researchEntityId) {
        const authorship = {
            researchEntity: researchEntityId,
            document: document.id
        };
        return AuthorshipGroup.create(authorship)
            .then(()=>document);
    }
});
<commit_msg>Fixed bug on group verify<commit_after>/* global Reference, SqlService, Promise, Group */
'use strict';

/**
 * Group.js
 *
 * @description :: TODO: You might write a short summary of how this model works and what it represents here.
 * @docs        :: http://sailsjs.org/#!documentation/models
 */

var _ = require('lodash');
var researchEntity = require('./ResearchEntity');

module.exports = _.merge({}, researchEntity, {
    attributes: {
        name: 'STRING',
        slug: 'STRING',
        shortname: 'TEXT',
        description: 'TEXT',
        publicationsAcronym: 'TEXT',
        memberships: {
            collection: 'membership',
            via: 'group'
        },
        collaborations: {
            collection: 'collaboration',
            via: 'group'
        },
        administrators: {
            collection: 'user',
            via: 'admininstratedGroups'
        },
        drafts: {
            collection: 'Reference',
            via: 'draftGroupCreator'
        },
        documents: {
            collection: 'reference',
            via: 'groups',
            through: 'authorshipgroup'
        },
        authorships: {
            collection: 'authorshipGroup',
            via: 'researchEntity',
        },
        discardedReferences: {
            collection: 'Reference',
            via: 'discardedGroups'
        },
        suggestedDocuments: {
            collection: 'reference',
            via: 'groups',
            through: 'documentsuggestiongroup'
        },
        getType: function () {
            return 'group';
        },
        scopusId: {
            type: 'STRING'
        },
        institute: {
            model: 'institute'
        }
    },
    getAuthorshipsData: function (document) {
        return Promise.resolve({
            isVerifiable: true,
            document: document
        });
    },
    doVerifyDocument: function (document, researchEntityId) {
        const authorship = {
            researchEntity: researchEntityId,
            document: document.id
        };
        return AuthorshipGroup.create(authorship)
            .then(()=>document);
    }
});
<|endoftext|>


<commit_before>var Twitter = require('twitter');
var Cache = require('../../common/cache');

var apiKeys = require('../../private.js').twitter;

// 5 minute cache
var cache = new Cache(1000 * 60 * 5);
var client = new Twitter(apiKeys);

function get(req, res) {
    cache(function(resolve, reject) {
        // return resolve(mockData);
        client.get('search/tweets', {
            q: '#QOTD -filter:retweets',
            result_type: 'popular',
            lang: 'en'
        }, function(error, tweets) {
            if (error) reject(error);
            resolve(tweets.statuses.filter(tweet => {
                return (!tweet.entities.media || tweet.entities.media.length === 0) &&
                    (!tweet.entities.urls || tweet.entities.urls.length === 0);
            }).map(tweet => {
                return {
                    content: tweet.text,
                    source: `@${tweet.user.screen_name}`
                };
            }));
        });
    }).then(function(data) {
        res.json({
            status: 'success',
            data: data
        });
    }).catch(function(data) {
        res.status(500).json({
            status: 'error',
            data: data
        });
    });
}

module.exports.get = get;
<commit_msg>Disabled QOTD media filtering.<commit_after>var Twitter = require('twitter');
var Cache = require('../../common/cache');

var apiKeys = require('../../private.js').twitter;

// 5 minute cache
var cache = new Cache(1000 * 60 * 5);
var client = new Twitter(apiKeys);

function get(req, res) {
    cache(function(resolve, reject) {
        // return resolve(mockData);
        client.get('search/tweets', {
            q: '#QOTD -filter:retweets',
            result_type: 'popular',
            lang: 'en'
        }, function(error, tweets) {
            if (error) reject(error);
            resolve(tweets.statuses/* .filter(tweet => {
                return (!tweet.entities.media || tweet.entities.media.length === 0) &&
                    (!tweet.entities.urls || tweet.entities.urls.length === 0);
            })*/.map(tweet => {
                return {
                    content: tweet.text,
                    source: `@${tweet.user.screen_name}`
                };
            }));
        });
    }).then(function(data) {
        res.json({
            status: 'success',
            data: data
        });
    }).catch(function(data) {
        res.status(500).json({
            status: 'error',
            data: data
        });
    });
}

module.exports.get = get;
<|endoftext|>


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

module.exports = function(app, log, passport) {

	//
	// GET API ----------------------------------------------------------------------------
	//

	var jsondata = { test : 'test GET'};

	//PUBLIC API ABM AUTOMATIC BANKING MACHINE (without token oAuth.2.0)
	app.get('/api/test', function (req, res) {
         return res.json(jsondata);
	});

	//
	// POST API  ----------------------------------------------------------------------------
	//

	app.post('/api/test',
		//passport.authenticate('bearer', { session: false }),
		function(req, res) {
			//mandatory --------------------------------
			if (req.body.hasOwnProperty('test')	)
			{ //------------------------------------------

				return res.send({ status: 'OK', test:req.body.test });
			}
	});

	//
	// PUT API   ----------------------------------------------------------------------------
	//

	app.put('/api/abm/:id',
			//passport.authenticate('bearer', { session: false }),
			function (req, res) {

	            res.statusCode = 404;
	            return res.send({ status: 'OK', put : req.params.id });
	});

	//
	// DELETE API  ----------------------------------------------------------------------------
	//

	app.delete('/api/abm/:id',
		//passport.authenticate('bearer', { session: false }),
		function (req, res){
            res.statusCode = 404;
            return res.send({ status: 'OK', del : req.params.id });
	});

}<commit_msg>Delete testapi.js<commit_after><|endoftext|>