<commit_before>var Refresh = 4 // seconds
, _         = require('underscore')
, Check     = require('da_check').Check
, River     = require('da_river').River
, Topogo    = require('topogo').Topogo
, UID       = require('../App/UID').UID
, IM        = require('../IM/model').IM
, Website   = require('../Website/model').Website
, Folder    = require('../Folder/model').Folder
;

var WORLD = '@W';

var TABLE_NAME = 'Screen_Name';
var banned_screen_names = [
  '^megauni',
  '^miniuni',
  '^okdoki',
  '^pet-',
  '^bot-',
  '^(online|contact|info|official|about|news|home)$',
  '^(undefined|def|sex|sexy|xxx|ted|larry)$',
  '^[.]+-cola$'
];

// ================================================================
// ================== Helpers =====================================
// ================================================================

// OST = 0; // parseInt((new Date(2013, 0, 31)).getTime());

function since() {
  return (new Date).getTime();
}

function log() {
  var args = _.map(_.toArray(arguments), function (v, i) {
    if (!_.isArray(v))
      return v;
    var arr = v;
    return ((_.isArray(arr) && arr.length > 5) ? 'Array: ' + arr.length : arr);;
  });

  console['log'].apply(console, args);
}

// ================================================================
// ================== Main Stuff ==================================
// ================================================================

var S = exports.Screen_Name = function () { };
Website.require(exports);

Folder.screen_name(exports);

S.TABLE_NAME = TABLE_NAME;

S.expire_in = 4; // Refresh rate.

S.new = function (n) {
  var s         =  new S();
  s.is_screen_name = true;
  if (_.isString(n) || !n) {
    s.screen_name = n;
    s.data        = {};
  } else if (n) {
    s.data        = n;
    s.screen_name = n.screen_name;
  }

  return s;
};

S.prototype.customer = function (c) {
  if (c)
    this._customer = c;
  return this._customer;
};

S.prototype.heart_beep = function (on_fin) {
  var me = this;
  var n  = me.screen_name;

  var client = Redis.client.multi();

  client.hmset(n, {s: since()});
  client.expire(n, S.expire_in + 7); // online status
  client.expire(n + ':c',    secs + 7); // list of contacts
  client.expire(n + ':ims',  secs + 7); // list of ims by customer
  client.expire(n + ':dims', secs + 7); // list of direct ims to customer
  client.exec(on_fin);
};

S.prototype.is_update_able = function () {
  return _.isEqual( this.customer().data.id, this.data.owner_id);
};

// ================================================================
// ================== Create Validators ===========================
// ================================================================

var Validate_Create = Check.new('create screen name', function (vc) {

  vc.define('read_able', function (vador) {
    vador.contains_only(['@W', '@P', '@N'], "Allowed values: @W (world) @P (private) @N (no one)");
  });

  vc.define('screen_name', function (v) {
    var orig = v.val;

    v
    .to_upper_case()
    .match(/^[A-Z0-9\-\_\.]{3,15}$/, "Screen name must be: 3-15 valid chars: 0-9 a-z A-Z _ - .")
    ;

    _.each(banned_screen_names, function (pattern, i) {
      v.not_match(new RegExp(pattern, 'ig'), 'Screen name not allowed: ' + v.val);
    });

    v.sanitized('display_name', orig);
  });

  vc.define('body', function (v) {
    var val = (v.val || '').trim();
    if (val.length === 0)
      val = '* * *';
    v.sanitized(val);
  });

});

// ================================================================
// ================== Create ======================================
// ================================================================

S.create = function (customer, job) {

  var id = UID.create_id();
  var sn = S.new();
  sn.new_data = {'screen_name': customer.new_data.screen_name};

  var insert_data = {};

  River.new(job)

  .job('validate', 'screen name', function (j) {
    Validate_Create.run(sn, j);
  })

  .job('create', 'screen name', function (j) {

    insert_data = {
      owner_id     : customer.data.id || 0,
      screen_name  : sn.sanitized_data.screen_name,
      display_name : sn.sanitized_data.screen_name
    };

    Topogo.new(TABLE_NAME)
    .on_dup("screen_name", function (name) {
      j.finish('invalid', 'Screen name already taken: ' + sn.new_data.screen_name);
    })
    .create(insert_data, j);

  })
  .job(function (j, r) {
    if (customer.data.id)
      return j.finish(r);
    River.new(j)
    .job(function (j2) {
      Topogo.new(TABLE_NAME).update(r.id, {owner_id: r.id}, j2);
    })
    .job(function (j2, r) {
      customer.data.id = customer.sanitized_data.id = r.id;
      j.finish(r);
    })
    .run();
  })
  .job(function (j, r) {
    River.new(j)
    .job(function (j2) {
      Website.create({type_id: 1, owner_id: r.id}, j2);
    })
    .job(function (j2, website) {
      Folder.create({num: 1, website_id: website.data.id, owner_id: r.id, title: "My Journal"}, j2)
    })
    .job(function (j2) {
      j.finish(r);
    })
    .run();
  })
  .job(function (j, r) {
    customer.push_screen_name_row(_.extend(insert_data, r));
    return j.finish(customer);
  })

  .run();

};

// ================================================================
// ================== Read ========================================
// ================================================================

S.prototype.is_world_read_able = function () {
  return _.contains(this.data.read_able || [], WORLD);
};

S.read_by_id = function (id, flow) {
  River.new(arguments)
  .job('read screen name id:', id, function (j) {
    Topogo.new(TABLE_NAME).read_by_id(id, j);
  })
  .job(function (j, r) {
    return j.finish(S.new(r));
  })
  .run();
};

S.read_by_screen_name = function (n, customer, flow) {
  if (arguments.length === 2) {
    flow = customer;
    customer = null;
  }

  River.new(flow)
  .job('read screen name:', n, function (j) {
    Topogo.new(TABLE_NAME).read_one({screen_name: n.toUpperCase()}, j)
  })
  .job(function (j, r) {
    if (!r)
      return j.finish();
    var sn = S.new(r);
    sn.customer(customer);
    j.finish(sn);
  })
  .run();
};

S.read_list = function (c, flow) {
  River.new(arguments)
  .job('read screen names', c.data.id, function (j) {
    Topogo.new(TABLE_NAME).read_list({owner_id: j.id}, j)
  })
  .job('push', 'screen_names', function (j, r) {
    _.each(r, function (row) {
      c.push_screen_name_row(row);
    });
    return j.finish(c);
  })
  .run();
};

S.prototype.read_screen_names = function (flow) {
  var me = this;

  River.new(arguments)

  .job('read screen names for:', me.data.id, function (j) {
    Topogo.new(TABLE_NAME).read_list({owner_id: j.id}, j);
  })

  .job(function (j, names) {
    if (!names.length)
      return flow.finish('not_valid', new Error('No screen names found for customer id: ' + me.data.id));

    me.data.screen_name_rows = null;

    _.each(names, function (v, k) {
      me.push_screen_name_row(v);
    });

    return j.finish(me);
  })

  .run();

};

// ================================================================
// =================== Update Validations =========================
// ================================================================

S.prototype.edit_homepage_title = function (val) {
  var new_val = val.toString().trim();
  if (new_val.length === 0)
    new_val = null;
  this.push_sanitized_data('homepage_title', new_val);
};

S.prototype.edit_about = function (val) {
  var new_val = val.toString().trim();
  if (new_val.length === 0)
    new_val = null;
  this.push_sanitized_data('about', new_val);
};

S.prototype.edit_homepage_allow = function (val) {
  this.validator.check(val, "'allow' must be an array.").isArray();
  this.push_sanitized_data('homepage_allow', val);
};

S.prototype.edit_screen_name = function (n) {

  var old = this.new_data.old_screen_name;

  if (old) // updating old name
    this.push_sanitized_data('screen_name_id', this.screen_name_id(old));
  else {
    // inserting new name
  }

  this['new_screen_name'](n);
};

S.prototype.edit_read_able = function (v) {
  switch (v) {
    case 'W':
      break;
    case 'N':
      break;
    case 'S':
      break;
    default:
      throw new Error('Unknown read_able value: ' + v);
  };

  this.push_sanitized_data('read_able', v);
}

S.prototype.edit_read_able_list = function (v) {
  if (this.sanitized_data.read_able !== 'S')
    return false;

  if (!v)
    throw new Error('read_able_list can\'t be false-y: ' + typeof(v));

  var list = _.reject(v.trim().split(/[,\s]+/ig), function (str, i) {
    return str === "";
  });

  if (list.length === 0)
    this.push_sanitized_data.read_able = 'N';
  else
    this.push_sanitized_data('read_able_list', list);
}

S.prototype.edit_at_url = function (v) {
  return edit_bot_url(this, 'at_url', v);
};

S.prototype.edit_at_pass_phrase = function (v) {
  return edit_bot_pass_phrase(this, 'at_pass_phrase', v);
};

S.prototype.edit_bot_url = function (v) {
  return edit_bot_url(this, 'bot_url', v);
};

S.prototype.edit_bot_pass_phrase = function (v) {
  return edit_bot_pass_phrase(this, 'bot_pass_phrase', v);
};

// ================================================================
// =================== Update =====================================
// ================================================================

var Validate_Update = Check.new('update screen name', function (vu) {

  vu.define('read_able', Validate_Create);

  vu.define('screen_name', Validate_Create.validations['screen_name']);

  vu.define('about', function (vador) {
    vador
    .is_null_if_empty()
    ;
  });

  vu.define('nick_name', function (vador) {
    vador
    .is_null_if_empty()
    ;
  });

  vu.define('home-page-title', function (vador) {
    vador
    .is_null_if_empty()
    ;
  });

});

S.update = function ( customer, flow ) {
  var me      = S.new();
  if (customer.new_data) {
    me.new_data = customer.new_data;
  } else {
    if (customer.owner)  {
      me.new_data = _.clone(customer);
      customer = me.new_data.owner;
      delete me.new_data.owner;
    } else {
      me.new_data = customer;
      customer = customer.owner;
    }
  }

  var row = customer.screen_name_row(me.new_data.old_screen_name || me.new_data.screen_name);

  if (!Validate_Update.run(me))
    return flow.invalid(me.errors);

  var set = {}, final_data = {};

  _.each('screen_name about nick_name home-page-title read_able non_read_able'.split(' '), function (key) {
    if (!me.sanitized_data.hasOwnProperty(key))
      return;

    switch (key) {

      case 'screen_name':
        if (me.new_data.old_screen_name) {
        set.screen_name = me.sanitized_data.screen_name;
        set.display_name = me.sanitized_data.display_name;
        final_data.old_screen_name = me.new_data.old_screen_name.toUpperCase();
      }
      break;

      default:
        set[key] = me.sanitized_data[key];

    };
  });

  if(set.settings)
    set.settings = JSON.stringify(set.settings);
  if(set.details)
    set.details  = JSON.stringify(set.details);

  River.new(arguments)
  .job('update screen name', me.data.screen_name, function (j) {
    Topogo.new(TABLE_NAME).update(row.id, set, j)
  })
  .job(function (j, row) {
    customer.push_screen_name_row(_.extend(set, row, final_data));
    return j.finish(customer);
  })
  .run();

};

// ================================================================
// =================== Trash/Delete ===============================
// ================================================================

S.untrash = function (id, flow) {
  Topogo.new(TABLE_NAME)
  .untrash(id, flow);
};

S.trash = function (id, flow) {
  Topogo.new(TABLE_NAME)
  .trash(id, flow);
};

S.delete_trashed = function (flow) {
  Topogo.new(TABLE_NAME)
  .delete_trashed(flow);
};

S.delete_by_owner_ids = function (arr, flow) {
  var sql = "DELETE FROM \"" + TABLE_NAME + "\" WHERE owner_id IN ( " +
    _.map(arr, function (n, i) { return "$" + (i + 1); }).join(', ') +
    " ) RETURNING * ;";

  Topogo
  .run(sql, arr, flow);
};

<commit_msg>Temp solution: stranger object in place of non-logged in users.<commit_after>var Refresh = 4 // seconds
, _         = require('underscore')
, Check     = require('da_check').Check
, River     = require('da_river').River
, Topogo    = require('topogo').Topogo
, UID       = require('../App/UID').UID
, IM        = require('../IM/model').IM
, Website   = require('../Website/model').Website
, Folder    = require('../Folder/model').Folder
;

var WORLD = '@W';

var TABLE_NAME = 'Screen_Name';
var banned_screen_names = [
  '^megauni',
  '^miniuni',
  '^okdoki',
  '^pet-',
  '^bot-',
  '^(online|contact|info|official|about|news|home)$',
  '^(undefined|def|sex|sexy|xxx|ted|larry)$',
  '^[.]+-cola$'
];

// ================================================================
// ================== Helpers =====================================
// ================================================================

// OST = 0; // parseInt((new Date(2013, 0, 31)).getTime());

function since() {
  return (new Date).getTime();
}

function log() {
  var args = _.map(_.toArray(arguments), function (v, i) {
    if (!_.isArray(v))
      return v;
    var arr = v;
    return ((_.isArray(arr) && arr.length > 5) ? 'Array: ' + arr.length : arr);;
  });

  console['log'].apply(console, args);
}

var stranger = {
  is_stranger: true,
  data: { id: 0 },
  screen_name_ids: function () { return [0]; }
};

// ================================================================
// ================== Main Stuff ==================================
// ================================================================

var S = exports.Screen_Name = function () { };
Website.require(exports);

Folder.screen_name(exports);

S.TABLE_NAME = TABLE_NAME;

S.expire_in = 4; // Refresh rate.

S.new = function (n) {
  var s         =  new S();
  s.is_screen_name = true;
  if (_.isString(n) || !n) {
    s.screen_name = n;
    s.data        = {};
  } else if (n) {
    s.data        = n;
    s.screen_name = n.screen_name;
  }

  return s;
};

S.prototype.customer = function (c) {
  if (c)
    this._customer = c;
  return this._customer;
};

S.prototype.heart_beep = function (on_fin) {
  var me = this;
  var n  = me.screen_name;

  var client = Redis.client.multi();

  client.hmset(n, {s: since()});
  client.expire(n, S.expire_in + 7); // online status
  client.expire(n + ':c',    secs + 7); // list of contacts
  client.expire(n + ':ims',  secs + 7); // list of ims by customer
  client.expire(n + ':dims', secs + 7); // list of direct ims to customer
  client.exec(on_fin);
};

S.prototype.is_update_able = function () {
  return _.isEqual( this.customer().data.id, this.data.owner_id);
};

// ================================================================
// ================== Create Validators ===========================
// ================================================================

var Validate_Create = Check.new('create screen name', function (vc) {

  vc.define('read_able', function (vador) {
    vador.contains_only(['@W', '@P', '@N'], "Allowed values: @W (world) @P (private) @N (no one)");
  });

  vc.define('screen_name', function (v) {
    var orig = v.val;

    v
    .to_upper_case()
    .match(/^[A-Z0-9\-\_\.]{3,15}$/, "Screen name must be: 3-15 valid chars: 0-9 a-z A-Z _ - .")
    ;

    _.each(banned_screen_names, function (pattern, i) {
      v.not_match(new RegExp(pattern, 'ig'), 'Screen name not allowed: ' + v.val);
    });

    v.sanitized('display_name', orig);
  });

  vc.define('body', function (v) {
    var val = (v.val || '').trim();
    if (val.length === 0)
      val = '* * *';
    v.sanitized(val);
  });

});

// ================================================================
// ================== Create ======================================
// ================================================================

S.create = function (customer, job) {

  var id = UID.create_id();
  var sn = S.new();
  sn.new_data = {'screen_name': customer.new_data.screen_name};

  var insert_data = {};

  River.new(job)

  .job('validate', 'screen name', function (j) {
    Validate_Create.run(sn, j);
  })

  .job('create', 'screen name', function (j) {

    insert_data = {
      owner_id     : customer.data.id || 0,
      screen_name  : sn.sanitized_data.screen_name,
      display_name : sn.sanitized_data.screen_name
    };

    Topogo.new(TABLE_NAME)
    .on_dup("screen_name", function (name) {
      j.finish('invalid', 'Screen name already taken: ' + sn.new_data.screen_name);
    })
    .create(insert_data, j);

  })
  .job(function (j, r) {
    if (customer.data.id)
      return j.finish(r);
    River.new(j)
    .job(function (j2) {
      Topogo.new(TABLE_NAME).update(r.id, {owner_id: r.id}, j2);
    })
    .job(function (j2, r) {
      customer.data.id = customer.sanitized_data.id = r.id;
      j.finish(r);
    })
    .run();
  })
  .job(function (j, r) {
    River.new(j)
    .job(function (j2) {
      Website.create({type_id: 1, owner_id: r.id}, j2);
    })
    .job(function (j2, website) {
      Folder.create({num: 1, website_id: website.data.id, owner_id: r.id, title: "My Journal"}, j2)
    })
    .job(function (j2) {
      j.finish(r);
    })
    .run();
  })
  .job(function (j, r) {
    customer.push_screen_name_row(_.extend(insert_data, r));
    return j.finish(customer);
  })

  .run();

};

// ================================================================
// ================== Read ========================================
// ================================================================

S.prototype.is_world_read_able = function () {
  return _.contains(this.data.read_able || [], WORLD);
};

S.read_by_id = function (id, flow) {
  River.new(arguments)
  .job('read screen name id:', id, function (j) {
    Topogo.new(TABLE_NAME).read_by_id(id, j);
  })
  .job(function (j, r) {
    return j.finish(S.new(r));
  })
  .run();
};

S.read_by_screen_name = function (n, customer, flow) {
  if (arguments.length === 2) {
    flow = customer;
    customer = null;
  }

  River.new(flow)
  .job('read screen name:', n, function (j) {
    Topogo.new(TABLE_NAME).read_one({screen_name: n.toUpperCase()}, j)
  })
  .job(function (j, r) {
    if (!r)
      return j.finish();
    var sn = S.new(r);
    sn.customer(customer || stranger);
    j.finish(sn);
  })
  .run();
};

S.read_list = function (c, flow) {
  River.new(arguments)
  .job('read screen names', c.data.id, function (j) {
    Topogo.new(TABLE_NAME).read_list({owner_id: j.id}, j)
  })
  .job('push', 'screen_names', function (j, r) {
    _.each(r, function (row) {
      c.push_screen_name_row(row);
    });
    return j.finish(c);
  })
  .run();
};

S.prototype.read_screen_names = function (flow) {
  var me = this;

  River.new(arguments)

  .job('read screen names for:', me.data.id, function (j) {
    Topogo.new(TABLE_NAME).read_list({owner_id: j.id}, j);
  })

  .job(function (j, names) {
    if (!names.length)
      return flow.finish('not_valid', new Error('No screen names found for customer id: ' + me.data.id));

    me.data.screen_name_rows = null;

    _.each(names, function (v, k) {
      me.push_screen_name_row(v);
    });

    return j.finish(me);
  })

  .run();

};

// ================================================================
// =================== Update Validations =========================
// ================================================================

S.prototype.edit_homepage_title = function (val) {
  var new_val = val.toString().trim();
  if (new_val.length === 0)
    new_val = null;
  this.push_sanitized_data('homepage_title', new_val);
};

S.prototype.edit_about = function (val) {
  var new_val = val.toString().trim();
  if (new_val.length === 0)
    new_val = null;
  this.push_sanitized_data('about', new_val);
};

S.prototype.edit_homepage_allow = function (val) {
  this.validator.check(val, "'allow' must be an array.").isArray();
  this.push_sanitized_data('homepage_allow', val);
};

S.prototype.edit_screen_name = function (n) {

  var old = this.new_data.old_screen_name;

  if (old) // updating old name
    this.push_sanitized_data('screen_name_id', this.screen_name_id(old));
  else {
    // inserting new name
  }

  this['new_screen_name'](n);
};

S.prototype.edit_read_able = function (v) {
  switch (v) {
    case 'W':
      break;
    case 'N':
      break;
    case 'S':
      break;
    default:
      throw new Error('Unknown read_able value: ' + v);
  };

  this.push_sanitized_data('read_able', v);
}

S.prototype.edit_read_able_list = function (v) {
  if (this.sanitized_data.read_able !== 'S')
    return false;

  if (!v)
    throw new Error('read_able_list can\'t be false-y: ' + typeof(v));

  var list = _.reject(v.trim().split(/[,\s]+/ig), function (str, i) {
    return str === "";
  });

  if (list.length === 0)
    this.push_sanitized_data.read_able = 'N';
  else
    this.push_sanitized_data('read_able_list', list);
}

S.prototype.edit_at_url = function (v) {
  return edit_bot_url(this, 'at_url', v);
};

S.prototype.edit_at_pass_phrase = function (v) {
  return edit_bot_pass_phrase(this, 'at_pass_phrase', v);
};

S.prototype.edit_bot_url = function (v) {
  return edit_bot_url(this, 'bot_url', v);
};

S.prototype.edit_bot_pass_phrase = function (v) {
  return edit_bot_pass_phrase(this, 'bot_pass_phrase', v);
};

// ================================================================
// =================== Update =====================================
// ================================================================

var Validate_Update = Check.new('update screen name', function (vu) {

  vu.define('read_able', Validate_Create);

  vu.define('screen_name', Validate_Create.validations['screen_name']);

  vu.define('about', function (vador) {
    vador
    .is_null_if_empty()
    ;
  });

  vu.define('nick_name', function (vador) {
    vador
    .is_null_if_empty()
    ;
  });

  vu.define('home-page-title', function (vador) {
    vador
    .is_null_if_empty()
    ;
  });

});

S.update = function ( customer, flow ) {
  var me      = S.new();
  if (customer.new_data) {
    me.new_data = customer.new_data;
  } else {
    if (customer.owner)  {
      me.new_data = _.clone(customer);
      customer = me.new_data.owner;
      delete me.new_data.owner;
    } else {
      me.new_data = customer;
      customer = customer.owner;
    }
  }

  var row = customer.screen_name_row(me.new_data.old_screen_name || me.new_data.screen_name);

  if (!Validate_Update.run(me))
    return flow.invalid(me.errors);

  var set = {}, final_data = {};

  _.each('screen_name about nick_name home-page-title read_able non_read_able'.split(' '), function (key) {
    if (!me.sanitized_data.hasOwnProperty(key))
      return;

    switch (key) {

      case 'screen_name':
        if (me.new_data.old_screen_name) {
        set.screen_name = me.sanitized_data.screen_name;
        set.display_name = me.sanitized_data.display_name;
        final_data.old_screen_name = me.new_data.old_screen_name.toUpperCase();
      }
      break;

      default:
        set[key] = me.sanitized_data[key];

    };
  });

  if(set.settings)
    set.settings = JSON.stringify(set.settings);
  if(set.details)
    set.details  = JSON.stringify(set.details);

  River.new(arguments)
  .job('update screen name', me.data.screen_name, function (j) {
    Topogo.new(TABLE_NAME).update(row.id, set, j)
  })
  .job(function (j, row) {
    customer.push_screen_name_row(_.extend(set, row, final_data));
    return j.finish(customer);
  })
  .run();

};

// ================================================================
// =================== Trash/Delete ===============================
// ================================================================

S.untrash = function (id, flow) {
  Topogo.new(TABLE_NAME)
  .untrash(id, flow);
};

S.trash = function (id, flow) {
  Topogo.new(TABLE_NAME)
  .trash(id, flow);
};

S.delete_trashed = function (flow) {
  Topogo.new(TABLE_NAME)
  .delete_trashed(flow);
};

S.delete_by_owner_ids = function (arr, flow) {
  var sql = "DELETE FROM \"" + TABLE_NAME + "\" WHERE owner_id IN ( " +
    _.map(arr, function (n, i) { return "$" + (i + 1); }).join(', ') +
    " ) RETURNING * ;";

  Topogo
  .run(sql, arr, flow);
};

<|endoftext|>


<commit_before>import React from 'react';
import { render } from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import {red500} from 'material-ui/styles/colors';

const style = {
    margin: 12
}

class Login extends React.Component {
    constructor(props) {
        super(props);
        this.usernameErr = error.usernameErr.length ? error.usernameErr[0] : null;
        this.passwordErr = error.passwordErr.length ? error.passwordErr[0] : null;
        this.errorText = error.error.length ? error.error[0] : null;
        this.username = error.username;
    }

    handleSubmit() {};

    render() {
        const ErrorText = this.errorText ?
{this.errorText}
 : null;
        return (
            <MuiThemeProvider>

            {ErrorText}
            <form action="/login" method="post">
                <TextField
                    name="username"
                    hintText="enter username"
                    defaultValue={this.username}
                    floatingLabelText="username"
                    errorText={this.usernameErr}
                />

                <TextField
                    name="password"
                    hintText="password"
                    floatingLabelText="password"
                    errorText={this.passwordErr}
                    type="password"
                />

                <RaisedButton label="cancel"/><RaisedButton label="login" type="submit" primary={true} style={style}/>
            </form>

            </MuiThemeProvider>
        )
    }
};

render(<Login />, document.getElementById('login'));<commit_msg>fix: effective cancel button in IE<commit_after>import React from 'react';
import { render } from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import {red500} from 'material-ui/styles/colors';

const style = {
    margin: 12
}

class Login extends React.Component {
    constructor(props) {
        super(props);
        this.usernameErr = error.usernameErr.length ? error.usernameErr[0] : null;
        this.passwordErr = error.passwordErr.length ? error.passwordErr[0] : null;
        this.errorText = error.error.length ? error.error[0] : null;
        this.username = error.username;
    }

    handleSubmit() {};
    handleCancel() {
        location.replace('/');
    }

    render() {
        const ErrorText = this.errorText ?
{this.errorText}
 : null;
        return (
            <MuiThemeProvider>

            {ErrorText}
            <form action="/login" method="post">
                <TextField
                    name="username"
                    hintText="enter username"
                    defaultValue={this.username}
                    floatingLabelText="username"
                    errorText={this.usernameErr}
                />

                <TextField
                    name="password"
                    hintText="password"
                    floatingLabelText="password"
                    errorText={this.passwordErr}
                    type="password"
                />

                {/* <RaisedButton label="cancel"/><RaisedButton label="login" type="submit" primary={true} style={style}/> */}
                <RaisedButton label="cancel" style={style} onClick={this.handleCancel}/><RaisedButton label="login" type="submit" primary={true} style={style}/>
            </form>

            </MuiThemeProvider>
        )
    }
};

render(<Login />, document.getElementById('login'));<|endoftext|>


<commit_before>import {_BaseCollection as BaseCollection} from './collection';

export default function aqlQuery(strings, ...args) {
  const bindVars = {};
  let query = strings[0];
  for (let i = 0; i < args.length; i++) {
    let value = args[i];
    let name = `value${i}`;
    if (
      value instanceof BaseCollection
      || (value.constructor && value.constructor.name === 'ArangoCollection')
    ) {
      name = `@${name}`;
      value = typeof value.name === 'function' ? value.name() : value.name;
    }
    bindVars[name] = value;
    query += `@${name}${strings[i + 1]}`;
  }
  return {query, bindVars};
}
<commit_msg>aqlQuery should handle null/undefined<commit_after>import {_BaseCollection as BaseCollection} from './collection';

export default function aqlQuery(strings, ...args) {
  const bindVars = {};
  let query = strings[0];
  for (let i = 0; i < args.length; i++) {
    let value = args[i];
    let name = `value${i}`;
    if (
      value instanceof BaseCollection
      || (value && value.constructor && value.constructor.name === 'ArangoCollection')
    ) {
      name = `@${name}`;
      value = typeof value.name === 'function' ? value.name() : value.name;
    }
    bindVars[name] = value;
    query += `@${name}${strings[i + 1]}`;
  }
  return {query, bindVars};
}
<|endoftext|>


<commit_before>var cookie = require('cookie');
var yargs = require('yargs');

var parseCurlCommand = function(curlCommand) {
    var newlineFound = /\r|\n/.exec(curlCommand);
    if (newlineFound) {
        // remove newlines
        curlCommand = curlCommand.replace(/\\\r|\\\n/g, '');
    }
    var yargObject = yargs(curlCommand.trim());
    var parsedArguments = yargObject.argv;
    var cookieString;
    var cookies;
    var url = parsedArguments._[1];
    // if url argument wasn't where we expected it, check other places
    // it shows up
    if (!url && parsedArguments['L']) {
        url = parsedArguments['L'];
    }
    if (!url && parsedArguments['compressed']) {
        url = parsedArguments['compressed'];
    }
    var headers;
    if (parsedArguments.H) {
        headers = {};
        if (!Array.isArray(parsedArguments.H)) {
            parsedArguments.H = [parsedArguments.H];
        }
        parsedArguments.H.forEach(function (header) {
            if (header.indexOf('Cookie') !== -1) {
                cookieString = header;
            } else {
                var colonIndex = header.indexOf(':');
                var headerName = header.substring(0, colonIndex);
                var headerValue = header.substring(colonIndex + 1).trim();
                headers[headerName] = headerValue;
            }
        });
    }
    if (cookieString) {
        var cookieParseOptions = {
            decode: function(s) {return s;}
        };
        cookies = cookie.parse(cookieString.replace('Cookie: ', ''), cookieParseOptions);
    }
    var method;
    if (parsedArguments.X === 'POST') {
        method = 'post';
    } else if (parsedArguments.d || parsedArguments.data || parsedArguments['data-binary']) {
        method = 'post';
    } else {
        method = 'get';
    }
    var request = {
        url: url,
        method: method
    };
    if (headers) {
        request.headers = headers;
    }
    if (cookies) {
        request.cookies = cookies;
    }
    if (parsedArguments.data) {
        request.data = parsedArguments.data;
    } else if (parsedArguments['data-binary']) {
        request.data = parsedArguments['data-binary'];
    } else if (parsedArguments['d']) {
        request.data = parsedArguments['d'];
    }
    if (Array.isArray(request.data)) {
        request.data = joinDataArguments(request.data);
    }
    return request;
};

/**
 * given this: [ 'msg1=value1', 'msg2=value2' ]
 * output this: 'msg1=value1&msg2=value2'
 * @param dataArguments
 */
var joinDataArguments = function(dataArguments) {
    var data = '';
    dataArguments.forEach(function(argument, i) {
        if (i === 0) {
            data += argument;
        } else {
            data += '&' + argument;
        }
    });
    return data;
};

var serializeCookies = function(cookieDict) {
    var cookieString = '';
    var i = 0;
    var cookieCount = Object.keys(cookieDict).length;
    for (var cookieName in cookieDict) {
        var cookieValue = cookieDict[cookieName];
        cookieString += cookieName + '=' + cookieValue;
        if (i < cookieCount - 1) {
            cookieString += '; ';
        }
        i++;
    }
    return cookieString;
};

module.exports = {
    parseCurlCommand: parseCurlCommand,
    serializeCookies: serializeCookies
};

<commit_msg>rearrange function definitions to fix jshint<commit_after>var cookie = require('cookie');
var yargs = require('yargs');

/**
 * given this: [ 'msg1=value1', 'msg2=value2' ]
 * output this: 'msg1=value1&msg2=value2'
 * @param dataArguments
 */
var joinDataArguments = function(dataArguments) {
    var data = '';
    dataArguments.forEach(function(argument, i) {
        if (i === 0) {
            data += argument;
        } else {
            data += '&' + argument;
        }
    });
    return data;
};

var parseCurlCommand = function(curlCommand) {
    var newlineFound = /\r|\n/.exec(curlCommand);
    if (newlineFound) {
        // remove newlines
        curlCommand = curlCommand.replace(/\\\r|\\\n/g, '');
    }
    var yargObject = yargs(curlCommand.trim());
    var parsedArguments = yargObject.argv;
    var cookieString;
    var cookies;
    var url = parsedArguments._[1];
    // if url argument wasn't where we expected it, check other places
    // it shows up
    if (!url && parsedArguments['L']) {
        url = parsedArguments['L'];
    }
    if (!url && parsedArguments['compressed']) {
        url = parsedArguments['compressed'];
    }
    var headers;
    if (parsedArguments.H) {
        headers = {};
        if (!Array.isArray(parsedArguments.H)) {
            parsedArguments.H = [parsedArguments.H];
        }
        parsedArguments.H.forEach(function (header) {
            if (header.indexOf('Cookie') !== -1) {
                cookieString = header;
            } else {
                var colonIndex = header.indexOf(':');
                var headerName = header.substring(0, colonIndex);
                var headerValue = header.substring(colonIndex + 1).trim();
                headers[headerName] = headerValue;
            }
        });
    }
    if (cookieString) {
        var cookieParseOptions = {
            decode: function(s) {return s;}
        };
        cookies = cookie.parse(cookieString.replace('Cookie: ', ''), cookieParseOptions);
    }
    var method;
    if (parsedArguments.X === 'POST') {
        method = 'post';
    } else if (parsedArguments.d || parsedArguments.data || parsedArguments['data-binary']) {
        method = 'post';
    } else {
        method = 'get';
    }
    var request = {
        url: url,
        method: method
    };
    if (headers) {
        request.headers = headers;
    }
    if (cookies) {
        request.cookies = cookies;
    }
    if (parsedArguments.data) {
        request.data = parsedArguments.data;
    } else if (parsedArguments['data-binary']) {
        request.data = parsedArguments['data-binary'];
    } else if (parsedArguments['d']) {
        request.data = parsedArguments['d'];
    }
    if (Array.isArray(request.data)) {
        request.data = joinDataArguments(request.data);
    }
    return request;
};

var serializeCookies = function(cookieDict) {
    var cookieString = '';
    var i = 0;
    var cookieCount = Object.keys(cookieDict).length;
    for (var cookieName in cookieDict) {
        var cookieValue = cookieDict[cookieName];
        cookieString += cookieName + '=' + cookieValue;
        if (i < cookieCount - 1) {
            cookieString += '; ';
        }
        i++;
    }
    return cookieString;
};

module.exports = {
    parseCurlCommand: parseCurlCommand,
    serializeCookies: serializeCookies
};

<|endoftext|>


<commit_before>'use strict';

var aws             = require('aws-sdk');
var bunyan          = require('bunyan');
var crypto          = require('crypto');

var config          = require('config.js');

const LOGGER = bunyan.createLogger({
  name: 'jellyfish',
  streams: [
    {
      level: config.logLevel,
      stream: process.stdout
    },
    {
      level: 'error',
      type: 'rotating-file',
      path: config.logError,
      period: '1d',
      count: 7
    }
  ],
  serializers: bunyan.stdSerializers
});
module.exports.logger = LOGGER;
LOGGER.info('logger setup ready ....');

aws.config.update({
  accessKeyId: config.awsAccess,
  secretAccessKey: process.env.SECRET_ACCESS || config.awsSecret,
  region: config.awsRegion
});
const S3 = new aws.S3();
module.exports.s3 = S3;
LOGGER.info('s3 setup ready ....');

module.exports.hash = function(password, salt) {
  var hash = crypto.createHmac(config.hmac, salt);
  hash.update(password);

  return hash.digest('hex');
};

module.exports.getBucket = function(username) {
  return 'jellyfish-carpteas-' + username;
};

module.exports.getRandom = function(filepath, bucket) {
  return module.exports.hash(filepath, bucket);
};

module.exports.getKey = function(filename, fileext) {
  return filename + '.' + fileext;
};<commit_msg>bucket name randomized<commit_after>'use strict';

var aws             = require('aws-sdk');
var bunyan          = require('bunyan');
var crypto          = require('crypto');

var config          = require('config.js');

const LOGGER = bunyan.createLogger({
  name: 'jellyfish',
  streams: [
    {
      level: config.logLevel,
      stream: process.stdout
    },
    {
      level: 'error',
      type: 'rotating-file',
      path: config.logError,
      period: '1d',
      count: 7
    }
  ],
  serializers: bunyan.stdSerializers
});
module.exports.logger = LOGGER;
LOGGER.info('logger setup ready ....');

aws.config.update({
  accessKeyId: config.awsAccess,
  secretAccessKey: process.env.SECRET_ACCESS || config.awsSecret,
  region: config.awsRegion
});
const S3 = new aws.S3();
module.exports.s3 = S3;
LOGGER.info('s3 setup ready ....');

function hash(password, salt) {
  var hash = crypto.createHmac(config.hmac, salt);
  hash.update(password);

  return hash.digest('hex');
}
module.exports.hash = hash;

module.exports.getBucket = function(username) {
  return hash(username, 'jellyfish').substr(0, 6) + '-' + username;
};

module.exports.getRandom = function(filepath, bucket) {
  return hash(filepath, bucket);
};

module.exports.getKey = function(filename, fileext) {
  return filename + '.' + fileext;
};<|endoftext|>


<commit_before>function isInt(n) {
	return Number(n) === n && n % 1 === 0;
}

var fact_arr = [1, 1];
function factorial(n) {
	for (var i = 2; i <= n; ++i) {
		fact_arr[i] = i * fact_arr[i-1];
	}
	return fact_arr[n];
}

function permutation(arr, n) {
	var perm = [];
	var rest = arr.slice();
	for (var i = 0; i < arr.length; ++i) {
		var f = factorial(arr.length - i - 1);
		var pos = Math.floor(n / f);
		n = n % f;
		perm.push(rest.splice(pos, 1)[0]);
	}

	return perm;
}

function create_map(n, func) {
	var result = [];
	var i;
	for (i = 0; i < n; ++i) {
		result.push(func(i));
	}
	return result;
}

function create_matrix(n, m, func) {
	var i, j;
	var result = create_map(n, function(i) {
		return create_map(m, function (j) {
			return func(i, j);
		});
	});
	result.width = m;
	result.height = n;
	result.forEach = function (callback, thisArg) {
		var that = thisArg || this;
		for (i = 0; i < result.height; ++i) {
			for (j = 0; j < result.width; ++j) {
				callback(that[i][j], i, j, that);
			}
		}
	};
	return result;
}

function copy_matrix(matr) {
	var i, j;
	var result = [];
	result.width  = matr.width;
	result.height = matr.height;
	for (i = 0; i < matr.height; ++i) {
		result[i] = [];
		for (j = 0; j < matr.width; ++j) {
			result[i][j] = matr[i][j];
		}
	}
	result.matrForEach = matr.matrForEach;
	return result;
}

function copy_matrix_wo_col(matr, col) {
	return create_matrix(matr.height, matr.width - 1, function(i, j) {
		return j < col ? matr[i][j] : matr[i][j+1];
	});
}

function copy_matrix_wo_row(matr, row) {
	return create_matrix(matr.height - 1, matr.width, function(i, j) {
		return i < row ? matr[i][j] : matr[i+1][j];
	});
}

function cr_const(n) {
	return function() {
		return n;
	};
}

function combinations_arr (n, kmin, kmax) {
	if (kmax < 0 || n < kmin) {
		return [];
	}

	if (n === 0) {
		return [[]];
	}

	if (n === 1) {
		var res = [];
		if (kmax > 0) {
			res.push([1]);
		}
		if (kmin <= 0) {
			res.push([0]);
		}
		console.log(res);
		return res;
	}

	var combsPlus = combinations (n-1, kmin-1, kmax-1);
	var combsMin  = combinations (n-1, kmin,   kmax);

	combsPlus.map(function (el) { el.splice(0, 0, 1); return el; });
	combsMin.map( function (el) { el.splice(0, 0, 0); return el; });
	return combsPlus.concat(combsMin);
}

function merge_in (arr1, arr2) {
	var s = arr1.slice();
	var lp = 0;
	for (var i = 0; i < arr2.length; ++i) {
		while (lp in s) {
			++lp;
		}
		s[lp] = arr2[i];
	}
	return s;
}
<commit_msg>Fix errors made while moving `combinations_arr`<commit_after>function isInt(n) {
	return Number(n) === n && n % 1 === 0;
}

var fact_arr = [1, 1];
function factorial(n) {
	for (var i = 2; i <= n; ++i) {
		fact_arr[i] = i * fact_arr[i-1];
	}
	return fact_arr[n];
}

function permutation(arr, n) {
	var perm = [];
	var rest = arr.slice();
	for (var i = 0; i < arr.length; ++i) {
		var f = factorial(arr.length - i - 1);
		var pos = Math.floor(n / f);
		n = n % f;
		perm.push(rest.splice(pos, 1)[0]);
	}

	return perm;
}

function create_map(n, func) {
	var result = [];
	var i;
	for (i = 0; i < n; ++i) {
		result.push(func(i));
	}
	return result;
}

function create_matrix(n, m, func) {
	var i, j;
	var result = create_map(n, function(i) {
		return create_map(m, function (j) {
			return func(i, j);
		});
	});
	result.width = m;
	result.height = n;
	result.forEach = function (callback, thisArg) {
		var that = thisArg || this;
		for (i = 0; i < result.height; ++i) {
			for (j = 0; j < result.width; ++j) {
				callback(that[i][j], i, j, that);
			}
		}
	};
	return result;
}

function copy_matrix(matr) {
	var i, j;
	var result = [];
	result.width  = matr.width;
	result.height = matr.height;
	for (i = 0; i < matr.height; ++i) {
		result[i] = [];
		for (j = 0; j < matr.width; ++j) {
			result[i][j] = matr[i][j];
		}
	}
	result.matrForEach = matr.matrForEach;
	return result;
}

function copy_matrix_wo_col(matr, col) {
	return create_matrix(matr.height, matr.width - 1, function(i, j) {
		return j < col ? matr[i][j] : matr[i][j+1];
	});
}

function copy_matrix_wo_row(matr, row) {
	return create_matrix(matr.height - 1, matr.width, function(i, j) {
		return i < row ? matr[i][j] : matr[i+1][j];
	});
}

function cr_const(n) {
	return function() {
		return n;
	};
}

function combinations_arr (n, kmin, kmax) {
	if (kmax < 0 || n < kmin) {
		return [];
	}

	if (n === 0) {
		return [[]];
	}

	if (n === 1) {
		var res = [];
		if (kmax > 0) {
			res.push([1]);
		}
		if (kmin <= 0) {
			res.push([0]);
		}
		return res;
	}

	var combsPlus = combinations_arr (n-1, kmin-1, kmax-1);
	var combsMin  = combinations_arr (n-1, kmin,   kmax);

	combsPlus.map(function (el) { el.splice(0, 0, 1); return el; });
	combsMin.map( function (el) { el.splice(0, 0, 0); return el; });
	return combsPlus.concat(combsMin);
}

function merge_in (arr1, arr2) {
	var s = arr1.slice();
	var lp = 0;
	for (var i = 0; i < arr2.length; ++i) {
		while (lp in s) {
			++lp;
		}
		s[lp] = arr2[i];
	}
	return s;
}
<|endoftext|>


<commit_before>"use strict";

const strUtils = require('./stringUtils');

function getMatches(str) {
  const pattern = /(\w{2,}er)[^\w]+|(\w{2,}er)$/gi;

  return str.match(pattern) || [];
}

function cleanMatches(matches) {
  const pattern = /[^\w]+$/;

  return matches.map(str => {
    return str.replace(pattern, "");
  });
}

function splitByEr(word) {
  return strUtils.splitWord(word, "er");
}

function formatSplitWordParts(parts) {
  const capFirst = strUtils.capitalizeFirstCharacter;

  return `${capFirst(parts[0])} '${parts[1]}?!`;
}

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

function isTwentyFivePercentChance() {
  return getRandomInt(0, 4) === 0;
}

function shouldRespond(username, matches) {
  return username !== 'slackbot'
    && matches.length !== 0
    && isTwentyFivePercentChance();
}

function bot(req, res) {
  const text = req.body.text;
  const username = req.body.user_name;
  const matches = cleanMatches(getMatches(text));
  const linkify = strUtils.linkifySlackUsername;

  if (!shouldRespond(username, matches)) {
    return res.status(200).end();
  }

  const message = matches
    .map(splitByEr)
    .map(formatSplitWordParts)
    .join(" ");

  const payload = {
    text: `${linkify(username)}: ${message} I barely know 'er!`,
  };

  return res.status(200).json(payload);
}

module.exports = {
  getMatches: getMatches,
  bot: bot,
};
<commit_msg>Use non-redundant ES6 object syntax<commit_after>"use strict";

const strUtils = require('./stringUtils');

function getMatches(str) {
  const pattern = /(\w{2,}er)[^\w]+|(\w{2,}er)$/gi;

  return str.match(pattern) || [];
}

function cleanMatches(matches) {
  const pattern = /[^\w]+$/;

  return matches.map(str => {
    return str.replace(pattern, "");
  });
}

function splitByEr(word) {
  return strUtils.splitWord(word, "er");
}

function formatSplitWordParts(parts) {
  const capFirst = strUtils.capitalizeFirstCharacter;

  return `${capFirst(parts[0])} '${parts[1]}?!`;
}

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

function isTwentyFivePercentChance() {
  return getRandomInt(0, 4) === 0;
}

function shouldRespond(username, matches) {
  return username !== 'slackbot'
    && matches.length !== 0
    && isTwentyFivePercentChance();
}

function bot(req, res) {
  const text = req.body.text;
  const username = req.body.user_name;
  const matches = cleanMatches(getMatches(text));
  const linkify = strUtils.linkifySlackUsername;

  if (!shouldRespond(username, matches)) {
    return res.status(200).end();
  }

  const message = matches
    .map(splitByEr)
    .map(formatSplitWordParts)
    .join(" ");

  const payload = {
    text: `${linkify(username)}: ${message} I barely know 'er!`,
  };

  return res.status(200).json(payload);
}

module.exports = {
  getMatches,
  bot,
};
<|endoftext|>


<commit_before>//= require "header"
//= require "extentions/event.js"

/*
 * based on:
 *    Justin Palmer's EventSelectors (http://encytemedia.com/event-selectors)
 *    Dan Webb's LowPro (http://svn.danwebb.net/external/lowpro)
 */

CD3.Behaviors = function(rules){
	document.observe('dom:loaded', CD3.Behaviors.assign.curry(rules, null));
}

Object.extend(CD3.Behaviors, (function(){
	function observe(element, event, observer){
		if (Object.isFunction(observer)){
			Event.observe(element, event, observer);
		} else {
			for(var selector in observer){
				Event.delegate(element, selector, event, observer[selector]);
			}
		}
	}
	return {
		assign: function(rules, parent){
			parent = parent || document;
			for (var selector in rules){
				var observer = rules[selector];
				selector.split(',').each(function(sel){
					var parts = sel.split(/:(?=[a-z]+$)/), css = parts.shift(), event = parts.join('');
					Selector.findChildElements(parent, [css]).each(function(element){
						if (event) {
							observe(element, event, observer);
						} else if (Object.isArray(observer)){
							var klass = observer.shift();
							new klass(element, observer.shift());
						} else if (observer.prototype && observer.prototype.initialize){
							new observer(element);
						} else if (Object.isFunction(observer)){
							observer.call(element, element);
						} else {
							for(var e in observer) observe(element, e, observer[e]);
						}
					});
				});
			}
		},
		when: function(selector, rules){
			document.observe('dom:loaded', CD3.Behaviors.assignIf.curry(selector, rules));
		},
		assignIf: function(selector, rules){
			var parent = $$(selector).first();
			if (parent) CD3.Behaviors.assign(Object.isFunction(rules) ? rules(parent) : rules, parent);
		}
	};
})());
<commit_msg>move CD3.Behaviors.(assign|assignIf|when) into the CD3.Behaviors<commit_after>//= require "header"
//= require "extentions/event.js"

/*
 * based on:
 *    Justin Palmer's EventSelectors (http://encytemedia.com/event-selectors)
 *    Dan Webb's LowPro (http://svn.danwebb.net/external/lowpro)
 */

CD3.Behaviors = (function(){
	function observe(element, event, observer){
		if (Object.isFunction(observer)){
			Event.observe(element, event, observer);
		} else {
			for(var selector in observer){
				Event.delegate(element, selector, event, observer[selector]);
			}
		}
	}

	function assign(root, rules){
		var selector, observer;
		for (selector in rules){
			observer = rules[selector];
			selector.split(',').each(function(selector){
				var parts = selector.split(/:(?=[a-z]+$)/), event = parts.pop(), css = parts.join('');
				Selector.findChildElements(root, [css]).each(function(element){
					if (event) {
						observe(element, event, observer);
					} else if (observer.prototype && observer.prototype.initialize){
						new observer(element);
					} else if (Object.isFunction(observer)){
						observer.call(element, element);
					} else if (Object.isArray(observer)){
						var klass = observer.shift();
						new klass(element, observer.shift());
					} else {
						for(var e in observer) observe(element, e, observer[e]);
					}
				});
			});
		}
	}

	function run(args){
		if (args.length == 1){
			var root = document, rules = args[0];
		} else {
			var root = $$(args[0]).first(), rules = args[1];
		}

		if (root) assign(root, Object.isFunction(rules) ? rules(root) : rules);
	}

	return function(){
		if (document.loaded){
			run(arguments);
		} else {
			document.observe('dom:loaded', run.curry(arguments));
		}
	};
})();

<|endoftext|>


<commit_before>import expect from 'expect';
import { parse } from 'graphql/language';
import { validate } from 'graphql/validation';
import adrenalineTestUtils from 'adrenaline/lib/graphql/test-utils/expect';

import schema from '../../../../shared/schema';
import TodoApp from '../TodoApp';

expect.extend(adrenalineTestUtils);

describe('Queries regression', () => {
  it('for TodoApp', () => {
    expect(TodoApp).toBeValidAgainst(schema);
  });
});
<commit_msg>fix example<commit_after>import expect from 'expect';
import adrenalineTestUtils from 'adrenaline/lib/graphql/test-utils/expect';

import schema from '../../../../shared/schema';
import TodoApp from '../TodoApp';

expect.extend(adrenalineTestUtils);

describe('Queries regression', () => {
  it('for TodoApp', () => {
    expect(TodoApp).toBeValidAgainst(schema);
  });
});
<|endoftext|>


<commit_before>/*
 * Generate RFC4122 (v1 and v4) UUIDs
 *
 * Documentation at https://github.com/broofa/node-uuid
 */
(function() {
  var _global = this;

  // Random number generator (feature-detected below)
  var _rng;

  // node.js 'crypto' API
  // http://nodejs.org/docs/v0.6.2/api/crypto.html#randomBytes
  try {
    _rng = require('crypto').randomBytes;
  } catch (e) {}

  // WHATWG crypto api, available in Chrome
  // http://wiki.whatwg.org/wiki/Crypto
  if (!_rng && _global.crypto && crypto.getRandomValues) {
    var _rnds = new Uint32Array(4), _rndBytes = new Array(16);
    var _rng = function() {
      // Get 32-bit rnds
      crypto.getRandomValues(_rnds);

      // Unpack into byte array
      for (var c = 0 ; c < 16; c++) {
        _rndBytes[c] = _rnds[c >> 2] >>> ((c & 0x03) * 8) & 0xff;
      }
      return _rndBytes;
    };
  }

  // Math.random - least desirable option since it does not guarantee
  // cryptographic quality.
  if (!_rng) {
    var _rndBytes = new Array(16);
    _rng = function() {
      var r, b = _rndBytes, i = 0;

      for (var i = 0, r; i < 16; i++) {
        if ((i & 0x03) == 0) r = Math.random() * 0x100000000;
        b[i] = r >>> ((i & 0x03) << 3) & 0xff;
      }

      return b;
    };
  }

  // Buffer class to use
  var BufferClass = typeof(Buffer) == 'function' ? Buffer : Array;

  // Maps for number <-> hex string conversion
  var _byteToHex = [];
  var _hexToByte = {};
  for (var i = 0; i < 256; i++) {
    _byteToHex[i] = (i + 0x100).toString(16).substr(1);
    _hexToByte[_byteToHex[i]] = i;
  }

  /** See docs at https://github.com/broofa/node-uuid */
  function parse(s, buf, offset) {
    var i = (buf && offset) || 0, ii = 0;

    buf = buf || [];
    s.toLowerCase().replace(/[0-9a-f]{2}/g, function(byte) {
      if (ii < 16) { // Don't overflow!
        buf[i + ii++] = _hexToByte[byte];
      }
    });

    // Zero out remaining bytes if string was short
    while (ii < 16) {
      buf[i + ii++] = 0;
    }

    return buf;
  }

  /** See docs at https://github.com/broofa/node-uuid */
  function unparse(buf, offset) {
    var i = offset || 0, bth = _byteToHex;
    return  bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]];
  }

  // Pre allocate array for constructing uuids
  var _buffer = new BufferClass(16);

  //
  // v1 UUID support
  //
  // Inspired by https://github.com/LiosK/UUID.js
  // and http://docs.python.org/library/uuid.html
  //

  // Per 4.1.4 - Offset (in msecs) from JS time to UUID (gregorian) time
  var EPOCH_OFFSET = 12219292800000;

  // random #'s we need to init node and clockseq
  var _seedBytes = _rng(10);

  // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
  var _nodeId = [
    _seedBytes[0] | 0x01,
    _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
  ];

  // Per 4.2.2, randomize (14 bit) clockseq
  var _clockSeq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;

  // Previous uuid creation time
  var _last = 0;

  // Count of UUIDs created during current time tick
  var _count = 0;

  /** See docs at https://github.com/broofa/node-uuid */
  function v1(options, buf, offset) {
    var i = buf && offset || 0;
    var b = buf || _buffer;

    options = options || {};

    // JS Numbers aren't capable of representing time in the RFC-specified
    // 100-nanosecond units. To deal with this, we represent time using two
    // values: 'msecs', as the usual JS milliseconds (here), and 'nsecs', an
    // additional 100-nanosecond unit offset (set below)
    var msecs = (options.msecs || new Date().getTime()) + EPOCH_OFFSET;

    if (msecs < _last) {
      // Clock regression - Per 4.2.1.2, increment clock seq
      _clockSeq++;
      _count = 0;
    } else {
      // Per 4.2.1.2, use a count of uuid's generated during the current
      // clock cycle to simulate higher resolution clock
      _count = (msecs == _last) ? _count + 1 : 0;
    }
    _last = msecs;

    // Per 4.2.1.2 If generator creates more than one id per uuid 100-ns
    // interval, throw an error
    // (Requires generating > 10M uuids/sec. While unlikely, it's not
    // entirely inconceivable given the benchmark results we're getting)
    if (_count >= 10000) {
      throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
    }

    // Additional 100-nanosecond units offset
    var nsecs = options.nsecs || _count;

    // Per 4.1.4, timestamp composition

    // time_low
    var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
    b[i++] = tl >>> 24 & 0xff;
    b[i++] = tl >>> 16 & 0xff;
    b[i++] = tl >>> 8 & 0xff;
    b[i++] = tl & 0xff;

    // time_mid
    var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
    b[i++] = tmh >>> 8 & 0xff;
    b[i++] = tmh & 0xff;

    // time_high_and_version
    b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
    b[i++] = tmh >>> 16 & 0xff;

    // Clock sequence
    var cs = options.clockseq != null ? options.clockseq : _clockSeq;

    // clock_seq_hi_and_reserved (Per 4.2.2 - include variant)
    b[i++] = cs >>> 8 | 0x80;

    // clock_seq_low
    b[i++] = cs & 0xff;

    // node
    var node = options.node || _nodeId;
    for (var n = 0; n < 6; n++) {
      b[i + n] = node[n];
    }

    return buf ? buf : unparse(b);
  }

  //
  // v4 UUID support
  //

  /** See docs at https://github.com/broofa/node-uuid */
  function v4(options, buf, offset) {
    // Deprecated - 'format' argument, as supported in v1.2
    var i = buf && offset || 0;
    if (typeof(options) == 'string') {
      buf = options == 'binary' ? new BufferClass(16) : null;
      options = null;
    }

    var rnds = options && options.random || _rng(16);
    // Per 4.4, set bits for version and clock_seq_hi_and_reserved
    rnds[6] = (rnds[6] & 0x0f) | 0x40;
    rnds[8] = (rnds[8] & 0x3f) | 0x80;

    // Copy bytes to buffer, if provided
    if (buf) {
      for (var ii = 0; ii < 16; ii++) {
        buf[i + ii] = rnds[ii];
      }
    }

    return buf || unparse(rnds);
  }

  //
  // Export API
  //

  var uuid = v4;
  uuid.v1 = v1;
  uuid.v4 = v4;
  uuid.parse = parse;
  uuid.unparse = unparse;
  uuid.BufferClass = BufferClass;

  if (typeof(module) != 'undefined') {
    module.exports = uuid;
  } else {
    var _previousRoot = _global.uuid;
    uuid.noConflict = function() {
      _global.uuid = _previousRoot;
      return uuid;
    }
    _global.uuid = uuid;
  }
}());
<commit_msg>Avoid 14bit integer overflow in clock_seq<commit_after>/*
 * Generate RFC4122 (v1 and v4) UUIDs
 *
 * Documentation at https://github.com/broofa/node-uuid
 */
(function() {
  var _global = this;

  // Random number generator (feature-detected below)
  var _rng;

  // node.js 'crypto' API
  // http://nodejs.org/docs/v0.6.2/api/crypto.html#randomBytes
  try {
    _rng = require('crypto').randomBytes;
  } catch (e) {}

  // WHATWG crypto api, available in Chrome
  // http://wiki.whatwg.org/wiki/Crypto
  if (!_rng && _global.crypto && crypto.getRandomValues) {
    var _rnds = new Uint32Array(4), _rndBytes = new Array(16);
    var _rng = function() {
      // Get 32-bit rnds
      crypto.getRandomValues(_rnds);

      // Unpack into byte array
      for (var c = 0 ; c < 16; c++) {
        _rndBytes[c] = _rnds[c >> 2] >>> ((c & 0x03) * 8) & 0xff;
      }
      return _rndBytes;
    };
  }

  // Math.random - least desirable option since it does not guarantee
  // cryptographic quality.
  if (!_rng) {
    var _rndBytes = new Array(16);
    _rng = function() {
      var r, b = _rndBytes, i = 0;

      for (var i = 0, r; i < 16; i++) {
        if ((i & 0x03) == 0) r = Math.random() * 0x100000000;
        b[i] = r >>> ((i & 0x03) << 3) & 0xff;
      }

      return b;
    };
  }

  // Buffer class to use
  var BufferClass = typeof(Buffer) == 'function' ? Buffer : Array;

  // Maps for number <-> hex string conversion
  var _byteToHex = [];
  var _hexToByte = {};
  for (var i = 0; i < 256; i++) {
    _byteToHex[i] = (i + 0x100).toString(16).substr(1);
    _hexToByte[_byteToHex[i]] = i;
  }

  /** See docs at https://github.com/broofa/node-uuid */
  function parse(s, buf, offset) {
    var i = (buf && offset) || 0, ii = 0;

    buf = buf || [];
    s.toLowerCase().replace(/[0-9a-f]{2}/g, function(byte) {
      if (ii < 16) { // Don't overflow!
        buf[i + ii++] = _hexToByte[byte];
      }
    });

    // Zero out remaining bytes if string was short
    while (ii < 16) {
      buf[i + ii++] = 0;
    }

    return buf;
  }

  /** See docs at https://github.com/broofa/node-uuid */
  function unparse(buf, offset) {
    var i = offset || 0, bth = _byteToHex;
    return  bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]];
  }

  // Pre allocate array for constructing uuids
  var _buffer = new BufferClass(16);

  //
  // v1 UUID support
  //
  // Inspired by https://github.com/LiosK/UUID.js
  // and http://docs.python.org/library/uuid.html
  //

  // Per 4.1.4 - Offset (in msecs) from JS time to UUID (gregorian) time
  var EPOCH_OFFSET = 12219292800000;

  // random #'s we need to init node and clockseq
  var _seedBytes = _rng(10);

  // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
  var _nodeId = [
    _seedBytes[0] | 0x01,
    _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
  ];

  // Per 4.2.2, randomize (14 bit) clockseq
  var _clockSeq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;

  // Previous uuid creation time
  var _last = 0;

  // Count of UUIDs created during current time tick
  var _count = 0;

  /** See docs at https://github.com/broofa/node-uuid */
  function v1(options, buf, offset) {
    var i = buf && offset || 0;
    var b = buf || _buffer;

    options = options || {};

    // JS Numbers aren't capable of representing time in the RFC-specified
    // 100-nanosecond units. To deal with this, we represent time using two
    // values: 'msecs', as the usual JS milliseconds (here), and 'nsecs', an
    // additional 100-nanosecond unit offset (set below)
    var msecs = (options.msecs || new Date().getTime()) + EPOCH_OFFSET;

    if (msecs < _last) {
      // Clock regression - Per 4.2.1.2, increment clock seq
      _clockSeq = (_clockSeq + 1) & 0x3fff
      _count = 0;
    } else {
      // Per 4.2.1.2, use a count of uuid's generated during the current
      // clock cycle to simulate higher resolution clock
      _count = (msecs == _last) ? _count + 1 : 0;
    }
    _last = msecs;

    // Per 4.2.1.2 If generator creates more than one id per uuid 100-ns
    // interval, throw an error
    // (Requires generating > 10M uuids/sec. While unlikely, it's not
    // entirely inconceivable given the benchmark results we're getting)
    if (_count >= 10000) {
      throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
    }

    // Additional 100-nanosecond units offset
    var nsecs = options.nsecs || _count;

    // Per 4.1.4, timestamp composition

    // time_low
    var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
    b[i++] = tl >>> 24 & 0xff;
    b[i++] = tl >>> 16 & 0xff;
    b[i++] = tl >>> 8 & 0xff;
    b[i++] = tl & 0xff;

    // time_mid
    var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
    b[i++] = tmh >>> 8 & 0xff;
    b[i++] = tmh & 0xff;

    // time_high_and_version
    b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
    b[i++] = tmh >>> 16 & 0xff;

    // Clock sequence
    var cs = options.clockseq != null ? options.clockseq : _clockSeq;

    // clock_seq_hi_and_reserved (Per 4.2.2 - include variant)
    b[i++] = cs >>> 8 | 0x80;

    // clock_seq_low
    b[i++] = cs & 0xff;

    // node
    var node = options.node || _nodeId;
    for (var n = 0; n < 6; n++) {
      b[i + n] = node[n];
    }

    return buf ? buf : unparse(b);
  }

  //
  // v4 UUID support
  //

  /** See docs at https://github.com/broofa/node-uuid */
  function v4(options, buf, offset) {
    // Deprecated - 'format' argument, as supported in v1.2
    var i = buf && offset || 0;
    if (typeof(options) == 'string') {
      buf = options == 'binary' ? new BufferClass(16) : null;
      options = null;
    }

    var rnds = options && options.random || _rng(16);
    // Per 4.4, set bits for version and clock_seq_hi_and_reserved
    rnds[6] = (rnds[6] & 0x0f) | 0x40;
    rnds[8] = (rnds[8] & 0x3f) | 0x80;

    // Copy bytes to buffer, if provided
    if (buf) {
      for (var ii = 0; ii < 16; ii++) {
        buf[i + ii] = rnds[ii];
      }
    }

    return buf || unparse(rnds);
  }

  //
  // Export API
  //

  var uuid = v4;
  uuid.v1 = v1;
  uuid.v4 = v4;
  uuid.parse = parse;
  uuid.unparse = unparse;
  uuid.BufferClass = BufferClass;

  if (typeof(module) != 'undefined') {
    module.exports = uuid;
  } else {
    var _previousRoot = _global.uuid;
    uuid.noConflict = function() {
      _global.uuid = _previousRoot;
      return uuid;
    }
    _global.uuid = uuid;
  }
}());
<|endoftext|>


<commit_before>import hbs from 'htmlbars-inline-precompile';
import sinon from 'sinon';
import {click, find, findAll, render} from '@ember/test-helpers';
import {describe, it} from 'mocha';
import {expect} from 'chai';
import {setupRenderingTest} from 'ember-mocha';

describe('Integration: Component: gh-theme-table', function () {
    setupRenderingTest();

    it('renders', async function () {
        this.set('themes', [
            {name: 'Daring', package: {name: 'Daring', version: '0.1.4'}, active: true},
            {name: 'casper', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'oscar-ghost-1.1.0', package: {name: 'Lanyon', version: '1.1.0'}},
            {name: 'foo'}
        ]);
        this.set('actionHandler', sinon.spy());

        await render(hbs`{{gh-theme-table
            themes=themes
            activateTheme=(action actionHandler)
            downloadTheme=(action actionHandler)
            deleteTheme=(action actionHandler)
        }}`);

        expect(findAll('[data-test-themes-list]').length, 'themes list is present').to.equal(1);
        expect(findAll('[data-test-theme-id]').length, 'number of rows').to.equal(4);

        let packageNames = findAll('[data-test-theme-title]').map(name => name.textContent.trim());

        expect(
            packageNames,
            'themes are ordered by label, casper has "default"'
        ).to.deep.equal([
            'Casper (default)',
            'Daring',
            'foo',
            'Lanyon'
        ]);

        expect(
            find('[data-test-theme-active="true"]').querySelector('[data-test-theme-title]'),
            'active theme is highlighted'
        ).to.have.trimmed.text('Daring');

        expect(
            findAll('[data-test-theme-activate-button]').length,
            'non-active themes have an activate link'
        ).to.equal(3);

        expect(
            find('[data-test-theme-active="true"]').querySelector('[data-test-theme-activate-button]'),
            'active theme doesn\'t have an activate link'
        ).to.not.exist;

        expect(
            findAll('[data-test-theme-download-button]').length,
            'all themes have a download link'
        ).to.equal(4);

        expect(
            find('[data-test-theme-id="foo"]').querySelector('[data-test-theme-delete-button]'),
            'non-active, non-casper theme has delete link'
        ).to.exist;

        expect(
            find('[data-test-theme-id="casper"]').querySelector('[data-test-theme-delete-button]'),
            'casper doesn\'t have delete link'
        ).to.not.exist;

        expect(
            find('[data-test-theme-active="true"]').querySelector('[data-test-theme-delete-button]'),
            'active theme doesn\'t have delete link'
        ).to.not.exist;
    });

    it('delete link triggers passed in action', async function () {
        let deleteAction = sinon.spy();
        let actionHandler = sinon.spy();

        this.set('themes', [
            {name: 'Foo', active: true},
            {name: 'Bar'}
        ]);
        this.set('deleteAction', deleteAction);
        this.set('actionHandler', actionHandler);

        await render(hbs`{{gh-theme-table
            themes=themes
            activateTheme=(action actionHandler)
            downloadTheme=(action actionHandler)
            deleteTheme=(action deleteAction)
        }}`);

        await click('[data-test-theme-id="Bar"] [data-test-theme-delete-button]');

        expect(deleteAction.calledOnce).to.be.true;
        expect(deleteAction.firstCall.args[0].name).to.equal('Bar');
    });

    it('download link triggers passed in action', async function () {
        let downloadAction = sinon.spy();
        let actionHandler = sinon.spy();

        this.set('themes', [
            {name: 'Foo', active: true},
            {name: 'Bar'}
        ]);
        this.set('downloadAction', downloadAction);
        this.set('actionHandler', actionHandler);

        await render(hbs`{{gh-theme-table
            themes=themes
            activateTheme=(action actionHandler)
            downloadTheme=(action downloadAction)
            deleteTheme=(action actionHandler)
        }}`);

        await click('[data-test-theme-id="Foo"] [data-test-theme-download-button]');

        expect(downloadAction.calledOnce).to.be.true;
        expect(downloadAction.firstCall.args[0].name).to.equal('Foo');
    });

    it('activate link triggers passed in action', async function () {
        let activateAction = sinon.spy();
        let actionHandler = sinon.spy();

        this.set('themes', [
            {name: 'Foo', active: true},
            {name: 'Bar'}
        ]);
        this.set('activateAction', activateAction);
        this.set('actionHandler', actionHandler);

        await render(hbs`{{gh-theme-table
            themes=themes
            activateTheme=(action activateAction)
            downloadTheme=(action actionHandler)
            deleteTheme=(action actionHandler)
        }}`);

        await click('[data-test-theme-id="Bar"] [data-test-theme-activate-button]');

        expect(activateAction.calledOnce).to.be.true;
        expect(activateAction.firstCall.args[0].name).to.equal('Bar');
    });

    it('displays folder names if there are duplicate package names', async function () {
        this.set('themes', [
            {name: 'daring', package: {name: 'Daring', version: '0.1.4'}, active: true},
            {name: 'daring-0.1.5', package: {name: 'Daring', version: '0.1.4'}},
            {name: 'casper', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'another', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'mine', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'foo'}
        ]);
        this.set('actionHandler', sinon.spy());

        await render(hbs`{{gh-theme-table
            themes=themes
            activateTheme=(action actionHandler)
            downloadTheme=(action actionHandler)
            deleteTheme=(action actionHandler)
        }}`);

        let packageNames = findAll('[data-test-theme-title]').map(name => name.textContent.trim());

        expect(
            packageNames,
            'themes are ordered by label, folder names shown for duplicates'
        ).to.deep.equal([
            'Casper (another)',
            'Casper (default)',
            'Casper (mine)',
            'Daring (daring)',
            'Daring (daring-0.1.5)',
            'foo'
        ]);
    });
});
<commit_msg>Updated <GhThemeTable> test<commit_after>import hbs from 'htmlbars-inline-precompile';
import sinon from 'sinon';
import {click, find, findAll, render} from '@ember/test-helpers';
import {describe, it} from 'mocha';
import {expect} from 'chai';
import {setupRenderingTest} from 'ember-mocha';

describe('Integration: Component: gh-theme-table', function () {
    setupRenderingTest();

    it('renders', async function () {
        this.set('themes', [
            {name: 'Daring', package: {name: 'Daring', version: '0.1.4'}, active: true},
            {name: 'casper', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'oscar-ghost-1.1.0', package: {name: 'Lanyon', version: '1.1.0'}},
            {name: 'foo'}
        ]);

        await render(hbs`<GhThemeTable @themes={{themes}} />`);

        expect(findAll('[data-test-themes-list]').length, 'themes list is present').to.equal(1);
        expect(findAll('[data-test-theme-id]').length, 'number of rows').to.equal(4);

        let packageNames = findAll('[data-test-theme-title]').map(name => name.textContent.trim());

        expect(packageNames[0]).to.match(/Casper \(default\)/);
        expect(packageNames[1]).to.match(/Daring\s+Active/);
        expect(packageNames[2]).to.match(/foo/);
        expect(packageNames[3]).to.match(/Lanyon/);

        expect(
            find('[data-test-theme-active="true"]').querySelector('[data-test-theme-title]'),
            'active theme is highlighted'
        ).to.contain.text('Daring');

        expect(
            findAll('[data-test-button="activate"]').length,
            'non-active themes have an activate link'
        ).to.equal(3);

        expect(
            find('[data-test-theme-active="true"]').querySelector('[data-test-button="activate"]'),
            'active theme doesn\'t have an activate link'
        ).to.not.exist;
    });

    it('has download button in actions dropdown for all themes', async function () {
        const themes = [
            {name: 'Daring', package: {name: 'Daring', version: '0.1.4'}, active: true},
            {name: 'casper', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'oscar-ghost-1.1.0', package: {name: 'Lanyon', version: '1.1.0'}},
            {name: 'foo'}
        ];
        this.set('themes', themes);

        await render(hbs`<GhThemeTable @themes={{themes}} />`);

        for (const theme of themes) {
            await click(`[data-test-theme-id="${theme.name}"] [data-test-button="actions"]`);
            expect(
                find(`[data-test-actions-for="${theme.name}"] [data-test-button="download"]`)
            ).to.exist;
        }
    });

    it('has delete button for non-active, non-default, themes', async function () {
        const themes = [
            {name: 'Daring', package: {name: 'Daring', version: '0.1.4'}},
            {name: 'oscar-ghost-1.1.0', package: {name: 'Lanyon', version: '1.1.0'}},
            {name: 'foo'}
        ];
        this.set('themes', themes);

        await render(hbs`<GhThemeTable @themes={{themes}} />`);

        for (const theme of themes) {
            await click(`[data-test-theme-id="${theme.name}"] [data-test-button="actions"]`);
            expect(
                find(`[data-test-actions-for="${theme.name}"] [data-test-button="delete"]`)
            ).to.exist;
        }
    });

    it('does not show delete action for casper', async function () {
        const themes = [
            {name: 'Daring', package: {name: 'Daring', version: '0.1.4'}, active: true},
            {name: 'casper', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'oscar-ghost-1.1.0', package: {name: 'Lanyon', version: '1.1.0'}},
            {name: 'foo'}
        ];
        this.set('themes', themes);

        await render(hbs`<GhThemeTable @themes={{themes}} />`);

        await click(`[data-test-theme-id="casper"] [data-test-button="actions"]`);
        expect(find('[data-test-actions-for="casper"]')).to.exist;
        expect(
            find(`[data-test-actions-for="casper"] [data-test-button="delete"]`)
        ).to.not.exist;
    });

    it('does not show delete action for active theme', async function () {
        const themes = [
            {name: 'Daring', package: {name: 'Daring', version: '0.1.4'}, active: true},
            {name: 'casper', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'oscar-ghost-1.1.0', package: {name: 'Lanyon', version: '1.1.0'}},
            {name: 'foo'}
        ];
        this.set('themes', themes);

        await render(hbs`<GhThemeTable @themes={{themes}} />`);

        await click(`[data-test-theme-id="Daring"] [data-test-button="actions"]`);
        expect(find('[data-test-actions-for="Daring"]')).to.exist;
        expect(
            find(`[data-test-actions-for="Daring"] [data-test-button="delete"]`)
        ).to.not.exist;
    });

    it('displays folder names if there are duplicate package names', async function () {
        this.set('themes', [
            {name: 'daring', package: {name: 'Daring', version: '0.1.4'}},
            {name: 'daring-0.1.5', package: {name: 'Daring', version: '0.1.4'}},
            {name: 'casper', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'another', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'mine', package: {name: 'Casper', version: '1.3.1'}},
            {name: 'foo'}
        ]);

        await render(hbs`<GhThemeTable @themes={{themes}} />`);

        let packageNames = findAll('[data-test-theme-title]').map(name => name.textContent.trim());

        expect(
            packageNames,
            'themes are ordered by label, folder names shown for duplicates'
        ).to.deep.equal([
            'Casper (another)',
            'Casper (default)',
            'Casper (mine)',
            'Daring (daring)',
            'Daring (daring-0.1.5)',
            'foo'
        ]);
    });
});
<|endoftext|>


<commit_before>function create () {
  return [0, 0]
}

function set (a, b) {
  a[0] = b[0]
  a[1] = b[1]
  return a
}

function equals (a, b) {
  return a[0] === b[0] &&
    a[1] === b[1]
}

function copy (a) {
  return a.slice(0)
}

function add (a, b) {
  a[0] += b[0]
  a[1] += b[1]
  return a
}

function sub (a, b) {
  a[0] -= b[0]
  a[1] -= b[1]
  return a
}

function scale (a, n) {
  a[0] *= n
  a[1] *= n
  return a
}

function dot (a, b) {
  return a[0] * b[0] + a[1] * b[1]
}

function length (a) {
  var x = a[0]
  var y = a[1]
  return Math.sqrt(x * x + y * y)
}

function lengthSq (a) {
  var x = a[0]
  var y = a[1]
  return x * x + y * y
}

function normalize (a) {
  var x = a[0]
  var y = a[1]
  var l = Math.sqrt(x * x + y * y)

  l = 1.0 / (l || 1)
  a[0] *= l
  a[1] *= l
  return a
}

function distance (a, b) {
  return distance2(a, b[0], b[1])
}

function distanceSq (a, b) {
  return distanceSq2(a, b[0], b[1], b[2])
}

function limit (a, n) {
  var x = a[0]
  var y = a[1]

  var dsq = x * x + y * y
  var lsq = n * n

  if (lsq > 0 && dsq > lsq) {
    var nd = n / Math.sqrt(dsq)
    a[0] *= nd
    a[1] *= nd
  }

  return a
}

function lerp (a, b, n) {
  var x = a[0]
  var y = a[1]

  a[0] = x + (b[0] - x) * n
  a[1] = y + (b[1] - y) * n

  return a
}

function toString (a, precision) {
  var scale = Math.pow(10, precision !== undefined ? precision : 4)
  var s = '['
  s += Math.floor(a[0] * scale) / scale + ', '
  s += Math.floor(a[1] * scale) / scale + ']'
  return s
}

function addScaled (v, w, n) {
  v[0] += w[0] * n
  v[1] += w[1] * n

  return v
}

var Vec2 = {
  create: create,
  set: set,
  copy: copy,
  equals: equals,
  add: add,
  sub: sub,
  scale: scale,
  dot: dot,
  length: length,
  lengthSq: lengthSq,
  normalize: normalize,
  distance: distance,
  distanceSq: distanceSq,
  limit: limit,
  lerp: lerp,
  toString: toString
}

module.exports = Vec2
<commit_msg>Replace dead methods with implementation<commit_after>function create () {
  return [0, 0]
}

function set (a, b) {
  a[0] = b[0]
  a[1] = b[1]
  return a
}

function equals (a, b) {
  return a[0] === b[0] &&
    a[1] === b[1]
}

function copy (a) {
  return a.slice(0)
}

function add (a, b) {
  a[0] += b[0]
  a[1] += b[1]
  return a
}

function sub (a, b) {
  a[0] -= b[0]
  a[1] -= b[1]
  return a
}

function scale (a, n) {
  a[0] *= n
  a[1] *= n
  return a
}

function dot (a, b) {
  return a[0] * b[0] + a[1] * b[1]
}

function length (a) {
  var x = a[0]
  var y = a[1]
  return Math.sqrt(x * x + y * y)
}

function lengthSq (a) {
  var x = a[0]
  var y = a[1]
  return x * x + y * y
}

function normalize (a) {
  var x = a[0]
  var y = a[1]
  var l = Math.sqrt(x * x + y * y)

  l = 1.0 / (l || 1)
  a[0] *= l
  a[1] *= l
  return a
}

function distance (a, b) {
  var dx = b[0] - a[0]
  var dy = b[1] - a[1]
  return Math.sqrt(dx * dx + dy * dy)
}

function distanceSq (a, b) {
  var dx = b[0] - a[0]
  var dy = b[1] - a[1]
  return dx * dx + dy * dy
}

function limit (a, n) {
  var x = a[0]
  var y = a[1]

  var dsq = x * x + y * y
  var lsq = n * n

  if (lsq > 0 && dsq > lsq) {
    var nd = n / Math.sqrt(dsq)
    a[0] *= nd
    a[1] *= nd
  }

  return a
}

function lerp (a, b, n) {
  var x = a[0]
  var y = a[1]

  a[0] = x + (b[0] - x) * n
  a[1] = y + (b[1] - y) * n

  return a
}

function toString (a, precision) {
  var scale = Math.pow(10, precision !== undefined ? precision : 4)
  var s = '['
  s += Math.floor(a[0] * scale) / scale + ', '
  s += Math.floor(a[1] * scale) / scale + ']'
  return s
}

function addScaled (v, w, n) {
  v[0] += w[0] * n
  v[1] += w[1] * n

  return v
}

var Vec2 = {
  create: create,
  set: set,
  copy: copy,
  equals: equals,
  add: add,
  sub: sub,
  scale: scale,
  dot: dot,
  length: length,
  lengthSq: lengthSq,
  normalize: normalize,
  distance: distance,
  distanceSq: distanceSq,
  limit: limit,
  lerp: lerp,
  toString: toString
}

module.exports = Vec2
<|endoftext|>


<commit_before>var VibeJs = {

	testingState       : "paused",
	theme              : null,
	widgetContainer    : null,
	widget             : null,
	highlightedElement : null,
	ratingForm         : null,
	commentButton      : null,
	commentText        : null,
	targetElements     : ["DIV", "SPAN"],

	DrawWidget       : function()
	{
		this.widgetContainer = document.querySelectorAll ("vibejs")[0];
		this.widget = document.createElement ("div");
		this.widget.className = "feedBackWidget " + this.theme;
		this.widgetContainer.appendChild (this.widget);

		this.widget.addEventListener ("click", function (event)
		{
			if (VibeJs.testingState == "paused")
			{
				VibeJs.testingState = "recording";
				VibeJs.widget.style.backgroundImage = 'url("vibe.js/pause.png")';

				document.addEventListener ("mouseover", function (event)
				{
					if (VibeJs.testingState == "recording")
					{
						VibeJs.HighlightElement (event.target);
					}
				});
			}
			else if (VibeJs.testingState == "recording")
			{
				VibeJs.testingState = "paused";
				VibeJs.widget.style.backgroundImage = 'url("vibe.js/talk.png")';
				VibeJs.highlightedElement = null;

				var elements = document.querySelectorAll ("*");

				for (index in elements)
				{
					if (elements[index].dataset && elements[index].dataset.rating)
					{
						console.log (VibeJs.GetXPath (elements[index]));
						console.log (elements[index].dataset.rating);
						console.log (elements[index].dataset.comment);
					}
				}

				console.log (navigator.userAgent);
			}
		})
	},

	DrawRatingForm   : function (element)
	{
		var ratingFormsOnPage = document.querySelectorAll (".ratingForm");

		for (var ratingForm in ratingFormsOnPage)
		{
			if (ratingFormsOnPage[ratingForm].parentElement)
			{
				ratingFormsOnPage[ratingForm].parentElement.removeChild (ratingFormsOnPage[ratingForm]);
			}
		}

		var ratingForm = document.createElement ("div");
		ratingForm.className = "ratingForm";
		ratingForm.style.zIndex = "1979";
		ratingForm.style.float = "right";
		element.insertBefore (ratingForm, element.firstChild);

		VibeJs.DrawStarBar (ratingForm);
		VibeJs.ratingForm = ratingForm;
	},

	DrawStarBar      : function (element)
	{
		var starBar = document.createElement ("div");
		starBar.className = "starBar";

		var starBarRating1 = document.createElement ("span");
		starBarRating1.className = "star";
		starBarRating1.setAttribute ("disabled", "true");

		var starBarRating2 = document.createElement ("span");
		starBarRating2.className = "star";
		starBarRating2.setAttribute ("disabled", "true");

		var starBarRating3 = document.createElement ("span");
		starBarRating3.className = "star";
		starBarRating3.setAttribute ("disabled", "true");

		var starBarRating4 = document.createElement ("span");
		starBarRating4.className = "star";
		starBarRating4.setAttribute ("disabled", "true");

		var starBarRating5 = document.createElement ("span");
		starBarRating5.className = "star";
		starBarRating5.setAttribute ("disabled", "true");

		starBar.appendChild (starBarRating1);
		starBar.appendChild (starBarRating2);
		starBar.appendChild (starBarRating3);
		starBar.appendChild (starBarRating4);
		starBar.appendChild (starBarRating5);

		element.appendChild (starBar);

		var stars = element.querySelectorAll (".star");

		for (var index = 0; index < stars.length; ++index)
		{
			if (stars[index].nodeName == "SPAN")
			{
				DrawStarRating (stars[VibeJs.highlightedElement.getAttribute ("data-rating")]);

				stars[index].addEventListener ("mouseover", function (event)
				{
					DrawStarRating (event.target);
				});
			}
		}

		function DrawStarRating (target)
		{
			var starBarElement = element.querySelectorAll (".star");

			for (var index = 0; index < starBarElement.length; ++index)
			{
				if (starBarElement[index] == target)
				{
					for (var nodeIndex = 0; nodeIndex <= index; ++nodeIndex)
					{
						starBarElement[nodeIndex].style.backgroundImage = 'url("vibe.js/star.png")';
						starBarElement[nodeIndex].removeAttribute ("disabled");
					}

					if (VibeJs.highlightedElement.dataset.rating)
					{
						VibeJs.CommentButton (VibeJs.highlightedElement);
					}

					target.addEventListener ("click", function (event)
					{
						VibeJs.CommentButton (VibeJs.highlightedElement, "open");

						for (var index = 0; index < stars.length; ++index)
						{
							if (stars[index] == target){VibeJs.highlightedElement.dataset.rating = index};
						}
					});
				}
				else
				{
					starBarElement[index].style.backgroundImage = 'url("vibe.js/disabledstar.png")';
					starBarElement[index].setAttribute ("disabled", "true");
				}
			}
		}
	},

	CommentButton    : function (state)
	{
		var commentButtonsOnPage = document.querySelectorAll (".commentButton");

		for (var commentButtons in commentButtonsOnPage)
		{
			if (commentButtonsOnPage[commentButtons].parentElement)
			{
				commentButtonsOnPage[commentButtons].parentElement.removeChild (commentButtonsOnPage[commentButtons]);
			}
		}

		var commentButton = document.createElement ("div");
		commentButton.className = "commentButton";
		commentButton.style.left = VibeJs.highlightedElement.offsetWidth - 65 + "px";
		commentButton.style.top = VibeJs.highlightedElement.offsetHeight - 65 + "px";

		VibeJs.commentButton = commentButton;
		VibeJs.highlightedElement.appendChild (commentButton);

		if (state == "open")
		{
			VibeJs.CommentText();
		}
		else
		{
			commentButton.addEventListener ("click", function (event)
			{
				VibeJs.CommentText();
			});
		}
	},

	CommentText      : function()
	{
		if (!VibeJs.commentText)
		{
			var commentText = document.createElement ("div");
			commentText.className = "commentText";
			commentText.style.width = VibeJs.highlightedElement.offsetWidth - 20 + "px";
			commentText.style.height = VibeJs.highlightedElement.offsetHeight - 70 + "px";
			commentText.style.left = "5px";
			commentText.style.top = "40px";
			commentText.style.padding = "10px";
			commentText.style.overflow = "auto";
			commentText.setAttribute ("contenteditable", "true");

			commentText.innerText = VibeJs.highlightedElement.dataset.comment || "";

			VibeJs.highlightedElement.appendChild (commentText);
			VibeJs.commentText = commentText;

			commentText.addEventListener ("mouseout", function()
			{
				VibeJs.highlightedElement.dataset.comment = commentText.innerText;
			});
		}
	},

	HighlightElement : function (element)
	{
		var highlightElement = false;

		if (element && element.nodeName && element != VibeJs.ratingForm && element != VibeJs.commentButton && element != VibeJs.widget)
		{
			while (element && !highlightElement)
			{
				var elementNodeName = element.nodeName;

				for (index in VibeJs.targetElements)
				{
					if (elementNodeName == VibeJs.targetElements[index])
					{
						highlightElement = true;
					}
				}

				if (!highlightElement){element = element.parentElement;}
			}

			if (element && !VibeJs.highlightedElement)
			{
				VibeJs.highlightedElement = element;

				var originalOutlineColor = VibeJs.highlightedElement.style.outlineColor || null;
				var originalOutlineStyle = VibeJs.highlightedElement.style.outlineStyle || null;
				var originalBoxShadow = VibeJs.highlightedElement.style.boxShadow || null;
				var originalPosition = VibeJs.highlightedElement.style.position || null;

				VibeJs.highlightedElement.style.outlineColor = "#00A1FF";
				VibeJs.highlightedElement.style.outlineStyle = "dashed";
				VibeJs.highlightedElement.style.boxShadow = "0px 0px 15px #00A1FF";

				if (originalPosition != "absolute" && originalPosition != "fixed"){VibeJs.highlightedElement.style.position = "relative";}

				VibeJs.DrawRatingForm (VibeJs.highlightedElement);

				VibeJs.highlightedElement.addEventListener ("mouseenter", function (event)
				{
					if (VibeJs.highlightedElement)
					{
						VibeJs.DrawRatingForm (VibeJs.highlightedElement);
					}
				});

				VibeJs.highlightedElement.addEventListener ("mouseleave", function (event)
				{
					if (VibeJs.highlightedElement)
					{
						VibeJs.highlightedElement.style.outlineColor = originalOutlineColor;
						VibeJs.highlightedElement.style.outlineStyle = originalOutlineStyle;
						VibeJs.highlightedElement.style.boxShadow = originalBoxShadow;
						VibeJs.highlightedElement.style.position = originalPosition;
					}

					if (VibeJs.ratingForm && VibeJs.ratingForm.parentElement)
					{
						VibeJs.ratingForm.parentElement.removeChild (VibeJs.ratingForm);
						VibeJs.ratingForm = null;
					}

					if (VibeJs.commentButton && VibeJs.commentButton.parentElement)
					{
						VibeJs.commentButton.parentElement.removeChild (VibeJs.commentButton);
						VibeJs.commentButton = null;
					}

					if (VibeJs.commentText && VibeJs.commentText.parentElement)
					{
						VibeJs.commentText.parentElement.removeChild (VibeJs.commentText);
						VibeJs.commentText = null;
					}

					VibeJs.highlightedElement = null;
				})
			}
		}
	},

	GetXPath         : function (element)
	{
		if (element.tagName == 'HTML'){return '/HTML[1]'};
		if (element === document.body){return '/HTML[1]/BODY[1]'};

		var index = 0;
		var siblings = element.parentNode.childNodes;

		for (var siblingIndex = 0; siblingIndex < siblings.length; siblingIndex++)
		{
			var sibling = siblings[siblingIndex];

			if (sibling === element)
			{
				return VibeJs.GetXPath (element.parentNode) + '/' + element.tagName + '[' + (index + 1) + ']';
			}

			if (sibling.nodeType === 1 && sibling.tagName === element.tagName){index++};
		}
	}
}
<commit_msg>Cleaned up the logic for adding rating stars.<commit_after>var VibeJs = {

	testingState       : "paused",
	theme              : null,
	widgetContainer    : null,
	widget             : null,
	highlightedElement : null,
	ratingForm         : null,
	commentButton      : null,
	commentText        : null,
	targetElements     : ["DIV", "SPAN"],

	DrawWidget       : function()
	{
		this.widgetContainer = document.querySelectorAll ("vibejs")[0];
		this.widget = document.createElement ("div");
		this.widget.className = "feedBackWidget " + this.theme;
		this.widgetContainer.appendChild (this.widget);

		this.widget.addEventListener ("click", function (event)
		{
			if (VibeJs.testingState == "paused")
			{
				VibeJs.testingState = "recording";
				VibeJs.widget.style.backgroundImage = 'url("vibe.js/pause.png")';

				document.addEventListener ("mouseover", function (event)
				{
					if (VibeJs.testingState == "recording")
					{
						VibeJs.HighlightElement (event.target);
					}
				});
			}
			else if (VibeJs.testingState == "recording")
			{
				VibeJs.testingState = "paused";
				VibeJs.widget.style.backgroundImage = 'url("vibe.js/talk.png")';
				VibeJs.highlightedElement = null;

				var elements = document.querySelectorAll ("*");

				for (index in elements)
				{
					if (elements[index].dataset && elements[index].dataset.rating)
					{
						console.log (VibeJs.GetXPath (elements[index]));
						console.log (elements[index].dataset.rating);
						console.log (elements[index].dataset.comment);
					}
				}

				console.log (navigator.userAgent);
			}
		})
	},

	DrawRatingForm   : function (element)
	{
		var ratingFormsOnPage = document.querySelectorAll (".ratingForm");

		for (var ratingForm in ratingFormsOnPage)
		{
			if (ratingFormsOnPage[ratingForm].parentElement)
			{
				ratingFormsOnPage[ratingForm].parentElement.removeChild (ratingFormsOnPage[ratingForm]);
			}
		}

		var ratingForm = document.createElement ("div");
		ratingForm.className = "ratingForm";
		ratingForm.style.zIndex = "1979";
		ratingForm.style.float = "right";
		element.insertBefore (ratingForm, element.firstChild);

		VibeJs.DrawStarBar (ratingForm);
		VibeJs.ratingForm = ratingForm;
	},

	DrawStarBar      : function (element)
	{
		var starBar = document.createElement ("div");
		starBar.className = "starBar";

		for (count = 1; count <= 5; count++)
		{
			var starBarRating = document.createElement ("span");
			starBarRating.className = "star";
			starBarRating.setAttribute ("disabled", "true");
			starBar.appendChild (starBarRating);
		}

		element.appendChild (starBar);

		var stars = element.querySelectorAll (".star");

		for (var index = 0; index < stars.length; ++index)
		{
			if (stars[index].nodeName == "SPAN")
			{
				DrawStarRating (stars[VibeJs.highlightedElement.getAttribute ("data-rating")]);

				stars[index].addEventListener ("mouseover", function (event)
				{
					DrawStarRating (event.target);
				});
			}
		}

		function DrawStarRating (target)
		{
			var starBarElement = element.querySelectorAll (".star");

			for (var index = 0; index < starBarElement.length; ++index)
			{
				if (starBarElement[index] == target)
				{
					for (var nodeIndex = 0; nodeIndex <= index; ++nodeIndex)
					{
						starBarElement[nodeIndex].style.backgroundImage = 'url("vibe.js/star.png")';
						starBarElement[nodeIndex].removeAttribute ("disabled");
					}

					if (VibeJs.highlightedElement.dataset.rating)
					{
						VibeJs.CommentButton (VibeJs.highlightedElement);
					}

					target.addEventListener ("click", function (event)
					{
						VibeJs.CommentButton (VibeJs.highlightedElement, "open");

						for (var index = 0; index < stars.length; ++index)
						{
							if (stars[index] == target){VibeJs.highlightedElement.dataset.rating = index};
						}
					});
				}
				else
				{
					starBarElement[index].style.backgroundImage = 'url("vibe.js/disabledstar.png")';
					starBarElement[index].setAttribute ("disabled", "true");
				}
			}
		}
	},

	CommentButton    : function (state)
	{
		var commentButtonsOnPage = document.querySelectorAll (".commentButton");

		for (var commentButtons in commentButtonsOnPage)
		{
			if (commentButtonsOnPage[commentButtons].parentElement)
			{
				commentButtonsOnPage[commentButtons].parentElement.removeChild (commentButtonsOnPage[commentButtons]);
			}
		}

		var commentButton = document.createElement ("div");
		commentButton.className = "commentButton";
		commentButton.style.left = VibeJs.highlightedElement.offsetWidth - 65 + "px";
		commentButton.style.top = VibeJs.highlightedElement.offsetHeight - 65 + "px";

		VibeJs.commentButton = commentButton;
		VibeJs.highlightedElement.appendChild (commentButton);

		if (state == "open")
		{
			VibeJs.CommentText();
		}
		else
		{
			commentButton.addEventListener ("click", function (event)
			{
				VibeJs.CommentText();
			});
		}
	},

	CommentText      : function()
	{
		if (!VibeJs.commentText)
		{
			var commentText = document.createElement ("div");
			commentText.className = "commentText";
			commentText.style.width = VibeJs.highlightedElement.offsetWidth - 20 + "px";
			commentText.style.height = VibeJs.highlightedElement.offsetHeight - 70 + "px";
			commentText.style.left = "5px";
			commentText.style.top = "40px";
			commentText.style.padding = "10px";
			commentText.style.overflow = "auto";
			commentText.setAttribute ("contenteditable", "true");

			commentText.innerText = VibeJs.highlightedElement.dataset.comment || "";

			VibeJs.highlightedElement.appendChild (commentText);
			VibeJs.commentText = commentText;

			commentText.addEventListener ("mouseout", function()
			{
				VibeJs.highlightedElement.dataset.comment = commentText.innerText;
			});
		}
	},

	HighlightElement : function (element)
	{
		var highlightElement = false;

		if (element && element.nodeName && element != VibeJs.ratingForm && element != VibeJs.commentButton && element != VibeJs.widget)
		{
			while (element && !highlightElement)
			{
				var elementNodeName = element.nodeName;

				for (index in VibeJs.targetElements)
				{
					if (elementNodeName == VibeJs.targetElements[index])
					{
						highlightElement = true;
					}
				}

				if (!highlightElement){element = element.parentElement;}
			}

			if (element && !VibeJs.highlightedElement)
			{
				VibeJs.highlightedElement = element;

				var originalOutlineColor = VibeJs.highlightedElement.style.outlineColor || null;
				var originalOutlineStyle = VibeJs.highlightedElement.style.outlineStyle || null;
				var originalBoxShadow = VibeJs.highlightedElement.style.boxShadow || null;
				var originalPosition = VibeJs.highlightedElement.style.position || null;

				VibeJs.highlightedElement.style.outlineColor = "#00A1FF";
				VibeJs.highlightedElement.style.outlineStyle = "dashed";
				VibeJs.highlightedElement.style.boxShadow = "0px 0px 15px #00A1FF";

				if (originalPosition != "absolute" && originalPosition != "fixed"){VibeJs.highlightedElement.style.position = "relative";}

				VibeJs.DrawRatingForm (VibeJs.highlightedElement);

				VibeJs.highlightedElement.addEventListener ("mouseenter", function (event)
				{
					if (VibeJs.highlightedElement)
					{
						VibeJs.DrawRatingForm (VibeJs.highlightedElement);
					}
				});

				VibeJs.highlightedElement.addEventListener ("mouseleave", function (event)
				{
					if (VibeJs.highlightedElement)
					{
						VibeJs.highlightedElement.style.outlineColor = originalOutlineColor;
						VibeJs.highlightedElement.style.outlineStyle = originalOutlineStyle;
						VibeJs.highlightedElement.style.boxShadow = originalBoxShadow;
						VibeJs.highlightedElement.style.position = originalPosition;
					}

					if (VibeJs.ratingForm && VibeJs.ratingForm.parentElement)
					{
						VibeJs.ratingForm.parentElement.removeChild (VibeJs.ratingForm);
						VibeJs.ratingForm = null;
					}

					if (VibeJs.commentButton && VibeJs.commentButton.parentElement)
					{
						VibeJs.commentButton.parentElement.removeChild (VibeJs.commentButton);
						VibeJs.commentButton = null;
					}

					if (VibeJs.commentText && VibeJs.commentText.parentElement)
					{
						VibeJs.commentText.parentElement.removeChild (VibeJs.commentText);
						VibeJs.commentText = null;
					}

					VibeJs.highlightedElement = null;
				})
			}
		}
	},

	GetXPath         : function (element)
	{
		if (element.tagName == 'HTML'){return '/HTML[1]'};
		if (element === document.body){return '/HTML[1]/BODY[1]'};

		var index = 0;
		var siblings = element.parentNode.childNodes;

		for (var siblingIndex = 0; siblingIndex < siblings.length; siblingIndex++)
		{
			var sibling = siblings[siblingIndex];

			if (sibling === element)
			{
				return VibeJs.GetXPath (element.parentNode) + '/' + element.tagName + '[' + (index + 1) + ']';
			}

			if (sibling.nodeType === 1 && sibling.tagName === element.tagName){index++};
		}
	}
}
<|endoftext|>