<commit_before>// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Copyright (c) 2011 Jxck
//
// Originally from node.js (http://nodejs.org)
// Copyright Joyent, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

(function(global) {

// Object.create compatible in IE
var create = Object.create || function(p) {
  if (!p) throw Error('no type');
  function f() {};
  f.prototype = p;
  return new f();
};

// UTILITY
var util = {
  inherits: function(ctor, superCtor) {
    ctor.super_ = superCtor;
    ctor.prototype = create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  }
};

var pSlice = Array.prototype.slice;

// from https://github.com/substack/node-deep-equal
var Object_keys = typeof Object.keys === 'function'
    ? Object.keys
    : function (obj) {
        var keys = [];
        for (var key in obj) keys.push(key);
        return keys;
    }
;

// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.

var assert = ok;

global['assert'] = assert;

if (typeof module === 'object' && typeof module.exports === 'object') {
  module.exports = assert;
};

// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
//                             actual: actual,
//                             expected: expected })

assert.AssertionError = function AssertionError(options) {
  this.name = 'AssertionError';
  this.message = options.message;
  this.actual = options.actual;
  this.expected = options.expected;
  this.operator = options.operator;
  var stackStartFunction = options.stackStartFunction || fail;

  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, stackStartFunction);
  } else {
    // try to throw an error now, and from the stack property
    // work out the line that called in to assert.js.
    try {
      this.stack = (new Error).stack.toString();
    } catch (e) {}
  }
};

// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);

function replacer(key, value) {
  if (value === undefined) {
    return '' + value;
  }
  if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
    return value.toString();
  }
  if (typeof value === 'function' || value instanceof RegExp) {
    return value.toString();
  }
  return value;
}

function truncate(s, n) {
  if (typeof s == 'string') {
    return s.length < n ? s : s.slice(0, n);
  } else {
    return s;
  }
}

assert.AssertionError.prototype.toString = function() {
  if (this.message) {
    return [this.name + ':', this.message].join(' ');
  } else {
    return [
      this.name + ':',
      truncate(JSON.stringify(this.actual, replacer), 128),
      this.operator,
      truncate(JSON.stringify(this.expected, replacer), 128)
    ].join(' ');
  }
};

// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.

// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided.  All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.

function fail(actual, expected, message, operator, stackStartFunction) {
  throw new assert.AssertionError({
    message: message,
    actual: actual,
    expected: expected,
    operator: operator,
    stackStartFunction: stackStartFunction
  });
}

// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;

// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.

function ok(value, message) {
  if (!!!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;

// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);

assert.equal = function equal(actual, expected, message) {
  if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};

// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);

assert.notEqual = function notEqual(actual, expected, message) {
  if (actual == expected) {
    fail(actual, expected, message, '!=', assert.notEqual);
  }
};

// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);

assert.deepEqual = function deepEqual(actual, expected, message) {
  if (!_deepEqual(actual, expected)) {
    fail(actual, expected, message, 'deepEqual', assert.deepEqual);
  }
};

function _deepEqual(actual, expected) {
  // 7.1. All identical values are equivalent, as determined by ===.
  if (actual === expected) {
    return true;

//  } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
//    if (actual.length != expected.length) return false;
//
//    for (var i = 0; i < actual.length; i++) {
//      if (actual[i] !== expected[i]) return false;
//    }
//
//    return true;
//
  // 7.2. If the expected value is a Date object, the actual value is
  // equivalent if it is also a Date object that refers to the same time.
  } else if (actual instanceof Date && expected instanceof Date) {
    return actual.getTime() === expected.getTime();

  // 7.3 If the expected value is a RegExp object, the actual value is
  // equivalent if it is also a RegExp object with the same source and
  // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
  } else if (actual instanceof RegExp && expected instanceof RegExp) {
    return actual.source === expected.source &&
           actual.global === expected.global &&
           actual.multiline === expected.multiline &&
           actual.lastIndex === expected.lastIndex &&
           actual.ignoreCase === expected.ignoreCase;

  // 7.4. Other pairs that do not both pass typeof value == 'object',
  // equivalence is determined by ==.
  } else if (typeof actual != 'object' && typeof expected != 'object') {
    return actual == expected;

  // 7.5 For all other Object pairs, including Array objects, equivalence is
  // determined by having the same number of owned properties (as verified
  // with Object.prototype.hasOwnProperty.call), the same set of keys
  // (although not necessarily the same order), equivalent values for every
  // corresponding key, and an identical 'prototype' property. Note: this
  // accounts for both named and indexed properties on Arrays.
  } else {
    return objEquiv(actual, expected);
  }
}

function isUndefinedOrNull(value) {
  return value === null || value === undefined;
}

function isArguments(object) {
  return Object.prototype.toString.call(object) == '[object Arguments]';
}

function objEquiv(a, b) {
  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
    return false;
  // an identical 'prototype' property.
  if (a.prototype !== b.prototype) return false;
  //~~~I've managed to break Object.keys through screwy arguments passing.
  //   Converting to array solves the problem.
  if (isArguments(a)) {
    if (!isArguments(b)) {
      return false;
    }
    a = pSlice.call(a);
    b = pSlice.call(b);
    return _deepEqual(a, b);
  }
  try {
    var ka = Object_keys(a),
        kb = Object_keys(b),
        key, i;
  } catch (e) {//happens when one is a string literal and the other isn't
    return false;
  }
  // having the same number of owned properties (keys incorporates
  // hasOwnProperty)
  if (ka.length != kb.length)
    return false;
  //the same set of keys (although not necessarily the same order),
  ka.sort();
  kb.sort();
  //~~~cheap key test
  for (i = ka.length - 1; i >= 0; i--) {
    if (ka[i] != kb[i])
      return false;
  }
  //equivalent values for every corresponding key, and
  //~~~possibly expensive deep test
  for (i = ka.length - 1; i >= 0; i--) {
    key = ka[i];
    if (!_deepEqual(a[key], b[key])) return false;
  }
  return true;
}

// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);

assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  if (_deepEqual(actual, expected)) {
    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
  }
};

// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);

assert.strictEqual = function strictEqual(actual, expected, message) {
  if (actual !== expected) {
    fail(actual, expected, message, '===', assert.strictEqual);
  }
};

// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==.  assert.notStrictEqual(actual, expected, message_opt);

assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  if (actual === expected) {
    fail(actual, expected, message, '!==', assert.notStrictEqual);
  }
};

function expectedException(actual, expected) {
  if (!actual || !expected) {
    return false;
  }

  if (Object.prototype.toString.call(expected) == '[object RegExp]') {
    return expected.test(actual);
  } else if (actual instanceof expected) {
    return true;
  } else if (expected.call({}, actual) === true) {
    return true;
  }

  return false;
}

function _throws(shouldThrow, block, expected, message) {
  var actual;

  if (typeof expected === 'string') {
    message = expected;
    expected = null;
  }

  try {
    block();
  } catch (e) {
    actual = e;
  }

  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
            (message ? ' ' + message : '.');

  if (shouldThrow && !actual) {
    fail(actual, expected, 'Missing expected exception' + message);
  }

  if (!shouldThrow && expectedException(actual, expected)) {
    fail(actual, expected, 'Got unwanted exception' + message);
  }

  if ((shouldThrow && actual && expected &&
      !expectedException(actual, expected)) || (!shouldThrow && actual)) {
    throw actual;
  }
}

// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);

assert.throws = function(block, /*optional*/error, /*optional*/message) {
  _throws.apply(this, [true].concat(pSlice.call(arguments)));
};

// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/message) {
  _throws.apply(this, [false].concat(pSlice.call(arguments)));
};

assert.ifError = function(err) { if (err) {throw err;}};

if (typeof define === 'function' && define.amd) {
  define('assert', function () {
    return assert;
  });
}

})(this);

<commit_msg>Updated assert.js to b22eaf70cb3f31a34fcae4a57b499548e7242133.<commit_after>// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Copyright (c) 2011 Jxck
//
// Originally from node.js (http://nodejs.org)
// Copyright Joyent, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

(function(global) {

// Object.create compatible in IE
var create = Object.create || function(p) {
  if (!p) throw Error('no type');
  function f() {};
  f.prototype = p;
  return new f();
};

// UTILITY
var util = {
  inherits: function(ctor, superCtor) {
    ctor.super_ = superCtor;
    ctor.prototype = create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  },
  isArray: function(ar) {
    return Array.isArray(ar);
  },
  isBoolean: function(arg) {
    return typeof arg === 'boolean';
  },
  isNull: function(arg) {
    return arg === null;
  },
  isNullOrUndefined: function(arg) {
    return arg == null;
  },
  isNumber: function(arg) {
    return typeof arg === 'number';
  },
  isString: function(arg) {
    return typeof arg === 'string';
  },
  isSymbol: function(arg) {
    return typeof arg === 'symbol';
  },
  isUndefined: function(arg) {
    return arg === void 0;
  },
  isRegExp: function(re) {
    return util.isObject(re) && util.objectToString(re) === '[object RegExp]';
  },
  isObject: function(arg) {
    return typeof arg === 'object' && arg !== null;
  },
  isDate: function(d) {
    return util.isObject(d) && util.objectToString(d) === '[object Date]';
  },
  isError: function(e) {
    return isObject(e) &&
      (objectToString(e) === '[object Error]' || e instanceof Error);
  },
  isFunction: function(arg) {
    return typeof arg === 'function';
  },
  isPrimitive: function(arg) {
    return arg === null ||
      typeof arg === 'boolean' ||
      typeof arg === 'number' ||
      typeof arg === 'string' ||
      typeof arg === 'symbol' ||  // ES6 symbol
      typeof arg === 'undefined';
  },
  objectToString: function(o) {
    return Object.prototype.toString.call(o);
  }
};

var pSlice = Array.prototype.slice;

// from https://github.com/substack/node-deep-equal
var Object_keys = typeof Object.keys === 'function'
    ? Object.keys
    : function (obj) {
        var keys = [];
        for (var key in obj) keys.push(key);
        return keys;
    }
;

// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.

var assert = ok;

global['assert'] = assert;

if (typeof module === 'object' && typeof module.exports === 'object') {
  module.exports = assert;
};

// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
//                             actual: actual,
//                             expected: expected })

assert.AssertionError = function AssertionError(options) {
  this.name = 'AssertionError';
  this.actual = options.actual;
  this.expected = options.expected;
  this.operator = options.operator;
  if (options.message) {
    this.message = options.message;
    this.generatedMessage = false;
  } else {
    this.message = getMessage(this);
    this.generatedMessage = true;
  }
  var stackStartFunction = options.stackStartFunction || fail;

  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, stackStartFunction);
  } else {
    // try to throw an error now, and from the stack property
    // work out the line that called in to assert.js.
    try {
      this.stack = (new Error).stack.toString();
    } catch (e) {}
  }
};

// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);

function replacer(key, value) {
  if (util.isUndefined(value)) {
    return '' + value;
  }
  if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) {
    return value.toString();
  }
  if (util.isFunction(value) || util.isRegExp(value)) {
    return value.toString();
  }
  return value;
}

function truncate(s, n) {
  if (util.isString(s)) {
    return s.length < n ? s : s.slice(0, n);
  } else {
    return s;
  }
}

function getMessage(self) {
  return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
         self.operator + ' ' +
         truncate(JSON.stringify(self.expected, replacer), 128);
}

// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.

// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided.  All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.

function fail(actual, expected, message, operator, stackStartFunction) {
  throw new assert.AssertionError({
    message: message,
    actual: actual,
    expected: expected,
    operator: operator,
    stackStartFunction: stackStartFunction
  });
}

// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;

// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.

function ok(value, message) {
  if (!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;

// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);

assert.equal = function equal(actual, expected, message) {
  if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};

// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);

assert.notEqual = function notEqual(actual, expected, message) {
  if (actual == expected) {
    fail(actual, expected, message, '!=', assert.notEqual);
  }
};

// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);

assert.deepEqual = function deepEqual(actual, expected, message) {
  if (!_deepEqual(actual, expected)) {
    fail(actual, expected, message, 'deepEqual', assert.deepEqual);
  }
};

function _deepEqual(actual, expected) {
  // 7.1. All identical values are equivalent, as determined by ===.
  if (actual === expected) {
    return true;

  // } else if (util.isBuffer(actual) && util.isBuffer(expected)) {
  //   if (actual.length != expected.length) return false;
  //
  //   for (var i = 0; i < actual.length; i++) {
  //     if (actual[i] !== expected[i]) return false;
  //   }
  //
  //   return true;

  // 7.2. If the expected value is a Date object, the actual value is
  // equivalent if it is also a Date object that refers to the same time.
  } else if (util.isDate(actual) && util.isDate(expected)) {
    return actual.getTime() === expected.getTime();

  // 7.3 If the expected value is a RegExp object, the actual value is
  // equivalent if it is also a RegExp object with the same source and
  // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
  } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
    return actual.source === expected.source &&
           actual.global === expected.global &&
           actual.multiline === expected.multiline &&
           actual.lastIndex === expected.lastIndex &&
           actual.ignoreCase === expected.ignoreCase;

  // 7.4. Other pairs that do not both pass typeof value == 'object',
  // equivalence is determined by ==.
  } else if (!util.isObject(actual) && !util.isObject(expected)) {
    return actual == expected;

  // 7.5 For all other Object pairs, including Array objects, equivalence is
  // determined by having the same number of owned properties (as verified
  // with Object.prototype.hasOwnProperty.call), the same set of keys
  // (although not necessarily the same order), equivalent values for every
  // corresponding key, and an identical 'prototype' property. Note: this
  // accounts for both named and indexed properties on Arrays.
  } else {
    return objEquiv(actual, expected);
  }
}

function isArguments(object) {
  return Object.prototype.toString.call(object) == '[object Arguments]';
}

function objEquiv(a, b) {
  if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
    return false;
  // an identical 'prototype' property.
  if (a.prototype !== b.prototype) return false;
  //~~~I've managed to break Object.keys through screwy arguments passing.
  //   Converting to array solves the problem.
  if (isArguments(a)) {
    if (!isArguments(b)) {
      return false;
    }
    a = pSlice.call(a);
    b = pSlice.call(b);
    return _deepEqual(a, b);
  }
  try {
    var ka = Object_keys(a),
        kb = Object_keys(b),
        key, i;
  } catch (e) {//happens when one is a string literal and the other isn't
    return false;
  }
  // having the same number of owned properties (keys incorporates
  // hasOwnProperty)
  if (ka.length != kb.length)
    return false;
  //the same set of keys (although not necessarily the same order),
  ka.sort();
  kb.sort();
  //~~~cheap key test
  for (i = ka.length - 1; i >= 0; i--) {
    if (ka[i] != kb[i])
      return false;
  }
  //equivalent values for every corresponding key, and
  //~~~possibly expensive deep test
  for (i = ka.length - 1; i >= 0; i--) {
    key = ka[i];
    if (!_deepEqual(a[key], b[key])) return false;
  }
  return true;
}

// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);

assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  if (_deepEqual(actual, expected)) {
    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
  }
};

// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);

assert.strictEqual = function strictEqual(actual, expected, message) {
  if (actual !== expected) {
    fail(actual, expected, message, '===', assert.strictEqual);
  }
};

// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==.  assert.notStrictEqual(actual, expected, message_opt);

assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  if (actual === expected) {
    fail(actual, expected, message, '!==', assert.notStrictEqual);
  }
};

function expectedException(actual, expected) {
  if (!actual || !expected) {
    return false;
  }

  if (Object.prototype.toString.call(expected) == '[object RegExp]') {
    return expected.test(actual);
  } else if (actual instanceof expected) {
    return true;
  } else if (expected.call({}, actual) === true) {
    return true;
  }

  return false;
}

function _throws(shouldThrow, block, expected, message) {
  var actual;

  if (util.isString(expected)) {
    message = expected;
    expected = null;
  }

  try {
    block();
  } catch (e) {
    actual = e;
  }

  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
            (message ? ' ' + message : '.');

  if (shouldThrow && !actual) {
    fail(actual, expected, 'Missing expected exception' + message);
  }

  if (!shouldThrow && expectedException(actual, expected)) {
    fail(actual, expected, 'Got unwanted exception' + message);
  }

  if ((shouldThrow && actual && expected &&
      !expectedException(actual, expected)) || (!shouldThrow && actual)) {
    throw actual;
  }
}

// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);

assert.throws = function(block, /*optional*/error, /*optional*/message) {
  _throws.apply(this, [true].concat(pSlice.call(arguments)));
};

// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/message) {
  _throws.apply(this, [false].concat(pSlice.call(arguments)));
};

assert.ifError = function(err) { if (err) {throw err;}};

if (typeof define === 'function' && define.amd) {
  define('assert', function () {
    return assert;
  });
}

})(this);

<|endoftext|>


<commit_before>import Ember from 'ember';
import DS from 'ember-data';
import syncLoads from 'ember-data-offline/logics/sync-loads';
import Queue from 'ember-data-offline/queue';

export default DS.Store.extend({
  syncLoads: syncLoads.create(),
  EDOQueue: Queue.create(),
  adapterFor() {
    return this._super.apply(this, arguments).get('offlineAdapter');
  }
});
<commit_msg>Update store.js<commit_after>import Ember from 'ember';
import DS from 'ember-data';
import syncLoads from 'ember-data-offline/logics/sync-loads';
import Queue from 'ember-data-offline/queue';

export default DS.Store.extend({
  syncLoads: syncLoads.create(),
  EDOQueue: Queue.create(),
  adapterFor() {
    return this._super.apply(this, arguments).get('offlineAdapter') || this._super.apply(this, arguments);
  }
});
<|endoftext|>


<commit_before>module.exports = {
  normalizeEntityName: function() {},

  afterInstall: function() {
    var self = this;
    return this.addBowerPackageToProject('flag-icon-css').then(function(){
      self.addBowerPackageToProject('bootstrap3-wysiwyg');
    });
  }
};<commit_msg>fix deps<commit_after>module.exports = {
  normalizeEntityName: function() {},

  afterInstall: function() {
    this.addBowerPackageToProject('flag-icon-css');
    return this.addBowerPackageToProject('bootstrap3-wysiwyg');
  }
};<|endoftext|>


<commit_before>core.service("WsApi", function($q, $http, wsservice, AuthServiceApi) {

	var WsApi = this;

	WsApi.listen = function(apiReq) {
		var request = '/ws/'+apiReq.controller+'/' + apiReq.method;
		var channel = '/' + apiReq.endpoint + "/" + apiReq.controller;

		if(apiReq.method) {
			channel +=  "/" + apiReq.method;
		}
		return wsservice.subscribe(channel);
	};

	WsApi.fetch = function(apiReq) {

		var request = '/ws/'+apiReq.controller+'/' + apiReq.method;
		var channel = apiReq.endpoint + "/" + apiReq.controller + "/" + apiReq.method;

		var headers = {
			'jwt': sessionStorage.token,
			'data': (typeof apiReq.data != 'undefined') ? apiReq.data : '{}'
		};

		var fetchPromise = wsservice.send(request, headers, {}, channel);

		fetchPromise.then(null, null, function(data) {

			var meta = JSON.parse(data.body).meta;

			if(meta.type == "REFRESH") {
				if(sessionStorage.assumedUser) {
					AuthServiceApi.getAssumedUser(JSON.parse(sessionStorage.assumedUser)).then(function() {
						wsservice.pendingReq[meta.id].resend();
					});
				} else {
					AuthServiceApi.getRefreshToken().then(function() {
						wsservice.pendingReq[meta.id].resend();
					});
				}
			}
		});

		return fetchPromise;
	};

});
<commit_msg>Remove forward slash in front of channel on listen.<commit_after>core.service("WsApi", function($q, $http, wsservice, AuthServiceApi) {

	var WsApi = this;

	WsApi.listen = function(apiReq) {
		var request = '/ws/'+apiReq.controller+'/' + apiReq.method;
		var channel = apiReq.endpoint + "/" + apiReq.controller;

		if(apiReq.method) {
			channel +=  "/" + apiReq.method;
		}
		return wsservice.subscribe(channel);
	};

	WsApi.fetch = function(apiReq) {

		var request = '/ws/'+apiReq.controller+'/' + apiReq.method;
		var channel = apiReq.endpoint + "/" + apiReq.controller + "/" + apiReq.method;

		var headers = {
			'jwt': sessionStorage.token,
			'data': (typeof apiReq.data != 'undefined') ? apiReq.data : '{}'
		};

		var fetchPromise = wsservice.send(request, headers, {}, channel);

		fetchPromise.then(null, null, function(data) {

			var meta = JSON.parse(data.body).meta;

			if(meta.type == "REFRESH") {
				if(sessionStorage.assumedUser) {
					AuthServiceApi.getAssumedUser(JSON.parse(sessionStorage.assumedUser)).then(function() {
						wsservice.pendingReq[meta.id].resend();
					});
				} else {
					AuthServiceApi.getRefreshToken().then(function() {
						wsservice.pendingReq[meta.id].resend();
					});
				}
			}
		});

		return fetchPromise;
	};

});
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview this file provides the bootstrap interface between the
 * Chrome event and extension bindings JavaScript files, and the CEEE
 * native IE interface, as well as initialization hooks for the native
 * interface.
 */

// Console is diverted to nativeContentScriptApi.Log method.
var console = console || {};

// Any function declared native in the Chrome extension bindings files
// is diverted to the ceee namespace to allow the IE JS engine
// to grok the code.
var ceee = ceee || {};

(function () {
// Keep a reference to the global environment in
// effect during boostrap script parsing.
var global = this;

var chromeHidden = {};
var nativeContentScriptApi = null;

// Supply a JSON implementation by leeching off closure.
global.JSON = goog.json;
global.JSON.stringify = JSON.serialize;

ceee.AttachEvent = function (eventName) {
  nativeContentScriptApi.AttachEvent(eventName);
};

ceee.DetachEvent = function (eventName) {
  nativeContentScriptApi.DetachEvent(eventName);
};

ceee.OpenChannelToExtension = function (sourceId, targetId, name) {
  return nativeContentScriptApi.OpenChannelToExtension(sourceId,
                                                       targetId,
                                                       name);
};

ceee.CloseChannel = function (portId) {
  return nativeContentScriptApi.CloseChannel(portId);
};

ceee.PortAddRef = function (portId) {
  return nativeContentScriptApi.PortAddRef(portId);
};

ceee.PortRelease = function (portId) {
  return nativeContentScriptApi.PortRelease(portId);
};

ceee.PostMessage = function (portId, msg) {
  return nativeContentScriptApi.PostMessage(portId, msg);
};

ceee.GetChromeHidden = function () {
  return chromeHidden;
};

// This function is invoked from the native CEEE implementation by name
// to pass in the native CEEE interface implementation at the start of
// script engine initialization. This allows us to provide logging
// and any other required or convenient services during the initialization
// of other boostrap scripts.
ceee.startInit_ = function (nativenativeContentScriptApi, extensionId) {
  nativeContentScriptApi = nativenativeContentScriptApi;
};

// Last uninitialization callback.
ceee.onUnload_ = function () {
  // Dispatch the onUnload event.
  chromeHidden.dispatchOnUnload();

  // Release the native API as very last act.
  nativeContentScriptApi = null;
};

// This function is invoked from the native CEEE implementation by name
// to pass in the extension ID, and to allow any final initialization of
// the script environment before the content scripts themselves are loaded.
ceee.endInit_ = function (nativenativeContentScriptApi, extensionId) {
  chrome.initExtension(extensionId);

  // Provide the native implementation with the the the
  // event notification dispatchers.
  nativeContentScriptApi.onLoad = chromeHidden.dispatchOnLoad;
  nativeContentScriptApi.onUnload = ceee.onUnload_;

  // And the port notification dispatchers.
  // function(portId, channelName, tab, extensionId)
  nativeContentScriptApi.onPortConnect = chromeHidden.Port.dispatchOnConnect;

  // function(portId)
  nativeContentScriptApi.onPortDisconnect =
      chromeHidden.Port.dispatchOnDisconnect;
  // function(msg, portId)
  nativeContentScriptApi.onPortMessage =
      chromeHidden.Port.dispatchOnMessage;

  // TODO(siggi@chromium.org): If there is a different global
  //    environment at this point (i.e. we have cloned the scripting
  //    engine for a new window) this is where we can restore goog,
  //    JSON and chrome.

  // Delete the ceee namespace from globals.
  delete ceee;
};

ceee.initGlobals_ = function() {
  // The window object of the page is exposed in its entirety to the script
  // host via the 'unsafeWindow' variable similar to how greasemonkey scripts
  // implement access to it. We expose a 'safe' window object as 'window' that
  // only has access to a subset of the actual window's native properties.

  // Create the window variable and assign it to 'this' which is the context
  // of the global scope. Doing this will make variables defined in the global
  // scope or defined as properties of window be one and the same.
  window = this;

  // Now expose a subset of the Window interface defined at
  // http://www.w3.org/TR/html5/browsers.html#the-window-object
  // to the global namespace and to the 'safe' window object. We purposely skip
  // all event handler attributes (e.g. onclick).

  // Browsing context.
  self = unsafeWindow.self;
  document = unsafeWindow.document;
  name = unsafeWindow.name;
  location = unsafeWindow.location;
  history = unsafeWindow.history;
  undoManager = unsafeWindow.undoManager;
  locationbar = unsafeWindow.locationbar;
  menubar = unsafeWindow.menubar;
  scrollbars = unsafeWindow.scrollbars;
  statusbar = unsafeWindow.statusbar;
  toolbar = unsafeWindow.toolbar;
  close = unsafeWindow.close;
  stop = unsafeWindow.stop;
  focus = unsafeWindow.focus;
  blur = unsafeWindow.blur;

  // Other browsing contexts.
  frames = unsafeWindow.frames;
  length = unsafeWindow.length;
  top = unsafeWindow.top;
  opener = unsafeWindow.opener;
  parent = unsafeWindow.parent;
  frameElement = unsafeWindow.frameElement;
  open = unsafeWindow.open;

  // User agent.
  navigator = unsafeWindow.navigator;
  applicationCache = unsafeWindow.applicationCache;

  // User prompts.
  alert = unsafeWindow.alert;
  confirm = unsafeWindow.confirm;
  prompt = unsafeWindow.prompt;
  print = unsafeWindow.print;
  showModalDialog = unsafeWindow.showModalDialog;

  // EventTarget interface.
  addEventListener = unsafeWindow.addEventListener;
  removeEventListener = unsafeWindow.removeEventListener;
  dispatchEvent = unsafeWindow.dispatchEvent;

  // Old IE event model.
  attachEvent = unsafeWindow.attachEvent;
  detachEvent = unsafeWindow.detachEvent;
};

console.log = console.log || function (msg) {
  if (nativeContentScriptApi)
    nativeContentScriptApi.Log("info", msg);
};

console.error = console.error || function (msg) {
  if (nativeContentScriptApi)
    nativeContentScriptApi.Log("error", msg);
}

// Provide an indexOf member for arrays if it's not already there
// to satisfy the Chrome extension bindings expectations.
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/) {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++) {
      if (from in this && this[from] === elt)
        return from;
    }
    return -1;
  }
};

})();
<commit_msg>IE CEEE: Wrap frameElement access in ceee_bootstrap.js to prevent access denied error. BUG=none TEST=none<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview this file provides the bootstrap interface between the
 * Chrome event and extension bindings JavaScript files, and the CEEE
 * native IE interface, as well as initialization hooks for the native
 * interface.
 */

// Console is diverted to nativeContentScriptApi.Log method.
var console = console || {};

// Any function declared native in the Chrome extension bindings files
// is diverted to the ceee namespace to allow the IE JS engine
// to grok the code.
var ceee = ceee || {};

(function () {
// Keep a reference to the global environment in
// effect during boostrap script parsing.
var global = this;

var chromeHidden = {};
var nativeContentScriptApi = null;

// Supply a JSON implementation by leeching off closure.
global.JSON = goog.json;
global.JSON.stringify = JSON.serialize;

ceee.AttachEvent = function (eventName) {
  nativeContentScriptApi.AttachEvent(eventName);
};

ceee.DetachEvent = function (eventName) {
  nativeContentScriptApi.DetachEvent(eventName);
};

ceee.OpenChannelToExtension = function (sourceId, targetId, name) {
  return nativeContentScriptApi.OpenChannelToExtension(sourceId,
                                                       targetId,
                                                       name);
};

ceee.CloseChannel = function (portId) {
  return nativeContentScriptApi.CloseChannel(portId);
};

ceee.PortAddRef = function (portId) {
  return nativeContentScriptApi.PortAddRef(portId);
};

ceee.PortRelease = function (portId) {
  return nativeContentScriptApi.PortRelease(portId);
};

ceee.PostMessage = function (portId, msg) {
  return nativeContentScriptApi.PostMessage(portId, msg);
};

ceee.GetChromeHidden = function () {
  return chromeHidden;
};

// This function is invoked from the native CEEE implementation by name
// to pass in the native CEEE interface implementation at the start of
// script engine initialization. This allows us to provide logging
// and any other required or convenient services during the initialization
// of other boostrap scripts.
ceee.startInit_ = function (nativenativeContentScriptApi, extensionId) {
  nativeContentScriptApi = nativenativeContentScriptApi;
};

// Last uninitialization callback.
ceee.onUnload_ = function () {
  // Dispatch the onUnload event.
  chromeHidden.dispatchOnUnload();

  // Release the native API as very last act.
  nativeContentScriptApi = null;
};

// This function is invoked from the native CEEE implementation by name
// to pass in the extension ID, and to allow any final initialization of
// the script environment before the content scripts themselves are loaded.
ceee.endInit_ = function (nativenativeContentScriptApi, extensionId) {
  chrome.initExtension(extensionId);

  // Provide the native implementation with the the the
  // event notification dispatchers.
  nativeContentScriptApi.onLoad = chromeHidden.dispatchOnLoad;
  nativeContentScriptApi.onUnload = ceee.onUnload_;

  // And the port notification dispatchers.
  // function(portId, channelName, tab, extensionId)
  nativeContentScriptApi.onPortConnect = chromeHidden.Port.dispatchOnConnect;

  // function(portId)
  nativeContentScriptApi.onPortDisconnect =
      chromeHidden.Port.dispatchOnDisconnect;
  // function(msg, portId)
  nativeContentScriptApi.onPortMessage =
      chromeHidden.Port.dispatchOnMessage;

  // TODO(siggi@chromium.org): If there is a different global
  //    environment at this point (i.e. we have cloned the scripting
  //    engine for a new window) this is where we can restore goog,
  //    JSON and chrome.

  // Delete the ceee namespace from globals.
  delete ceee;
};

ceee.initGlobals_ = function() {
  // The window object of the page is exposed in its entirety to the script
  // host via the 'unsafeWindow' variable similar to how greasemonkey scripts
  // implement access to it. We expose a 'safe' window object as 'window' that
  // only has access to a subset of the actual window's native properties.

  // Create the window variable and assign it to 'this' which is the context
  // of the global scope. Doing this will make variables defined in the global
  // scope or defined as properties of window be one and the same.
  window = this;

  // Now expose a subset of the Window interface defined at
  // http://www.w3.org/TR/html5/browsers.html#the-window-object
  // to the global namespace and to the 'safe' window object. We purposely skip
  // all event handler attributes (e.g. onclick).

  // Browsing context.
  self = unsafeWindow.self;
  document = unsafeWindow.document;
  name = unsafeWindow.name;
  location = unsafeWindow.location;
  history = unsafeWindow.history;
  undoManager = unsafeWindow.undoManager;
  locationbar = unsafeWindow.locationbar;
  menubar = unsafeWindow.menubar;
  scrollbars = unsafeWindow.scrollbars;
  statusbar = unsafeWindow.statusbar;
  toolbar = unsafeWindow.toolbar;
  close = unsafeWindow.close;
  stop = unsafeWindow.stop;
  focus = unsafeWindow.focus;
  blur = unsafeWindow.blur;

  // Other browsing contexts.
  frames = unsafeWindow.frames;
  length = unsafeWindow.length;
  top = unsafeWindow.top;
  opener = unsafeWindow.opener;
  parent = unsafeWindow.parent;
  try {
    // IE will throw an Access Denied error if the parent browsing context does
    // not have the same effective script origin as the entry script. See:
    // http://www.w3.org/TR/html5/browsers.html#dom-frameelement
    // TODO(ericdingle@chromium.org): See if we can wrap this attribute with a
    // getter so that we can mimic IE's behavior when it is accessed.
    frameElement = unsafeWindow.frameElement;
  } catch (e) {}
  open = unsafeWindow.open;

  // User agent.
  navigator = unsafeWindow.navigator;
  applicationCache = unsafeWindow.applicationCache;

  // User prompts.
  alert = unsafeWindow.alert;
  confirm = unsafeWindow.confirm;
  prompt = unsafeWindow.prompt;
  print = unsafeWindow.print;
  showModalDialog = unsafeWindow.showModalDialog;

  // EventTarget interface.
  addEventListener = unsafeWindow.addEventListener;
  removeEventListener = unsafeWindow.removeEventListener;
  dispatchEvent = unsafeWindow.dispatchEvent;

  // Old IE event model.
  attachEvent = unsafeWindow.attachEvent;
  detachEvent = unsafeWindow.detachEvent;
};

console.log = console.log || function (msg) {
  if (nativeContentScriptApi)
    nativeContentScriptApi.Log("info", msg);
};

console.error = console.error || function (msg) {
  if (nativeContentScriptApi)
    nativeContentScriptApi.Log("error", msg);
}

// Provide an indexOf member for arrays if it's not already there
// to satisfy the Chrome extension bindings expectations.
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/) {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++) {
      if (from in this && this[from] === elt)
        return from;
    }
    return -1;
  }
};

})();
<|endoftext|>


<commit_before>(function() {

function GraphEditCommand(graph) {
	if (!(graph instanceof Graph))
		throw new Error('GraphEditCommand requires graph')
	this.graph = graph
}

GraphEditCommand.prototype.execute = function() {
	return this.redo()
}

// -------------------------------

function removeNode() {
	var sid, connection, slotIndex = 0
	var node = this.node
	var graph = this.graph

	if (node.plugin.isGraph) {
		this.nodeInfo = {
			order: [ // restore in same render order
				graph.nodes.indexOf(node),
				graph.children.indexOf(node)
			]
		}
	} else if (node.parent_graph && node.parent_graph.plugin) {
		if (node.plugin.id === 'input_proxy') {
			sid = node.parent_graph.plugin.state.input_sids[node.uid]

			if (node.parent_graph.plugin.node.inputs.length) {
				connection = node.parent_graph.plugin.node.inputs.filter(function(input) {
					return input.dst_slot.uid === sid
				})[0]

				slotIndex = connection.dst_slot.index
			}
		} else if (node.plugin.id === 'output_proxy') {
			sid = node.parent_graph.plugin.state.output_sids[node.uid]

			if (node.parent_graph.plugin.node.outputs.length) {
				connection = node.parent_graph.plugin.node.outputs.filter(function(output) {
					return output.src_slot.uid === sid
				})[0]

				slotIndex = connection.src_slot.index
			}
		}

		if (sid !== undefined) {
			console.log('RemoveNode', sid, slotIndex, !!connection)
			this.nodeInfo = {
				proxy: {
					sid: sid,
					index: slotIndex,
					connection: connection ? connection.serialise() : null
				}
			}
		}
	}

	E2.app.dispatcher.dispatch({
		actionType: 'uiNodeRemoved',
		graph: this.graph,
		node: this.node,
		info: this.nodeInfo
	})
}

function addNode() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiNodeAdded',
		graph: this.graph,
		node: this.node,
		info: this.nodeInfo
	})
}

function AddNode(graph, node) {
	GraphEditCommand.apply(this, arguments)
	this.node = node
	this.title = 'Add node ' + node.title
}
AddNode.prototype = Object.create(GraphEditCommand.prototype)
AddNode.prototype.undo = removeNode
AddNode.prototype.redo = addNode

// -------------------------------

function RemoveNode(graph, node) {
	GraphEditCommand.apply(this, arguments)
	this.node = node
	this.title = 'Remove node ' + node.title
}
RemoveNode.prototype = Object.create(GraphEditCommand.prototype)
RemoveNode.prototype.undo = addNode
RemoveNode.prototype.redo = removeNode

// -------------------------------

function RenameNode(graph, node, title) {
	GraphEditCommand.apply(this, arguments)
	this.node = node
	this.origNodeTitle = node.title
	this.newNodeTitle = title
	this.title = 'Rename node ' + node.title + ' to ' + title
}
RenameNode.prototype = Object.create(GraphEditCommand.prototype)
RenameNode.prototype.undo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiNodeRenamed',
		graph: this.graph,
		node: this.node,
		title: this.origNodeTitle
	})
}

RenameNode.prototype.redo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiNodeRenamed',
		graph: this.graph,
		node: this.node,
		title: this.newNodeTitle
	})
}

// -------------------------------

function Connect(graph, connection) {
	GraphEditCommand.apply(this, arguments)
	this.title = 'Connect'
	this.connection = connection
}
Connect.prototype = Object.create(GraphEditCommand.prototype)

Connect.prototype.undo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiDisconnected',
		graph: this.graph,
		connection: this.connection
	})
}

Connect.prototype.redo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiConnected',
		graph: this.graph,
		connection: this.connection
	})
}

// -------------------------------

function Disconnect(graph, connection) {
	GraphEditCommand.apply(this, arguments)
	this.title = 'Disconnect'
	this.connection = connection
}
Disconnect.prototype = Object.create(GraphEditCommand.prototype)

Disconnect.prototype.undo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiConnected',
		graph: this.graph,
		connection: this.connection
	})
}

Disconnect.prototype.redo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiDisconnected',
		graph: this.graph,
		connection: this.connection
	})
}

// -------------------------------

function _gatherConnections(nodes) {
	return nodes.reduce(function(arr, node) {
		return arr.concat(node.inputs.concat(node.outputs))
	}, [])
}

function Move(graph, nodes, dx, dy) {
	GraphEditCommand.apply(this, arguments)
	this.title = 'Move'
	this.nodes = nodes
	this.delta = { x: dx, y: dy }
}
Move.prototype = Object.create(GraphEditCommand.prototype)

Move.prototype.undo = function() {
	var connections = _gatherConnections(this.nodes)
	E2.app.executeNodeDrag(this.nodes, connections, this.delta.x * -1, this.delta.y * -1)
}

Move.prototype.redo = function() {
	var connections = _gatherConnections(this.nodes)
	E2.app.executeNodeDrag(this.nodes, connections, this.delta.x, this.delta.y)
}

// -------------------------------

function Reorder(graph, original, sibling, insertAfter) {
	GraphEditCommand.apply(this, arguments)
	this.title = 'Reorder'
	this.original = original
	this.sibling = sibling
	this.insertAfter = insertAfter
}
Reorder.prototype = Object.create(GraphEditCommand.prototype)

Reorder.prototype.undo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiGraphTreeReordered',
		graph: this.graph,
		original: this.sibling,
		sibling: this.original,
		insertAfter: this.insertAfter
	})
}

Reorder.prototype.redo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiGraphTreeReordered',
		graph: this.graph,
		original: this.original,
		sibling: this.sibling,
		insertAfter: this.insertAfter
	})
}

// -------------------------------

function ChangePluginState(graph, node, key, oldValue, newValue, title) {
	GraphEditCommand.apply(this, arguments)
	this.title = title || 'Value Change'
	this.node = node
	this.key = key

	this.oldValue = oldValue
	this.newValue = newValue
}
ChangePluginState.prototype = Object.create(GraphEditCommand.prototype)

ChangePluginState.prototype.undo = function() {
	this.node.plugin.state[this.key] = this.oldValue
	this.node.plugin.updated = true
	if (this.node.ui)
		this.node.plugin.state_changed(this.node.ui.plugin_ui)
}

ChangePluginState.prototype.redo = function() {
	this.node.plugin.state[this.key] = this.newValue
	this.node.plugin.updated = true
	if (this.node.ui)
		this.node.plugin.state_changed(this.node.ui.plugin_ui)
}

// -------------------------------

function Undoable(oldValue, newValue, setterFn, title) {
	this.title = title || 'Value Change'
	this.oldValue = oldValue
	this.newValue = newValue
	this.setterFn = setterFn
}

Undoable.prototype.undo = function() {
	this.setterFn(this.oldValue)
}

Undoable.prototype.redo = function() {
	this.setterFn(this.newValue)
}

// -------------------------------

if (typeof(E2) !== 'undefined') {
	if (!E2.commands)
		E2.commands = {}
	if (!E2.commands.graph)
		E2.commands.graph = {}

	E2.commands.Undoable = Undoable

	E2.commands.graph.AddNode = AddNode
	E2.commands.graph.RemoveNode = RemoveNode
	E2.commands.graph.RenameNode = RenameNode
	E2.commands.graph.Connect = Connect
	E2.commands.graph.Disconnect = Disconnect
	E2.commands.graph.Move = Move
	E2.commands.graph.Reorder = Reorder

	E2.commands.graph.ChangePluginState = ChangePluginState
}

if (typeof(module) !== 'undefined') {
	module.exports = E2.commands.graph
}

})()
<commit_msg>fix removal of unconnected input proxy when other proxies are connected<commit_after>(function() {

function GraphEditCommand(graph) {
	if (!(graph instanceof Graph))
		throw new Error('GraphEditCommand requires graph')
	this.graph = graph
}

GraphEditCommand.prototype.execute = function() {
	return this.redo()
}

// -------------------------------

function removeNode() {
	var sid, connection, slotIndex = 0
	var node = this.node
	var graph = this.graph

	if (node.plugin.isGraph) {
		this.nodeInfo = {
			order: [ // restore in same render order
				graph.nodes.indexOf(node),
				graph.children.indexOf(node)
			]
		}
	} else if (node.parent_graph && node.parent_graph.plugin) {
		if (node.plugin.id === 'input_proxy') {
			sid = node.parent_graph.plugin.state.input_sids[node.uid]

			if (node.parent_graph.plugin.node.inputs.length) {
				connection = node.parent_graph.plugin.node.inputs.filter(function(input) {
					return input.dst_slot.uid === sid
				})[0]

				if (connection)
					slotIndex = connection.dst_slot.index
			}
		} else if (node.plugin.id === 'output_proxy') {
			sid = node.parent_graph.plugin.state.output_sids[node.uid]

			if (node.parent_graph.plugin.node.outputs.length) {
				connection = node.parent_graph.plugin.node.outputs.filter(function(output) {
					return output.src_slot.uid === sid
				})[0]

				if (connection)
					slotIndex = connection.src_slot.index
			}
		}

		if (sid !== undefined) {
			console.log('RemoveNode', sid, slotIndex, !!connection)
			this.nodeInfo = {
				proxy: {
					sid: sid,
					index: slotIndex,
					connection: connection ? connection.serialise() : null
				}
			}
		}
	}

	E2.app.dispatcher.dispatch({
		actionType: 'uiNodeRemoved',
		graph: this.graph,
		node: this.node,
		info: this.nodeInfo
	})
}

function addNode() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiNodeAdded',
		graph: this.graph,
		node: this.node,
		info: this.nodeInfo
	})
}

function AddNode(graph, node) {
	GraphEditCommand.apply(this, arguments)
	this.node = node
	this.title = 'Add node ' + node.title
}
AddNode.prototype = Object.create(GraphEditCommand.prototype)
AddNode.prototype.undo = removeNode
AddNode.prototype.redo = addNode

// -------------------------------

function RemoveNode(graph, node) {
	GraphEditCommand.apply(this, arguments)
	this.node = node
	this.title = 'Remove node ' + node.title
}
RemoveNode.prototype = Object.create(GraphEditCommand.prototype)
RemoveNode.prototype.undo = addNode
RemoveNode.prototype.redo = removeNode

// -------------------------------

function RenameNode(graph, node, title) {
	GraphEditCommand.apply(this, arguments)
	this.node = node
	this.origNodeTitle = node.title
	this.newNodeTitle = title
	this.title = 'Rename node ' + node.title + ' to ' + title
}
RenameNode.prototype = Object.create(GraphEditCommand.prototype)
RenameNode.prototype.undo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiNodeRenamed',
		graph: this.graph,
		node: this.node,
		title: this.origNodeTitle
	})
}

RenameNode.prototype.redo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiNodeRenamed',
		graph: this.graph,
		node: this.node,
		title: this.newNodeTitle
	})
}

// -------------------------------

function Connect(graph, connection) {
	GraphEditCommand.apply(this, arguments)
	this.title = 'Connect'
	this.connection = connection
}
Connect.prototype = Object.create(GraphEditCommand.prototype)

Connect.prototype.undo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiDisconnected',
		graph: this.graph,
		connection: this.connection
	})
}

Connect.prototype.redo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiConnected',
		graph: this.graph,
		connection: this.connection
	})
}

// -------------------------------

function Disconnect(graph, connection) {
	GraphEditCommand.apply(this, arguments)
	this.title = 'Disconnect'
	this.connection = connection
}
Disconnect.prototype = Object.create(GraphEditCommand.prototype)

Disconnect.prototype.undo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiConnected',
		graph: this.graph,
		connection: this.connection
	})
}

Disconnect.prototype.redo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiDisconnected',
		graph: this.graph,
		connection: this.connection
	})
}

// -------------------------------

function _gatherConnections(nodes) {
	return nodes.reduce(function(arr, node) {
		return arr.concat(node.inputs.concat(node.outputs))
	}, [])
}

function Move(graph, nodes, dx, dy) {
	GraphEditCommand.apply(this, arguments)
	this.title = 'Move'
	this.nodes = nodes
	this.delta = { x: dx, y: dy }
}
Move.prototype = Object.create(GraphEditCommand.prototype)

Move.prototype.undo = function() {
	var connections = _gatherConnections(this.nodes)
	E2.app.executeNodeDrag(this.nodes, connections, this.delta.x * -1, this.delta.y * -1)
}

Move.prototype.redo = function() {
	var connections = _gatherConnections(this.nodes)
	E2.app.executeNodeDrag(this.nodes, connections, this.delta.x, this.delta.y)
}

// -------------------------------

function Reorder(graph, original, sibling, insertAfter) {
	GraphEditCommand.apply(this, arguments)
	this.title = 'Reorder'
	this.original = original
	this.sibling = sibling
	this.insertAfter = insertAfter
}
Reorder.prototype = Object.create(GraphEditCommand.prototype)

Reorder.prototype.undo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiGraphTreeReordered',
		graph: this.graph,
		original: this.sibling,
		sibling: this.original,
		insertAfter: this.insertAfter
	})
}

Reorder.prototype.redo = function() {
	E2.app.dispatcher.dispatch({
		actionType: 'uiGraphTreeReordered',
		graph: this.graph,
		original: this.original,
		sibling: this.sibling,
		insertAfter: this.insertAfter
	})
}

// -------------------------------

function ChangePluginState(graph, node, key, oldValue, newValue, title) {
	GraphEditCommand.apply(this, arguments)
	this.title = title || 'Value Change'
	this.node = node
	this.key = key

	this.oldValue = oldValue
	this.newValue = newValue
}
ChangePluginState.prototype = Object.create(GraphEditCommand.prototype)

ChangePluginState.prototype.undo = function() {
	this.node.plugin.state[this.key] = this.oldValue
	this.node.plugin.updated = true
	if (this.node.ui)
		this.node.plugin.state_changed(this.node.ui.plugin_ui)
}

ChangePluginState.prototype.redo = function() {
	this.node.plugin.state[this.key] = this.newValue
	this.node.plugin.updated = true
	if (this.node.ui)
		this.node.plugin.state_changed(this.node.ui.plugin_ui)
}

// -------------------------------

function Undoable(oldValue, newValue, setterFn, title) {
	this.title = title || 'Value Change'
	this.oldValue = oldValue
	this.newValue = newValue
	this.setterFn = setterFn
}

Undoable.prototype.undo = function() {
	this.setterFn(this.oldValue)
}

Undoable.prototype.redo = function() {
	this.setterFn(this.newValue)
}

// -------------------------------

if (typeof(E2) !== 'undefined') {
	if (!E2.commands)
		E2.commands = {}
	if (!E2.commands.graph)
		E2.commands.graph = {}

	E2.commands.Undoable = Undoable

	E2.commands.graph.AddNode = AddNode
	E2.commands.graph.RemoveNode = RemoveNode
	E2.commands.graph.RenameNode = RenameNode
	E2.commands.graph.Connect = Connect
	E2.commands.graph.Disconnect = Disconnect
	E2.commands.graph.Move = Move
	E2.commands.graph.Reorder = Reorder

	E2.commands.graph.ChangePluginState = ChangePluginState
}

if (typeof(module) !== 'undefined') {
	module.exports = E2.commands.graph
}

})()
<|endoftext|>


<commit_before>var React = require('react-native');
// var api = require('../Utils/api');

var {
  View,
  Text,
  StyleSheet,
  Navigator,
  TouchableOpacity
} = React;

class RequestFeedbackView extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userId: this.props.route.userId,
      classId: this.props.route.classId
    };
  }

  selectFeebackOption(type) {
    console.log(type);
    // this.props.navigator.push({
    //   component: RequestFeedbackView,
    //   userId: this.state.userId,
    //   classId: classId,
    //   sceneConfig: {
    //     ...Navigator.SceneConfigs.FloatFromBottom,
    //     gestures: {}
    //   }
    // });
    // this.setState({
    //   isLoading: false,
    //   error:false
    // });
  }

  render() {
    return (
      <View style={{flex: 1, backgroundColor: '#ededed'}}>
        <View style={styles.viewContainer}>
          <View style={styles.titleContainer}>
            <Text style={styles.pageText}> Request Feedback: </Text>
          </View>
          <View style={styles.buttonsContainer}>
            <View style={styles.buttonContainer}>
              <TouchableOpacity onPress={this.selectFeebackOption.bind(this, 'thumbs')} style={styles.button}>
                <Text style={styles.buttonText}> Thumbs Check </Text>
              </TouchableOpacity>
            </View>
            <View style={styles.buttonContainer}>
              <TouchableOpacity onPress={this.selectFeebackOption.bind(this, 'multChoice')} style={styles.button}>
                <Text style={styles.buttonText}> Multiple Choice </Text>
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  viewContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  pageText: {
    fontSize: 20
  },
  buttonsContainer: {
    padding: 20
  },
  buttonContainer: {
    margin: 20
  },
  button: {

  },
  buttonText: {
    fontSize: 20
  }
});

module.exports = RequestFeedbackView;<commit_msg>Factor out hardcoded feedback options into state<commit_after>var React = require('react-native');
// var api = require('../Utils/api');

var {
  View,
  Text,
  StyleSheet,
  Navigator,
  TouchableOpacity
} = React;

class RequestFeedbackView extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userId: this.props.route.userId,
      classId: this.props.route.classId,
      lessonId: 'default',
      feedbackOptions: [
        {
          id: 1,
          name: 'Thumbs Check',
          /*options:{for preset answers?}*/
        },
        {
          id: 2,
          name: 'Multiple Choice'
        }
      ]
    };
  }

  selectFeebackOption(optionId) {
    console.log(optionId);
    // this.props.navigator.push({
    //   component: RequestFeedbackView,
    //   userId: this.state.userId,
    //   classId: classId,
    //   sceneConfig: {
    //     ...Navigator.SceneConfigs.FloatFromBottom,
    //     gestures: {}
    //   }
    // });
    // this.setState({
    //   isLoading: false,
    //   error:false
    // });
  }

  renderFeedbackOptions(options) {
    return options.map((option, index) => {
      return (
        <View style={styles.buttonContainer} key={index}>
          <TouchableOpacity onPress={this.selectFeebackOption.bind(this, option.id)} style={styles.button}>
            <Text style={styles.buttonText}> {option.name} </Text>
          </TouchableOpacity>
        </View>
      )
    })
  }

  render() {
    //need end class / back button
    return (
      <View style={{flex: 1, backgroundColor: '#ededed'}}>
        <View style={styles.viewContainer}>
          <View style={styles.titleContainer}>
            <Text style={styles.pageText}> Request Feedback: </Text>
          </View>
          <View style={styles.buttonsContainer}>
            {this.renderFeedbackOptions(this.state.feedbackOptions)}
          </View>
        </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  viewContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  pageText: {
    fontSize: 20
  },
  buttonsContainer: {
    padding: 20
  },
  buttonContainer: {
    margin: 20
  },
  button: {

  },
  buttonText: {
    fontSize: 20
  }
});

module.exports = RequestFeedbackView;<|endoftext|>


<commit_before>/**
 *   Drag & Drop Web Workspace
 *   Copyright (C) 2015 eCaresoft Inc
 *   Ernesto Angel Celis de la Fuente <developer@celisdelafuente.net>
 *
 *   This file is part of Iridescence Smart Connector
 *
 *   Iridescence Smart Connector is free software: you can redistribute it
 *   under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or (at
 *   your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
  Triggered when a shape starts moving
*/
var dragger = function() {
  // TODO Fix for paths
  switch(this.type) {
    case "rect":
      this.ox = this.attr("x");
      this.oy = this.attr("y");
      break;
    case "circle":
    case "ellipse":
      this.ox = this.attr("cx");
      this.oy = this.attr("cy");
      break;
   case "path":
     break;
  }
  this.animate({"fill-opacity": .2}, 500);
}

/**
  Triggered when a shape is moving
  */
var move = function(dx, dy) {
  // TODO Fix for paths
  if (this.type == "rect") {
    att = {x: this.ox + dx, y: this.oy + dy};
  } else {
    att ={ cx: this.ox + dx, cy: this.oy + dy};
  }
  this.attr(att);
  // TODO
  for(var i = connections.length; i--;) {
    paper.connection(connections[i]);
  }
  paper.safari();
}

/**
  Triggered when a shape stops moving
  */
var up = function() {
  this.animate({"fill-opacity": 0}, 500);
}

/**
 * Triggered when a shape is clicked, populates the
 * properties panel
 * @method modify
 * */
var modify = function() {
  switch(this.type) {
    case "rect":
      if (connect.length < 2) {   // If the connection queue's length < 2
        if(connect[0] != this) {  // and If shape isn't already in queue
          connect.push(this);     // add shape to queue
        }
      }
      break;
    case "path":
      // TODO Maybe make it a function and call it on drag and on click
      // for the path shape in toolbar
      if(connect.length == 2) {
        connections.push(paper.connection(connect[0], connect[1], "#000"));
        connect = [];     // Empty queue
      }
      break;
  }
  var p = this.data("props");
  $('#blk-name').val(p.name);
  $('#blk-url').val(p.url);
  $('#blk-id').val(this.id);
}

var setData = function(shape) {
  var d = new DataModel();
  shape.data("props", d);
}

/**
 * Add a new element from Toolbar to Workspace
 * @method addToDiagram
 * @param {Object} shape Raphael Element object
 * */
var addToDiagram = function (shape) {
  var color = Raphael.getColor(); // Get next color in spectrum
  var newShape = shape.clone();   // Hello Dolly!
  setData(newShape);              // Give Dolly a Soul
  if(newShape.type === "path") {
    newShape.attr({});
  } else {
    newShape.attr({fill: color,
                  stroke: color,
                  "fill-opacity": 0,
                  "stroke-width": 2,
                  "width": 50,
                  "height": 30,
                  "x": 50 + Math.floor(Math.random()*160),
                  "y": 70 + Math.floor(Math.random()*160)});
  }
  newShape.drag(move, dragger, up).click(modify);
  w.push(newShape);   // Append new shape to workspace
}

/**
 * Triggers when an element from Toolbar is dragged into workspace
 * @method toolUp
 * */
var release = function() {
  this.attr("x", tx + 5);
  this.attr("y", ty + 5);
  addToDiagram(this);
}

var util = new Util();
// Global settings
var tx = 20, ty = 20;
var paper = Raphael(10, 50, 500, 380);  // Creates canvas 320×200@10,50
var w = paper.set();                    // Create a default workspace
connections = [];                       // Connections between shapes
connect = [];                           // Temporary queue for connections
var toolbar = paper.rect(tx, ty, 40, 300); // Placeholder for the tools
// We'll derive other shapes from this one
var basicShape = paper
  .rect(tx + 5, ty + 5, 30, 20)
  .attr({"fill": "#CCC",
        "fill-opacity": 0,
        "stroke-width": 2,
        cursor: "move"});
// Same as basicShape its a basic connector, derive other from it
var connectShape = paper
  .path("M25 55L55 80")
  .attr({"stroke-width": 2,
        cursor: "move"});

/**
 * Save workspace to YAML in the server
 * @method save
 * */
var save = function() {
  //TODO
  var payload = [];
  w.forEach(function(s) {
    payload.push(s.data("props"));
  });
  $.post("/api/", {"__anti-forgery-token": $('#__anti-forgery-token').val(),
         "workspace":JSON.stringify(payload)});
}

/**
 * Remove shape from workspace
 * @method remove
 * @param {Integer} id of the Raphael element
 * */
var remove = function(id) {
  // TODO Fix this, should be donw within w.remove
  var s = paper.getById(id);
  w.exclude(s);
  s.remove();
}

/**
 * Clone a shape by id
 * @method cloneBlk
 * @param {Integer} id of the Raphael element
 * */
var clone = function(id) {
  addToDiagram(paper.getById(id));
}

/**
 * Update the shape properties data 'props' with values from
 * the properties panel
 * @method updateShape
 * @param {Integer} id of Raphael element
 * */
var update = function(id) {
  // TODO Fix it, values get borked in the panel
  var s = paper.getById(id);
  s.data("props").id = id;
  s.data("props").type = $('#blk-type').val();
  s.data("props").name = $('#blk-name').val();
  s.data("props").url = $('#blk-url').val();
  s.attr({'title': s.data("props").name,
          'text':s.data("props").name});
}

// Attach listeners to Toolbar elements
basicShape.drag(move, dragger, release);
connectShape.drag(move, dragger, release);
// Bind listeners to Properties controls
// TODO Do this in one iteration of all form controls
$('#type-lst li a').click(function(){
  var type = $(this).text().toUpperCase().replace(' ','');
  $('#btn-type').html(type + '');
  $('#blk-type').val(type);
  update($('#blk-id').val());
});
$('#blk-name').change(function(){update($('#blk-id').val())});
$('#blk-url').change(function(){update($('#blk-id').val())});
$('#remove-btn').click(function(){remove($('#blk-id').val())});
$('#clone-btn').click(function(){clone($('#blk-id').val())});
$('#save-btn').click(function(){save()});

<commit_msg>FIX adding connections between shapes with one click<commit_after>/**
 *   Drag & Drop Web Workspace
 *   Copyright (C) 2015 eCaresoft Inc
 *   Ernesto Angel Celis de la Fuente <developer@celisdelafuente.net>
 *
 *   This file is part of Iridescence Smart Connector
 *
 *   Iridescence Smart Connector is free software: you can redistribute it
 *   under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or (at
 *   your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
  Triggered when a shape starts moving
*/
var dragger = function() {
  // TODO Fix for paths
  switch(this.type) {
    case "rect":
      this.ox = this.attr("x");
      this.oy = this.attr("y");
      break;
    case "circle":
    case "ellipse":
      this.ox = this.attr("cx");
      this.oy = this.attr("cy");
      break;
   case "path":
     break;
  }
  this.animate({"fill-opacity": .2}, 500);
}

/**
  Triggered when a shape is moving
  */
var move = function(dx, dy) {
  // TODO Fix for paths
  if (this.type == "rect") {
    att = {x: this.ox + dx, y: this.oy + dy};
  } else {
    att ={ cx: this.ox + dx, cy: this.oy + dy};
  }
  this.attr(att);
  // TODO
  for(var i = connections.length; i--;) {
    paper.connection(connections[i]);
  }
  paper.safari();
}

/**
  Triggered when a shape stops moving
  */
var up = function() {
  this.animate({"fill-opacity": 0}, 500);
}

/**
 * Triggered when a shape is clicked, populates the
 * properties panel
 * @method modify
 * */
var modify = function() {
  switch(this.type) {
    case "rect":
      if (connect.length < 2) {   // If the connection queue's length < 2
        if(connect[0] != this) {  // and If shape isn't already in queue
          connect.push(this);     // add shape to queue
        }
      }
      break;
    case "path":
      // TODO Maybe make it a function and call it on drag and on click
      // for the path shape in toolbar
            break;
  }
  var p = this.data("props");
  $('#blk-name').val(p.name);
  $('#blk-url').val(p.url);
  $('#blk-id').val(this.id);
}

var setData = function(shape) {
  var d = new DataModel();
  shape.data("props", d);
}

/**
 * Add a new element from Toolbar to Workspace
 * @method addToDiagram
 * @param {Object} shape Raphael Element object
 * */
var addToDiagram = function (shape) {
  var color = Raphael.getColor(); // Get next color in spectrum
  var newShape = shape.clone();   // Hello Dolly!
  setData(newShape);              // Give Dolly a Soul
  if(newShape.type === "path") {
    newShape.attr({});
    newShape.click(function(){addToDiagram(this)});
    if(connect.length == 2) {
      connections.push(paper.connection(connect[0], connect[1], "#000"));
      connect = [];     // Empty queue
    } else {
      return;           // 2 shapes in queue are required to make a connection
    }
  } else {
    newShape.attr({fill: color,
                  stroke: color,
                  "fill-opacity": 0,
                  "stroke-width": 2,
                  "width": 50,
                  "height": 30,
                  "x": 50 + Math.floor(Math.random()*160),
                  "y": 70 + Math.floor(Math.random()*160)});
    newShape.drag(move, dragger, up).click(modify);
  }
  w.push(newShape);   // Append new shape to workspace
}

/**
 * Triggers when an element from Toolbar is dragged into workspace
 * @method toolUp
 * */
var release = function() {
  this.attr("x", tx + 5);
  this.attr("y", ty + 5);
  addToDiagram(this);
}

var util = new Util();
// Global settings
var tx = 20, ty = 20;
var paper = Raphael(10, 50, 500, 380);  // Creates canvas 320×200@10,50
var w = paper.set();                    // Create a default workspace
connections = [];                       // Connections between shapes
connect = [];                           // Temporary queue for connections
var toolbar = paper.rect(tx, ty, 40, 300); // Placeholder for the tools
// We'll derive other shapes from this one
var basicShape = paper
  .rect(tx + 5, ty + 5, 30, 20)
  .attr({"fill": "#CCC",
        "fill-opacity": 0,
        "stroke-width": 2,
        cursor: "move"});
// Same as basicShape its a basic connector, derive other from it
var connectShape = paper
  .path("M25 55L55 80")
  .attr({"stroke-width": 2,
        cursor: "move"});

/**
 * Save workspace to YAML in the server
 * @method save
 * */
var save = function() {
  //TODO
  var payload = [];
  w.forEach(function(s) {
    payload.push(s.data("props"));
  });
  $.post("/api/", {"__anti-forgery-token": $('#__anti-forgery-token').val(),
         "workspace":JSON.stringify(payload)});
}

/**
 * Remove shape from workspace
 * @method remove
 * @param {Integer} id of the Raphael element
 * */
var remove = function(id) {
  // TODO Fix this, should be donw within w.remove
  var s = paper.getById(id);
  w.exclude(s);
  s.remove();
}

/**
 * Clone a shape by id
 * @method cloneBlk
 * @param {Integer} id of the Raphael element
 * */
var clone = function(id) {
  addToDiagram(paper.getById(id));
}

/**
 * Update the shape properties data 'props' with values from
 * the properties panel
 * @method updateShape
 * @param {Integer} id of Raphael element
 * */
var update = function(id) {
  // TODO Fix it, values get borked in the panel
  var s = paper.getById(id);
  s.data("props").id = id;
  s.data("props").type = $('#blk-type').val();
  s.data("props").name = $('#blk-name').val();
  s.data("props").url = $('#blk-url').val();
  s.attr({'title': s.data("props").name,
          'text':s.data("props").name});
}

// Attach listeners to Toolbar elements
basicShape.drag(move, dragger, release);
connectShape.click(function(){addToDiagram(this)});
// Bind listeners to Properties controls
// TODO Do this in one iteration of all form controls
$('#type-lst li a').click(function(){
  var type = $(this).text().toUpperCase().replace(' ','');
  $('#btn-type').html(type + '');
  $('#blk-type').val(type);
  update($('#blk-id').val());
});
$('#blk-name').change(function(){update($('#blk-id').val())});
$('#blk-url').change(function(){update($('#blk-id').val())});
$('#remove-btn').click(function(){remove($('#blk-id').val())});
$('#clone-btn').click(function(){clone($('#blk-id').val())});
$('#save-btn').click(function(){save()});

<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var Constants = require('./constants');

var { AsyncStorage } = React;

var SessionManager = {
  login: function(user) {
    return new Promise(function(resolve, reject) {
      var url = Constants.APP_SERVER_HOST + '/users/register';
      fetch(url, {
        method: 'post',
        body: JSON.stringify({user: user}),
        headers: new Headers({
          'Content-Type': 'application/json'
        })
      })
      .then(response => {
        if(response.ok) {
          return response.json();
        } else {
          reject(new Error(JSON.parse(response._bodyText).error)); //FixIt - Shoudn't be using the quasi private method
        }
      })
      .then(response => {
        var user = {
          name: response.user.name,
          email: response.user.email,
          avatar: response.user.gravatar_url
        }
        console.log(user);
        AsyncStorage
        .setItem(Constants.CURRENT_USER_STORAGE_KEY, JSON.stringify(user))
        .then((value) => resolve(value));
      })
      .catch(error => reject(error));
    });
  },

  getCurrentUser: function() {
    return new Promise(function(resolve, reject) {
      AsyncStorage.getItem(Constants.CURRENT_USER_STORAGE_KEY)
      .then((value) => {
        if(value === null) reject(Error('No user logged in!'));
        resolve(JSON.parse(value));
      });
    });
  }
};

module.exports = SessionManager;
<commit_msg>Move the CURRENT_USER_STORAGE_KEY constant to SessionManager<commit_after>'use strict';

var React = require('react-native');
var Constants = require('./constants');

var { AsyncStorage } = React;

const CURRENT_USER_STORAGE_KEY = 'currentUser';

var SessionManager = {
  login: function(user) {
    return new Promise(function(resolve, reject) {
      var url = Constants.APP_SERVER_HOST + '/users/register';
      fetch(url, {
        method: 'post',
        body: JSON.stringify({user: user}),
        headers: new Headers({
          'Content-Type': 'application/json'
        })
      })
      .then(response => {
        if(response.ok) {
          return response.json();
        } else {
          reject(new Error(JSON.parse(response._bodyText).error)); //FixIt - Shoudn't be using the quasi private method
        }
      })
      .then(response => {
        var user = {
          name: response.user.name,
          email: response.user.email,
          avatar: response.user.gravatar_url
        }
        console.log(user);
        AsyncStorage
        .setItem(CURRENT_USER_STORAGE_KEY, JSON.stringify(user))
        .then((value) => resolve(value));
      })
      .catch(error => reject(error));
    });
  },

  getCurrentUser: function() {
    return new Promise(function(resolve, reject) {
      AsyncStorage.getItem(CURRENT_USER_STORAGE_KEY)
      .then((value) => {
        if(value === null) reject(Error('No user logged in!'));
        resolve(JSON.parse(value));
      });
    });
  }
};

module.exports = SessionManager;
<|endoftext|>


<commit_before>var React = require('react-native');
var FeedbackView = require('./display_feedback/feedbackView');
var api = require('./../../utils/api');
var NavBar = require('./../shared/navbar');
var Button = require('./../shared/button');

var {
  View,
  Text,
  StyleSheet,
  Navigator,
  TouchableOpacity,
  TouchableHighlight,
  Modal,
  TextInput,
  Dimensions,
} = React;

class RequestFeedbackView extends React.Component {
  constructor(props) {
    super(props);
    var {height, width} = Dimensions.get('window');
    this.state = {
      lessonId: this.props.route.lessonId,
      classId: this.props.route.classId,
      socket: this.props.route.socket,
      modal: false,
      height: height,
      width: width,
      feedbackOptions: [
        {
          id: 1,
          name: 'Thumbs Check',
          /*options:{for preset answers?}*/
        },
        {
          id: 2,
          name: 'Multiple Choice'
        }
      ],
      numberOfStudentHands: 0,
      raisedHandList: ['A','B','C'],
    };
    //populate feedbackOptions with anything custom from lesson
    this.state.socket.on('studentRaisedHand', function(student){
      var numberOfStudentHands = this.state.numberOfStudentHands + 1;
      var raisedHandList = this.state.raisedHandList.slice();
      raisedHandList.push(student.userId);
      this.setState({
        numberOfStudentHands: numberOfStudentHands,
        raisedHandList: raisedHandList
      });
    }.bind(this))

  }

  clickRaisedHand() {
    this.setState({
      modal: !this.state.modal,
    })
  }

  dismissClass() {
    // emit socket dismissClass
    this.state.socket.emit('dismiss');
    // if quickClass, need to disconnect from socket
    if(this.state.lessonId = 'Quick Class') {
      this.state.socket.disconnect();
    }
    this.props.navigator.pop();
  }

  beforeLogout() {
    this.state.socket.emit('teacherLoggingOut');
  }

  listStudent(list) {
    return list.map((student, index) => {
      return (
        <View key={index}>
          <Text style={styles.studentTextSize}>
            {student}
          </Text>
        </View>
      )
    })
  }
  clearList() {
    this.setState({
      raisedHandList: [],
      numberOfStudentHands: 0
    })
  }
  selectFeebackOption(feedbackOption) {
    api.startPoll(feedbackOption, this.state.lessonId, this.state.classId)
    .then((response) => {
      if(response.status === 500) {
        console.error('Server error', response);
      } else if(response.status === 201) {
        var pollId = JSON.parse(response._bodyText).pollId;
        this.props.navigator.push({
          component: FeedbackView,
          lessonId: this.state.lessonId,
          pollId: pollId,
          feedbackOption: feedbackOption,
          socket: this.state.socket,
          sceneConfig: {
            ...Navigator.SceneConfigs.FloatFromRight,
            gestures: {}
          }
        });
      } else {
        console.error('Error getting poll data', response);
      }
    })
    .catch((err) => {
      console.error('Error starting poll', err);
    });
  }

  renderFeedbackOptions(feedbackOptions) {
    return feedbackOptions.map((feedbackOption, index) => {
      return (
        <Button key={index} onPress={this.selectFeebackOption.bind(this, feedbackOption)} text={feedbackOption.name} />
      )
    })
  }

  render() {
    return (
      <View style={{flex: 1, backgroundColor: '#ededed'}}>
        <NavBar navi={this.props.navigator} beforeLogout={this.beforeLogout.bind(this)}
          onBack={this.dismissClass.bind(this)}>
          Request Feedback
        </NavBar>
        <View style={styles.viewContainer}>
          <Button onPress={this.dismissClass.bind(this)} text={'Dismiss Class'}/>
          {this.renderFeedbackOptions(this.state.feedbackOptions)}
        </View>
        <View style={{flexDirection: 'column', height:60, width: null}}>
          <TouchableOpacity onPress={this.clickRaisedHand.bind(this)} style={{ alignItems: 'center', justifyContent: 'center', flexDirection: 'column', backgroundColor:'yellow', height:60, width: 100, alignSelf:'flex-end'}}>
             <Text style={styles.textSize}>
                {this.state.numberOfStudentHands}
              </Text>
          </TouchableOpacity>
        </View>

        <Modal visible={this.state.modal} transparent={true} animated={true}>
          <View style={styles.modal}>
            <View style={{height:this.state.height * 0.8, width:this.state.width * 0.9}}>
              <View style={styles.modalBox}>
                <Text style={styles.textSizeModal}> Raised hand student: </Text>
                {this.listStudent(this.state.raisedHandList)}
              </View>
              <Button onPress={this.clickRaisedHand.bind(this)} text={'Close'}/>
              <Button onPress={this.clearList.bind(this)} text={'clear'}/>
            </View>
          </View>
        </Modal>

      </View>
    )
  }
}

const styles = StyleSheet.create({
  viewContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  modal: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.8)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  modalBox: {
    flex: 1,
    borderRadius: 10,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white'
  },
  textSizeModal: {
    fontSize : 20,
    fontWeight: 'bold',
  },
  studentTextSize: {
    fontSize: 35,
    fontWeight: 'bold',
  },
  textSize: {
    fontSize : 25,
    fontWeight: 'bold',
  },
});

module.exports = RequestFeedbackView;
<commit_msg>Fix raise hands for new user object<commit_after>var React = require('react-native');
var FeedbackView = require('./display_feedback/feedbackView');
var api = require('./../../utils/api');
var NavBar = require('./../shared/navbar');
var Button = require('./../shared/button');

var {
  View,
  Text,
  StyleSheet,
  Navigator,
  TouchableOpacity,
  TouchableHighlight,
  Modal,
  TextInput,
  Dimensions,
} = React;

class RequestFeedbackView extends React.Component {
  constructor(props) {
    super(props);
    var {height, width} = Dimensions.get('window');
    this.state = {
      lessonId: this.props.route.lessonId,
      classId: this.props.route.classId,
      socket: this.props.route.socket,
      modal: false,
      height: height,
      width: width,
      feedbackOptions: [
        {
          id: 1,
          name: 'Thumbs Check',
          /*options:{for preset answers?}*/
        },
        {
          id: 2,
          name: 'Multiple Choice'
        }
      ],
      numberOfStudentHands: 0,
      raisedHandList: ['A','B','C'],
    };
    //populate feedbackOptions with anything custom from lesson
    this.state.socket.on('studentRaisedHand', function(data){
      var numberOfStudentHands = this.state.numberOfStudentHands + 1;
      var raisedHandList = this.state.raisedHandList.slice();
      raisedHandList.push(data.user.uid);
      this.setState({
        numberOfStudentHands: numberOfStudentHands,
        raisedHandList: raisedHandList
      });
    }.bind(this))

  }

  clickRaisedHand() {
    this.setState({
      modal: !this.state.modal,
    })
  }

  dismissClass() {
    // emit socket dismissClass
    this.state.socket.emit('dismiss');
    // if quickClass, need to disconnect from socket
    if(this.state.lessonId = 'Quick Class') {
      this.state.socket.disconnect();
    }
    this.props.navigator.pop();
  }

  beforeLogout() {
    this.state.socket.emit('teacherLoggingOut');
  }

  listStudent(list) {
    return list.map((student, index) => {
      return (
        <View key={index}>
          <Text style={styles.studentTextSize}>
            {student}
          </Text>
        </View>
      )
    })
  }
  clearList() {
    this.setState({
      raisedHandList: [],
      numberOfStudentHands: 0
    })
  }
  selectFeebackOption(feedbackOption) {
    api.startPoll(feedbackOption, this.state.lessonId, this.state.classId)
    .then((response) => {
      if(response.status === 500) {
        console.error('Server error', response);
      } else if(response.status === 201) {
        var pollId = JSON.parse(response._bodyText).pollId;
        this.props.navigator.push({
          component: FeedbackView,
          lessonId: this.state.lessonId,
          pollId: pollId,
          feedbackOption: feedbackOption,
          socket: this.state.socket,
          sceneConfig: {
            ...Navigator.SceneConfigs.FloatFromRight,
            gestures: {}
          }
        });
      } else {
        console.error('Error getting poll data', response);
      }
    })
    .catch((err) => {
      console.error('Error starting poll', err);
    });
  }

  renderFeedbackOptions(feedbackOptions) {
    return feedbackOptions.map((feedbackOption, index) => {
      return (
        <Button key={index} onPress={this.selectFeebackOption.bind(this, feedbackOption)} text={feedbackOption.name} />
      )
    })
  }

  render() {
    return (
      <View style={{flex: 1, backgroundColor: '#ededed'}}>
        <NavBar navi={this.props.navigator} beforeLogout={this.beforeLogout.bind(this)}
          onBack={this.dismissClass.bind(this)}>
          Request Feedback
        </NavBar>
        <View style={styles.viewContainer}>
          <Button onPress={this.dismissClass.bind(this)} text={'Dismiss Class'}/>
          {this.renderFeedbackOptions(this.state.feedbackOptions)}
        </View>
        <View style={{flexDirection: 'column', height:60, width: null}}>
          <TouchableOpacity onPress={this.clickRaisedHand.bind(this)} style={{ alignItems: 'center', justifyContent: 'center', flexDirection: 'column', backgroundColor:'yellow', height:60, width: 100, alignSelf:'flex-end'}}>
             <Text style={styles.textSize}>
                {this.state.numberOfStudentHands}
              </Text>
          </TouchableOpacity>
        </View>

        <Modal visible={this.state.modal} transparent={true} animated={true}>
          <View style={styles.modal}>
            <View style={{height:this.state.height * 0.8, width:this.state.width * 0.9}}>
              <View style={styles.modalBox}>
                <Text style={styles.textSizeModal}> Raised hand student: </Text>
                {this.listStudent(this.state.raisedHandList)}
              </View>
              <Button onPress={this.clickRaisedHand.bind(this)} text={'Close'}/>
              <Button onPress={this.clearList.bind(this)} text={'clear'}/>
            </View>
          </View>
        </Modal>

      </View>
    )
  }
}

const styles = StyleSheet.create({
  viewContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  modal: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.8)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  modalBox: {
    flex: 1,
    borderRadius: 10,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white'
  },
  textSizeModal: {
    fontSize : 20,
    fontWeight: 'bold',
  },
  studentTextSize: {
    fontSize: 35,
    fontWeight: 'bold',
  },
  textSize: {
    fontSize : 25,
    fontWeight: 'bold',
  },
});

module.exports = RequestFeedbackView;
<|endoftext|>