<commit_before>/*jslint jquery:true*/
/*global test,module,deepEqual,equal,core*/
(function($) {
  'use strict';

  /*
    ======== A Handy Little QUnit Reference ========
    http://api.qunitjs.com/

    Test methods:
      module(name, {[setup][ ,teardown]})
      test(name, callback)
      expect(numberOfAssertions)
      stop(increment)
      start(decrement)
    Test assertions:
      ok(value, [message])
      equal(actual, expected, [message])
      notEqual(actual, expected, [message])
      deepEqual(actual, expected, [message])
      notDeepEqual(actual, expected, [message])
      strictEqual(actual, expected, [message])
      notStrictEqual(actual, expected, [message])
      throws(block, [expected], [message])
  */

  module('jQuery#core', {
    // This will run before each test in this module.
    setup: function() {
      this.elems = $('#qunit-fixture').children();
    }
  });

  test('ord', function() {
    var i,str,ones,tens,ord;

    equal(core.ord(3), 'rd', 'should be rd.');
    for(i=1;i<120;i++){
      str = i.toString();
      ones = str.slice(-1);
      tens = str.length > 1 ? str.slice(-2).charAt(0) : 0;
      ord = 'th';
      if(ones==='1' && tens!=='1'){
        ord = 'st';
      }
      if(ones==='2' && tens!=='1'){
        ord = 'nd';
      }
      if(ones==='3' && tens!=='1'){
        ord = 'rd';
      }
      equal(core.ord(i), ord, 'for '+i+', ones is '+ones+' and tens is '+tens+' so the ord is '+ord+'.');

    }
  });

  test('fnMore',function(){
    var fn1 = function(fnArg){
          this.fn1Arg = fnArg;
          this.fn1Prop = 'fn1';
        },
        fn2 = function(fnArg){
          this.fn2Arg = fnArg;
          this.fn2Prop = 'fn2';
        },
        obj = {
          name:'obj'
        },
        fnMore = core.fnMore(fn1,fn2,obj);

    deepEqual(obj,{name:'obj'},'unmutated object');

    fnMore('an arg');

    deepEqual(
        obj,
        {
            name:'obj',
            fn1Arg:'an arg',
            fn1Prop:'fn1',
            fn2Prop:'fn2',
            fn2Arg:'an arg'
        },
        'mutated object'
    );

  });

}(jQuery));
<commit_msg>removing extra ord test<commit_after>/*jslint jquery:true*/
/*global test,module,deepEqual,equal,core*/
(function($) {
  'use strict';

  /*
    ======== A Handy Little QUnit Reference ========
    http://api.qunitjs.com/

    Test methods:
      module(name, {[setup][ ,teardown]})
      test(name, callback)
      expect(numberOfAssertions)
      stop(increment)
      start(decrement)
    Test assertions:
      ok(value, [message])
      equal(actual, expected, [message])
      notEqual(actual, expected, [message])
      deepEqual(actual, expected, [message])
      notDeepEqual(actual, expected, [message])
      strictEqual(actual, expected, [message])
      notStrictEqual(actual, expected, [message])
      throws(block, [expected], [message])
  */

  module('jQuery#core', {
    // This will run before each test in this module.
    setup: function() {
      this.elems = $('#qunit-fixture').children();
    }
  });

  test('ord', function() {
    var i,str,ones,tens,ord;

    for(i=1;i<120;i++){
      str = i.toString();
      ones = str.slice(-1);
      tens = str.length > 1 ? str.slice(-2).charAt(0) : 0;
      ord = 'th';
      if(ones==='1' && tens!=='1'){
        ord = 'st';
      }
      if(ones==='2' && tens!=='1'){
        ord = 'nd';
      }
      if(ones==='3' && tens!=='1'){
        ord = 'rd';
      }
      equal(core.ord(i), ord, 'for '+i+', ones is '+ones+' and tens is '+tens+' so the ord is '+ord+'.');

    }
  });

  test('fnMore',function(){
    var fn1 = function(fnArg){
          this.fn1Arg = fnArg;
          this.fn1Prop = 'fn1';
        },
        fn2 = function(fnArg){
          this.fn2Arg = fnArg;
          this.fn2Prop = 'fn2';
        },
        obj = {
          name:'obj'
        },
        fnMore = core.fnMore(fn1,fn2,obj);

    deepEqual(obj,{name:'obj'},'unmutated object');

    fnMore('an arg');

    deepEqual(
        obj,
        {
            name:'obj',
            fn1Arg:'an arg',
            fn1Prop:'fn1',
            fn2Prop:'fn2',
            fn2Arg:'an arg'
        },
        'mutated object'
    );

  });

}(jQuery));
<|endoftext|>


<commit_before>'use strict';

module.exports.convertVocab = function(vocab) {

  var refactoredVocab = {};
  refactoredVocab.word = vocab.english.translation;
  var alternateLanguage = vocab.japanese ? 'japanese' : 'korean';

  refactoredVocab.translation = vocab[alternateLanguage].translation;
  refactoredVocab.timesTested = vocab[alternateLanguage].timesTested;
  refactoredVocab.timesCorrect = vocab[alternateLanguage].timesCorrect;
  refactoredVocab.lastTested = vocab[alternateLanguage].lastTested | '';
  return refactoredVocab;
};
<commit_msg>Renames a method<commit_after>'use strict';

module.exports.migrate = function(vocab) {

  var refactoredVocab = {};
  refactoredVocab.word = vocab.english.translation;
  var alternateLanguage = vocab.japanese ? 'japanese' : 'korean';

  refactoredVocab.translation = vocab[alternateLanguage].translation;
  refactoredVocab.timesTested = vocab[alternateLanguage].timesTested;
  refactoredVocab.timesCorrect = vocab[alternateLanguage].timesCorrect;
  refactoredVocab.lastTested = vocab[alternateLanguage].lastTested | '';
  return refactoredVocab;
};
<|endoftext|>


<commit_before>import { configure } from '@storybook/react';
import { setOptions } from '@storybook/addon-options';

setOptions({
  name: 'React Power Select',
  addonPanelInRight: true,
});

// automatically import all files ending in *.stories.js
const req = require.context('../stories', true, /.stories.js$/);
function loadStories() {
  req.keys().forEach((filename) => req(filename));
}

configure(loadStories, module);
<commit_msg>Add github url to demo<commit_after>import { configure } from '@storybook/react';
import { setOptions } from '@storybook/addon-options';

setOptions({
  name: 'React Power Select',
  url: 'https://github.com/selvagsz/react-power-select',
  addonPanelInRight: true,
  enableShortcuts: true,
});

// automatically import all files ending in *.stories.js
const req = require.context('../stories', true, /.stories.js$/);
function loadStories() {
  req.keys().forEach((filename) => req(filename));
}

configure(loadStories, module);
<|endoftext|>


<commit_before><commit_msg>Update constants.js<commit_after><|endoftext|>


<commit_before>"use babel";

const COURSE_TYPES = {
  DARWIN: { courseType: 1, apiType: 1, courseName: "DARWIN" },
  "OL SHORT VIDEO": { courseType: 19, apiType: 24, courseName: "OL SHORT VIDEO" },
  LT: { courseType: 2, apiType: 2, courseName: "LT" },
  PT: { courseType: 3, apiType: 3, courseName: "PT" },
  OCC: { courseType: 4, apiType: 4, courseName: "OCC" },
  BE: { courseType: 4, apiType: 5, courseName: "BE" },
  PILOT: { courseType: 4, apiType: 6, courseName: "PILOT" },
  PHONICS: { courseType: 5, apiType: 7, courseName: "PHONICS" },
  BELL: { courseType: 6, apiType: 8, courseName: "BELL" },
  TOURISM: { courseType: 1, apiType: 9, courseName: "TOURISM" },
  LINGOCHAMP: { courseType: 7, apiType: 10, courseName: "LINGOCHAMP" },
  "DARWIN BUSINESS": {
    courseType: 1,
    apiType: 9,
    courseName: "DARWIN BUSINESS"
  },
  "DARWIN HIFI": { courseType: 1, apiType: 15, courseName: "DARWIN HIFI" },
  "DARWIN HOMEWORK": {
    courseType: 1,
    apiType: 17,
    courseName: "DARWIN HOMEWORK"
  },
  AIX: { courseType: 15, apiType: 18, courseName: "AIX" },
  "SPROUT DAILY READERS": {
    courseType: 16,
    apiType: 19,
    courseName: "SPROUT DAILY READERS"
  },
  "Darwin PvP": { courseType: 1, apiType: 20, courseName: "Darwin PvP" },
  "SPROUT WORD COURSE": {
    courseType: 17,
    apiType: 21,
    courseName: "SPROUT DAILY WORDS"
  },
  "SPROUT EXTENSION":{
    courseType: 18,
    apiType: 22,
    courseName: "SPROUT EXTENSION"
  },
  "SPROUT GOODNIGHT": {
    courseType: 18,
    apiType: 23,
    courseName: "SPROUT GOODNIGHT"
  },
};

export default COURSE_TYPES;
<commit_msg>feat: cms-1579 (#209)<commit_after>"use babel";

const COURSE_TYPES = {
  DARWIN: { courseType: 1, apiType: 1, courseName: "DARWIN" },
  "OL SHORT VIDEO": { courseType: 19, apiType: 24, courseName: "OL SHORT VIDEO" },
  LT: { courseType: 2, apiType: 2, courseName: "LT" },
  PT: { courseType: 3, apiType: 3, courseName: "PT" },
  OCC: { courseType: 4, apiType: 4, courseName: "OCC" },
  BE: { courseType: 4, apiType: 5, courseName: "BE" },
  PILOT: { courseType: 4, apiType: 6, courseName: "PILOT" },
  PHONICS: { courseType: 5, apiType: 7, courseName: "PHONICS" },
  BELL: { courseType: 6, apiType: 8, courseName: "BELL" },
  TOURISM: { courseType: 1, apiType: 9, courseName: "TOURISM" },
  LINGOCHAMP: { courseType: 7, apiType: 10, courseName: "LINGOCHAMP" },
  "DARWIN BUSINESS": {
    courseType: 1,
    apiType: 9,
    courseName: "DARWIN BUSINESS"
  },
  "DARWIN EXTENSION": { courseType: 1, apiType: 26, courseName: "DARWIN EXTENSION" },
  "DARWIN HIFI": { courseType: 1, apiType: 15, courseName: "DARWIN HIFI" },
  "DARWIN HOMEWORK": {
    courseType: 1,
    apiType: 17,
    courseName: "DARWIN HOMEWORK"
  },
  AIX: { courseType: 15, apiType: 18, courseName: "AIX" },
  "SPROUT DAILY READERS": {
    courseType: 16,
    apiType: 19,
    courseName: "SPROUT DAILY READERS"
  },
  "Darwin PvP": { courseType: 1, apiType: 20, courseName: "Darwin PvP" },
  "SPROUT WORD COURSE": {
    courseType: 17,
    apiType: 21,
    courseName: "SPROUT DAILY WORDS"
  },
  "SPROUT EXTENSION":{
    courseType: 18,
    apiType: 22,
    courseName: "SPROUT EXTENSION"
  },
  "SPROUT GOODNIGHT": {
    courseType: 18,
    apiType: 23,
    courseName: "SPROUT GOODNIGHT"
  },
};

export default COURSE_TYPES;
<|endoftext|>


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

  if (typeof sigma === 'undefined')
    throw 'sigma is not declared';

  /**
   * Sigma ForceAtlas2.5 Webworker
   * ==============================
   *
   * Author: Guillaume Plique (Yomguithereal)
   * Algorithm author: Mathieu Jacomy @ Sciences Po Medialab & WebAtlas
   * Version: 0.1
   */

  /**
   * Worker Function Wrapper
   * ------------------------
   *
   * The worker has to be wrapped into a single stringified function
   * to be passed afterwards as a BLOB object to the supervisor.
   */
  var Worker = function(undefined) {
    'use strict';

    /**
     * Worker settings and namespace
     */
    var W = {
      ppn: 10,
      ppe: 3,
      maxForce: 10,
      iterations: 0,
      settings: {
        linLogMode: false,
        outboundAttractionDistribution: false,
        adjustSizes: false,
        edgeWeightInfluence: 0,
        scalingRatio: 1,
        strongGravityMode: false,
        gravity: 1,
        barnesHutOptimize: false,
        barnesHutTheta: 1.2,
        outboundAttCompensation: 1,
        totalSwinging: 0,
        totalEffectiveTraction: 0,
        speedEfficiency: 1,
        complexIntervals: 500,
        simpleIntervals: 1000,
        converged: false
      }
    };

    /**
     * Helpers namespace
     */
    var helpers = {
      extend: function() {
        var i,
            k,
            res = {},
            l = arguments.length;

        for (i = l - 1; i >= 0; i--)
          for (k in arguments[i])
            res[k] = arguments[i][k];
        return res;
      }
    };

    /**
     * Matrices properties accessors
     */
    var nodeProperties = {
      x: 0,
      y: 1,
      dx: 2,
      dy: 3,
      old_dx: 4,
      old_dy: 5,
      mass: 6,
      convergence: 7,
      size: 8,
      fixed: 9
    };

    var edgeProperties = {
      source: 0,
      target: 1,
      weight: 2
    };

    function np(i, p) {

      // DEBUG: safeguards
      if ((i % W.ppn) !== 0)
        throw 'np: non correct (' + i + ').';
      if (i !== parseInt(i))
        throw '_np: non int.';

      if (p in nodeProperties)
        return i + nodeProperties[p];
      else
        throw 'ForceAtlas2.Worker - ' +
              'Inexistant node property given (' + p + ').';
    }

    function ep(i, p) {

      // DEBUG: safeguards
      if ((i % W.ppe) !== 0)
        throw 'ep: non correct (' + i + ').';
      if (i !== parseInt(i))
        throw 'ep: non int.';

      if (p in edgeProperties)
        return i + edgeProperties[p];
      else
        throw 'ForceAtlas2.Worker - ' +
              'Inexistant edge property given (' + p + ').';
    }

    // DEBUG
    function nan(v) {
      if (isNaN(v))
        throw 'NaN alert!';
    }

    /**
     * Barnes-Hut functions
     */

    var barnesHutDepthLimit = 20;

    function Region(nodes, depth) {
      var n, l, mass, size, distance;

      // Region
      var r = {
        size: 0,
        nodes: nodes,
        subregions: [],
        depth: depth,
        mass: 0,
        massCenterX: 0,
        massCenterY: 0,
        massSumX: 0,
        massSumY: 0
      };

      // Updating mass and geometry
      if (r.nodes.length > 1) {

        // Iterating through nodes
        for (n = 0, l = r.nodes.length; n < l; n++) {
          mass = W.nodeMatrix[np(n, 'mass')];
          r.mass += mass;
          r.massSumX += W.nodeMatrix[np(n, 'x')] * mass;
          r.massSumY += W.nodeMatrix[np(n, 'y')] * mass;
        }

        var massCenterX = r.massSumX / r.mass,
            massCenterY = r.massSumY / r.mass;

        // Computing size
        // MATH: something is amiss in the max thingy under here
        for (i = 0, l = r.nodes.length; n < l; n++) {
          distance = 2 * Math.sqrt(
            Math.pow((W.nodeMatrix[np(n, 'x')] - r.massCenterX), 2) +
            Math.pow((W.nodeMatrix[np(n, 'y')] - r.massCenterY), 2)
          );
          size = (size === undefined) ?
            distance :
            Math.max(size, distance);
        }
      }

      // Finalizing region
      r.massCenterX = massCenterX;
      r.massCenterY = massCenterY;
      r.size = size;

      return r;
    }

    /**
     * Algorithm initialization
     */

    // TODO: autosettings
    function init(nodes, edges, config) {
      var i, l;

      // Matrices
      W.nodeMatrix = nodes;
      W.edgeMatrix = edges;

      // Length
      W.nodesLength = W.nodeMatrix.length;
      W.edgesLength = W.edgeMatrix.length;
    }

    /**
     * Algorithm pass
     */

    // MATH: get distances stuff and power 2 issues
    function pass() {
      var n, n1, n2, e, s, t, w;

      var rootRegion,
          outboundAttCompensation;

      // 1) Initializing layout data
      //-----------------------------

      // Resetting positions
      for (n = 0; n < W.nodesLength; n += W.ppn) {
        W.nodeMatrix[np(n, 'old_dx')] = W.nodeMatrix[np(n, 'dx')];
        W.nodeMatrix[np(n, 'old_dy')] = W.nodeMatrix[np(n, 'dy')];
        W.nodeMatrix[np(n, 'dx')] = 0;
        W.nodeMatrix[np(n, 'dy')] = 0;
      }

      // Barnes-Hut root region
      if (W.settings.barnesHutOptimize) {

        // TODO: build region and subregions
      }

      // If outbound attraction distribution, compensate
      if (W.settings.outboundAttractionDistribution) {
        outboundAttCompensation = 0;
        for (n = 0, l = W.nodes.length; n < l; n++) {
          outboundAttCompensation += W.nodeMatrix[np(n, 'mass')];
        }

        outboundAttCompensation /= l;
      }

      // 2) Repulsion
      //--------------

      if (W.settings.barnesHutOptimize) {

        // TODO: apply forces to regions
      }
      else {

        // Square iteration
        for (n1 = 0; n1 < W.nodesLength; n1 += W.ppn) {
          for (n2 = 0; n2 < W.nodesLength; n2 += W.ppn) {

            // TODO: apply repulsion
          }
        }
      }

      // 3) Gravity
      //------------
      for (n = 0; n < W.nodesLength; n += W.ppn) {

        // TODO: apply gravity
      }

      // 4) Attraction
      //---------------
      for (e = 0; e < W.edgesLength; e += W.ppe) {
        s = W.edgeMatrix[ep(e, 'source')];
        t = W.edgeMatrix[ep(e, 'target')];
        w = W.edgeMatrix[ep(e, 'weight')];

        // TODO: apply attraction
      }

      // 5) Apply Forces
      //-----------------
      var force,
          swinging,
          traction,
          nodespeed;

      // MATH: sqrt and square distances
      if (W.settings.adjustSizes) {

        for (n = 0; n < W.nodesLength; n += W.ppn) {
          if (!W.nodeMatrix[np(n, 'fixed')]) {
            force = Math.sqrt(
              Math.pow(W.nodeMatrix[np(n, 'dx')], 2) +
              Math.pow(W.nodeMatrix[np(n, 'dy')], 2)
            );

            if (force > W.maxForce) {
              W.nodeMatrix[np(n, 'dx')] =
                W.nodeMatrix[np(n, 'dx')] * maxForce / force;
              W.nodeMatrix[np(n, 'dy')] =
                W.nodeMatrix[np(n, 'dy')] * maxForce / force;
            }

            swinging = W.nodeMatrix[np(n, 'mass')] *
              Math.sqrt(
                (W.nodeMatrix[np(n, 'old_dx')] - W.nodeMatrix[np(n, 'dx')]) *
                (W.nodeMatrix[np(n, 'old_dx')] - W.nodeMatrix[np(n, 'dx')]) +
                (W.nodeMatrix[np(n, 'old_dy')] - W.nodeMatrix[np(n, 'dy')]) *
                (W.nodeMatrix[np(n, 'old_dy')] - W.nodeMatrix[np(n, 'dy')])
              );

            traction = Math.sqrt(
              (W.nodeMatrix[np(n, 'old_dx')] + W.nodeMatrix[np(n, 'dx')]) *
              (W.nodeMatrix[np(n, 'old_dx')] + W.nodeMatrix[np(n, 'dx')]) +
              (W.nodeMatrix[np(n, 'old_dy')] + W.nodeMatrix[np(n, 'dy')]) *
              (W.nodeMatrix[np(n, 'old_dy')] + W.nodeMatrix[np(n, 'dy')])
            ) / 2;

            nodespeed =
              0.1 * Math.log(1 + traction) / (1 + Math.sqrt(swinging));

            // Updating node's positon
            W.nodeMatrix[np(n, 'x')] =
              W.nodeMatrix[np(n, 'x')] + W.nodeMatrix[np(n, 'dx')] * nodespeed;
            W.nodeMatrix[np(n, 'y')] =
              W.nodeMatrix[np(n, 'y')] + W.nodeMatrix[np(n, 'dy')] * nodespeed;
          }
        }
      }
      else {

        for (n = 0; n < W.nodesLength; n += W.ppn) {
          if (!W.nodeMatrix[np(n, 'fixed')]) {

            swinging = W.nodeMatrix[np(n, 'mass')] *
              Math.sqrt(
                (W.nodeMatrix[np(n, 'old_dx')] - W.nodeMatrix[np(n, 'dx')]) *
                (W.nodeMatrix[np(n, 'old_dx')] - W.nodeMatrix[np(n, 'dx')]) +
                (W.nodeMatrix[np(n, 'old_dy')] - W.nodeMatrix[np(n, 'dy')]) *
                (W.nodeMatrix[np(n, 'old_dy')] - W.nodeMatrix[np(n, 'dy')])
              );

            traction = Math.sqrt(
              (W.nodeMatrix[np(n, 'old_dx')] + W.nodeMatrix[np(n, 'dx')]) *
              (W.nodeMatrix[np(n, 'old_dx')] + W.nodeMatrix[np(n, 'dx')]) +
              (W.nodeMatrix[np(n, 'old_dy')] + W.nodeMatrix[np(n, 'dy')]) *
              (W.nodeMatrix[np(n, 'old_dy')] + W.nodeMatrix[np(n, 'dy')])
            ) / 2;

            nodespeed = W.nodeMatrix[np(n, 'convergence')] *
              Math.log(1 + traction) / (1 + Math.sqrt(swinging));

            // Updating node convergence
            W.nodeMatrix[np(n, 'convergence')] =
              Math.min(1, Math.sqrt(
                nodespeed *
                (Math.pow(W.nodeMatrix[np(n, 'dx')], 2) +
                 Math.pow(W.nodeMatrix[np(n, 'dy')], 2)) /
                (1 + Math.sqrt(swinging))
              ));

            // Updating node's positon
            W.nodeMatrix[np(n, 'x')] =
              W.nodeMatrix[np(n, 'x')] + W.nodeMatrix[np(n, 'dx')] * nodespeed;
            W.nodeMatrix[np(n, 'y')] =
              W.nodeMatrix[np(n, 'y')] + W.nodeMatrix[np(n, 'dy')] * nodespeed;
          }
        }
      }

      // Counting one more iteration
      W.iterations++;
    }

    /**
     * Message reception & sending
     */

    // Sending data back to the supervisor
    var sendNewCoords;

    if (typeof window !== 'undefined' && window.document) {

      // From same document as sigma
      sendNewCoords = function() {
        var e = new Event('newCoords');
        e.data = {
          nodes: W.nodeMatrix.buffer
        };
        requestAnimationFrame(function() {
          document.dispatchEvent(e);
        });
      };
    }
    else {

      // From a WebWorker
      sendNewCoords = function() {
        self.postMessage(
          {nodes: W.nodeMatrix.buffer},
          [W.nodeMatrix.buffer]
        );
      };
    }

    // One algorithm pass
    function run() {
      pass();
      sendNewCoords();
    }

    // On supervisor message
    self.addEventListener('message', function(e) {
      switch (e.data.action) {
        case 'start':
          init(
            new Float32Array(e.data.nodes),
            new Float32Array(e.data.edges),
            e.data.config
          );

          // First iteration
          run();
          break;

        case 'loop':
          W.nodeMatrix = new Float32Array(e.data.nodes);
          run();
          break;

        default:
      }
    });
  };

  /**
   * Exporting
   * ----------
   *
   * Crush the worker function and make it accessible by sigma's instances so
   * the supervisor can call it.
   */
  function crush(fnString) {
    var pattern,
        i,
        l;

    var np = [
      'x',
      'y',
      'dx',
      'dy',
      'old_dx',
      'old_dy',
      'mass',
      'convergence',
      'size',
      'fixed'
    ];

    var ep = [
      'source',
      'target',
      'weight'
    ];

    // Replacing matrix accessors by incremented indexes
    for (i = 0, l = np.length; i < l; i++) {
      pattern = new RegExp('np\\(([^,]*), \'' + np[i] + '\'\\)', 'g');
      fnString = fnString.replace(
        pattern,
        (i === 0) ? '$1' : '$1 + ' + i
      );
    }

    for (i = 0, l = ep.length; i < l; i++) {
      pattern = new RegExp('ep\\(([^,]*), \'' + ep[i] + '\'\\)', 'g');
      fnString = fnString.replace(
        pattern,
        (i === 0) ? '$1' : '$1 + ' + i
      );
    }

    return fnString;
  }

  sigma.prototype.getForceAtlas2Worker = function() {
    return ';(' + crush(Worker.toString()) + ').call(this);';
  };
}).call(this);
<commit_msg>Linear repulsion<commit_after>;(function(undefined) {
  'use strict';

  if (typeof sigma === 'undefined')
    throw 'sigma is not declared';

  /**
   * Sigma ForceAtlas2.5 Webworker
   * ==============================
   *
   * Author: Guillaume Plique (Yomguithereal)
   * Algorithm author: Mathieu Jacomy @ Sciences Po Medialab & WebAtlas
   * Version: 0.1
   */

  /**
   * Worker Function Wrapper
   * ------------------------
   *
   * The worker has to be wrapped into a single stringified function
   * to be passed afterwards as a BLOB object to the supervisor.
   */
  var Worker = function(undefined) {
    'use strict';

    /**
     * Worker settings and namespace
     */
    var W = {
      ppn: 10,
      ppe: 3,
      maxForce: 10,
      iterations: 0,
      settings: {
        linLogMode: false,
        outboundAttractionDistribution: false,
        adjustSizes: false,
        edgeWeightInfluence: 0,
        scalingRatio: 1,
        strongGravityMode: false,
        gravity: 1,
        barnesHutOptimize: false,
        barnesHutTheta: 1.2,
        outboundAttCompensation: 1,
        totalSwinging: 0,
        totalEffectiveTraction: 0,
        speedEfficiency: 1,
        complexIntervals: 500,
        simpleIntervals: 1000,
        converged: false
      }
    };

    /**
     * Helpers namespace
     */
    var helpers = {
      extend: function() {
        var i,
            k,
            res = {},
            l = arguments.length;

        for (i = l - 1; i >= 0; i--)
          for (k in arguments[i])
            res[k] = arguments[i][k];
        return res;
      }
    };

    /**
     * Matrices properties accessors
     */
    var nodeProperties = {
      x: 0,
      y: 1,
      dx: 2,
      dy: 3,
      old_dx: 4,
      old_dy: 5,
      mass: 6,
      convergence: 7,
      size: 8,
      fixed: 9
    };

    var edgeProperties = {
      source: 0,
      target: 1,
      weight: 2
    };

    function np(i, p) {

      // DEBUG: safeguards
      if ((i % W.ppn) !== 0)
        throw 'np: non correct (' + i + ').';
      if (i !== parseInt(i))
        throw '_np: non int.';

      if (p in nodeProperties)
        return i + nodeProperties[p];
      else
        throw 'ForceAtlas2.Worker - ' +
              'Inexistant node property given (' + p + ').';
    }

    function ep(i, p) {

      // DEBUG: safeguards
      if ((i % W.ppe) !== 0)
        throw 'ep: non correct (' + i + ').';
      if (i !== parseInt(i))
        throw 'ep: non int.';

      if (p in edgeProperties)
        return i + edgeProperties[p];
      else
        throw 'ForceAtlas2.Worker - ' +
              'Inexistant edge property given (' + p + ').';
    }

    // DEBUG
    function nan(v) {
      if (isNaN(v))
        throw 'NaN alert!';
    }

    /**
     * Barnes-Hut functions
     */

    var barnesHutDepthLimit = 20;

    function Region(nodes, depth) {
      var n, l, mass, size, distance;

      // Region
      var r = {
        size: 0,
        nodes: nodes,
        subregions: [],
        depth: depth,
        mass: 0,
        massCenterX: 0,
        massCenterY: 0,
        massSumX: 0,
        massSumY: 0
      };

      // Updating mass and geometry
      if (r.nodes.length > 1) {

        // Iterating through nodes
        for (n = 0, l = r.nodes.length; n < l; n++) {
          mass = W.nodeMatrix[np(n, 'mass')];
          r.mass += mass;
          r.massSumX += W.nodeMatrix[np(n, 'x')] * mass;
          r.massSumY += W.nodeMatrix[np(n, 'y')] * mass;
        }

        var massCenterX = r.massSumX / r.mass,
            massCenterY = r.massSumY / r.mass;

        // Computing size
        // MATH: something is amiss in the max thingy under here
        for (i = 0, l = r.nodes.length; n < l; n++) {
          distance = 2 * Math.sqrt(
            Math.pow((W.nodeMatrix[np(n, 'x')] - r.massCenterX), 2) +
            Math.pow((W.nodeMatrix[np(n, 'y')] - r.massCenterY), 2)
          );
          size = (size === undefined) ?
            distance :
            Math.max(size, distance);
        }
      }

      // Finalizing region
      r.massCenterX = massCenterX;
      r.massCenterY = massCenterY;
      r.size = size;

      return r;
    }

    /**
     * Algorithm initialization
     */

    // TODO: autosettings
    function init(nodes, edges, config) {
      var i, l;

      // Matrices
      W.nodeMatrix = nodes;
      W.edgeMatrix = edges;

      // Length
      W.nodesLength = W.nodeMatrix.length;
      W.edgesLength = W.edgeMatrix.length;
    }

    /**
     * Algorithm pass
     */

    // MATH: get distances stuff and power 2 issues
    function pass() {
      var n, n1, n2, e, s, t, w;

      var rootRegion,
          outboundAttCompensation,
          xDist,
          yDist,
          distance,
          factor;

      // 1) Initializing layout data
      //-----------------------------

      // Resetting positions
      for (n = 0; n < W.nodesLength; n += W.ppn) {
        W.nodeMatrix[np(n, 'old_dx')] = W.nodeMatrix[np(n, 'dx')];
        W.nodeMatrix[np(n, 'old_dy')] = W.nodeMatrix[np(n, 'dy')];
        W.nodeMatrix[np(n, 'dx')] = 0;
        W.nodeMatrix[np(n, 'dy')] = 0;
      }

      // Barnes-Hut root region
      if (W.settings.barnesHutOptimize) {

        // TODO: build region and subregions
      }

      // If outbound attraction distribution, compensate
      if (W.settings.outboundAttractionDistribution) {
        outboundAttCompensation = 0;
        for (n = 0, l = W.nodes.length; n < l; n++) {
          outboundAttCompensation += W.nodeMatrix[np(n, 'mass')];
        }

        outboundAttCompensation /= l;
      }

      // 2) Repulsion
      //--------------
      // NOTES: adjustSize = antiCollision & scalingRatio = coefficient

      if (W.settings.barnesHutOptimize) {

        // TODO: apply forces to regions
      }
      else {

        // Square iteration
        for (n1 = 0; n1 < W.nodesLength; n1 += W.ppn) {
          for (n2 = 0; n2 < W.nodesLength; n2 += W.ppn) {

            // Common to both methods
            xDist = W.nodeMatrix[np(n1, 'x')] - W.nodeMatrix[np(n2, 'x')];
            yDist = W.nodeMatrix[np(n1, 'y')] - W.nodeMatrix[np(n2, 'y')];

            if (W.settings.adjustSize) {

              //-- Anticollision Linear Repulsion
              distance = Math.sqrt(xDist * xDist + yDist * yDist) -
                W.nodeMatrix[np(n1, 'size')] -
                W.nodeMatrix[np(n2, 'size')];

              if (distance > 0) {
                factor = W.settings.scalingRatio *
                  W.nodeMatrix[np(n1, 'mass')] *
                  W.nodeMatrix[np(n2, 'mass')] /
                  distance / distance;

                // Updating nodes' dx and dy
                W.nodeMatrix[np(n1, 'dx')] += xDist * factor;
                W.nodeMatrix[np(n1, 'dy')] += yDist * factor;

                W.nodeMatrix[np(n2, 'dx')] += xDist * factor;
                W.nodeMatrix[np(n2, 'dy')] += yDist * factor;
              }
              else if (distance < 0) {
                factor = 100 * W.settings.scalingRatio *
                  W.nodeMatrix[np(n1, 'mass')] *
                  W.nodeMatrix[np(n2, 'mass')];

                // Updating nodes' dx and dy
                W.nodeMatrix[np(n1, 'dx')] += xDist * factor;
                W.nodeMatrix[np(n1, 'dy')] += yDist * factor;

                W.nodeMatrix[np(n2, 'dx')] += xDist * factor;
                W.nodeMatrix[np(n2, 'dy')] += yDist * factor;
              }
            }
            else {

              //-- Linear Repulsion
              distance = Math.sqrt(xDist * xDist + yDist * yDist);

              if (distance > 0) {
                factor = W.settings.scalingRatio *
                  W.nodeMatrix[np(n1, 'mass')] *
                  W.nodeMatrix[np(n2, 'mass')] /
                  distance / distance;

                // Updating nodes' dx and dy
                W.nodeMatrix[np(n1, 'dx')] += xDist * factor;
                W.nodeMatrix[np(n1, 'dy')] += yDist * factor;

                W.nodeMatrix[np(n2, 'dx')] += xDist * factor;
                W.nodeMatrix[np(n2, 'dy')] += yDist * factor;
              }
            }
          }
        }
      }

      // 3) Gravity
      //------------
      for (n = 0; n < W.nodesLength; n += W.ppn) {

        // TODO: apply gravity
      }

      // 4) Attraction
      //---------------
      for (e = 0; e < W.edgesLength; e += W.ppe) {
        s = W.edgeMatrix[ep(e, 'source')];
        t = W.edgeMatrix[ep(e, 'target')];
        w = W.edgeMatrix[ep(e, 'weight')];

        // TODO: apply attraction
      }

      // 5) Apply Forces
      //-----------------
      var force,
          swinging,
          traction,
          nodespeed;

      // MATH: sqrt and square distances
      if (W.settings.adjustSizes) {

        for (n = 0; n < W.nodesLength; n += W.ppn) {
          if (!W.nodeMatrix[np(n, 'fixed')]) {
            force = Math.sqrt(
              Math.pow(W.nodeMatrix[np(n, 'dx')], 2) +
              Math.pow(W.nodeMatrix[np(n, 'dy')], 2)
            );

            if (force > W.maxForce) {
              W.nodeMatrix[np(n, 'dx')] =
                W.nodeMatrix[np(n, 'dx')] * maxForce / force;
              W.nodeMatrix[np(n, 'dy')] =
                W.nodeMatrix[np(n, 'dy')] * maxForce / force;
            }

            swinging = W.nodeMatrix[np(n, 'mass')] *
              Math.sqrt(
                (W.nodeMatrix[np(n, 'old_dx')] - W.nodeMatrix[np(n, 'dx')]) *
                (W.nodeMatrix[np(n, 'old_dx')] - W.nodeMatrix[np(n, 'dx')]) +
                (W.nodeMatrix[np(n, 'old_dy')] - W.nodeMatrix[np(n, 'dy')]) *
                (W.nodeMatrix[np(n, 'old_dy')] - W.nodeMatrix[np(n, 'dy')])
              );

            traction = Math.sqrt(
              (W.nodeMatrix[np(n, 'old_dx')] + W.nodeMatrix[np(n, 'dx')]) *
              (W.nodeMatrix[np(n, 'old_dx')] + W.nodeMatrix[np(n, 'dx')]) +
              (W.nodeMatrix[np(n, 'old_dy')] + W.nodeMatrix[np(n, 'dy')]) *
              (W.nodeMatrix[np(n, 'old_dy')] + W.nodeMatrix[np(n, 'dy')])
            ) / 2;

            nodespeed =
              0.1 * Math.log(1 + traction) / (1 + Math.sqrt(swinging));

            // Updating node's positon
            W.nodeMatrix[np(n, 'x')] =
              W.nodeMatrix[np(n, 'x')] + W.nodeMatrix[np(n, 'dx')] * nodespeed;
            W.nodeMatrix[np(n, 'y')] =
              W.nodeMatrix[np(n, 'y')] + W.nodeMatrix[np(n, 'dy')] * nodespeed;
          }
        }
      }
      else {

        for (n = 0; n < W.nodesLength; n += W.ppn) {
          if (!W.nodeMatrix[np(n, 'fixed')]) {

            swinging = W.nodeMatrix[np(n, 'mass')] *
              Math.sqrt(
                (W.nodeMatrix[np(n, 'old_dx')] - W.nodeMatrix[np(n, 'dx')]) *
                (W.nodeMatrix[np(n, 'old_dx')] - W.nodeMatrix[np(n, 'dx')]) +
                (W.nodeMatrix[np(n, 'old_dy')] - W.nodeMatrix[np(n, 'dy')]) *
                (W.nodeMatrix[np(n, 'old_dy')] - W.nodeMatrix[np(n, 'dy')])
              );

            traction = Math.sqrt(
              (W.nodeMatrix[np(n, 'old_dx')] + W.nodeMatrix[np(n, 'dx')]) *
              (W.nodeMatrix[np(n, 'old_dx')] + W.nodeMatrix[np(n, 'dx')]) +
              (W.nodeMatrix[np(n, 'old_dy')] + W.nodeMatrix[np(n, 'dy')]) *
              (W.nodeMatrix[np(n, 'old_dy')] + W.nodeMatrix[np(n, 'dy')])
            ) / 2;

            nodespeed = W.nodeMatrix[np(n, 'convergence')] *
              Math.log(1 + traction) / (1 + Math.sqrt(swinging));

            // Updating node convergence
            W.nodeMatrix[np(n, 'convergence')] =
              Math.min(1, Math.sqrt(
                nodespeed *
                (Math.pow(W.nodeMatrix[np(n, 'dx')], 2) +
                 Math.pow(W.nodeMatrix[np(n, 'dy')], 2)) /
                (1 + Math.sqrt(swinging))
              ));

            // Updating node's positon
            W.nodeMatrix[np(n, 'x')] =
              W.nodeMatrix[np(n, 'x')] + W.nodeMatrix[np(n, 'dx')] * nodespeed;
            W.nodeMatrix[np(n, 'y')] =
              W.nodeMatrix[np(n, 'y')] + W.nodeMatrix[np(n, 'dy')] * nodespeed;
          }
        }
      }

      // Counting one more iteration
      W.iterations++;
    }

    /**
     * Message reception & sending
     */

    // Sending data back to the supervisor
    var sendNewCoords;

    if (typeof window !== 'undefined' && window.document) {

      // From same document as sigma
      sendNewCoords = function() {
        var e = new Event('newCoords');
        e.data = {
          nodes: W.nodeMatrix.buffer
        };
        requestAnimationFrame(function() {
          document.dispatchEvent(e);
        });
      };
    }
    else {

      // From a WebWorker
      sendNewCoords = function() {
        self.postMessage(
          {nodes: W.nodeMatrix.buffer},
          [W.nodeMatrix.buffer]
        );
      };
    }

    // One algorithm pass
    function run() {
      pass();
      sendNewCoords();
    }

    // On supervisor message
    self.addEventListener('message', function(e) {
      switch (e.data.action) {
        case 'start':
          init(
            new Float32Array(e.data.nodes),
            new Float32Array(e.data.edges),
            e.data.config
          );

          // First iteration
          run();
          break;

        case 'loop':
          W.nodeMatrix = new Float32Array(e.data.nodes);
          run();
          break;

        default:
      }
    });
  };

  /**
   * Exporting
   * ----------
   *
   * Crush the worker function and make it accessible by sigma's instances so
   * the supervisor can call it.
   */
  function crush(fnString) {
    var pattern,
        i,
        l;

    var np = [
      'x',
      'y',
      'dx',
      'dy',
      'old_dx',
      'old_dy',
      'mass',
      'convergence',
      'size',
      'fixed'
    ];

    var ep = [
      'source',
      'target',
      'weight'
    ];

    // Replacing matrix accessors by incremented indexes
    for (i = 0, l = np.length; i < l; i++) {
      pattern = new RegExp('np\\(([^,]*), \'' + np[i] + '\'\\)', 'g');
      fnString = fnString.replace(
        pattern,
        (i === 0) ? '$1' : '$1 + ' + i
      );
    }

    for (i = 0, l = ep.length; i < l; i++) {
      pattern = new RegExp('ep\\(([^,]*), \'' + ep[i] + '\'\\)', 'g');
      fnString = fnString.replace(
        pattern,
        (i === 0) ? '$1' : '$1 + ' + i
      );
    }

    return fnString;
  }

  sigma.prototype.getForceAtlas2Worker = function() {
    return ';(' + crush(Worker.toString()) + ').call(this);';
  };
}).call(this);
<|endoftext|>


<commit_before>// namespace
var GNOVEL = GNOVEL || {};

(function() {
	"use strict";

	/**
	 * @class  Flow
	 * @constructor
	 */
	var Flow = function(page) {
		this._page = page;
		this._objs = [];
		this._customHandlers = {};

		this._reset();
	};

	Flow.prototype._reset = function() {
		this._flowCounter = 0;
		this._elements = null;
		this._labels = [];
		this._storedData = [];

		console.log("flow is reset");
	};

	Flow.DIALOG = "dialog";
	Flow.CHOICES = "choices";
	Flow.SHOW = "show";
	Flow.HIDE = "hide";
	Flow.GOTO = "goto";
	Flow.COMPARE = "compare";
	Flow.JUMP = "jump";
	Flow.CUSTOM = "custom";
	Flow.NOTHING = "nothing";

	Flow.prototype._set = function(flowElements) {
		this._reset();

		if(flowElements == null)
			flowElements = [];

		this._elements = flowElements;
		this._processLabels();
	};

	Flow.prototype._getPage = function() {
		return this._page;
	};

	Flow.prototype._jump = function(index) {
		this._flowCounter = index - 1;
		this._next();
	};

	Flow.prototype._peekNext = function() {
		if(this._elements === null)
			return null;

		return this._elements[this._flowCounter + 1];
	};

	Flow.prototype._exec = function() {
		var obj = this._elements[this._flowCounter];

		// hack
		if(obj == null)
			return;

		this._processParameters(obj);

		var type = obj.type;

		switch(type) {
			case Flow.DIALOG:
				this._handleDialog(obj);
				break;
			case Flow.CHOICES:
				this._handleChoices(obj);
				break;
			case Flow.SHOW:
				this._handleShow(obj);
				break;
			case Flow.HIDE:
				this._handleHide(obj);
				break;
			case Flow.GOTO:
				this._handleGoto(obj);
				break;
			case Flow.COMPARE:
				this._handleCompare(obj);
				break;
			case Flow.JUMP:
				this._handleJump(obj);
				break;
			case Flow.CUSTOM:
				this._handleCustom(obj);
				break;
			case Flow.NOTHING:
				this._handleNothing(obj);
				break;
			default:
				// if we have custom handler for that flow element
				if(this._customHandlers[type]) {
					this._customHandlers[type](obj, this);
				}
				break;
		}
	};

	Flow.prototype._next = function() {
		this._flowCounter++;
	};

	Flow.prototype._processLabels = function() {
		for(var i = 0; i < this._elements.length;i++) {
			var e = this._elements[i];
			if(e.label != null) {
				var label = e.label;
				this._labels[label] = i;
			}
		};
	};

	Flow.prototype._processParameters = function(obj) {
		// iterate over all properties in the obj
		for (var prop in obj) {
			if(obj.hasOwnProperty(prop)) {
				// check if this property's value start with '#'
				// which would mark this value as a label of other
				// flow element

				if(typeof (obj[prop]) === "string") {
					// check if it starts with '#'
					var c = obj[prop].charAt(0);
					if(c == '#') {
						// search for that label in labels dictionary

						var label = obj[prop].substring(1);
						var value = this._labels[label];

						if(typeof value === 'undefined' || value === null)
							console.log("cannot find " + label);

						obj[prop] = value;
					} else if(c == '%') {
						// search for that label in objs dictionary

						var label = obj[prop].substring(1);
						var value = this._objs[label];

						if(typeof value === 'undefined' || value === null)
							console.log("cannot find " + label);

						obj[prop] = value;
					} else if(c == '$') {
						// search for that label in storedData dictionary

						var label = obj[prop].substring(1);
						var value = this._storedData[label];

						if(typeof value === 'undefined' || value === null)
							console.log("no such data stored in " + label);

						obj[prop] = value;
					}
				} else if(typeof(obj[prop]) === "object") {
					// recurse to this object
					this._processParameters(obj[prop], this);
				}
			}
		}
	};

	Flow.prototype._handleDialog = function(obj) {
		var x = obj.x || 0; // optional
		var y = obj.y || 0; // optional
		var params = {};
		params.speaker = obj.speaker;
		params.charLine = obj.charLine;

		// pass the original flow element to params
		params.flowElement = obj;

		this._page._showDialog(obj.text, x, y, params);
	};

	Flow.prototype._handleChoices = function(obj) {
		var params = {};
		params.x = obj.x || 0; // optional
		params.y = obj.y || -250; // optional
		var page = this._page;

		// collect choices' text to its own array
		var choicesTextArr = [];
		for(var i = 0; i < obj.choices.length; i++) {
			choicesTextArr.push(obj.choices[i].text);
		}

		//array timed responses
		var timerResponseArr = [];
		if(obj.responses!=null){
			for(var i = 0; i < obj.responses.length; i++) {
				timerResponseArr.push(obj.responses[i].text);
			}
		}

		// collect choices' jump to its own array
		var jumpArr = [];
		for(var i=0; i < obj.choices.length;i++) {
			jumpArr.push(obj.choices[i].go);
		}

		// pass the original flow element to params
		params.flowElement = obj;

		//get speaker
		params.speaker = obj.speaker;
		params.charLine = obj.charLine;

		// check whether the choices is time-based
		params.seconds = obj.seconds || 0;

		params.onChoiceComplete = function(resultId) {
			if(obj.choices[resultId].onChoose && typeof obj.choices[resultId].onChoose === 'function') {
				obj.choices[resultId].onChoose(page);
			}
		};

		this._page._showChoices(choicesTextArr, timerResponseArr, params, jumpArr);
		//show time response dialog from speaker
	};

	Flow.prototype._handleShow = function(obj) {
		var img = obj.img;
		var params = {};

		if(obj.waitUntilShown != null) {
			params.waitUntilShown = obj.waitUntilShown;
		}

		// pass the original flow element to params
		params.flowElement = obj;

		this._page._show(img, params);
	};

	Flow.prototype._handleHide = function(obj) {
		var img = obj.img;
		var params = {};

		if(obj.waitUntilHidden != null) {
			params.waitUntilHidden = obj.waitUntilHidden;
		}

		this._page._hide(img, params);
	};

	Flow.prototype._handleGoto = function(obj) {
		var pageIndex = obj.page;
		var transitionType = obj.transition;

		switch(transitionType) {
			case "fade" :
			default:
				transitionType = GNOVEL.TransitionType.FADE;
				break;
		};

		if(typeof obj.page === 'string') {
			this._page.goToPageByLabel(obj.page, transitionType, null);
		} else {
			this._page.goToPage(pageIndex, transitionType, null);
		}
	};

	Flow.prototype._handleCompare = function(obj) {
		var diff = obj.leftop - obj.rightop;
		var result;
		switch(obj.operator) {
			case "equal" :
				result = (diff === 0);
				break;
			case "less" :
				result = (diff < 0);
				break;
			case "greater" :
				result = (diff > 0);
				break;
			case "less equal" :
				result = (diff <= 0);
				break;
			case "greater equal" :
				result = (diff >= 0);
				break;
		}
		if(result) {
			this._jump(obj.goTrue);
		}
		else {
			this._jump(obj.goFalse);
		}
		this._exec();
	}

	Flow.prototype._handleJump = function(obj) {
		if (obj.condition) {
			this._jump(obj.goTrue);
		}
		else {
			this._jump(obj.goFalse);
		}
		this._exec();
	};

	Flow.prototype._handleNothing = function(obj) {
		this._next();
		this._exec();
	};

	Flow.prototype._setObjectTag = function(tag, obj) {
		this._objs[tag] = obj;
	};

	Flow.prototype._handleCustom = function(obj) {
		var label = obj.label;
		var func = obj.func;

		var data = func(this._page);

		// if there is data to be stored
		if(typeof data !== 'undefined') {
			// and if there is label to identify where the data will be stored
			if(typeof label !== 'undefined') {
				// we will store the data into that label
				this._storeFlowData(data);
			}
		}

		this._next();
		this._exec();
	};

	Flow.prototype._addCustomHandler = function(type, handler) {
		this._customHandlers[type] = handler;
	};

	Flow.prototype._storeFlowData = function(data) {
		var label = this._elements[this._flowCounter].label;

		this._storedData[label] = data;
		console.log("data stored : " + data + " in label : " + label);
	};

	GNOVEL.Flow = Flow;
}());
<commit_msg>showRelationInfo added to flow in handleGoto to test showing of character's images<commit_after>// namespace
var GNOVEL = GNOVEL || {};

(function() {
	"use strict";

	/**
	 * @class  Flow
	 * @constructor
	 */
	var Flow = function(page) {
		this._page = page;
		this._objs = [];
		this._customHandlers = {};

		this._reset();
	};

	Flow.prototype._reset = function() {
		this._flowCounter = 0;
		this._elements = null;
		this._labels = [];
		this._storedData = [];

		console.log("flow is reset");
	};

	Flow.DIALOG = "dialog";
	Flow.CHOICES = "choices";
	Flow.SHOW = "show";
	Flow.HIDE = "hide";
	Flow.GOTO = "goto";
	Flow.COMPARE = "compare";
	Flow.JUMP = "jump";
	Flow.CUSTOM = "custom";
	Flow.NOTHING = "nothing";

	Flow.prototype._set = function(flowElements) {
		this._reset();

		if(flowElements == null)
			flowElements = [];

		this._elements = flowElements;
		this._processLabels();
	};

	Flow.prototype._getPage = function() {
		return this._page;
	};

	Flow.prototype._jump = function(index) {
		this._flowCounter = index - 1;
		this._next();
	};

	Flow.prototype._peekNext = function() {
		if(this._elements === null)
			return null;

		return this._elements[this._flowCounter + 1];
	};

	Flow.prototype._exec = function() {
		var obj = this._elements[this._flowCounter];

		// hack
		if(obj == null)
			return;

		this._processParameters(obj);

		var type = obj.type;

		switch(type) {
			case Flow.DIALOG:
				this._handleDialog(obj);
				break;
			case Flow.CHOICES:
				this._handleChoices(obj);
				break;
			case Flow.SHOW:
				this._handleShow(obj);
				break;
			case Flow.HIDE:
				this._handleHide(obj);
				break;
			case Flow.GOTO:
				this._handleGoto(obj);
				break;
			case Flow.COMPARE:
				this._handleCompare(obj);
				break;
			case Flow.JUMP:
				this._handleJump(obj);
				break;
			case Flow.CUSTOM:
				this._handleCustom(obj);
				break;
			case Flow.NOTHING:
				this._handleNothing(obj);
				break;
			default:
				// if we have custom handler for that flow element
				if(this._customHandlers[type]) {
					this._customHandlers[type](obj, this);
				}
				break;
		}
	};

	Flow.prototype._next = function() {
		this._flowCounter++;
	};

	Flow.prototype._processLabels = function() {
		for(var i = 0; i < this._elements.length;i++) {
			var e = this._elements[i];
			if(e.label != null) {
				var label = e.label;
				this._labels[label] = i;
			}
		};
	};

	Flow.prototype._processParameters = function(obj) {
		// iterate over all properties in the obj
		for (var prop in obj) {
			if(obj.hasOwnProperty(prop)) {
				// check if this property's value start with '#'
				// which would mark this value as a label of other
				// flow element

				if(typeof (obj[prop]) === "string") {
					// check if it starts with '#'
					var c = obj[prop].charAt(0);
					if(c == '#') {
						// search for that label in labels dictionary

						var label = obj[prop].substring(1);
						var value = this._labels[label];

						if(typeof value === 'undefined' || value === null)
							console.log("cannot find " + label);

						obj[prop] = value;
					} else if(c == '%') {
						// search for that label in objs dictionary

						var label = obj[prop].substring(1);
						var value = this._objs[label];

						if(typeof value === 'undefined' || value === null)
							console.log("cannot find " + label);

						obj[prop] = value;
					} else if(c == '$') {
						// search for that label in storedData dictionary

						var label = obj[prop].substring(1);
						var value = this._storedData[label];

						if(typeof value === 'undefined' || value === null)
							console.log("no such data stored in " + label);

						obj[prop] = value;
					}
				} else if(typeof(obj[prop]) === "object") {
					// recurse to this object
					this._processParameters(obj[prop], this);
				}
			}
		}
	};

	Flow.prototype._handleDialog = function(obj) {
		var x = obj.x || 0; // optional
		var y = obj.y || 0; // optional
		var params = {};
		params.speaker = obj.speaker;
		params.charLine = obj.charLine;

		// pass the original flow element to params
		params.flowElement = obj;

		this._page._showDialog(obj.text, x, y, params);
	};

	Flow.prototype._handleChoices = function(obj) {
		var params = {};
		params.x = obj.x || 0; // optional
		params.y = obj.y || -250; // optional
		var page = this._page;

		// collect choices' text to its own array
		var choicesTextArr = [];
		for(var i = 0; i < obj.choices.length; i++) {
			choicesTextArr.push(obj.choices[i].text);
		}

		//array timed responses
		var timerResponseArr = [];
		if(obj.responses!=null){
			for(var i = 0; i < obj.responses.length; i++) {
				timerResponseArr.push(obj.responses[i].text);
			}
		}

		// collect choices' jump to its own array
		var jumpArr = [];
		for(var i=0; i < obj.choices.length;i++) {
			jumpArr.push(obj.choices[i].go);
		}

		// pass the original flow element to params
		params.flowElement = obj;

		//get speaker
		params.speaker = obj.speaker;
		params.charLine = obj.charLine;

		// check whether the choices is time-based
		params.seconds = obj.seconds || 0;

		params.onChoiceComplete = function(resultId) {
			if(obj.choices[resultId].onChoose && typeof obj.choices[resultId].onChoose === 'function') {
				obj.choices[resultId].onChoose(page);
			}
		};

		this._page._showChoices(choicesTextArr, timerResponseArr, params, jumpArr);
		//show time response dialog from speaker
	};

	Flow.prototype._handleShow = function(obj) {
		var img = obj.img;
		var params = {};

		if(obj.waitUntilShown != null) {
			params.waitUntilShown = obj.waitUntilShown;
		}

		// pass the original flow element to params
		params.flowElement = obj;

		this._page._show(img, params);
	};

	Flow.prototype._handleHide = function(obj) {
		var img = obj.img;
		var params = {};

		if(obj.waitUntilHidden != null) {
			params.waitUntilHidden = obj.waitUntilHidden;
		}

		this._page._hide(img, params);
	};

	Flow.prototype._handleGoto = function(obj) {
		var pageIndex = obj.page;
		var curPage = this._page;
		var transitionType = obj.transition;

		switch(transitionType) {
			case "fade" :
			default:
				transitionType = GNOVEL.TransitionType.FADE;
				break;
		};

		this._page._showRelationshipInfo("Ryan");
		var delay = 1;
		var tempTween = new TWEEN.Tween(delay)
		.to(0,1000)
		.easing(TWEEN.Easing.Cubic.Out)
		.onComplete(function(){
			if(typeof obj.page === 'string') {
				curPage.goToPageByLabel(obj.page, transitionType, null);
			} else {
				curPage.goToPage(pageIndex, transitionType, null);
			}
		})
		tempTween.start();
/*
		if(typeof obj.page === 'string') {
			this._page.goToPageByLabel(obj.page, transitionType, null);
		} else {
			this._page.goToPage(pageIndex, transitionType, null);
		}*/
	};

	Flow.prototype._handleCompare = function(obj) {
		var diff = obj.leftop - obj.rightop;
		var result;
		switch(obj.operator) {
			case "equal" :
				result = (diff === 0);
				break;
			case "less" :
				result = (diff < 0);
				break;
			case "greater" :
				result = (diff > 0);
				break;
			case "less equal" :
				result = (diff <= 0);
				break;
			case "greater equal" :
				result = (diff >= 0);
				break;
		}
		if(result) {
			this._jump(obj.goTrue);
		}
		else {
			this._jump(obj.goFalse);
		}
		this._exec();
	}

	Flow.prototype._handleJump = function(obj) {
		if (obj.condition) {
			this._jump(obj.goTrue);
		}
		else {
			this._jump(obj.goFalse);
		}
		this._exec();
	};

	Flow.prototype._handleNothing = function(obj) {
		this._next();
		this._exec();
	};

	Flow.prototype._setObjectTag = function(tag, obj) {
		this._objs[tag] = obj;
	};

	Flow.prototype._handleCustom = function(obj) {
		var label = obj.label;
		var func = obj.func;

		var data = func(this._page);

		// if there is data to be stored
		if(typeof data !== 'undefined') {
			// and if there is label to identify where the data will be stored
			if(typeof label !== 'undefined') {
				// we will store the data into that label
				this._storeFlowData(data);
			}
		}

		this._next();
		this._exec();
	};

	Flow.prototype._addCustomHandler = function(type, handler) {
		this._customHandlers[type] = handler;
	};

	Flow.prototype._storeFlowData = function(data) {
		var label = this._elements[this._flowCounter].label;

		this._storedData[label] = data;
		console.log("data stored : " + data + " in label : " + label);
	};

	GNOVEL.Flow = Flow;
}());
<|endoftext|>


<commit_before>var app = angular.module('calcApp',[]);

app.controller('calcController', ['$scope',function($scope){
  //set default display
  $scope.display = "--";

  $scope.buttonPress = function(btnStr){
    var lastChar = $scope.display.charAt($scope.display.length-1);
    if ($scope.display==="--"){
      if ("*/0".indexOf(btnStr) === -1){
        $scope.display = btnStr;
      } else {
        $scope.display = $scope.display;
      }
    } else if ("+-/*.".indexOf(lastChar) != -1 && "+/*".indexOf(btnStr) != -1 || lastChar =="." && btnStr == "."){
    $scope.display = $scope.display;
    }
    else {
      $scope.display = $scope.display.concat(btnStr);
    }
  };
  $scope.equals = function(){
    var decimals = document.getElementById("decimalplaces").value;
    $scope.display = eval($scope.display).toFixed(decimals).toString();
  };
  $scope.clear = function(){
    $scope.display = "--";
  };
  $scope.backspace = function (){
    var length = $scope.display.length
    if (length > 1 && $scope.display !== "--"){
      $scope.display = $scope.display.substring(0, length - 1)
    } else {
      $scope.display = "--";
    }
  }
}])<commit_msg>added functionality to evaluation/bug fixes<commit_after>var app = angular.module('calcApp',[]);

app.controller('calcController', ['$scope',function($scope){
  //set default display
  $scope.display = "--";
  //check if last button hit was equals
  $scope.hitEquals = false;
  $scope.buttonPress = function(btnStr){
    var lastChar = $scope.display.charAt($scope.display.length-1)
    //if display is blank or the last button hit was equals, start new display
    if ($scope.display==="--" || $scope.hitEquals){
      $scope.hitEquals = false;
      if ("*/0".indexOf(btnStr) === -1){
        $scope.display = btnStr;
      } else {
        $scope.display = $scope.display;
      }
    } else if ("+-/*.".indexOf(lastChar) != -1 && "+/*-".indexOf(btnStr) != -1 || lastChar =="." && btnStr == "."){
      $scope.display = $scope.display;
    }
    else {
      $scope.display = $scope.display.concat(btnStr);
    }
  };
  $scope.equals = function(){
    var lastChar = $scope.display.charAt($scope.display.length-1)
    $scope.hitEquals = true;
    //if last button entered before equals was a function, remove it and still evaluate
    if ("+-/*.".indexOf(lastChar) != -1){
      $scope.display = $scope.display.substr(0,$scope.display.length-1)
    }
    var decimals = document.getElementById("decimalplaces").value;
    $scope.display = eval($scope.display).toFixed(decimals).toString();
  };
  $scope.clear = function(){
    $scope.hitEquals = false;
    $scope.display = "--";
  };
  $scope.backspace = function (){
    $scope.hitEquals = false;
    var length = $scope.display.length
    if (length > 1 && $scope.display !== "--"){
      $scope.display = $scope.display.substring(0, length - 1)
    } else {
      $scope.display = "--";
    }
  }
}])<|endoftext|>


<commit_before>var Lab = require('lab');
var Hapi = require('hapi');
var ElasticSearchPlugin = require('../plugin');

var lab = exports.lab = Lab.script();

lab.experiment('ElasticSearch Hapi Plugin', function () {
  var server;
  var pack;
  var plugin;

  lab.before(function (next) {
    server = new Hapi.Server(0);
    pack = server.pack;
    next();
  });

  lab.test('is registered with a hapi server pack', function (next) {
    pack.register({plugin: ElasticSearchPlugin}, function (err) {
      Lab.expect(err).to.not.exist;

      plugin = pack.plugins['elasticsearch-hapi-plugin'];
      Lab.expect(plugin).to.have.property('es');
      next();
    });
  });
});
<commit_msg>Increased test coverage to 100%<commit_after>var Lab = require('lab');
var Hapi = require('hapi');
var ElasticSearchPlugin = require('../plugin');

var lab = exports.lab = Lab.script();

lab.experiment('ElasticSearch Hapi Plugin', function () {
  var server;
  var pack;
  var plugin;

  lab.before(function (next) {
    server = new Hapi.Server(0);
    pack = server.pack;
    next();
  });

  lab.test('is registered with a hapi server pack', function (next) {
    pack.register({
      plugin: ElasticSearchPlugin,
      options: {
        keepAlive: false
      }
    }, function (err) {
      Lab.expect(err).to.not.exist;

      plugin = pack.plugins['elasticsearch-hapi-plugin'];
      Lab.expect(plugin).to.have.property('es');
      next();
    });
  });
});
<|endoftext|>


<commit_before>Template.journal.onCreated(function () {
  var self = this
  self.subscribe('journal_entries', get_setting(10, 'public', 'posts_per_page'), skip_entries)
})

Template.journal.helpers({
  journal_entries: function () {
    return Journal_entries.find()
  }
})

Template.journal.onRendered(function () {
  var self = this
  var pager = self.find('.pager')
  var limit = get_setting(10, 'public', 'posts_per_page')
  var skip = skip_entries
  Meteor.call('getEntryCount', function (err, entryCount) {
    if(err) return
    pager.innerHTML = renderPrevLink(skip, limit)
    pager.innerHTML += renderNextLink(entryCount, skip, limit)
  })
})<commit_msg>Scroll to top after clicking pager<commit_after>Template.journal.onCreated(function () {
  var self = this
  self.subscribe('journal_entries', get_setting(10, 'public', 'posts_per_page'), skip_entries)
})

Template.journal.helpers({
  journal_entries: function () {
    return Journal_entries.find()
  }
})

Template.journal.onRendered(function () {
  var self = this
  var pager = self.find('.pager')
  var limit = get_setting(10, 'public', 'posts_per_page')
  var skip = skip_entries
  Meteor.call('getEntryCount', function (err, entryCount) {
    if(err) return
    pager.innerHTML = renderPrevLink(skip, limit)
    pager.innerHTML += renderNextLink(entryCount, skip, limit)
  })
})

Template.journal.events({
  'click .pager': function () {
    scrollTo(0, 0)
  }
})<|endoftext|>


<commit_before>var HistoryManager = new Object();

HistoryManager.init = function() {
    this.initialState = this._parseStateFromHash(window.location.hash);
    this._parseWorkspaceFromPathName(window.location.pathname, this.initialState);

    if ('history' in window && 'pushState' in window.history) {
        Event.observe(window,
            "popstate",
            this._onpopstate.bind(this),
            true);
        history.replaceState(this.initialState, "", window.location.href);
        this.currentState = this.initialState;

        this._pushState = function(data, title, url) {
            history.pushState(data, "", url);
            this.currentState = data;
        };

    } else if ('onhashchange' in document || 'onhashchange' in window) {
        Event.observe(window,
            "hashchange",
            this._onhashchange.bind(this),
            true);
        this.currentState = this.initialState;

        this._pushState = function(data, title, url) {
            var url = this._buildURL(data);
            window.location = url;
        };
    }
    this.stateChangeEnabled = true;
};

HistoryManager._parseStateFromHash = function(hash) {
    var definitions, i, pair, key, value, data = {};

    if (hash.charAt(0) === '#') {
        hash = hash.substr(1);
    }
    if (hash.length === 0) {
        return data;
    }

    definitions = hash.split('&');
    for (i = 0; i < definitions.length; i += 1) {
        pair = definitions[i].split('=');
        key = decodeURIComponent(pair[0]);
        value = decodeURIComponent(pair[1]);
        data[key] = value;
    }

    return data;
};

HistoryManager._parseWorkspaceFromPathName = function(pathname, status) {
    var index, index2;

    index = pathname.lastIndexOf('/');
    index2 = pathname.lastIndexOf('/', index - 1);

    status.workspace_creator = pathname.substring(index2 + 1, index);
    status.workspace_name = pathname.substring(index + 1);
};

HistoryManager._prepareData = function(data) {
    var default_data = {
        view: "dragboard"
    }
    data = Object.extend(default_data, data);
    for (key in data) {
        data[key] = "" + data[key];
    }
    return data;
};

HistoryManager._buildURL = function(data) {
    var key,
        hash = '',
        lite = '';

    for (key in data) {
        if (key === 'workspace_name' || key === 'workspace_creator') {
            continue;
        }
        hash += '&' + encodeURI(key) + '=' + encodeURI(data[key]);
    }

    return window.location.protocol + "//" +
        window.location.host + lite +
        "/" + data.workspace_creator + '/' + data.workspace_name +
        window.location.search +
        '#' + hash.substr(1);
};

HistoryManager.pushState = function(data) {
    var url, key, equal;

    if (!this.stateChangeEnabled) {
        return;
    }

    data = this._prepareData(data);
    equal = true;
    for (key in data) {
        if (data[key] !== this.currentState[key]) {
            equal = false;
            break;
        }
    }
    if (equal) {
        return;
    }
    url = this._buildURL(data);

    this._pushState(data, "", url);
};

HistoryManager._onhashchange = function() {
    this.stateChangeEnabled = false;

    var hash = window.location.hash;
    var state = Object.clone(this.initialState);
    Object.extend(state, this._parseStateFromHash(hash));
    this.currentState = state;

    LayoutManagerFactory.getInstance().onHashChange(state);

    this.stateChangeEnabled = true;
};

HistoryManager._onpopstate = function(event) {
    if (event.state === null) {
        return;
    }
    this.stateChangeEnabled = false;

    this.currentState = event.state;
    LayoutManagerFactory.getInstance().onHashChange(event.state);

    this.stateChangeEnabled = true;
};

HistoryManager.getCurrentState = function() {
    return Object.clone(this.currentState);
};

HistoryManager.cloneCurrentState = function() {
    return Object.clone(this.currentState);
};
<commit_msg>Fix jshint bugs in HistoryManager.js<commit_after>/*global Event, LayoutManagerFactory*/

(function () {

    "use strict";

    var HistoryManager = {};

    HistoryManager.init = function init() {
        this.initialState = this._parseStateFromHash(window.location.hash);
        this._parseWorkspaceFromPathName(window.location.pathname, this.initialState);

        if ('history' in window && 'pushState' in window.history) {
            Event.observe(window,
                "popstate",
                this._onpopstate.bind(this),
                true);
            history.replaceState(this.initialState, "", window.location.href);
            this.currentState = this.initialState;

            this._pushState = function (data, title, url) {
                history.pushState(data, "", url);
                this.currentState = data;
            };

        } else if ('onhashchange' in document || 'onhashchange' in window) {
            Event.observe(window,
                "hashchange",
                this._onhashchange.bind(this),
                true);
            this.currentState = this.initialState;

            this._pushState = function (data, title, url) {
                window.location = url;
            };
        }
        this.stateChangeEnabled = true;
    };

    HistoryManager._parseStateFromHash = function _parseStateFromHash(hash) {
        var definitions, i, pair, key, value, data = {};

        if (hash.charAt(0) === '#') {
            hash = hash.substr(1);
        }
        if (hash.length === 0) {
            return data;
        }

        definitions = hash.split('&');
        for (i = 0; i < definitions.length; i += 1) {
            pair = definitions[i].split('=');
            key = decodeURIComponent(pair[0]);
            value = decodeURIComponent(pair[1]);
            data[key] = value;
        }

        return data;
    };

    HistoryManager._parseWorkspaceFromPathName = function _parseWorkspaceFromPathName(pathname, status) {
        var index, index2;

        index = pathname.lastIndexOf('/');
        index2 = pathname.lastIndexOf('/', index - 1);

        status.workspace_creator = pathname.substring(index2 + 1, index);
        status.workspace_name = pathname.substring(index + 1);
    };

    HistoryManager._prepareData = function _prepareData(data) {
        var key, default_data = {
            view: "dragboard"
        };
        data = Object.extend(default_data, data);
        for (key in data) {
            data[key] = "" + data[key];
        }
        return data;
    };

    HistoryManager._buildURL = function _buildURL(data) {
        var key,
            hash = '',
            lite = '';

        for (key in data) {
            if (key === 'workspace_name' || key === 'workspace_creator') {
                continue;
            }
            hash += '&' + encodeURI(key) + '=' + encodeURI(data[key]);
        }

        return window.location.protocol + "//" +
            window.location.host + lite +
            "/" + data.workspace_creator + '/' + data.workspace_name +
            window.location.search +
            '#' + hash.substr(1);
    };

    HistoryManager.pushState = function pushState(data) {
        var url, key, equal;

        if (!this.stateChangeEnabled) {
            return;
        }

        data = this._prepareData(data);
        equal = true;
        for (key in data) {
            if (data[key] !== this.currentState[key]) {
                equal = false;
                break;
            }
        }
        if (equal) {
            return;
        }
        url = this._buildURL(data);

        this._pushState(data, "", url);
    };

    HistoryManager._onhashchange = function _onhashchange() {
        this.stateChangeEnabled = false;

        var hash = window.location.hash;
        var state = Object.clone(this.initialState);
        Object.extend(state, this._parseStateFromHash(hash));
        this.currentState = state;

        LayoutManagerFactory.getInstance().onHashChange(state);

        this.stateChangeEnabled = true;
    };

    HistoryManager._onpopstate = function _onpopstate(event) {
        if (event.state === null) {
            return;
        }
        this.stateChangeEnabled = false;

        this.currentState = event.state;
        LayoutManagerFactory.getInstance().onHashChange(event.state);

        this.stateChangeEnabled = true;
    };

    HistoryManager.getCurrentState = function getCurrentState() {
        return Object.clone(this.currentState);
    };

    HistoryManager.cloneCurrentState = function cloneCurrentState() {
        return Object.clone(this.currentState);
    };

    window.HistoryManager = HistoryManager;
})();
<|endoftext|>


<commit_before>/**
* map tab shown in cartodb admin
*/

cdb.admin.MapTab = cdb.core.View.extend({

  events: {
    'click .sqlview .clearview':    '_clearView',
    'click .sqlview .export_query': '_tableFromQuery'
  },

  className: 'map',
  animation_time: 300,

  initialize: function() {
    this.template = this.getTemplate('table/views/maptab');
    this.map = this.model;
    this.map_enabled = false;
    this.featureHovered = null;
    this.georeferenced = false;
    this.activeLayerView = null;

    this.add_related_model(this.map);

    var self = this;

    // Actions triggered in the right panel
    cdb.god.bind("panel_action", function(action) {
      self._moveInfo(action);
    }, this);

    this.add_related_model(cdb.god);

    this.map.bind('change:provider', this.switchMapType, this);

    _.bindAll(this, 'showNoGeoRefWarning');
  },

  deactivated: function() {
    if(this.map_enabled) {
      this.clearMap();
    }
  },

  clearMap: function() {
    clearTimeout(this.autoSaveBoundsTimer);
    this.mapView.clean();
    this.basemapDropdown.clean();
    this.zoom.clean();
    if(this.infowindow) {
      this.infowindow.clean();
    }
    if(this.geometryEditor) this.geometryEditor.clean();
    if(this.table) {
      this.table.unbind(null, null, this);
    }

    delete this.mapView;
    delete this.basemapDropdown;
    delete this.zoom;
    delete this.infowindow;
    delete this.geometryEditor;

    this.map_enabled = false;

    // place the map DOM object again
    this.render();
  },

  /**
   *  Hide the infowindow when a query is applied or cleared
   */
  _hideInfowindow: function() {
    if(this.infowindow) {
      this.infowindow.model.set('visibility', false);
    }
  },

  /**
  * this function is used when the map library is changed. Each map library
  * works in different way and need to recreate all the components again
  */
  switchMapType: function() {
    if (this.map_enabled) {
      this.clearMap();
      this.render();
      this.enableMap();
    }
  },

  /**
  * map can't be loaded from the beggining, it needs the DOM to be loaded
  * so we wait until is actually shown to create the mapview and show it
  */
  enableMap: function() {

    this.$('.tipsy').remove();
    var self = this;

    if (!this.map_enabled) {

      var div = this.$('.cartodb-map');

      var mapViewClass = cdb.geo.LeafletMapView;

      if(this.map.get('provider') === 'googlemaps') {
        mapViewClass = cdb.geo.GoogleMapsMapView;
      }

      this.mapView = new mapViewClass({
        el: div,
        map: this.map
      });

      this.clickTimeout = null;
      this._bindMissingClickEvents();

      this.map_enabled = true;

      //this.mapView.bind('newLayerView', self._bindDataLayer, self);

      // bind data layer if it is already added to the map
      /*var dataLayer = this.map.get('dataLayer');
      if(dataLayer) {
        var dl = this.mapView.getLayerByCid(self.map.get('dataLayer').cid);
        this._bindDataLayer(dl);
      }*/

      // Create Base Layer chooser
      if (!this.basemapDropdown) {

        this.basemapDropdown = new cdb.admin.DropdownBasemap({
          target: $('.basemap_dropdown'),
          position: "position",
          template_base: "common/views/dropdown_basemap",
          model: this.map,
          mapview: this.mapView,
          baseLayers: this.options.baseLayers,
          tick: "left",
          horizontal_position: "left",
          horizontal_offset: "40px"
        });

        this.addView(this.basemapDropdown);

        cdb.god.bind("closeDialogs", this.basemapDropdown.hide, this.basemapDropdown);

        $(".basemap_dropdown").append(this.basemapDropdown.render().el);
      }

      // Set active base layer if it already exists
      if (this.map.getBaseLayer()) {
        this.basemapDropdown.setActiveBaselayer();
      }

      // Zoom control
      var zoomControl = new cdb.geo.ui.Zoom({
        model:    this.map,
        template: cdb.templates.getTemplate("table/views/zoom_control")
      });

      this.$el.append(zoomControl.render().$el);
      this.zoom = zoomControl;

      // Search control
      var searchControl = new cdb.geo.ui.Search({
        model:    this.map,
        template: cdb.templates.getTemplate("table/views/search_control")
      });

      this.$el.append(searchControl.render().$el);
      this.search = searchControl;

      // Zoom info
      var zoomInfo = this.zoomInfo = new cdb.geo.ui.ZoomInfo({
        model: this.map
      });

      this.$el.append(zoomInfo.render().$el);
      // Create tipsy and set to the zoom info element
      zoomInfo.$el.tipsy({
        title: function() { return "Zoom level" },
        fade: true,
        offset: 3,
        gravity: 'w'
      });

      // Tiles loader
      var tilesLoader = this.loader = new cdb.geo.ui.TilesLoader({
        template: cdb.templates.getTemplate("table/views/tiles_loader")
      });

      this.$el.append(tilesLoader.render().$el);
      // Create tipsy and set to the tiles loader
      tilesLoader.$el.find("div.loader").tipsy({
        title: function() { return "Loading tiles..." },
        fade: true,
        offset: 3,
        gravity: 'w'
      });

      this._addInfowindow();

      this.mapView.bind('newLayerView', function(layerView) {
        if(this.activeLayerView && layerView.model.cid == this.activeLayerView.model.cid) {
          this._bindDataLayer(this.activeLayerView);
        }
      }, this);

      if(this.activeLayerView) {
        this._bindDataLayer(this.activeLayerView);
      }

      // HACK
      // wait a little bit to give time to the mapview
      // to estabilize
      this.autoSaveBoundsTimer = setTimeout(function() {
        self.mapView.setAutoSaveBounds();
      }, 1000);
    }
  },

  bindGeoRefCheck: function() {
    if(!this.table.data().fetched) {
      this.table.bind('dataLoaded', function() {
        this.checkGeoRef();
      }, this);
    } else {
      this.checkGeoRef();
    }
  },

  activated: function() {
    $(window).scrollTop(0);
  },

  checkGeoRef: function() {
    if(this.options && this.table) {
      if(!this.table.isGeoreferenced()) {
        this.trigger('noGeoRef');
        this.showNoGeoRefWarning();
        this.georeferenced = false;
      } else {
        if(!this.georeferenced) {
          this.trigger('geoRef');
        }
        this.georeferenced = true;
        if(this.noGeoRefDialog) {
          this.noGeoRefDialog.hide();
        }
      }
    }
  },

  /**
  * this function binds click and dblclick events
  * in order to not raise click when user does a dblclick
  *
  * it raises a missingClick when the user clicks on the map
  * but not over a feature or ui component
  */
  _bindMissingClickEvents: function() {
    var self = this;
    this.mapView.bind('click', function(e) {
      if(self.clickTimeout === null) {
        self.clickTimeout = setTimeout(function() {
          self.clickTimeout = null;
          if(!self.featureHovered) {
            self.trigger('missingClick');
          }
        }, 150);
      }
      //google maps does not send an event
      if(!self.featureHovered && e.preventDefault) {
        e.preventDefault();
        e.stopPropagation();
      }
    });

    this.mapView.bind('dblclick', function() {
      if(self.clickTimeout !== null) {
        clearTimeout(self.clickTimeout);
        self.clickTimeout = null;
      }
    });
  },

  setActiveLayer: function(layerView) {
    this.activeLayerView = layerView;
    // check if the map is rendered and the layer is in the map
    if(this.mapView && this.mapView.getLayerByCid(layerView.model.cid)) {
      this._bindDataLayer(layerView);
    }
  },

  /**
  * when the layer view is created this method is called
  * to attach all the click events
  */
  _bindDataLayer: function(layerView) {
    var self = this;
    var layer = layerView.model;
    var layerType = layer.get('type');

    if (layerType === 'CartoDB') { // unbind previos stuff

      // Set data layer bindings
      if (self.layerDataView) {
        self.layerDataView.unbind(null, null, this);
      }
      self.infowindowModel = layer.infowindow;
      self._bindTable(layer.table);
      self._bindSQLView(layer.sqlView);
      self.layerDataView = self.mapView.getLayerByCid(layer.cid);

      if (self.layerDataView) {
        self.layerDataView.bind('featureClick', self.featureClick, self);
        self.layerDataView.bind('featureOut',   self.featureOut,   self);
        self.layerDataView.bind('featureOver',  self.featureOver,  self);
        self.layerDataView.bind('loading',      self.loadingTiles, self);
        self.layerDataView.bind('load',         self.loadTiles,    self);
      }

      // Set layer model binding
      if (layerView && layerView.model) {
        layerView && layerView.model.unbind('startEdition',this._addGeometry, this);
        layerView.model.bind('startEdition', this._addGeometry, this);
      }
    }
  },

  _addInfowindow: function() {
    if(this.infowindow) this.infowindow.clean();
    if(this.table && this.mapView) {
      this.infowindow = new cdb.admin.MapInfowindow({
        model: this.infowindowModel,
        mapView: this.mapView,
        table: this.table
      });
      this.mapView.$el.append(this.infowindow.el);

      // Editing geometry
      if(this.geometryEditor) this.geometryEditor.clean();

      this.geometryEditor = new cdb.admin.GeometryEditor({
        model: this.table
      });

      this.geometryEditor.mapView = this.mapView;
      this.mapView.$el.append(this.geometryEditor.render().el);
      this.geometryEditor.hide();

      this.geometryEditor.bind('editStart', this.hideDataLayer, this);
      this.geometryEditor.bind('editDiscard', this.showDataLayer, this);
      this.geometryEditor.bind('editFinish', this.showDataLayer, this);
      this.geometryEditor.bind('editFinish', this.updateDataLayerView, this);
      this.geometryEditor.bind('geomCreated', function(row) {
        this.table.data().add(row);
      }, this);

      this.infowindow.bind('editGeom', this.geometryEditor.editGeom, this.geometryEditor);
      this.table.bind('remove:row', this.updateDataLayerView, this);

      this.table.bind('change:dataSource', function() {
        this.geometryEditor.discard();
      }, this);
    }
  },

  _addGeometry: function(type) {
    this.geometryEditor.createGeom(this.table.data().newRow(), type);
  },

  _bindTable: function(table) {

    if(this.table) {
      this.table.unbind(null, null, this);
    }
    this.table = table;

    this.table.bind('change:dataSource', this._hideInfowindow, this);

    this.table.bind('data:saved', function() {
      this.updateDataLayerView();
    }, this);

    this.table.bind('change:schema', function() {
      //dataLayer.invalidate();
    }, this);

    // infowindow
    this._addInfowindow();

    this.bindGeoRefCheck();
  },

  _bindSQLView: function(sqlView) {
    if(this.sqlView) {
      this.sqlView.unbind(null, null, this);
    }
    this.sqlView = sqlView;
    this.sqlView.bind('reset error', this._updateSQLHeader, this);
  },

  _updateSQLHeader: function() {
    if(this.table.isInSQLView()) {
      this._addSQLViewHeader();
    } else {
      this._removeSQLViewHeader();
    }
  },

  loadingTiles: function() {
    this.loader.show()
  },

  loadTiles: function() {
    this.loader.hide()
  },

  featureOver: function(e, latlon, pxPos, data) {
    if(this.infowindowModel.get('disabled')) return;
    this.mapView.setCursor('pointer');
    this.featureHovered = data;
  },

  featureOut: function() {
    if(this.infowindowModel.get('disabled')) return;
    this.mapView.setCursor('auto');
    this.featureHovered = null;
  },

  featureClick: function(e, latlon, pxPos, data) {
    if(this.infowindowModel.get('disabled')) return;
    if(!this.geometryEditor.isEditing()) {
      if(data.cartodb_id) {
        this.infowindow
        .setLatLng(latlon)
        .setFeatureInfo(data.cartodb_id)
        .showInfowindow();
      } else {
        cdb.log.error("can't show infowindow, no cartodb_id on data");
      }
    }
  },

  /**
   *  Move all necessary blocks when panel is openned (normal, narrowed,...) or closed
   */
  _moveInfo: function(type) {
    if (type == "show") {
      this.$el
        .removeClass('narrow')
        .addClass('displaced');
    } else if (type == "hide") {
      this.$el.removeClass('narrow displaced');
    } else if (type == "narrow") {
      this.$el.addClass('narrow displaced');
    }
  },

  render: function() {
    this.$el.html('');
    this.$el.append(this.template());
    return this;
  },

  showDataLayer: function() {
    this.layerDataView.setInteraction(true);
    this.layerDataView.setOpacity(1.0);
  },

  hideDataLayer: function() {
    //this.layerDataView.hide();
    this.layerDataView.setInteraction(false);
    this.layerDataView.setOpacity(0.5);
  },

  /**
  * reload tiles
  */
  updateDataLayerView: function() {
    if(this.layerDataView) {
      this.layerDataView.reload();
    }
  },
  /**
  * Paints a dialog with a warning when the user hasn't any georeferenced row
  * @method showNoGeorefWarning
  */
  showNoGeoRefWarning: function() {
    var warningStorageName = '';
    if(this.table.data().length > 0) {
      warningStorageName = 'georefContentWarningShowed' + this.table.id;
    } else {
      warningStorageName = 'georefNoContentWarningShowed' + this.table.id;
    }

    if(!this.noGeoRefDialog && !this.table.isInSQLView() && (!localStorage[warningStorageName])) {
      localStorage[warningStorageName] = true;
      this.noGeoRefDialog = new cdb.admin.NoGeoRefDataDialog({
        model: this.table
      });
      this.retrigger('georeference', this.noGeoRefDialog);
      this.retrigger('manual', this.noGeoRefDialog);
      this.noGeoRefDialog.render().$el.appendTo(this.$el);
    }
    // if the dialog already has been shown, we don't show it again
  },

  //adds the green indicator when a query is applied
  _addSQLViewHeader: function() {
    this.$('.sqlview').remove();
    var total = this.table.data().size();
    var html = this.getTemplate('table/views/sql_view_notice')({
      empty: !total
    });
    this.$('.cartodb-map').after(html);
  },

  _removeSQLViewHeader: function() {
    this.$('.sqlview').remove();
  },

  _clearView: function(e) {
    this.killEvent(e);
    this.activeLayerView.model.clearSQLView();
    return false;
  },

  _tableFromQuery: function(e) {
    this.killEvent(e);

    var duplicate_dialog = new cdb.admin.DuplicateTableDialog({
      model: this.table
    });
    duplicate_dialog.appendToBody().open();
  }

});

<commit_msg>no georef data dialog correctly showed<commit_after>/**
* map tab shown in cartodb admin
*/

cdb.admin.MapTab = cdb.core.View.extend({

  events: {
    'click .sqlview .clearview':    '_clearView',
    'click .sqlview .export_query': '_tableFromQuery'
  },

  className: 'map',
  animation_time: 300,

  initialize: function() {
    this.template = this.getTemplate('table/views/maptab');
    this.map = this.model;
    this.map_enabled = false;
    this.featureHovered = null;
    this.georeferenced = false;
    this.activeLayerView = null;

    this.add_related_model(this.map);

    var self = this;

    // Actions triggered in the right panel
    cdb.god.bind("panel_action", function(action) {
      self._moveInfo(action);
    }, this);

    this.add_related_model(cdb.god);

    this.map.bind('change:provider', this.switchMapType, this);

    _.bindAll(this, 'showNoGeoRefWarning');
  },

  deactivated: function() {
    if(this.map_enabled) {
      this.clearMap();
    }
  },

  clearMap: function() {
    clearTimeout(this.autoSaveBoundsTimer);
    this.mapView.clean();
    this.basemapDropdown.clean();
    this.zoom.clean();
    if(this.infowindow) {
      this.infowindow.clean();
    }
    if(this.geometryEditor) this.geometryEditor.clean();
    if(this.table) {
      this.table.unbind(null, null, this);
    }

    delete this.mapView;
    delete this.basemapDropdown;
    delete this.zoom;
    delete this.infowindow;
    delete this.geometryEditor;

    this.map_enabled = false;

    // place the map DOM object again
    this.render();
  },

  /**
   *  Hide the infowindow when a query is applied or cleared
   */
  _hideInfowindow: function() {
    if(this.infowindow) {
      this.infowindow.model.set('visibility', false);
    }
  },

  /**
  * this function is used when the map library is changed. Each map library
  * works in different way and need to recreate all the components again
  */
  switchMapType: function() {
    if (this.map_enabled) {
      this.clearMap();
      this.render();
      this.enableMap();
    }
  },

  /**
  * map can't be loaded from the beggining, it needs the DOM to be loaded
  * so we wait until is actually shown to create the mapview and show it
  */
  enableMap: function() {

    this.$('.tipsy').remove();
    var self = this;

    if (!this.map_enabled) {

      var div = this.$('.cartodb-map');

      var mapViewClass = cdb.geo.LeafletMapView;

      if(this.map.get('provider') === 'googlemaps') {
        mapViewClass = cdb.geo.GoogleMapsMapView;
      }

      this.mapView = new mapViewClass({
        el: div,
        map: this.map
      });

      this.clickTimeout = null;
      this._bindMissingClickEvents();

      this.map_enabled = true;

      //this.mapView.bind('newLayerView', self._bindDataLayer, self);

      // bind data layer if it is already added to the map
      /*var dataLayer = this.map.get('dataLayer');
      if(dataLayer) {
        var dl = this.mapView.getLayerByCid(self.map.get('dataLayer').cid);
        this._bindDataLayer(dl);
      }*/

      // Create Base Layer chooser
      if (!this.basemapDropdown) {

        this.basemapDropdown = new cdb.admin.DropdownBasemap({
          target: $('.basemap_dropdown'),
          position: "position",
          template_base: "common/views/dropdown_basemap",
          model: this.map,
          mapview: this.mapView,
          baseLayers: this.options.baseLayers,
          tick: "left",
          horizontal_position: "left",
          horizontal_offset: "40px"
        });

        this.addView(this.basemapDropdown);

        cdb.god.bind("closeDialogs", this.basemapDropdown.hide, this.basemapDropdown);

        $(".basemap_dropdown").append(this.basemapDropdown.render().el);
      }

      // Set active base layer if it already exists
      if (this.map.getBaseLayer()) {
        this.basemapDropdown.setActiveBaselayer();
      }

      // Zoom control
      var zoomControl = new cdb.geo.ui.Zoom({
        model:    this.map,
        template: cdb.templates.getTemplate("table/views/zoom_control")
      });

      this.$el.append(zoomControl.render().$el);
      this.zoom = zoomControl;

      // Search control
      var searchControl = new cdb.geo.ui.Search({
        model:    this.map,
        template: cdb.templates.getTemplate("table/views/search_control")
      });

      this.$el.append(searchControl.render().$el);
      this.search = searchControl;

      // Zoom info
      var zoomInfo = this.zoomInfo = new cdb.geo.ui.ZoomInfo({
        model: this.map
      });

      this.$el.append(zoomInfo.render().$el);
      // Create tipsy and set to the zoom info element
      zoomInfo.$el.tipsy({
        title: function() { return "Zoom level" },
        fade: true,
        offset: 3,
        gravity: 'w'
      });

      // Tiles loader
      var tilesLoader = this.loader = new cdb.geo.ui.TilesLoader({
        template: cdb.templates.getTemplate("table/views/tiles_loader")
      });

      this.$el.append(tilesLoader.render().$el);
      // Create tipsy and set to the tiles loader
      tilesLoader.$el.find("div.loader").tipsy({
        title: function() { return "Loading tiles..." },
        fade: true,
        offset: 3,
        gravity: 'w'
      });

      this._addInfowindow();

      this.mapView.bind('newLayerView', function(layerView) {
        if(this.activeLayerView && layerView.model.cid == this.activeLayerView.model.cid) {
          this._bindDataLayer(this.activeLayerView);
        }
      }, this);

      if(this.activeLayerView) {
        this._bindDataLayer(this.activeLayerView);
      }

      // HACK
      // wait a little bit to give time to the mapview
      // to estabilize
      this.autoSaveBoundsTimer = setTimeout(function() {
        self.mapView.setAutoSaveBounds();
      }, 1000);
    }
  },

  bindGeoRefCheck: function() {
    if(!this.table.data().fetched) {
      this.table.bind('dataLoaded', function() {
        this.checkGeoRef();
      }, this);
    } else {
      this.checkGeoRef();
    }
  },

  activated: function() {
    $(window).scrollTop(0);
  },

  checkGeoRef: function() {
    if(this.options && this.table) {
      if(!this.table.isGeoreferenced()) {
        this.trigger('noGeoRef');
        this.showNoGeoRefWarning();
        this.georeferenced = false;
      } else {
        if(!this.georeferenced) {
          this.trigger('geoRef');
        }
        this.georeferenced = true;
        if(this.noGeoRefDialog) {
          this.noGeoRefDialog.hide();
        }
      }
    }
  },

  /**
  * this function binds click and dblclick events
  * in order to not raise click when user does a dblclick
  *
  * it raises a missingClick when the user clicks on the map
  * but not over a feature or ui component
  */
  _bindMissingClickEvents: function() {
    var self = this;
    this.mapView.bind('click', function(e) {
      if(self.clickTimeout === null) {
        self.clickTimeout = setTimeout(function() {
          self.clickTimeout = null;
          if(!self.featureHovered) {
            self.trigger('missingClick');
          }
        }, 150);
      }
      //google maps does not send an event
      if(!self.featureHovered && e.preventDefault) {
        e.preventDefault();
        e.stopPropagation();
      }
    });

    this.mapView.bind('dblclick', function() {
      if(self.clickTimeout !== null) {
        clearTimeout(self.clickTimeout);
        self.clickTimeout = null;
      }
    });
  },

  setActiveLayer: function(layerView) {
    this.activeLayerView = layerView;
    // check if the map is rendered and the layer is in the map
    if(this.mapView && this.mapView.getLayerByCid(layerView.model.cid)) {
      this._bindDataLayer(layerView);
    }
  },

  /**
  * when the layer view is created this method is called
  * to attach all the click events
  */
  _bindDataLayer: function(layerView) {
    var self = this;
    var layer = layerView.model;
    var layerType = layer.get('type');

    if (layerType === 'CartoDB') { // unbind previos stuff

      // Set data layer bindings
      if (self.layerDataView) {
        self.layerDataView.unbind(null, null, this);
      }
      self.infowindowModel = layer.infowindow;
      self._bindTable(layer.table);
      self._bindSQLView(layer.sqlView);
      self.layerDataView = self.mapView.getLayerByCid(layer.cid);

      if (self.layerDataView) {
        self.layerDataView.bind('featureClick', self.featureClick, self);
        self.layerDataView.bind('featureOut',   self.featureOut,   self);
        self.layerDataView.bind('featureOver',  self.featureOver,  self);
        self.layerDataView.bind('loading',      self.loadingTiles, self);
        self.layerDataView.bind('load',         self.loadTiles,    self);
      }

      // Set layer model binding
      if (layerView && layerView.model) {
        layerView && layerView.model.unbind('startEdition',this._addGeometry, this);
        layerView.model.bind('startEdition', this._addGeometry, this);
      }
    }
  },

  _addInfowindow: function() {
    if(this.infowindow) this.infowindow.clean();
    if(this.table && this.mapView) {
      this.infowindow = new cdb.admin.MapInfowindow({
        model: this.infowindowModel,
        mapView: this.mapView,
        table: this.table
      });
      this.mapView.$el.append(this.infowindow.el);

      // Editing geometry
      if(this.geometryEditor) this.geometryEditor.clean();

      this.geometryEditor = new cdb.admin.GeometryEditor({
        model: this.table
      });

      this.geometryEditor.mapView = this.mapView;
      this.mapView.$el.append(this.geometryEditor.render().el);
      this.geometryEditor.hide();

      this.geometryEditor.bind('editStart', this.hideDataLayer, this);
      this.geometryEditor.bind('editDiscard', this.showDataLayer, this);
      this.geometryEditor.bind('editFinish', this.showDataLayer, this);
      this.geometryEditor.bind('editFinish', this.updateDataLayerView, this);
      this.geometryEditor.bind('geomCreated', function(row) {
        this.table.data().add(row);
      }, this);

      this.infowindow.bind('editGeom', this.geometryEditor.editGeom, this.geometryEditor);
      this.table.bind('remove:row', this.updateDataLayerView, this);

      this.table.bind('change:dataSource', function() {
        this.geometryEditor.discard();
      }, this);
    }
  },

  _addGeometry: function(type) {
    this.geometryEditor.createGeom(this.table.data().newRow(), type);
  },

  _bindTable: function(table) {

    if(this.table) {
      this.table.unbind(null, null, this);
    }
    this.table = table;

    this.table.bind('change:dataSource', this._hideInfowindow, this);

    this.table.bind('data:saved', function() {
      this.updateDataLayerView();
    }, this);

    this.table.bind('change:schema', function() {
      //dataLayer.invalidate();
    }, this);

    // infowindow
    this._addInfowindow();

    this.bindGeoRefCheck();
  },

  _bindSQLView: function(sqlView) {
    if(this.sqlView) {
      this.sqlView.unbind(null, null, this);
    }
    this.sqlView = sqlView;
    this.sqlView.bind('reset error', this._updateSQLHeader, this);
  },

  _updateSQLHeader: function() {
    if(this.table.isInSQLView()) {
      this._addSQLViewHeader();
    } else {
      this._removeSQLViewHeader();
    }
  },

  loadingTiles: function() {
    this.loader.show()
  },

  loadTiles: function() {
    this.loader.hide()
  },

  featureOver: function(e, latlon, pxPos, data) {
    if(this.infowindowModel.get('disabled')) return;
    this.mapView.setCursor('pointer');
    this.featureHovered = data;
  },

  featureOut: function() {
    if(this.infowindowModel.get('disabled')) return;
    this.mapView.setCursor('auto');
    this.featureHovered = null;
  },

  featureClick: function(e, latlon, pxPos, data) {
    if(this.infowindowModel.get('disabled')) return;
    if(!this.geometryEditor.isEditing()) {
      if(data.cartodb_id) {
        this.infowindow
        .setLatLng(latlon)
        .setFeatureInfo(data.cartodb_id)
        .showInfowindow();
      } else {
        cdb.log.error("can't show infowindow, no cartodb_id on data");
      }
    }
  },

  /**
   *  Move all necessary blocks when panel is openned (normal, narrowed,...) or closed
   */
  _moveInfo: function(type) {
    if (type == "show") {
      this.$el
        .removeClass('narrow')
        .addClass('displaced');
    } else if (type == "hide") {
      this.$el.removeClass('narrow displaced');
    } else if (type == "narrow") {
      this.$el.addClass('narrow displaced');
    }
  },

  render: function() {
    this.$el.html('');
    this.$el.append(this.template());
    return this;
  },

  showDataLayer: function() {
    this.layerDataView.setInteraction(true);
    this.layerDataView.setOpacity(1.0);
  },

  hideDataLayer: function() {
    //this.layerDataView.hide();
    this.layerDataView.setInteraction(false);
    this.layerDataView.setOpacity(0.5);
  },

  /**
  * reload tiles
  */
  updateDataLayerView: function() {
    if(this.layerDataView) {
      this.layerDataView.reload();
    }
  },
  /**
  * Paints a dialog with a warning when the user hasn't any georeferenced row
  * @method showNoGeorefWarning
  */
  showNoGeoRefWarning: function() {
    var warningStorageName = '';
    if(this.table.data().length > 0) {
      warningStorageName = 'georefContentWarningShowed' + this.table.id;
    } else {
      warningStorageName = 'georefNoContentWarningShowed' + this.table.id;
    }

    // if the dialog already has been shown, we don't show it again
    if(!this.noGeoRefDialog && !this.table.isInSQLView() && (!localStorage[warningStorageName])) {
      localStorage[warningStorageName] = true;
      this.noGeoRefDialog = new cdb.admin.NoGeoRefDataDialog({
        model: this.table
      });
      this.retrigger('georeference', this.noGeoRefDialog);
      this.retrigger('manual', this.noGeoRefDialog);

      this.noGeoRefDialog
        .appendToBody()
        .open();
    }

  },

  //adds the green indicator when a query is applied
  _addSQLViewHeader: function() {
    this.$('.sqlview').remove();
    var total = this.table.data().size();
    var html = this.getTemplate('table/views/sql_view_notice')({
      empty: !total
    });
    this.$('.cartodb-map').after(html);
  },

  _removeSQLViewHeader: function() {
    this.$('.sqlview').remove();
  },

  _clearView: function(e) {
    this.killEvent(e);
    this.activeLayerView.model.clearSQLView();
    return false;
  },

  _tableFromQuery: function(e) {
    this.killEvent(e);

    var duplicate_dialog = new cdb.admin.DuplicateTableDialog({
      model: this.table
    });
    duplicate_dialog.appendToBody().open();
  }

});

<|endoftext|>