<commit_before>var description = new (function Description() {
  var t = this;
  var skill = null;
  var
    // name
    name = $("#skill-name"),

    // main block
    level = $("#skill-level .w"),
    mp = $("#skill-mp .w"),
    required_weaps = {main:$("#skill-required-weapon"), desc:$("#skill-required-weapon .w")},
    type = $("#skill-type .w"),
    cd = $("#skill-cd .w"),
    total_sp = $("#skill-total-sp .w"),

    // level up reqs
    required_level = {main:$("#skill-required-level"), desc:$("#skill-required-level .w")},
    skills_required = {main:$("#skills-required"), desc:$("#skills-required")},
    sp_required = {main:$("#sp-required"), desc:$("#sp-required")},
    sp = {main:$("#skill-sp"), desc:$("#skill-sp .w")},

    // descriptions
    desc = $("#skill-description .d"),
    ndesc = {main:$("#next-description"), desc:$("#next-description .d")};

  this.updateTop = function() {
    if (!skill) {
      return;
    }

    var top = $(window).scrollTop(),
      minTop = $("#skill-tree-0").offset().top,
      maxTop = $("#skill-tree-2").offset().top;

    if (dnss.isFullScreen() && minTop < top) {
      if (maxTop < top) {
        $("#sidebar-2").css("top", (maxTop - minTop) + "px");
      } else {
        $("#sidebar-2").css("top", (top - minTop) + "px");
      }
    } else {
      $("#sidebar-2").css("top",0);
    }
  };

  this.use = function(s) {
    if (skill == s) { // no need to update more than once
      return;
    }

    skill = s;
    this.updateTop();
    this.update();
  };

  this.update = function() {
    if (!skill) {
      return;
    }

    // name
    setName();

    // main block
    setLevel();
    setMP();
    setRequiredWeapons();
    setType();
    setCD();
    setTotalSP();

    // level up reqs
    setRequiredLevel();
    setRequiredSkills();
    setRequiredSP();
    setSP();

    // descriptions
    setDescriptions();

    // if level up reqs are all hidden, just hide the level up req stuff
    var sep = $("#sidebar-2 .separator").first();
    if (required_level.main.is(":hidden") && skills_required.main.is(":hidden") && sp_required.main.is(":hidden") && sp.main.is(":hidden")) {
      sep.hide();
      sep.next().hide();
    } else {
      sep.show();
      sep.next().show();
    }
  };

  this.hook = function() {
    $("#mode").val(description.getMode());

    if (! skill) {
      return;
    }

    setMP();
    setCD();
    setDescriptions();
  };

  this.getMode = function() {
    return build.get(build.FLAG_POS) & 1 ? "pvp" : "pve";
  };

  function currOrNext(e, curr, next) {
    var after = e.data("after") ? " " + e.data("after") : "";
    e.html((curr == -1 ? next : curr) + after);
  }

  function showOrHide(e, text) {
    if (text == -1) {
      e.main.hide();
      return;
    }

    e.desc.html(text);
    e.main.show();
  }

  // Name
  function setName() {
    name.html(skill.getName());
  }

  // main block
  function setLevel() {
    currOrNext(level, skill.getLevel() ? skill.getLevel() : -1, skill.getNextLevel());
  }

  function setMP() {
    currOrNext(mp, skill.getLevel() ? skill.getMPUsage() : -1,  skill.getNextMPUsage());
  }

  function setRequiredWeapons() {
    showOrHide(required_weaps, skill.getRequiredWeapons());
  }

  function setType() {
    type.html(skill.getType());
  }

  function setCD() {
    currOrNext(cd, skill.getLevel() ? skill.getCD() : -1, skill.getNextCD());
  }

  function setTotalSP() {
    total_sp.html(skill.getTotalSPUsage());
  }

  // requirement block
  function setRequiredLevel() {
    showOrHide(required_level, skill.getNextRequiredLevel())
  }

  function setRequiredSkills() {
    showOrHide(skills_required, format(skill.getSkillRequirements()));
  }

  function setRequiredSP() {
    showOrHide(sp_required, format(skill.getSPRequirements()));
  }

  function setSP() {
    showOrHide(sp, skill.getLevel() < skill.getMaxLevel() ? skill.getNextSPUsage() : -1);
  }

  // description block
  function setDescriptions() {
    var d = skill.getDescription(), n = skill.getNextDescription();
    desc.html(format(d == -1 ? n : d));

    showOrHide(ndesc, d == -1  || n == -1 ? -1 : format(n));
  }

  function format(str) {
    if (str == -1) {
      return -1;
    }

    var c = 0, w = 0, p = 0, newStr = "", startPos = 0;
    for (var i = 0; i < str.length - 1; i++) {
      switch (str.substr(i, 2)) {
        case "#y": case "#p": case "#r":
          if (c - w == 1) { // needed a closing
            newStr += str.substring(startPos, i) + "";
          } else {
            newStr += str.substring(startPos, i) + "";
            c++;
          }

          startPos = i + 2;
          ++i;
          break;
        case "#w":
          if (w == c) { // early #w
            newStr +=  str.substring(startPos, i);
          } else {
            newStr += str.substring(startPos, i) + "";
            w++;
          }

          startPos = i + 2;
          ++i;
        default:
          break;
      }
    }

    newStr = newStr + str.substr(startPos);

    if (c != w) {
      newStr = newStr + "";
    }

    return newStr.replace(/\\n/g, "
");
  }

  $("#mode").click(function() {
    var mode = build.get(build.FLAG_POS) & 1;
    var flag  = (build.get(build.FLAG_POS) >> 1) << 1;
    build.put(build.FLAG_POS, flag | (mode?0:1));
    build.commit();

    t.hook();
  });
})();<commit_msg>v1.12:1 - Shortening code a bit.<commit_after>var description = new (function Description() {
  var t = this;
  var skill = null;
  var
    // name
    name = $("#skill-name"),

    // main block
    level = $("#skill-level .w"),
    mp = $("#skill-mp .w"),
    required_weaps = {main:$("#skill-required-weapon"), desc:$("#skill-required-weapon .w")},
    type = $("#skill-type .w"),
    cd = $("#skill-cd .w"),
    total_sp = $("#skill-total-sp .w"),

    // level up reqs
    required_level = {main:$("#skill-required-level"), desc:$("#skill-required-level .w")},
    skills_required = {main:$("#skills-required"), desc:$("#skills-required")},
    sp_required = {main:$("#sp-required"), desc:$("#sp-required")},
    sp = {main:$("#skill-sp"), desc:$("#skill-sp .w")},

    // descriptions
    desc = $("#skill-description .d"),
    ndesc = {main:$("#next-description"), desc:$("#next-description .d")};

  this.updateTop = function() {
    if (!skill) {
      return;
    }

    var top = $(window).scrollTop(),
      minTop = $("#skill-tree-0").offset().top,
      maxTop = $("#skill-tree-2").offset().top;

    if (dnss.isFullScreen() && minTop < top) {
      $("#sidebar-2").css("top", (Math.min(top, maxTop) - minTop) + "px");
    } else {
      $("#sidebar-2").css("top",0);
    }
  };

  this.use = function(s) {
    if (skill == s) { // no need to update more than once
      return;
    }

    skill = s;
    this.updateTop();
    this.update();
  };

  this.update = function() {
    if (!skill) {
      return;
    }

    // name
    setName();

    // main block
    setLevel();
    setMP();
    setRequiredWeapons();
    setType();
    setCD();
    setTotalSP();

    // level up reqs
    setRequiredLevel();
    setRequiredSkills();
    setRequiredSP();
    setSP();

    // descriptions
    setDescriptions();

    // if level up reqs are all hidden, just hide the level up req stuff
    var sep = $("#sidebar-2 .separator").first();
    if (required_level.main.is(":hidden") && skills_required.main.is(":hidden") && sp_required.main.is(":hidden") && sp.main.is(":hidden")) {
      sep.hide();
      sep.next().hide();
    } else {
      sep.show();
      sep.next().show();
    }
  };

  this.hook = function() {
    $("#mode").val(description.getMode());

    if (! skill) {
      return;
    }

    setMP();
    setCD();
    setDescriptions();
  };

  this.getMode = function() {
    return build.get(build.FLAG_POS) & 1 ? "pvp" : "pve";
  };

  function currOrNext(e, curr, next) {
    var after = e.data("after") ? " " + e.data("after") : "";
    e.html((curr == -1 ? next : curr) + after);
  }

  function showOrHide(e, text) {
    if (text == -1) {
      e.main.hide();
      return;
    }

    e.desc.html(text);
    e.main.show();
  }

  // Name
  function setName() {
    name.html(skill.getName());
  }

  // main block
  function setLevel() {
    currOrNext(level, skill.getLevel() ? skill.getLevel() : -1, skill.getNextLevel());
  }

  function setMP() {
    currOrNext(mp, skill.getLevel() ? skill.getMPUsage() : -1,  skill.getNextMPUsage());
  }

  function setRequiredWeapons() {
    showOrHide(required_weaps, skill.getRequiredWeapons());
  }

  function setType() {
    type.html(skill.getType());
  }

  function setCD() {
    currOrNext(cd, skill.getLevel() ? skill.getCD() : -1, skill.getNextCD());
  }

  function setTotalSP() {
    total_sp.html(skill.getTotalSPUsage());
  }

  // requirement block
  function setRequiredLevel() {
    showOrHide(required_level, skill.getNextRequiredLevel())
  }

  function setRequiredSkills() {
    showOrHide(skills_required, format(skill.getSkillRequirements()));
  }

  function setRequiredSP() {
    showOrHide(sp_required, format(skill.getSPRequirements()));
  }

  function setSP() {
    showOrHide(sp, skill.getLevel() < skill.getMaxLevel() ? skill.getNextSPUsage() : -1);
  }

  // description block
  function setDescriptions() {
    var d = skill.getDescription(), n = skill.getNextDescription();
    desc.html(format(d == -1 ? n : d));

    showOrHide(ndesc, d == -1  || n == -1 ? -1 : format(n));
  }

  function format(str) {
    if (str == -1) {
      return -1;
    }

    var c = 0, w = 0, p = 0, newStr = "", startPos = 0;
    for (var i = 0; i < str.length - 1; i++) {
      switch (str.substr(i, 2)) {
        case "#y": case "#p": case "#r":
          if (c - w == 1) { // needed a closing
            newStr += str.substring(startPos, i) + "";
          } else {
            newStr += str.substring(startPos, i) + "";
            c++;
          }

          startPos = i + 2;
          ++i;
          break;
        case "#w":
          if (w == c) { // early #w
            newStr +=  str.substring(startPos, i);
          } else {
            newStr += str.substring(startPos, i) + "";
            w++;
          }

          startPos = i + 2;
          ++i;
        default:
          break;
      }
    }

    newStr = newStr + str.substr(startPos);

    if (c != w) {
      newStr = newStr + "";
    }

    return newStr.replace(/\\n/g, "
");
  }

  $("#mode").click(function() {
    var mode = build.get(build.FLAG_POS) & 1;
    var flag  = (build.get(build.FLAG_POS) >> 1) << 1;
    build.put(build.FLAG_POS, flag | (mode?0:1));
    build.commit();

    t.hook();
  });
})();<|endoftext|>


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

/**
 * @fileoverview Earth Engine Developer's Guide examples
 *     from ee.FeatureView overview section
 */

// [START earthengine__featureview_overview__export]
// Import the WDPA feature collection.
var wdpa = ee.FeatureCollection('WCMC/WDPA/current/polygons');

// Export the WDPA FeatureCollection as a FeatureView asset.
Export.table.toFeatureView({
  collection: wdpa,
  assetId: 'wdpa-feature-view-demo',
  description: 'wdpa-feature-view-demo',
  maxFeaturesPerTile: 1500,
  thinningStrategy: 'HIGHER_DENSITY',
  thinningRanking: ['REP_AREA DESC'],
  zOrderRanking: ['REP_AREA DESC'],
});
// [END earthengine__featureview_overview__export]

// [START earthengine__featureview_overview__visualizing]
// Define the FeatureView asset ID.
var assetId = 'projects/google/feature-view-demo/wdpa';

// Import the FeatureView asset as a FeatureViewLayer.
var layer = ui.Map.FeatureViewLayer(assetId);

// Add the FeatureViewLayer to the map.
Map.add(layer);
// [END earthengine__featureview_overview__visualizing]

// [START earthengine__featureview_overview__styling]
// Set visualization properties for the defined layer.
layer.setVisParams({
  color: {
    property: 'MARINE',
    categories: [
      ['0', 'purple'],
      ['1', 'green'],
      ['2', 'blue'],
    ]
  },
  fillColor: {
    property: 'IUCN_CAT',
    defaultValue: 'd3d3d3',
    categories: [
      ['Ia', 'a6cee3'],
      ['Ib', '1f78b4'],
      ['II', 'b2df8a'],
      ['III', '33a02c'],
      ['IV', 'fb9a99'],
      ['V', 'e31a1c'],
      ['VI', 'fdbf6f'],
    ]
  },
  fillOpacity: {
    property: 'REP_AREA',
    mode: 'interval',
    palette: [
      [0, 0.5],
      [80, 0.35],
      [2000, 0.22],
      [5000, 0.15],
    ],
  },
  width: 1.0,
  pointSize: 6.0,
});
// [END earthengine__featureview_overview__styling]

// [START earthengine__featureview_overview__filtering]
// Define the FeatureView asset ID.
var assetId = 'projects/google/feature-view-demo/wdpa';

// Import the FeatureView asset as a FeatureViewLayer.
var layer = ui.Map.FeatureViewLayer(assetId, null, 'WDPA FeatureViewLayer');

// Callback function to update FeatureViewLayer style.
var updateVisParams = function() {
  layer.setVisParams({
    color: {
      property: 'MARINE',
      categories: [
        ['0', 'purple'],
        ['1', 'green'],
        ['2', 'blue'],
      ]
    },
    fillColor: {
      property: 'IUCN_CAT',
      defaultValue: 'd3d3d3',
      categories: [
        ['Ia', 'a6cee3'],
        ['Ib', '1f78b4'],
        ['II', 'b2df8a'],
        ['III', '33a02c'],
        ['IV', 'fb9a99'],
        ['V', 'e31a1c'],
        ['VI', 'fdbf6f'],
      ]
    },
    fillOpacity: {
      property: 'REP_AREA',
      mode: 'interval',
      palette: [
        [0, 0.5],
        [80, 0.35],
        [2000, 0.22],
        [5000, 0.15],
      ],
    },
    width: 1.0,
    pointSize: 6.0,
    rules: [
      {
        filter: ee.Filter.lt('REP_AREA', filterSlider.getValue()),
        isVisible: false,
      },
    ],
  });
};

// Slider widget that calls the updateVisParams function on change.
var filterSlider = ui.Slider({
  min: 0,
  max: 10000,
  step: 10,
  value: 0,
  style: { stretch: 'horizontal'},
  onChange: updateVisParams,
});
var filterSliderLabel = ui.Label(
  'Adjust slider to hide features less than the specified area (km²)');

// Add the slider to the map.
Map.add(ui.Panel([filterSliderLabel, filterSlider]));

// Initialize the FeatureViewLayer style.
updateVisParams();

// Add the FeatureViewLayer to the map.
Map.add(layer);
// [END earthengine__featureview_overview__filtering]
<commit_msg>Internal change<commit_after>/**
 * Copyright 2022 The Google Earth Engine Community Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Earth Engine Developer's Guide examples
 *     from ee.FeatureView overview section
 */

// [START earthengine__featureview_overview__export]
// Import the WDPA feature collection.
var wdpa = ee.FeatureCollection('WCMC/WDPA/current/polygons');

// Export the WDPA FeatureCollection as a FeatureView asset.
Export.table.toFeatureView({
  collection: wdpa,
  assetId: 'wdpa-featureview-demo',
  description: 'wdpa-featureview-demo',
  maxFeaturesPerTile: 1500,
  thinningStrategy: 'HIGHER_DENSITY',
  thinningRanking: ['REP_AREA DESC'],
  zOrderRanking: ['REP_AREA DESC'],
});
// [END earthengine__featureview_overview__export]

// [START earthengine__featureview_overview__visualizing]
// Define the FeatureView asset ID.
var assetId = 'WCMC/WDPA/current/polygons_FeatureView';

// Import the FeatureView asset as a FeatureViewLayer.
var layer = ui.Map.FeatureViewLayer(assetId);

// Add the FeatureViewLayer to the map.
Map.add(layer);
// [END earthengine__featureview_overview__visualizing]

// [START earthengine__featureview_overview__styling]
// Set visualization properties for the defined layer.
layer.setVisParams({
  color: {
    property: 'MARINE',
    categories: [
      ['0', 'purple'],
      ['1', 'green'],
      ['2', 'blue'],
    ]
  },
  fillColor: {
    property: 'IUCN_CAT',
    defaultValue: 'd3d3d3',
    categories: [
      ['Ia', 'a6cee3'],
      ['Ib', '1f78b4'],
      ['II', 'b2df8a'],
      ['III', '33a02c'],
      ['IV', 'fb9a99'],
      ['V', 'e31a1c'],
      ['VI', 'fdbf6f'],
    ]
  },
  fillOpacity: {
    property: 'REP_AREA',
    mode: 'interval',
    palette: [
      [0, 0.5],
      [80, 0.35],
      [2000, 0.22],
      [5000, 0.15],
    ],
  },
  width: 1.0,
  pointSize: 6.0,
});
// [END earthengine__featureview_overview__styling]

// [START earthengine__featureview_overview__filtering]
// Define the FeatureView asset ID.
var assetId = 'WCMC/WDPA/current/polygons_FeatureView';

// Import the FeatureView asset as a FeatureViewLayer.
var layer = ui.Map.FeatureViewLayer(assetId, null, 'WDPA FeatureViewLayer');

// Callback function to update FeatureViewLayer style.
var updateVisParams = function() {
  layer.setVisParams({
    color: {
      property: 'MARINE',
      categories: [
        ['0', 'purple'],
        ['1', 'green'],
        ['2', 'blue'],
      ]
    },
    fillColor: {
      property: 'IUCN_CAT',
      defaultValue: 'd3d3d3',
      categories: [
        ['Ia', 'a6cee3'],
        ['Ib', '1f78b4'],
        ['II', 'b2df8a'],
        ['III', '33a02c'],
        ['IV', 'fb9a99'],
        ['V', 'e31a1c'],
        ['VI', 'fdbf6f'],
      ]
    },
    fillOpacity: {
      property: 'REP_AREA',
      mode: 'interval',
      palette: [
        [0, 0.5],
        [80, 0.35],
        [2000, 0.22],
        [5000, 0.15],
      ],
    },
    width: 1.0,
    pointSize: 6.0,
    rules: [
      {
        filter: ee.Filter.lt('REP_AREA', filterSlider.getValue()),
        isVisible: false,
      },
    ],
  });
};

// Slider widget that calls the updateVisParams function on change.
var filterSlider = ui.Slider({
  min: 0,
  max: 10000,
  step: 10,
  value: 0,
  style: { stretch: 'horizontal'},
  onChange: updateVisParams,
});
var filterSliderLabel = ui.Label(
  'Adjust slider to hide features less than the specified area (km²)');

// Add the slider to the map.
Map.add(ui.Panel([filterSliderLabel, filterSlider]));

// Initialize the FeatureViewLayer style.
updateVisParams();

// Add the FeatureViewLayer to the map.
Map.add(layer);
// [END earthengine__featureview_overview__filtering]
<|endoftext|>


<commit_before>/*global numeral */
'use strict';

angular.module('ngNumeraljs', [])
    .provider('$numeraljsConfig', function () {
        var formats = {};

        this.setFormat = function (name, format) {
            formats[name] = format;
        };

        this.setDefaultFormat = function (format) {
            numeral.defaultFormat(format);
        };

        this.setLanguage = function (lang, def) {
            numeral.language(lang, def);
        };

        this.setCurrentLanguage = function (lang) {
            numeral.language(lang);
        };

        this.$get = function () {
            return {
                customFormat: function (name) {
                    return formats[name] || name;
                }
            };
        };
    })
    .filter('numeraljs', function ($numeraljsConfig) {
        return function (input, format) {
            if (!input) {
                return input;
            }

            format = $numeraljsConfig.customFormat(format);

            return numeral(input).format(format);
        };
    });
<commit_msg>make minification friendly<commit_after>/*global numeral */
'use strict';

angular.module('ngNumeraljs', [])
    .provider('$numeraljsConfig', function () {
        var formats = {};

        this.setFormat = function (name, format) {
            formats[name] = format;
        };

        this.setDefaultFormat = function (format) {
            numeral.defaultFormat(format);
        };

        this.setLanguage = function (lang, def) {
            numeral.language(lang, def);
        };

        this.setCurrentLanguage = function (lang) {
            numeral.language(lang);
        };

        this.$get = function () {
            return {
                customFormat: function (name) {
                    return formats[name] || name;
                }
            };
        };
    })
    .filter('numeraljs', ['$numeraljsConfig', function ($numeraljsConfig) {
        return function (input, format) {
            if (!input) {
                return input;
            }

            format = $numeraljsConfig.customFormat(format);

            return numeral(input).format(format);
        };
    }]);
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    plumber = require('gulp-plumber'),
    sass = require('gulp-sass'),
    cleanCSS = require('gulp-clean-css'),
    rename = require('gulp-rename'),
    util = require('gulp-util'),
    sourcemaps = require('gulp-sourcemaps');

gulp.task('styles', function () {
 return gulp.src('css/index.scss')
  .pipe(plumber())
  .pipe(sourcemaps.init())
    .pipe(sass())
    //TODO: add autoprefixer
    .pipe(process.env.NODE_ENV ? cleanCSS() : util.noop())
  .pipe(sourcemaps.write())
  .pipe(rename('bundle.min.css'))
  .pipe(gulp.dest('dist'))
  .pipe(gulp.browserSync.stream());
});
<commit_msg>Update styles.js<commit_after>var gulp = require('gulp'),
    plumber = require('gulp-plumber'),
    sass = require('gulp-sass'),
    cleanCSS = require('gulp-clean-css'),
    rename = require('gulp-rename'),
    util = require('gulp-util'),
    sourcemaps = require('gulp-sourcemaps');

gulp.task('styles', function () {
 return gulp.src('css/index.scss')
  .pipe(plumber())
  .pipe(sourcemaps.init())
    .pipe(sass.sync())
    //TODO: add autoprefixer
    .pipe(process.env.NODE_ENV ? cleanCSS() : util.noop())
  .pipe(sourcemaps.write())
  .pipe(rename('bundle.min.css'))
  .pipe(gulp.dest('dist'))
  .pipe(gulp.browserSync.stream());
});
<|endoftext|>


<commit_before>var ItemsA = new Meteor.Collection('ItemsA');
var ItemsB = new Meteor.Collection('ItemsB');

if (Meteor.isServer) {
  Meteor.methods({
    initDb: function() {
      ItemsA.remove({});
      ItemsB.remove({});
      for (var i = 1; i <= 11; i++) {
        ItemsA.insert({val: i, a: 1, b: 1, x: {a: 1, b: 1}});
        ItemsB.insert({val: i, a: 1, b: 1, x: {a: 1, b: 1}});
      }
    }
  });

  Meteor.smartPublish('items', function(l, r) {
    return [
      ItemsA.find({val: {$lt: l}}, {fields: {val: 1, a: 1, 'x.a': 1}}),
      ItemsA.find({val: {$gt: r}}, {fields: {val: 1, b: 1, 'x.b': 1}}),
      ItemsB.find({val: {$lt: r}}, {fields: {val: 1, a: 1, 'x.a': 1}}),
      ItemsB.find({val: {$gt: l}}, {fields: {val: 1, b: 1, 'x.b': 1}}),
    ];
  });
  Meteor.methods({
    updateA6To0: function() {
      ItemsA.update({val: 6}, {$set: {val: 0}});
    }
  });
}

if (Meteor.isClient) {
  Tinytest.addAsync('init', function(test, next) {
    Meteor.call('initDb', function(err) {
      test.isUndefined(err, 'error during initialization: ' + err);
      test.equal(ItemsA.find().count(), 0, 'ItemsA is not empty');
      test.equal(ItemsB.find().count(), 0, 'ItemsB is not empty');
      next();
    });
  });

  function getVals(coll, filter) {
    return _.pluck(coll.find(filter || {}, {fields: {val: 1}}).fetch(), 'val')
  }

  var subscr;
  Tinytest.addAsync('subscription start', function(test, next) {
    subscr = Meteor.subscribe('items', 4, 9, function() {
      test.equal(getVals(ItemsA), [1,2,3,10,11], 'ItemsA is invalid');
      test.equal(getVals(ItemsB), [1,2,3,4,5,6,7,8,9,10,11], 'ItemsB is invalid');

      test.equal(getVals(ItemsA,    {a : 1}), [1,2,3], 'ItemsA.a is invalid');
      test.equal(getVals(ItemsA, {'x.a': 1}), [1,2,3], 'ItemsA.x.a is invalid');
      test.equal(getVals(ItemsA,    {b : 1}), [10,11], 'ItemsA.b is invalid');
      test.equal(getVals(ItemsA, {'x.b': 1}), [10,11], 'ItemsA.x.b is invalid');
      test.equal(getVals(ItemsB,    {a : 1}), [1,2,3,4,5,6,7,8], 'ItemsB.a is invalid');
      test.equal(getVals(ItemsB, {'x.a': 1}), [1,2,3,4,5,6,7,8], 'ItemsB.x.a is invalid');
      test.equal(getVals(ItemsB,    {b : 1}), [5,6,7,8,9,10,11], 'ItemsB.b is invalid');
      test.equal(getVals(ItemsB, {'x.b': 1}), [5,6,7,8,9,10,11], 'ItemsB.x.b is invalid');
      next();
    });
  });

  Tinytest.addAsync('update with element remove', function(test, next) {
    ItemsA.update(ItemsA.findOne({val: 2})._id, {$set: {val: 4}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(ItemsA), [1,3,10,11], 'ItemsA');
      next();
    });
  });

  Tinytest.addAsync('update with element add', function(test, next) {
    Meteor.call('updateA6To0', function(err, res) {
      test.isUndefined(err, 'error during method call: ' + err);
      test.equal(getVals(ItemsA), [1,3,10,11,0], 'ItemsA');
      next();
    });
  });

  Tinytest.addAsync('update with field add', function(test, next) {
    var id = ItemsB.findOne({val: 2})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 2, a: 1, x: {a: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 5}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 5, a: 1, b: 1, x: {a: 1, b: 1}}, 'resulting fieldset');
      next();
    });
  });

  Tinytest.addAsync('update with field remove', function(test, next) {
    var id = ItemsB.findOne({val: 5})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 5, a: 1, b: 1, x: {a: 1, b: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 0}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 0, a: 1, x: {a: 1}}, 'resulting fieldset');
      next();
    });
  });

  Tinytest.addAsync('update with field remove&add', function(test, next) {
    var id = ItemsB.findOne({val: 3})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 3, a: 1, x: {a: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 12}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 12, b: 1, x: {b: 1}}, 'resulting fieldset');
      next();
    });
  });

  Tinytest.addAsync('update with field add&remove', function(test, next) {
    var id = ItemsB.findOne({val: 10})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 10, b: 1, x: {b: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 3}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 3, a: 1, x: {a: 1}}, 'resulting fieldset');
      next();
    });
  });
  Tinytest.addAsync('two-stage update with field add&remove (2->1)', function(test, next) {
    var id = ItemsB.findOne({val: 11})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 11, b: 1, x: {b: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 5.5}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 5.5, a: 1, b: 1, x: {a: 1, b: 1}}, 'intermediate fieldset');

      ItemsB.update(id, {$set: {val: -1}}, function(err, res) {
        test.isUndefined(err, 'error during update: ' + err);
        test.equal(ItemsB.findOne(id), {_id: id, val: -1, a: 1, x: {a: 1}}, 'resulting fieldset');
      });
      next();
    });
  });
  Tinytest.addAsync('two-stage update with field add&remove (1->2)', function(test, next) {
    var id = ItemsB.findOne({val: 1})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 1, a: 1, x: {a: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 5.5}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 5.5, a: 1, b: 1, x: {a: 1, b: 1}}, 'intermediate fieldset');

      ItemsB.update(id, {$set: {val: 13}}, function(err, res) {
        test.isUndefined(err, 'error during update: ' + err);
        test.equal(ItemsB.findOne(id), {_id: id, val: 13, b: 1, x: {b: 1}}, 'resulting fieldset');
      });
      next();
    });
  });

  Tinytest.addAsync('subscription stop', function(test, next) {
    subscr.stop();
    Meteor.setTimeout(function() {
      test.equal(ItemsA.find().count(), 0, 'ItemsA is not empty');
      test.equal(ItemsB.find().count(), 0, 'ItemsB is not empty');
      next();
    }, 100);
  });
}
<commit_msg>tests/several-cursors.js: added test for correctness of passing strange JSON values via several cursors which publish the same data<commit_after>var ItemsA = new Meteor.Collection('ItemsA');
var ItemsB = new Meteor.Collection('ItemsB');
var ItemsC = new Meteor.Collection('ItemsC');

var itemCValue = {
  _id: 'the only one',
  number0: 0,
  number1: 123,
  string0: '',
  string1: 'hello',
  bool0: false,
  bool1: true,
  arr0: [],
  arr1: [1, 2, 'hi', {obj: false}, null, {'': null}],
  arr2: [null],
  null: null,
  '': null
};

if (Meteor.isServer) {
  Meteor.methods({
    initDb: function() {
      ItemsA.remove({});
      ItemsB.remove({});
      ItemsC.remove({});
      for (var i = 1; i <= 11; i++) {
        ItemsA.insert({val: i, a: 1, b: 1, x: {a: 1, b: 1}});
        ItemsB.insert({val: i, a: 1, b: 1, x: {a: 1, b: 1}});
      }
      ItemsC.insert(itemCValue);
    }
  });

  Meteor.smartPublish('items', function(l, r) {
    return [
      ItemsA.find({val: {$lt: l}}, {fields: {val: 1, a: 1, 'x.a': 1}}),
      ItemsA.find({val: {$gt: r}}, {fields: {val: 1, b: 1, 'x.b': 1}}),
      ItemsB.find({val: {$lt: r}}, {fields: {val: 1, a: 1, 'x.a': 1}}),
      ItemsB.find({val: {$gt: l}}, {fields: {val: 1, b: 1, 'x.b': 1}}),
      ItemsC.find(),
      ItemsC.find(),
      ItemsC.find(),
    ];
  });
  Meteor.methods({
    updateA6To0: function() {
      ItemsA.update({val: 6}, {$set: {val: 0}});
    }
  });
}

if (Meteor.isClient) {
  Tinytest.addAsync('init', function(test, next) {
    Meteor.call('initDb', function(err) {
      test.isUndefined(err, 'error during initialization: ' + err);
      test.equal(ItemsA.find().count(), 0, 'ItemsA is not empty');
      test.equal(ItemsB.find().count(), 0, 'ItemsB is not empty');
      test.equal(ItemsC.find().count(), 0, 'Items is not empty');
      next();
    });
  });

  function getVals(coll, filter) {
    return _.pluck(coll.find(filter || {}, {fields: {val: 1}}).fetch(), 'val')
  }

  var subscr;
  Tinytest.addAsync('subscription start', function(test, next) {
    subscr = Meteor.subscribe('items', 4, 9, function() {
      test.equal(getVals(ItemsA), [1,2,3,10,11], 'ItemsA is invalid');
      test.equal(getVals(ItemsB), [1,2,3,4,5,6,7,8,9,10,11], 'ItemsB is invalid');

      test.equal(getVals(ItemsA,    {a : 1}), [1,2,3], 'ItemsA.a is invalid');
      test.equal(getVals(ItemsA, {'x.a': 1}), [1,2,3], 'ItemsA.x.a is invalid');
      test.equal(getVals(ItemsA,    {b : 1}), [10,11], 'ItemsA.b is invalid');
      test.equal(getVals(ItemsA, {'x.b': 1}), [10,11], 'ItemsA.x.b is invalid');
      test.equal(getVals(ItemsB,    {a : 1}), [1,2,3,4,5,6,7,8], 'ItemsB.a is invalid');
      test.equal(getVals(ItemsB, {'x.a': 1}), [1,2,3,4,5,6,7,8], 'ItemsB.x.a is invalid');
      test.equal(getVals(ItemsB,    {b : 1}), [5,6,7,8,9,10,11], 'ItemsB.b is invalid');
      test.equal(getVals(ItemsB, {'x.b': 1}), [5,6,7,8,9,10,11], 'ItemsB.x.b is invalid');
      next();
    });
  });

  Tinytest.addAsync('several publications of the same field', function(test, next) {
    test.equal(ItemsC.find().fetch(), [itemCValue], 'ItemsC is incorrect');
    next();
  });

  Tinytest.addAsync('update with element remove', function(test, next) {
    ItemsA.update(ItemsA.findOne({val: 2})._id, {$set: {val: 4}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(ItemsA), [1,3,10,11], 'ItemsA');
      next();
    });
  });

  Tinytest.addAsync('update with element add', function(test, next) {
    Meteor.call('updateA6To0', function(err, res) {
      test.isUndefined(err, 'error during method call: ' + err);
      test.equal(getVals(ItemsA), [1,3,10,11,0], 'ItemsA');
      next();
    });
  });

  Tinytest.addAsync('update with field add', function(test, next) {
    var id = ItemsB.findOne({val: 2})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 2, a: 1, x: {a: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 5}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 5, a: 1, b: 1, x: {a: 1, b: 1}}, 'resulting fieldset');
      next();
    });
  });

  Tinytest.addAsync('update with field remove', function(test, next) {
    var id = ItemsB.findOne({val: 5})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 5, a: 1, b: 1, x: {a: 1, b: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 0}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 0, a: 1, x: {a: 1}}, 'resulting fieldset');
      next();
    });
  });

  Tinytest.addAsync('update with field remove&add', function(test, next) {
    var id = ItemsB.findOne({val: 3})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 3, a: 1, x: {a: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 12}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 12, b: 1, x: {b: 1}}, 'resulting fieldset');
      next();
    });
  });

  Tinytest.addAsync('update with field add&remove', function(test, next) {
    var id = ItemsB.findOne({val: 10})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 10, b: 1, x: {b: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 3}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 3, a: 1, x: {a: 1}}, 'resulting fieldset');
      next();
    });
  });
  Tinytest.addAsync('two-stage update with field add&remove (2->1)', function(test, next) {
    var id = ItemsB.findOne({val: 11})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 11, b: 1, x: {b: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 5.5}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 5.5, a: 1, b: 1, x: {a: 1, b: 1}}, 'intermediate fieldset');

      ItemsB.update(id, {$set: {val: -1}}, function(err, res) {
        test.isUndefined(err, 'error during update: ' + err);
        test.equal(ItemsB.findOne(id), {_id: id, val: -1, a: 1, x: {a: 1}}, 'resulting fieldset');
      });
      next();
    });
  });
  Tinytest.addAsync('two-stage update with field add&remove (1->2)', function(test, next) {
    var id = ItemsB.findOne({val: 1})._id;
    test.equal(ItemsB.findOne(id), {_id: id, val: 1, a: 1, x: {a: 1}}, 'initial fieldset');
    ItemsB.update(id, {$set: {val: 5.5}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(ItemsB.findOne(id), {_id: id, val: 5.5, a: 1, b: 1, x: {a: 1, b: 1}}, 'intermediate fieldset');

      ItemsB.update(id, {$set: {val: 13}}, function(err, res) {
        test.isUndefined(err, 'error during update: ' + err);
        test.equal(ItemsB.findOne(id), {_id: id, val: 13, b: 1, x: {b: 1}}, 'resulting fieldset');
      });
      next();
    });
  });

  Tinytest.addAsync('subscription stop', function(test, next) {
    subscr.stop();
    Meteor.setTimeout(function() {
      test.equal(ItemsA.find().count(), 0, 'ItemsA is not empty');
      test.equal(ItemsB.find().count(), 0, 'ItemsB is not empty');
      next();
    }, 100);
  });
}
<|endoftext|>


<commit_before>'use strict';

var Plotly = require('../../plotly');
var htmlToUnicode = require('../../gl3d/lib/html2unicode');
var str2RGBArray = require('../../gl3d/lib/str2rgbarray');

function Axes2DOptions(scene) {
    this.scene = scene;
    this.gl = scene.gl;
    this.pixelRatio = scene.pixelRatio;

    this.screenBox = [0, 0, 1, 1];
    this.viewBox = [0 ,0, 1, 1];
    this.dataBox = [-1, -1, 1, 1];

    this.borderLineEnable = [false, false, false, false];
    this.borderLineWidth = [1, 1, 1, 1];
    this.borderLineColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.ticks = [[], []];
    this.tickEnable = [true, true, false, false];
    this.tickPad = [15, 15, 15, 15];
    this.tickAngle = [0, 0, 0, 0];
    this.tickColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];
    this.tickMarkLength = [0, 0, 0, 0];
    this.tickMarkWidth = [0, 0, 0, 0];
    this.tickMarkColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.labels = ['x', 'y'];
    this.labelEnable = [true, true, false, false];
    this.labelAngle  = [0, Math.PI/2, 0, 3.0*Math.PI/2];
    this.labelPad = [15, 15, 15, 15];
    this.labelSize = [12, 12];
    this.labelFont = ['sans-serif', 'sans-serif'];
    this.labelColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.title = '';
    this.titleEnable = true;
    this.titleCenter = [0, 0, 0, 0];
    this.titleAngle = 0;
    this.titleColor = [0, 0, 0, 1];
    this.titleFont = 'sans-serif';
    this.titleSize = 18;

    this.gridLineEnable = [true, true];
    this.gridLineColor = [
        [0, 0, 0, 0.5],
        [0, 0, 0, 0.5]
    ];
    this.gridLineWidth = [1, 1];

    this.zeroLineEnable = [true, true];
    this.zeroLineWidth = [1, 1];
    this.zeroLineColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.borderColor = [0, 0, 0, 0];
    this.backgroundColor = [0, 0, 0, 0];
}

var proto = Axes2DOptions.prototype;

var AXES = ['xaxis', 'yaxis'];

proto.merge = function(options) {

    // titles are rendered in SVG
    this.titleEnable = false;
    this.backgroundColor = str2RGBArray(options.plot_bgcolor);

    var axisName, ax, axTitle, axMirror;
    var hasAxisInDfltPos, hasAxisInAltrPos, hasSharedAxis, mirrorLines, mirrorTicks;
    var i, j;

    for(i = 0; i < 2; ++i) {
        axisName = AXES[i];

        // get options relevant to this subplot,
        // '_name' is e.g. xaxis, xaxis2, yaxis, yaxis4 ...
        ax = options[this.scene[axisName]._name];

        axTitle = /Click to enter .+ title/.test(ax.title) ?  '' : ax.title;

        for(j = 0; j <= 2; j += 2) {
            this.labelEnable[i+j] = false;
            this.labels[i+j] = htmlToUnicode(axTitle);
            this.labelColor[i+j] = str2RGBArray(ax.titlefont.color);
            this.labelFont[i+j] = ax.titlefont.family;
            this.labelSize[i+j] = ax.titlefont.size;
            this.labelPad[i+j] = this.getLabelPad(axisName, ax);

            this.tickEnable[i+j] = false;
            this.tickColor[i+j] = str2RGBArray((ax.tickfont || {}).color);
            this.tickAngle[i+j] = (ax.tickangle === 'auto') ? 0 : -ax.tickangle;
            this.tickPad[i+j] = this.getTickPad(ax);

            this.tickMarkLength[i+j] = 0;
            this.tickMarkWidth[i+j] = ax.tickwidth || 0;
            this.tickMarkColor[i+j] = str2RGBArray(ax.tickcolor);

            this.borderLineEnable[i+j] = false;
            this.borderLineColor[i+j] = str2RGBArray(ax.linecolor);
            this.borderLineWidth[i+j] = ax.linewidth || 0;
        }

        hasSharedAxis = this.hasSharedAxis(ax);
        hasAxisInDfltPos = this.hasAxisInDfltPos(axisName, ax) && !hasSharedAxis;
        hasAxisInAltrPos = this.hasAxisInAltrPos(axisName, ax) && !hasSharedAxis;

        axMirror = ax.mirror || false
        mirrorLines = hasSharedAxis ?
            (String(axMirror).indexOf('all') !== -1) :  // 'all' or 'allticks'
            !!axMirror;                                 // all but false
        mirrorTicks = hasSharedAxis ?
            (axMirror === 'allticks') :
            (String(axMirror).indexOf('ticks') !== -1); // 'ticks' or 'allticks'

        // Axis titles and tick labels can only appear of one side of the scene
        //  and are never show on subplots that share existing axes.

        if(hasAxisInDfltPos) this.labelEnable[i] = true;
        else if(hasAxisInAltrPos) this.labelEnable[i+2] = true;

        if(hasAxisInDfltPos) this.tickEnable[i] = ax.showticklabels;
        else if(hasAxisInAltrPos) this.tickEnable[i+2] = ax.showticklabels;

        // Grid lines and ticks can appear on both sides of the scene
        //  and can appear on subplot that share existing axes via `ax.mirror`.

        if(hasAxisInDfltPos || mirrorLines) this.borderLineEnable[i] = ax.showline;
        if(hasAxisInAltrPos || mirrorLines) this.borderLineEnable[i+2] = ax.showline;

        if(hasAxisInDfltPos || mirrorTicks) this.tickMarkLength[i] = this.getTickMarkLength(ax);
        if(hasAxisInAltrPos || mirrorTicks) this.tickMarkLength[i+2] = this.getTickMarkLength(ax);

        this.gridLineEnable[i] = ax.showgrid;
        this.gridLineColor[i] = str2RGBArray(ax.gridcolor);
        this.gridLineWidth[i] = ax.gridwidth;

        this.zeroLineEnable[i] = ax.zeroline;
        this.zeroLineColor[i] = str2RGBArray(ax.zerolinecolor);
        this.zeroLineWidth[i] = ax.zerolinewidth;
    }
};

// is an axis shared with an already-drawn subplot ?
proto.hasSharedAxis = function(ax) {
    var scene = this.scene,
        subplotIds = Plotly.Plots.getSubplotIds(scene.fullLayout, 'gl2d'),
        list = Plotly.Axes.findSubplotsWithAxis(subplotIds, ax);

    // if index === 0, then the subplot is already drawn as subplots
    // are drawn in order.
    return (list.indexOf(scene.id) !== 0);
};

// has an axis in default position (i.e. bottom/left) ?
proto.hasAxisInDfltPos = function(axisName, ax) {
    var axSide = ax.side;

    return {
        xaxis: (axSide === 'bottom'),
        yaxis: (axSide === 'left')
    }[axisName];
};

// has an axis in alternate position (i.e. top/right) ?
proto.hasAxisInAltrPos = function(axisName, ax) {
    var axSide = ax.side;

    return {
        xaxis: (axSide === 'top'),
        yaxis: (axSide === 'right')
    }[axisName];
};

proto.getLabelPad = function(axisName, ax) {
    var offsetBase = 1.5,
        fontSize = ax.titlefont.size,
        showticklabels = ax.showticklabels;

    return {
        xaxis: (ax.side === 'top') ?
            -10 + fontSize * (offsetBase + (showticklabels ? 1 : 0)) :
            -10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0)),
        yaxis: (ax.side === 'right') ?
            10 + fontSize * (offsetBase + (showticklabels ? 1 : 0.5)) :
            10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0))
    }[axisName];
};

proto.getTickPad = function(ax) {
    return (ax.ticks === 'outside') ? 10 + ax.ticklen : 15;
};

proto.getTickMarkLength = function(ax) {
    if(!ax.ticks) return 0;

    var ticklen = ax.ticklen;

    return (ax.ticks === 'inside') ? -ticklen : ticklen;
};

function createAxes2D(scene) {
    return new Axes2DOptions(scene);
}

module.exports = createAxes2D;
<commit_msg>perf gl2daxes<commit_after>'use strict';

var Plotly = require('../../plotly');
var htmlToUnicode = require('../../gl3d/lib/html2unicode');
var str2RGBArray = require('../../gl3d/lib/str2rgbarray');

function Axes2DOptions(scene) {
    this.scene = scene;
    this.gl = scene.gl;
    this.pixelRatio = scene.pixelRatio;

    this.screenBox = [0, 0, 1, 1];
    this.viewBox = [0 ,0, 1, 1];
    this.dataBox = [-1, -1, 1, 1];

    this.borderLineEnable = [false, false, false, false];
    this.borderLineWidth = [1, 1, 1, 1];
    this.borderLineColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.ticks = [[], []];
    this.tickEnable = [true, true, false, false];
    this.tickPad = [15, 15, 15, 15];
    this.tickAngle = [0, 0, 0, 0];
    this.tickColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];
    this.tickMarkLength = [0, 0, 0, 0];
    this.tickMarkWidth = [0, 0, 0, 0];
    this.tickMarkColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.labels = ['x', 'y'];
    this.labelEnable = [true, true, false, false];
    this.labelAngle  = [0, Math.PI/2, 0, 3.0*Math.PI/2];
    this.labelPad = [15, 15, 15, 15];
    this.labelSize = [12, 12];
    this.labelFont = ['sans-serif', 'sans-serif'];
    this.labelColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.title = '';
    this.titleEnable = true;
    this.titleCenter = [0, 0, 0, 0];
    this.titleAngle = 0;
    this.titleColor = [0, 0, 0, 1];
    this.titleFont = 'sans-serif';
    this.titleSize = 18;

    this.gridLineEnable = [true, true];
    this.gridLineColor = [
        [0, 0, 0, 0.5],
        [0, 0, 0, 0.5]
    ];
    this.gridLineWidth = [1, 1];

    this.zeroLineEnable = [true, true];
    this.zeroLineWidth = [1, 1];
    this.zeroLineColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.borderColor = [0, 0, 0, 0];
    this.backgroundColor = [0, 0, 0, 0];
}

var proto = Axes2DOptions.prototype;

var AXES = ['xaxis', 'yaxis'];

proto.merge = function(options) {

    // titles are rendered in SVG
    this.titleEnable = false;
    this.backgroundColor = str2RGBArray(options.plot_bgcolor);

    var axisName, ax, axTitle, axMirror;
    var hasAxisInDfltPos, hasAxisInAltrPos, hasSharedAxis, mirrorLines, mirrorTicks;
    var i, j;

    for(i = 0; i < 2; ++i) {
        axisName = AXES[i];

        // get options relevant to this subplot,
        // '_name' is e.g. xaxis, xaxis2, yaxis, yaxis4 ...
        ax = options[this.scene[axisName]._name];

        axTitle = /Click to enter .+ title/.test(ax.title) ?  '' : ax.title;

        for(j = 0; j <= 2; j += 2) {
            this.labelEnable[i+j] = false;
            this.labels[i+j] = htmlToUnicode(axTitle);
            this.labelColor[i+j] = str2RGBArray(ax.titlefont.color);
            this.labelFont[i+j] = ax.titlefont.family;
            this.labelSize[i+j] = ax.titlefont.size;
            this.labelPad[i+j] = this.getLabelPad(axisName, ax);

            this.tickEnable[i+j] = false;
            this.tickColor[i+j] = str2RGBArray((ax.tickfont || {}).color);
            this.tickAngle[i+j] = (ax.tickangle === 'auto') ? 0 : -ax.tickangle;
            this.tickPad[i+j] = this.getTickPad(ax);

            this.tickMarkLength[i+j] = 0;
            this.tickMarkWidth[i+j] = ax.tickwidth || 0;
            this.tickMarkColor[i+j] = str2RGBArray(ax.tickcolor);

            this.borderLineEnable[i+j] = false;
            this.borderLineColor[i+j] = str2RGBArray(ax.linecolor);
            this.borderLineWidth[i+j] = ax.linewidth || 0;
        }

        hasSharedAxis = this.hasSharedAxis(ax);
        hasAxisInDfltPos = this.hasAxisInDfltPos(axisName, ax) && !hasSharedAxis;
        hasAxisInAltrPos = this.hasAxisInAltrPos(axisName, ax) && !hasSharedAxis;

        axMirror = ax.mirror || false;
        mirrorLines = hasSharedAxis ?
            (String(axMirror).indexOf('all') !== -1) :  // 'all' or 'allticks'
            !!axMirror;                                 // all but false
        mirrorTicks = hasSharedAxis ?
            (axMirror === 'allticks') :
            (String(axMirror).indexOf('ticks') !== -1); // 'ticks' or 'allticks'

        // Axis titles and tick labels can only appear of one side of the scene
        //  and are never show on subplots that share existing axes.

        if(hasAxisInDfltPos) this.labelEnable[i] = true;
        else if(hasAxisInAltrPos) this.labelEnable[i+2] = true;

        if(hasAxisInDfltPos) this.tickEnable[i] = ax.showticklabels;
        else if(hasAxisInAltrPos) this.tickEnable[i+2] = ax.showticklabels;

        // Grid lines and ticks can appear on both sides of the scene
        //  and can appear on subplot that share existing axes via `ax.mirror`.

        if(hasAxisInDfltPos || mirrorLines) this.borderLineEnable[i] = ax.showline;
        if(hasAxisInAltrPos || mirrorLines) this.borderLineEnable[i+2] = ax.showline;

        if(hasAxisInDfltPos || mirrorTicks) this.tickMarkLength[i] = this.getTickMarkLength(ax);
        if(hasAxisInAltrPos || mirrorTicks) this.tickMarkLength[i+2] = this.getTickMarkLength(ax);

        this.gridLineEnable[i] = ax.showgrid;
        this.gridLineColor[i] = str2RGBArray(ax.gridcolor);
        this.gridLineWidth[i] = ax.gridwidth;

        this.zeroLineEnable[i] = ax.zeroline;
        this.zeroLineColor[i] = str2RGBArray(ax.zerolinecolor);
        this.zeroLineWidth[i] = ax.zerolinewidth;
    }
};

// is an axis shared with an already-drawn subplot ?
proto.hasSharedAxis = function(ax) {
    var scene = this.scene,
        subplotIds = Plotly.Plots.getSubplotIds(scene.fullLayout, 'gl2d'),
        list = Plotly.Axes.findSubplotsWithAxis(subplotIds, ax);

    // if index === 0, then the subplot is already drawn as subplots
    // are drawn in order.
    return (list.indexOf(scene.id) !== 0);
};

// has an axis in default position (i.e. bottom/left) ?
proto.hasAxisInDfltPos = function(axisName, ax) {
    var axSide = ax.side;

    if(axisName === 'xaxis') return (axSide === 'bottom');
    else if(axisName === 'yaxis') return (axSide === 'left');
};

// has an axis in alternate position (i.e. top/right) ?
proto.hasAxisInAltrPos = function(axisName, ax) {
    var axSide = ax.side;

    if(axisName === 'xaxis') return (axSide === 'top');
    else if(axisName === 'yaxis') return (axSide === 'right');
};

proto.getLabelPad = function(axisName, ax) {
    var offsetBase = 1.5,
        fontSize = ax.titlefont.size,
        showticklabels = ax.showticklabels;

    if(axisName === 'xaxis') {
        return (ax.side === 'top') ?
            -10 + fontSize * (offsetBase + (showticklabels ? 1 : 0)) :
            -10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0));
    }
    else if(axisName === 'yaxis') {
        return (ax.side === 'right') ?
            10 + fontSize * (offsetBase + (showticklabels ? 1 : 0.5)) :
            10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0));
    }
};

proto.getTickPad = function(ax) {
    return (ax.ticks === 'outside') ? 10 + ax.ticklen : 15;
};

proto.getTickMarkLength = function(ax) {
    if(!ax.ticks) return 0;

    var ticklen = ax.ticklen;

    return (ax.ticks === 'inside') ? -ticklen : ticklen;
};

function createAxes2D(scene) {
    return new Axes2DOptions(scene);
}

module.exports = createAxes2D;
<|endoftext|>


<commit_before>import './styles.scss';

import Emitter from 'helpers/Emitter';
import SoundManager from 'helpers/SoundManager';

import { Component } from 'react';

import {
  EXP_FLASH_MSG,
  EXP_INTRO_FLASH_MSG,
  EXP_SHOW_VIDEO,
  EXP_GOAL_ACHIEVE,
  EXP_TOGGLE_PAUSE_GAME
} from 'config/messages';

/**
 * FlashMessages component
 */
class FlashMessages extends Component {

  componentWillMount() {

    this.bind();

    this.enable = true;
  }

  componentDidMount() {

    this.addListeners();

    this.debug();
  }

  componentWillUnmount() {

    this.removeListeners();
  }

  debug() {
    window.debug.flashMessage = this.addFlashMessage;

    window.debug.goodFlashMessage = () => {

      this.addFlashMessage( 'good', 'Bonne nouvelle +3 lux', 3 );
    };

    window.debug.badFlashMessage = () => {

      this.addFlashMessage( 'danger', 'Mauvaise nouvelle :(', 3 );
    };

    const onKeyUp = ( ev )=> {

      if( ev.keyCode === 66 ) { // b

        this.addFlashMessage( 'danger', 'Mauvaise nouvelle :(', 3 );

      } else if( ev.keyCode === 71 ) { //g

        this.addFlashMessage( 'win', "Congratulations ! You've caught enough Lux to go on. Before going any deeper, here’s an explanation about what you’ve been through", 3 );

        setTimeout( () => { this.addFlashMessage( 'good', 'A video will start in ...', 3 ); }, 1000 );
        setTimeout( () => { this.addFlashMessage( 'good', '3', 3 ); }, 2000 );
        setTimeout( () => { this.addFlashMessage( 'good', '2', 3 ); }, 3000 );
        setTimeout( () => { this.addFlashMessage( 'good', '1', 3 ); }, 4000 );
        setTimeout( () => { Emitter.emit( EXP_SHOW_VIDEO ); }, 6000 );

      }

    };

    document.addEventListener( 'keyup', onKeyUp, false );
  }

  bind() {

    [ 'addFlashMessage', 'introFlashMessage', 'endFlashMessage' ]
        .forEach( ( fn ) => this[ fn ] = this[ fn ].bind( this ) );

  }

  addListeners() {

    Emitter.on( EXP_FLASH_MSG, this.addFlashMessage );
    Emitter.once( EXP_INTRO_FLASH_MSG, this.introFlashMessage );
    Emitter.once( EXP_GOAL_ACHIEVE, this.endFlashMessage );
  }

  removeListeners() {

    Emitter.off( EXP_GOAL_ACHIEVE, this.endFlashMessage );
    Emitter.off( EXP_FLASH_MSG, this.addFlashMessage );
    Emitter.off( EXP_INTRO_FLASH_MSG, this.introFlashMessage );
  }

  introFlashMessage() {

    this.addFlashMessage( 'anecdotic', 'Oh hi there ! You’ve reached the first abyssal area, called mesopelagic zone. Find and click on the fishes to get some light and dive deeper', 5 );
  }

  endFlashMessage() {

    Emitter.emit( EXP_TOGGLE_PAUSE_GAME, true );
    this.enable = false;

    this.addFlashMessage( 'win', "Congratulations ! You've caught enough Lux to go on. Before going any deeper, here’s an explanation about what you’ve been through", 3 );

    setTimeout( () => { this.addFlashMessage( 'good', 'A video will start in ...', 3 ); }, 1000 );
    setTimeout( () => { this.addFlashMessage( 'good', '3', 3 ); }, 2000 );
    setTimeout( () => { this.addFlashMessage( 'good', '2', 3 ); }, 3000 );
    setTimeout( () => { this.addFlashMessage( 'good', '1', 3 ); }, 4000 );
    setTimeout( () => { Emitter.emit( EXP_SHOW_VIDEO ); }, 6000 );

  }

  addFlashMessage( type = 'normal', msg = '', duration = 3 ) {

    if( !msg ) return;

    this.refs.container.innerHTML += `

        ${msg}

    `;

    if( type === 'good' ) {

      SoundManager.play( 'good-message' );
    } else if ( type === 'danger' ) {

      SoundManager.play( 'bad-message' );
    }

    const msgEls = this.refs.container.querySelectorAll( '.flash-messages__el' );
    const currentMsgEl = msgEls[ msgEls.length - 1 ];
    const currentMsgTxt = currentMsgEl.querySelector( 'span' );

    const tl = new TimelineMax({ onComplete: ()=> {
      setTimeout( ()=>{
        const msgEls = this.refs.container.querySelectorAll( '.flash-messages__el' );
        this.refs.container.removeChild( msgEls[ 0 ] );
      }, 300 );
    } });

    tl
      .fromTo( currentMsgEl, 1, { opacity: 0, x: -20 }, { opacity: 1, x: 0, ease: Expo.easeOut })
      .to( currentMsgTxt, 1, { opacity: 0, x: 20, ease: Expo.easeOut }, '+=' + duration );

  }

  render() {

    return (

    );
  }
}

export default FlashMessages;<commit_msg>Audio - Add to intro flashmesssage a fancy sound<commit_after>import './styles.scss';

import Emitter from 'helpers/Emitter';
import SoundManager from 'helpers/SoundManager';

import { Component } from 'react';

import {
  EXP_FLASH_MSG,
  EXP_INTRO_FLASH_MSG,
  EXP_SHOW_VIDEO,
  EXP_GOAL_ACHIEVE,
  EXP_TOGGLE_PAUSE_GAME
} from 'config/messages';

/**
 * FlashMessages component
 */
class FlashMessages extends Component {

  componentWillMount() {

    this.bind();

    this.enable = true;
  }

  componentDidMount() {

    this.addListeners();

    this.debug();
  }

  componentWillUnmount() {

    this.removeListeners();
  }

  debug() {
    window.debug.flashMessage = this.addFlashMessage;

    window.debug.goodFlashMessage = () => {

      this.addFlashMessage( 'good', 'Bonne nouvelle +3 lux', 3 );
    };

    window.debug.badFlashMessage = () => {

      this.addFlashMessage( 'danger', 'Mauvaise nouvelle :(', 3 );
    };

    const onKeyUp = ( ev )=> {

      if( ev.keyCode === 66 ) { // b

        this.addFlashMessage( 'danger', 'Mauvaise nouvelle :(', 3 );

      } else if( ev.keyCode === 71 ) { //g

        this.addFlashMessage( 'win', "Congratulations ! You've caught enough Lux to go on. Before going any deeper, here’s an explanation about what you’ve been through", 3 );

        setTimeout( () => { this.addFlashMessage( 'good', 'A video will start in ...', 3 ); }, 1000 );
        setTimeout( () => { this.addFlashMessage( 'good', '3', 3 ); }, 2000 );
        setTimeout( () => { this.addFlashMessage( 'good', '2', 3 ); }, 3000 );
        setTimeout( () => { this.addFlashMessage( 'good', '1', 3 ); }, 4000 );
        setTimeout( () => { Emitter.emit( EXP_SHOW_VIDEO ); }, 6000 );

      }

    };

    document.addEventListener( 'keyup', onKeyUp, false );
  }

  bind() {

    [ 'addFlashMessage', 'introFlashMessage', 'endFlashMessage' ]
        .forEach( ( fn ) => this[ fn ] = this[ fn ].bind( this ) );

  }

  addListeners() {

    Emitter.on( EXP_FLASH_MSG, this.addFlashMessage );
    Emitter.once( EXP_INTRO_FLASH_MSG, this.introFlashMessage );
    Emitter.once( EXP_GOAL_ACHIEVE, this.endFlashMessage );
  }

  removeListeners() {

    Emitter.off( EXP_GOAL_ACHIEVE, this.endFlashMessage );
    Emitter.off( EXP_FLASH_MSG, this.addFlashMessage );
    Emitter.off( EXP_INTRO_FLASH_MSG, this.introFlashMessage );
  }

  introFlashMessage() {
    SoundManager.play( 'good-message' );
    this.addFlashMessage( 'anecdotic', 'Oh hi there ! You’ve reached the first abyssal area, called mesopelagic zone. Find and click on the fishes to get some light and dive deeper', 5 );
  }

  endFlashMessage() {

    Emitter.emit( EXP_TOGGLE_PAUSE_GAME, true );
    this.enable = false;

    this.addFlashMessage( 'win', "Congratulations ! You've caught enough Lux to go on. Before going any deeper, here’s an explanation about what you’ve been through", 3 );

    setTimeout( () => { this.addFlashMessage( 'good', 'A video will start in ...', 3 ); }, 1000 );
    setTimeout( () => { this.addFlashMessage( 'good', '3', 3 ); }, 2000 );
    setTimeout( () => { this.addFlashMessage( 'good', '2', 3 ); }, 3000 );
    setTimeout( () => { this.addFlashMessage( 'good', '1', 3 ); }, 4000 );
    setTimeout( () => { Emitter.emit( EXP_SHOW_VIDEO ); }, 6000 );

  }

  addFlashMessage( type = 'normal', msg = '', duration = 3 ) {

    if( !msg ) return;

    this.refs.container.innerHTML += `

        ${msg}

    `;

    if( type === 'good' ) {

      SoundManager.play( 'good-message' );
    } else if ( type === 'danger' ) {

      SoundManager.play( 'bad-message' );
    }

    const msgEls = this.refs.container.querySelectorAll( '.flash-messages__el' );
    const currentMsgEl = msgEls[ msgEls.length - 1 ];
    const currentMsgTxt = currentMsgEl.querySelector( 'span' );

    const tl = new TimelineMax({ onComplete: ()=> {
      setTimeout( ()=>{
        const msgEls = this.refs.container.querySelectorAll( '.flash-messages__el' );
        this.refs.container.removeChild( msgEls[ 0 ] );
      }, 300 );
    } });

    tl
      .fromTo( currentMsgEl, 1, { opacity: 0, x: -20 }, { opacity: 1, x: 0, ease: Expo.easeOut })
      .to( currentMsgTxt, 1, { opacity: 0, x: 20, ease: Expo.easeOut }, '+=' + duration );

  }

  render() {

    return (

    );
  }
}

export default FlashMessages;
<|endoftext|>


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

'use strict'

let serial = require('serialport');
let amqp = require('amqplib/callback_api');

const defaultOptions = {
    baud: 115200,
    device: '/dev/ttyUSB0'
};

class Tach {
    constructor(options = defaultOptions) {
        this.port = new serial(options.device, {
            baudRate: options.baud,
            parser: serial.parsers.readline('\n')
        });
        this.port.on('data', this.onData);
    }

    onData(data) {
        console.log(data);
    }
}

var tach_reader = new Tach();
<commit_msg>Trying the OOP way is not working.<commit_after>#!/usr/bin/env node

'use strict'

let process = require('process');

const serialOptions = {
    baud: 115200,
    device: '/dev/ttyUSB0'
};

const queueOptions = {
    queue: 'tach_sensors',
    callback: (data) => { console.log(data) }
};

class PortMonitor {
    constructor(options = serialOptions) {
        let serial = require('serialport');
        this.settings = options;
        this.port = new serial(options.device, {
            baudRate: options.baud,
            parser: serial.parsers.readline('\n')
        });
        this.port.on('error', function (err) {
            console.log('Error: ', err.message);
        })
        this.port.on('data', this.transform);
    }

    transform(data) {
        let counts = JSON.parse(data);
        for (let i = 0; i < counts.length; i++) {
            let msg = { topic: 'tach_reading', id: i, value: counts[i] };
            if (this.settings.callback) this.settings.callback(msg);
        }
    }
};

class Publisher {
    constructor(options = queueOptions) {
        this.settings = options;
        let self = this;
        let open = require('amqplib').connect('amqp://localhost');

        open.then(function (conn) {
            return conn.createChannel();
        }).then(function (ch) {
            self.channel = ch;
        }).catch(console.warn);
    }

    publish(data) {
        console.log(data);
        let buffer = Buffer.from(JSON.stringify(data));

        return this.channel.assertQueue(this.settings.queue).then(function (ok) {
            return this.channel.sendToQueue(this.settings.queue, buffer);
        });
    }
};

//let publisher = new Publisher(queueOptions);
//serialOptions.callback = publisher.publish;
let mon = new PortMonitor(serialOptions);

process.on('SIGINT',()=>{
    process.exit();
});
<|endoftext|>


<commit_before>function Muppet(age, hobby) {
  this.age = age;
  this.hobby = hobby;

  this.answerNanny = function(){
	return "Everything's cool!";
  }
}

function SwedishChef(age, hobby, mood) {
  Muppet.call(this, age, hobby);
  this.mood = mood;

  this.cook = function() {
    return "Mmmm soup!";
  }
}

SwedishChef.prototype = new Muppet();

describe("About inheritance", function() {
  beforeEach(function(){
    this.muppet = new Muppet(2, "coding");
	this.swedishChef = new SwedishChef(2, "cooking", "chillin");
  });

  it("should be able to call a method on the derived object", function() {
    expect(this.swedishChef.cook()).toEqual(FILL_ME_IN);
  });

  it("should be able to call a method on the base object", function() {
    expect(this.swedishChef.answerNanny()).toEqual(FILL_ME_IN);
  });

  it("should set constructor parameters on the base object", function() {
    expect(this.swedishChef.age).toEqual(FILL_ME_IN);
    expect(this.swedishChef.hobby).toEqual(FILL_ME_IN);
  });

  it("should set constructor parameters on the derived object", function() {
    expect(this.swedishChef.mood).toEqual(FILL_ME_IN);
  });
});

// http://javascript.crockford.com/prototypal.html
Object.prototype.beget = function () {
  function F() {}
  F.prototype = this;
  return new F();
}

function Gonzo(age, hobby, trick) {
  Muppet.call(this, age, hobby);
  this.trick = trick;

  this.doTrick = function() {
    return this.trick;
  }
}

//no longer need to call the Muppet (base type) constructor
Gonzo.prototype = Muppet.prototype.beget();

describe("About Crockford's inheritance improvement", function() {
  beforeEach(function(){
  this.gonzo = new Gonzo(3, "daredevil performer", "eat a tire");
  });

  it("should be able to call a method on the derived object", function() {
    expect(this.gonzo.doTrick()).toEqual(FILL_ME_IN);
  });

  it("should be able to call a method on the base object", function() {
    expect(this.gonzo.answerNanny()).toEqual(FILL_ME_IN);
  });

  it("should set constructor parameters on the base object", function() {
    expect(this.gonzo.age).toEqual(FILL_ME_IN);
    expect(this.gonzo.hobby).toEqual(FILL_ME_IN);
  });

  it("should set constructor parameters on the derived object", function() {
    expect(this.gonzo.trick).toEqual(FILL_ME_IN);
  });
});
<commit_msg>Resolve about inheritance<commit_after>function Muppet(age, hobby) {
  this.age = age;
  this.hobby = hobby;

  this.answerNanny = function () {
	   return "Everything's cool!";
  };
}

function SwedishChef(age, hobby, mood) {
  Muppet.call(this, age, hobby);
  this.mood = mood;

  this.cook = function () {
    return "Mmmm soup!";
  };
}

SwedishChef.prototype = new Muppet();

describe("About inheritance", function () {
  beforeEach(function(){
    this.muppet = new Muppet(2, "coding");
	this.swedishChef = new SwedishChef(2, "cooking", "chillin");
  });

  it("should be able to call a method on the derived object", function () {
    expect(this.swedishChef.cook()).toEqual('Mmmm soup!');
  });

  it("should be able to call a method on the base object", function () {
    expect(this.swedishChef.answerNanny()).toEqual("Everything's cool!");
  });

  it("should set constructor parameters on the base object", function () {
    expect(this.swedishChef.age).toEqual(2);
    expect(this.swedishChef.hobby).toEqual('cooking');
  });

  it("should set constructor parameters on the derived object", function () {
    expect(this.swedishChef.mood).toEqual('chillin');
  });
});

// http://javascript.crockford.com/prototypal.html
Object.prototype.beget = function () {
  function F() {}
  F.prototype = this;
  return new F();
};

function Gonzo(age, hobby, trick) {
  Muppet.call(this, age, hobby);
  this.trick = trick;

  this.doTrick = function () {
    return this.trick;
  };
}

//no longer need to call the Muppet (base type) constructor
Gonzo.prototype = Muppet.prototype.beget();

describe("About Crockford's inheritance improvement", function () {
  beforeEach(function (){
  this.gonzo = new Gonzo(3, "daredevil performer", "eat a tire");
  });

  it("should be able to call a method on the derived object", function () {
    expect(this.gonzo.doTrick()).toEqual('eat a tire');
  });

  it("should be able to call a method on the base object", function () {
    expect(this.gonzo.answerNanny()).toEqual("Everything's cool!");
  });

  it("should set constructor parameters on the base object", function () {
    expect(this.gonzo.age).toEqual(3);
    expect(this.gonzo.hobby).toEqual('daredevil performer');
  });

  it("should set constructor parameters on the derived object", function () {
    expect(this.gonzo.trick).toEqual('eat a tire');
  });
});
<|endoftext|>


<commit_before>module.exports = function(app) {
    var path = require('path');
    var models = require(path.resolve(__dirname, '../model-config.json'));
    var datasources = require(path.resolve(__dirname, '../datasources.json'));

    function autoUpdateAll(){
        Object.keys(models).forEach(function(key) {
            if (typeof models[key].dataSource != 'undefined') {
                if (typeof datasources[models[key].dataSource] != 'undefined') {
                    app.dataSources[models[key].dataSource].autoupdate(key, function (err) {
                        if (err) throw err;
                        console.log('Model ' + key + ' updated');
                    });
                }
            }
        });
    }

    function autoMigrateAll(){
        Object.keys(models).forEach(function(key) {
            if (typeof models[key].dataSource != 'undefined') {
                if (typeof datasources[models[key].dataSource] != 'undefined') {
                    app.dataSources[models[key].dataSource].automigrate(key, function (err) {
                        if (err) throw err;
                        console.log('Model ' + key + ' migrated');
                    });
                }
            }
        });
    }
    //TODO: change to autoUpdateAll when ready for CI deployment to production
    // autoMigrateAll();
    // autoUpdateAll();

};
<commit_msg>Trigger updte<commit_after>module.exports = function(app) {
    var path = require('path');
    var models = require(path.resolve(__dirname, '../model-config.json'));
    var datasources = require(path.resolve(__dirname, '../datasources.json'));

    function autoUpdateAll(){
        Object.keys(models).forEach(function(key) {
            if (typeof models[key].dataSource != 'undefined') {
                if (typeof datasources[models[key].dataSource] != 'undefined') {
                    app.dataSources[models[key].dataSource].autoupdate(key, function (err) {
                        if (err) throw err;
                        console.log('Model ' + key + ' updated');
                    });
                }
            }
        });
    }

    function autoMigrateAll(){
        Object.keys(models).forEach(function(key) {
            if (typeof models[key].dataSource != 'undefined') {
                if (typeof datasources[models[key].dataSource] != 'undefined') {
                    app.dataSources[models[key].dataSource].automigrate(key, function (err) {
                        if (err) throw err;
                        console.log('Model ' + key + ' migrated');
                    });
                }
            }
        });
    }
    //TODO: change to autoUpdateAll when ready for CI deployment to production
    // autoMigrateAll();
    autoUpdateAll();

};
<|endoftext|>


<commit_before>/**
 * Dota game organisation handlers
 */

'use strict';

var Promise = require('bluebird');
var Game = require('../models/game');
var winston = require('winston');

const noGame = 'No game scheduled for today';

module.exports = function(bot) {

  // *****************************
  //    Game creation / reschedule
  // *****************************
  bot.onText(/^\/dog?t[ea]s?(?:@\w*)?\b\s*(?=(?:.*\b(\d{2})[:.;-]?(\d{2})\b)?)/i, function(msg, match) {
    winston.info('handler.game - game creation request received');
    var chatId = msg.chat.id;
    var details = match[2];
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    if (!match[1] && !match[2]) {
      // no valid time found, let the user know
      return bot.sendMessage(chatId, 'Unrecognised command. Usage example: `/dota at 1730`');
    }

    var gameTime = new Date();
    if (match[1]) gameTime.setHours(match[1]);
    if (match[2]) gameTime.setHours(match[2]);
    gameTime.setSeconds(0);

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(game) {
          // Update the existing game
          winston.info(' Game already exists. Updating');
          game.gameTime = gameTime;
          game.notified = false;
          game.shotgun(displayName);

          winston.info(' saving...');
          return game.save()
            .then(saved => bot.sendMessage(chatId, 'Dogte time modified'))
            .then(sent => game.sendTimeUpdate(bot, chatId));
        } else {
          // Create a new game
          game = new Game({
            gameTime: gameTime,
            chatId: chatId,
            complete: false,
            shotguns: [displayName]
          });
          return game.save()
            .then(sent => game.sendTimeUpdate(bot, chatId));
        }
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    Delete game
  // *****************************
  bot.onText(/^\/delete_dog?t[ae]s?(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - game deletion request received');
    var chatId = msg.chat.id;

    // Find game
    var a = Game.findOne({complete: false}).exec();
    var b = a.then(game => {
      if(game) {
        var messageText = 'Are you sure you wish to delete the game at '+game.gameTime+' (yes/no)?';
        return bot.sendMessage(chatId, messageText, {
          reply_markup: {
            force_reply: true
          }
        });
      }
      return null;
    });

    return Promise.join(a, b, (game, sent) => {
      if(!sent) {
        return bot.sendMessage(chatId, noGame);
      }
      winston.info(' waiting for message reply');
      return bot.onReplyToMessage(chatId, sent.message_id, reply => {
        winston.info(' reply received: '+reply.text);
        if(reply.text == 'yes') {
          return Game.remove({ _id: game._id }).exec().then(() => {
            bot.sendMessage(chatId, 'Dota event deleted');
            winston.info(' dota event deleted!');
          });
        }
      });
    }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    shotgun
  // *****************************
  bot.onText(/^\/shotgun(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - shotgun received');
    var chatId = msg.chat.id;
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(!game) { return bot.sendMessage(chatId, noGame); }
        game.shotgun(displayName);

        return game.save()
          .then(saved => game.sendShotgunUpdate(bot, chatId));
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    unshotgun
  // *****************************
  bot.onText(/^\/unshotgun(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - unshotgun received');
    var chatId = msg.chat.id;
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(!game) { return bot.sendMessage(chatId, noGame); }

        game.unshotgun(displayName);
        return game.save()
          .then(saved => bot.sendMessage(chatId, displayName + ', your shotgun has been cancelled'));
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    rdy
  // *****************************
  bot.onText(/^\/re?a?dy(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - rdy received');
    var chatId = msg.chat.id;
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(!game) { return bot.sendMessage(chatId, noGame); }

        var response = game.readyup(displayName);
        return game.save()
          .then(saved => game.sendStackUpdate(bot, chatId));
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    undry
  // *****************************
  bot.onText(/^\/unre?a?dy(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - unrdy received');
    var chatId = msg.chat.id;
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(!game) { return bot.sendMessage(chatId, noGame); }

        game.unreadyup(displayName);
        return game.save()
          .then(saved => bot.sendMessage(chatId, displayName + ', your rdy has been cancelled'));
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  // Error handler
  function handleError(err, chatId, msg) {
    winston.error('An error occurred: ',err);
    msg = msg || 'Oh noes! An error occurred';
    return bot.sendMessage(chatId, msg+': \n'+err);
  }
}
<commit_msg>allow generic dota-command to get current scheduled game<commit_after>/**
 * Dota game organisation handlers
 */

'use strict';

var Promise = require('bluebird');
var Game = require('../models/game');
var winston = require('winston');

const noGame = 'No game scheduled for today';

module.exports = function(bot) {

  // *****************************
  //    Game creation / reschedule
  // *****************************
  bot.onText(/^\/dog?t[ea]s?(?:@\w*)?\b\s*(?=(?:.*\b(\d{2})[:.;-]?(\d{2})\b)?)(.+)?/i, function(msg, match) {
    winston.info('handler.game - game creation request received');
    var chatId = msg.chat.id;
    var details = match[2];
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    if (match[1] && match[2]) {
      var gameTime = new Date();
      gameTime.setHours(match[1]);
      gameTime.setHours(match[2]);
      gameTime.setSeconds(0);
    } else if (match[3]) {
      // no valid time found, and there was other text that we do not currently recognise
      return bot.sendMessage(chatId, 'Unrecognised command. Usage example: `/dota at 1730`');
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(game) {
          if (gameTime) {
            // Update the existing game
            winston.info(' Game already exists. Updating');
            game.gameTime = gameTime;
            game.notified = false;
            game.shotgun(displayName);

            winston.info(' saving...');
            return game.save()
              .then(saved => bot.sendMessage(chatId, 'Dogte time modified'))
              .then(sent => game.sendTimeUpdate(bot, chatId));
          } else {
            return game.sendTimeUpdate(bot, chatId);
          }
        } else if (gameTime) {
          // Create a new game
          game = new Game({
            gameTime: gameTime,
            chatId: chatId,
            complete: false,
            shotguns: [displayName]
          });
          return game.save()
            .then(sent => game.sendTimeUpdate(bot, chatId));
        } else {
          bot.sendMessage(chatId, 'No currently scheduled dogte games.');
        }
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    Delete game
  // *****************************
  bot.onText(/^\/delete_dog?t[ae]s?(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - game deletion request received');
    var chatId = msg.chat.id;

    // Find game
    var a = Game.findOne({complete: false}).exec();
    var b = a.then(game => {
      if(game) {
        var messageText = 'Are you sure you wish to delete the game at '+game.gameTime+' (yes/no)?';
        return bot.sendMessage(chatId, messageText, {
          reply_markup: {
            force_reply: true
          }
        });
      }
      return null;
    });

    return Promise.join(a, b, (game, sent) => {
      if(!sent) {
        return bot.sendMessage(chatId, noGame);
      }
      winston.info(' waiting for message reply');
      return bot.onReplyToMessage(chatId, sent.message_id, reply => {
        winston.info(' reply received: '+reply.text);
        if(reply.text == 'yes') {
          return Game.remove({ _id: game._id }).exec().then(() => {
            bot.sendMessage(chatId, 'Dota event deleted');
            winston.info(' dota event deleted!');
          });
        }
      });
    }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    shotgun
  // *****************************
  bot.onText(/^\/shotgun(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - shotgun received');
    var chatId = msg.chat.id;
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(!game) { return bot.sendMessage(chatId, noGame); }
        game.shotgun(displayName);

        return game.save()
          .then(saved => game.sendShotgunUpdate(bot, chatId));
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    unshotgun
  // *****************************
  bot.onText(/^\/unshotgun(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - unshotgun received');
    var chatId = msg.chat.id;
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(!game) { return bot.sendMessage(chatId, noGame); }

        game.unshotgun(displayName);
        return game.save()
          .then(saved => bot.sendMessage(chatId, displayName + ', your shotgun has been cancelled'));
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    rdy
  // *****************************
  bot.onText(/^\/re?a?dy(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - rdy received');
    var chatId = msg.chat.id;
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(!game) { return bot.sendMessage(chatId, noGame); }

        var response = game.readyup(displayName);
        return game.save()
          .then(saved => game.sendStackUpdate(bot, chatId));
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  //    undry
  // *****************************
  bot.onText(/^\/unre?a?dy(?:@\w*)?/i, function(msg) {
    winston.info('handler.game - unrdy received');
    var chatId = msg.chat.id;
    var userName = msg.from.username;
    var displayName = msg.from.first_name;
    if(msg.from.last_name) {
      displayName += ' ' + msg.from.last_name;
    }

    // Find game
    return Game.findOne({complete: false}).exec()
      .then(game => {
        if(!game) { return bot.sendMessage(chatId, noGame); }

        game.unreadyup(displayName);
        return game.save()
          .then(saved => bot.sendMessage(chatId, displayName + ', your rdy has been cancelled'));
      }).catch(err => handleError(err, chatId));
  });

  // *****************************
  // Error handler
  function handleError(err, chatId, msg) {
    winston.error('An error occurred: ',err);
    msg = msg || 'Oh noes! An error occurred';
    return bot.sendMessage(chatId, msg+': \n'+err);
  }
}
<|endoftext|>


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

  angular
    .module('deck')
    .controller('DeckController', DeckController);

  /** @ngInject */
  function DeckController($stateParams, $state, BackendService, $log, DeckService, $mdDialog, $translate, $rootScope) {
    var vm = this;
    vm.selectedDeck = new BackendService.Deck();
    vm.load = false;
    vm.getDecks = getDecks;
    vm.selectedDeckChange = selectedDeckChange;
    vm.changeDeckName = changeDeckName;
    vm.textChange = textChange;
    vm.createDeck = createDeck;
    vm.selectDeck = selectDeck;
    vm.selectCard = selectCard;
    vm.removeCard = removeCard;
    vm.lostNetworkConnection = lostNetworkConnection;
    vm.clear = clear;
    vm.deckAccess = 'private';
    vm.emptyNameError = DeckService.getEmptyNameError();

    vm.access = $stateParams.access;

    function getDecks(query) {
      //for not loading list of deck on page init
      if (vm.load) {
        if (!vm.decks) {
          //create request for deck list
          vm.decks = BackendService.getDecks(vm.access);
        }
        return vm.decks
          .then(function (result) {
            var list = query ? result.filter(queryFilter(query)) : result;
            if (query){
              list.push({name:query});
            }
            return list;
          });
      } else {
        vm.load = true;
      }
    }

    function textChange(text) {
      DeckService.setNewDeckName(text)
    }

    function selectedDeckChange(deck) {
      if(deck === true){
        return changeDeckName();
      }
      if (deck) {
        if (deck.id){
          selectDeck(deck);
        } else {
          deck.access = vm.deckAccess;
          createDeck(deck);
        }
      }
    }

    function createDeck(deck) {
      DeckService.setDeckObj(deck);
      if($stateParams.deckId){
        $stateParams.deckId = null;
        $stateParams.cardId = null;
        initDeck(null);
      }
    }

    function selectDeck(deck) {
      DeckService.setDeckObj(deck);
      if (deck.id != $stateParams.deckId){
        $stateParams.deckId = deck.id;
        $stateParams.cardId = null;
        initDeck(deck.id);
      }
    }

    function changeDeckName() {
      if (!vm.selectedDeck){
        DeckService.setNewDeckName(vm.searchText);
      } else {
        vm.selectedDeck.changeName(vm.searchText, vm.deckAccess)
          .then(function success() {
            $state.go("deck.addCard", {deckId: vm.selectedDeck.id});
            $state.reload("deck");
          },
          function error() {
            var message = 'I cant update Deck name';
            alert(message);
            throw message;
          })
      }
    }

    function selectCard(card) {
      DeckService.setCardObj(card);
      //for selecting on ui (ng-repeat)
      if(card.id !=vm.selectedCardId) {
        vm.selectedCardId = card.id;
        $state.go("deck.addCard", {cardId: card.id}, {notify:true});
      } else {
        vm.selectedCardId = false;
        $state.go("deck.addCard", {cardId: null}, {notify:true});
      }
    }

    function removeCard(cardId){
      deleteCardDialog(cardId, vm.cards.length );
    }

    //LOCAL FUNCTIONS
    function queryFilter(query) {
      var lowercaseQuery = angular.lowercase(query);
      return function filterFn(deck) {
        if(deck.name){
          return (deck.name.toLowerCase().indexOf(lowercaseQuery) === 0);
        }
      };
    }

    function clear() {
      vm.searchText = null;
    }

    function getCards() {
      vm.selectedDeck.getFlashcards()
        .then(function (result) {
          vm.cards = result;
        }, function (e) {
          $log.error(e);
        });
    }

    //init current deck
    function initDeck(value) {
      if(value){
        BackendService.getDeckById(value)
          .then(function (result) {
            vm.selectedDeck = result;
            vm.selectedItem = vm.selectedDeck;
            DeckService.setNewDeckName(vm.selectedDeck.name);
            getCards();
          }, function (e) {
            $log.error(e);
          });
      } else {
        vm.selectedDeck = DeckService.getDeckObj();
        vm.selectedItem = vm.selectedDeck;
        vm.cards=[];
      }
      //clean card field
      if (!$stateParams.deckId){
        DeckService.setNewDeckName(null);
        vm.selectedDeck = DeckService.setDeckObj(null);
        vm.selectedItem = vm.selectedDeck;
      }
      $stateParams.cardId = null;
      if($state.$current == 'deck.addCard'){
        $state.reload('deck.addCard');
      }
    }
    initDeck($stateParams.deckId);

    function lostNetworkConnection(){
      $mdDialog.show(
          $mdDialog.alert()
            .clickOutsideToClose(false)
            .title($translate.instant('networkAlert-WARNING'))
            .textContent($translate.instant('deck-OFFLINE_REMOVE_CARD_MODAL'))
            .ariaLabel('Alert Dialog')
            .ok($translate.instant('networkAlert-AGREE'))
      );
    }

    //DELETE CARD DIALOG
    function deleteCardDialog(cardId, cardNo) {
      var content = $translate.instant("deck-REMOVE_CARD_MODAL");
      //info for last card
      if (cardNo < 2) {
        content = ($translate.instant("deck-REMOVE_LAST_CARD_MODAL"));
      }
      var confirm = $mdDialog.confirm()
        .title($translate.instant("deck-REMOVE_CARD"))
        .textContent(content)
        .ok($translate.instant("deck-YES"))
        .cancel($translate.instant("deck-NO"));
      $mdDialog.show(confirm)
        .then(function () {
          //delete card
          return vm.selectedDeck.removeFlashcard(cardId)
        }, function (e) {
          $log.error(e);
        })
        .then(function (result) {
          //delete deck if last card
          if (cardNo < 2) {
            $log.warn('last one flashcard');
            vm.selectedDeck.remove().then(function () {
              $state.go('decks');
            });
          } else {
            $state.go("deck.addCard", {deckId: vm.selectedDeck.id, cardId: null});
            getCards();
            $log.log(result);
          }
        }, function (e) {
          $log.error(e);
        });
    }
  }
})();
<commit_msg>fix STUDYBOX-286<commit_after>(function () {
  'use strict';

  angular
    .module('deck')
    .controller('DeckController', DeckController);

  /** @ngInject */
  function DeckController($stateParams, $state, BackendService, $log, DeckService, $mdDialog, $translate, $rootScope) {
    var vm = this;
    vm.selectedDeck = new BackendService.Deck();
    vm.load = false;
    vm.getDecks = getDecks;
    vm.selectedDeckChange = selectedDeckChange;
    vm.changeDeckName = changeDeckName;
    vm.textChange = textChange;
    vm.createDeck = createDeck;
    vm.selectDeck = selectDeck;
    vm.selectCard = selectCard;
    vm.removeCard = removeCard;
    vm.lostNetworkConnection = lostNetworkConnection;
    vm.clear = clear;
    vm.deckAccess = 'private';
    vm.emptyNameError = DeckService.getEmptyNameError();

    vm.access = $stateParams.access;

    function getDecks(query) {
      //for not loading list of deck on page init
      if (vm.load) {
        if (!vm.decks) {
          //create request for deck list
          vm.decks = BackendService.getDecks(vm.access);
        }
        return vm.decks
          .then(function (result) {
            var list = query ? result.filter(queryFilter(query)) : result;
            if (query){
              list.push({name:query});
            }
            return list;
          });
      } else {
        vm.load = true;
      }
    }

    function textChange(text) {
      DeckService.setNewDeckName(text)
    }

    function selectedDeckChange(deck) {
      if(deck === true){
        return changeDeckName();
      }
      if (deck) {
        if (deck.id){
          selectDeck(deck);
        } else {
          deck.access = vm.deckAccess;
          createDeck(deck);
        }
      }
    }

    function createDeck(deck) {
      DeckService.setDeckObj(deck);
      if($stateParams.deckId){
        $stateParams.deckId = null;
        $stateParams.cardId = null;
        initDeck(null);
      }
    }

    function selectDeck(deck) {
      DeckService.setDeckObj(deck);
      if (deck.id != $stateParams.deckId){
        $stateParams.deckId = deck.id;
        $stateParams.cardId = null;
        initDeck(deck.id);
      }
    }

    function changeDeckName() {
      if (!vm.selectedDeck){
        DeckService.setNewDeckName(vm.searchText);
      } else {
        vm.selectedDeck.changeName(vm.searchText, vm.deckAccess)
          .then(function success() {
            $state.go("deck.addCard", {deckId: vm.selectedDeck.id});
            $state.reload("deck");
          },
          function error() {
            var message = 'I cant update Deck name';
            alert(message);
            throw message;
          })
      }
    }

    function selectCard(card) {
      DeckService.setCardObj(card);
      //for selecting on ui (ng-repeat)
      if(card.id !=vm.selectedCardId) {
        vm.selectedCardId = card.id;
        $state.go("deck.addCard", {cardId: card.id}, {notify:true});
      } else {
        vm.selectedCardId = false;
        $state.go("deck.addCard", {cardId: null}, {notify:true});
      }
    }

    function removeCard(cardId){
      deleteCardDialog(cardId, vm.cards.length );
    }

    //LOCAL FUNCTIONS
    function queryFilter(query) {
      var lowercaseQuery = angular.lowercase(query);
      return function filterFn(deck) {
        if(deck.name){
          return (deck.name.toLowerCase().indexOf(lowercaseQuery) === 0);
        }
      };
    }

    function clear() {
      vm.searchText = null;
    }

    function getCards() {
      vm.selectedDeck.getFlashcards()
        .then(function (result) {
          vm.cards = result;
        }, function (e) {
          $log.error(e);
        });
    }

    //init current deck
    function initDeck(value) {
      if(value){
        BackendService.getDeckById(value)
          .then(function (result) {
            vm.selectedDeck = result;
            vm.selectedItem = vm.selectedDeck;
            DeckService.setNewDeckName(vm.selectedDeck.name);
            getCards();
          }, function (e) {
            $log.error(e);
          });
      } else {
        vm.selectedDeck = DeckService.getDeckObj();
        vm.selectedItem = vm.selectedDeck;
        vm.cards=[];
      }
      //clean card field
      if (!$stateParams.deckId){
        DeckService.setNewDeckName(null);
        vm.selectedDeck = DeckService.setDeckObj(null);
        vm.selectedItem = vm.selectedDeck;
      }
      $stateParams.cardId = null;
      if($state.$current == 'deck.addCard'){
        $state.reload('deck.addCard');
      }
    }
    initDeck($stateParams.deckId);

    function lostNetworkConnection(){
      $mdDialog.show(
          $mdDialog.alert()
            .clickOutsideToClose(false)
            .title($translate.instant('networkAlert-WARNING'))
            .textContent($translate.instant('deck-OFFLINE_REMOVE_CARD_MODAL'))
            .ariaLabel('Alert Dialog')
            .ok($translate.instant('networkAlert-AGREE'))
      );
    }

    //DELETE CARD DIALOG
    function deleteCardDialog(cardId, cardNo) {
      var content = $translate.instant("deck-REMOVE_CARD_MODAL");
      //info for last card
      if (cardNo < 2) {
        content = ($translate.instant("deck-REMOVE_LAST_CARD_MODAL"));
      }
      var confirm = $mdDialog.confirm()
        .title($translate.instant("deck-REMOVE_CARD"))
        .textContent(content)
        .ok($translate.instant("deck-YES"))
        .cancel($translate.instant("deck-NO"));
        $mdDialog.show(confirm)
          .then(function () {
            //delete card
            vm.selectedDeck.removeFlashcard(cardId)
              .then(function (result) {
                //delete deck if last card
                if (cardNo < 2) {
                  $log.warn('last one flashcard');
                  vm.selectedDeck.remove().then(function () {
                    $state.go('decks');
                  });
                } else {
                  $state.go("deck.addCard", {deckId: vm.selectedDeck.id, cardId: null});
                  getCards();
                  $log.log(result);
                }
              }, function (e) {
                $log.error(e);
              });
          }, function (e) {
            $log.error(e);
          })
    }
  }
})();
<|endoftext|>