<% end %>
<%= render "students/shared/links" %>
\ No newline at end of file
diff --git a/tutor/app/views/students/sessions/new.html.erb b/tutor/app/views/students/sessions/new.html.erb
index 9f99178a..5e1cf2d7 100644
--- a/tutor/app/views/students/sessions/new.html.erb
+++ b/tutor/app/views/students/sessions/new.html.erb
@@ -1,17 +1,27 @@
Sign in
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
-
<% end %>
<%= render "students/shared/links" %>
\ No newline at end of file
diff --git a/tutor/app/views/students/unlocks/new.html.erb b/tutor/app/views/students/unlocks/new.html.erb
index 32583423..f13e8c20 100644
--- a/tutor/app/views/students/unlocks/new.html.erb
+++ b/tutor/app/views/students/unlocks/new.html.erb
@@ -1,12 +1,13 @@
<% end %>
<%= render "teaching_assistants/shared/links" %>
\ No newline at end of file
diff --git a/tutor/app/views/teaching_assistants/sessions/new.html.erb b/tutor/app/views/teaching_assistants/sessions/new.html.erb
index de1d04f4..d9727994 100644
--- a/tutor/app/views/teaching_assistants/sessions/new.html.erb
+++ b/tutor/app/views/teaching_assistants/sessions/new.html.erb
@@ -1,17 +1,27 @@
Sign in
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
-
<% end %>
<%= render "teaching_assistants/shared/links" %>
\ No newline at end of file
diff --git a/tutor/app/views/teaching_assistants/unlocks/new.html.erb b/tutor/app/views/teaching_assistants/unlocks/new.html.erb
index fcb5ac32..467f3d09 100644
--- a/tutor/app/views/teaching_assistants/unlocks/new.html.erb
+++ b/tutor/app/views/teaching_assistants/unlocks/new.html.erb
@@ -1,12 +1,13 @@
diff --git a/tutor/vendor/assets/javascripts/jquery-2.1.0.js b/tutor/vendor/assets/javascripts/jquery-2.1.0.js
new file mode 100644
index 00000000..f7f42277
--- /dev/null
+++ b/tutor/vendor/assets/javascripts/jquery-2.1.0.js
@@ -0,0 +1,9111 @@
+/*!
+ * jQuery JavaScript Library v2.1.0
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2014-01-23T21:10Z
+ */
+
+(function( global, factory ) {
+
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // For CommonJS and CommonJS-like environments where a proper window is present,
+ // execute the factory and get jQuery
+ // For environments that do not inherently posses a window with a document
+ // (such as Node.js), expose a jQuery-making factory as module.exports
+ // This accentuates the need for the creation of a real window
+ // e.g. var jQuery = require("jquery")(window);
+ // See ticket #14549 for more info
+ module.exports = global.document ?
+ factory( global, true ) :
+ function( w ) {
+ if ( !w.document ) {
+ throw new Error( "jQuery requires a window with a document" );
+ }
+ return factory( w );
+ };
+ } else {
+ factory( global );
+ }
+
+// Pass this if window is not defined yet
+}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//
+
+var arr = [];
+
+var slice = arr.slice;
+
+var concat = arr.concat;
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var trim = "".trim;
+
+var support = {};
+
+
+
+var
+ // Use the correct document accordingly with window argument (sandbox)
+ document = window.document,
+
+ version = "2.1.0",
+
+ // Define a local copy of jQuery
+ jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ // Need init if jQuery is called (just allow error to be thrown if not included)
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Matches dashed string for camelizing
+ rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([\da-z])/gi,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn = jQuery.prototype = {
+ // The current version of jQuery being used
+ jquery: version,
+
+ constructor: jQuery,
+
+ // Start with an empty selector
+ selector: "",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ toArray: function() {
+ return slice.call( this );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num != null ?
+
+ // Return a 'clean' array
+ ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
+
+ // Return just the object
+ slice.call( this );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+
+ // Build a new jQuery matched element set
+ var ret = jQuery.merge( this.constructor(), elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+ ret.context = this.context;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ) );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ eq: function( i ) {
+ var len = this.length,
+ j = +i + ( i < 0 ? len : 0 );
+ return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: arr.sort,
+ splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+
+ // skip the boolean and the target
+ target = arguments[ i ] || {};
+ i++;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( i === length ) {
+ target = this;
+ i--;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray(src) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ // Unique for each copy of jQuery on the page
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+ // Assume jQuery is ready without the ready module
+ isReady: true,
+
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+
+ noop: function() {},
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return jQuery.type(obj) === "function";
+ },
+
+ isArray: Array.isArray,
+
+ isWindow: function( obj ) {
+ return obj != null && obj === obj.window;
+ },
+
+ isNumeric: function( obj ) {
+ // parseFloat NaNs numeric-cast false positives (null|true|false|"")
+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+ // subtraction forces infinities to NaN
+ return obj - parseFloat( obj ) >= 0;
+ },
+
+ isPlainObject: function( obj ) {
+ // Not plain objects:
+ // - Any object or value whose internal [[Class]] property is not "[object Object]"
+ // - DOM nodes
+ // - window
+ if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ // Support: Firefox <20
+ // The try/catch suppresses exceptions thrown when attempting to access
+ // the "constructor" property of certain host objects, ie. |window.location|
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
+ try {
+ if ( obj.constructor &&
+ !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
+ return false;
+ }
+ } catch ( e ) {
+ return false;
+ }
+
+ // If the function hasn't returned already, we're confident that
+ // |obj| is a plain object, created by {} or constructed with new Object
+ return true;
+ },
+
+ isEmptyObject: function( obj ) {
+ var name;
+ for ( name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ type: function( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+ // Support: Android < 4.0, iOS < 6 (functionish RegExp)
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ toString.call(obj) ] || "object" :
+ typeof obj;
+ },
+
+ // Evaluates a script in a global context
+ globalEval: function( code ) {
+ var script,
+ indirect = eval;
+
+ code = jQuery.trim( code );
+
+ if ( code ) {
+ // If the code includes a valid, prologue position
+ // strict mode pragma, execute code by injecting a
+ // script tag into the document.
+ if ( code.indexOf("use strict") === 1 ) {
+ script = document.createElement("script");
+ script.text = code;
+ document.head.appendChild( script ).parentNode.removeChild( script );
+ } else {
+ // Otherwise, avoid the DOM node creation, insertion
+ // and removal by using an indirect global eval
+ indirect( code );
+ }
+ }
+ },
+
+ // Convert dashed to camelCase; used by the css and data modules
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase: function( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+ },
+
+ // args is for internal usage only
+ each: function( obj, callback, args ) {
+ var value,
+ i = 0,
+ length = obj.length,
+ isArray = isArraylike( obj );
+
+ if ( args ) {
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback.apply( obj[ i ], args );
+
+ if ( value === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ value = callback.apply( obj[ i ], args );
+
+ if ( value === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback.call( obj[ i ], i, obj[ i ] );
+
+ if ( value === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ value = callback.call( obj[ i ], i, obj[ i ] );
+
+ if ( value === false ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return obj;
+ },
+
+ trim: function( text ) {
+ return text == null ? "" : trim.call( text );
+ },
+
+ // results is for internal usage only
+ makeArray: function( arr, results ) {
+ var ret = results || [];
+
+ if ( arr != null ) {
+ if ( isArraylike( Object(arr) ) ) {
+ jQuery.merge( ret,
+ typeof arr === "string" ?
+ [ arr ] : arr
+ );
+ } else {
+ push.call( ret, arr );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, arr, i ) {
+ return arr == null ? -1 : indexOf.call( arr, elem, i );
+ },
+
+ merge: function( first, second ) {
+ var len = +second.length,
+ j = 0,
+ i = first.length;
+
+ for ( ; j < len; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, invert ) {
+ var callbackInverse,
+ matches = [],
+ i = 0,
+ length = elems.length,
+ callbackExpect = !invert;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( ; i < length; i++ ) {
+ callbackInverse = !callback( elems[ i ], i );
+ if ( callbackInverse !== callbackExpect ) {
+ matches.push( elems[ i ] );
+ }
+ }
+
+ return matches;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var value,
+ i = 0,
+ length = elems.length,
+ isArray = isArraylike( elems ),
+ ret = [];
+
+ // Go through the array, translating each of the items to their new values
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( i in elems ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ var tmp, args, proxy;
+
+ if ( typeof context === "string" ) {
+ tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ args = slice.call( arguments, 2 );
+ proxy = function() {
+ return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ now: Date.now,
+
+ // jQuery.support is not used in Core but other projects attach their
+ // properties to it so it needs to exist.
+ support: support
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+ var length = obj.length,
+ type = jQuery.type( obj );
+
+ if ( type === "function" || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ if ( obj.nodeType === 1 && length ) {
+ return true;
+ }
+
+ return type === "array" || length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v1.10.16
+ * http://sizzlejs.com/
+ *
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2014-01-13
+ */
+(function( window ) {
+
+var i,
+ support,
+ Expr,
+ getText,
+ isXML,
+ compile,
+ outermostContext,
+ sortInput,
+ hasDuplicate,
+
+ // Local document vars
+ setDocument,
+ document,
+ docElem,
+ documentIsHTML,
+ rbuggyQSA,
+ rbuggyMatches,
+ matches,
+ contains,
+
+ // Instance-specific data
+ expando = "sizzle" + -(new Date()),
+ preferredDoc = window.document,
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ },
+
+ // General-purpose constants
+ strundefined = typeof undefined,
+ MAX_NEGATIVE = 1 << 31,
+
+ // Instance methods
+ hasOwn = ({}).hasOwnProperty,
+ arr = [],
+ pop = arr.pop,
+ push_native = arr.push,
+ push = arr.push,
+ slice = arr.slice,
+ // Use a stripped-down indexOf if we can't use a native one
+ indexOf = arr.indexOf || function( elem ) {
+ var i = 0,
+ len = this.length;
+ for ( ; i < len; i++ ) {
+ if ( this[i] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+ // Regular expressions
+
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+ // http://www.w3.org/TR/css3-syntax/#characters
+ characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+ // Loosely modeled on CSS identifier characters
+ // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = characterEncoding.replace( "w", "w#" ),
+
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+ "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+ // Prefer arguments quoted,
+ // then not containing pseudos/brackets,
+ // then attribute selectors/non-parenthetical expressions,
+ // then anything else
+ // These preferences are here to reduce the number of selectors
+ // needing tokenize in the PSEUDO preFilter
+ pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+ rpseudo = new RegExp( pseudos ),
+ ridentifier = new RegExp( "^" + identifier + "$" ),
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ },
+
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
+
+ rnative = /^[^{]+\{\s*\[native \w/,
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+ rsibling = /[+~]/,
+ rescape = /'|\\/g,
+
+ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+ funescape = function( _, escaped, escapedWhitespace ) {
+ var high = "0x" + escaped - 0x10000;
+ // NaN means non-codepoint
+ // Support: Firefox
+ // Workaround erroneous numeric interpretation of +"0x"
+ return high !== high || escapedWhitespace ?
+ escaped :
+ high < 0 ?
+ // BMP codepoint
+ String.fromCharCode( high + 0x10000 ) :
+ // Supplemental Plane codepoint (surrogate pair)
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+ };
+
+// Optimize for push.apply( _, NodeList )
+try {
+ push.apply(
+ (arr = slice.call( preferredDoc.childNodes )),
+ preferredDoc.childNodes
+ );
+ // Support: Android<4.0
+ // Detect silently failing push.apply
+ arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+ push = { apply: arr.length ?
+
+ // Leverage slice if possible
+ function( target, els ) {
+ push_native.apply( target, slice.call(els) );
+ } :
+
+ // Support: IE<9
+ // Otherwise append directly
+ function( target, els ) {
+ var j = target.length,
+ i = 0;
+ // Can't trust NodeList.length
+ while ( (target[j++] = els[i++]) ) {}
+ target.length = j - 1;
+ }
+ };
+}
+
+function Sizzle( selector, context, results, seed ) {
+ var match, elem, m, nodeType,
+ // QSA vars
+ i, groups, old, nid, newContext, newSelector;
+
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+ setDocument( context );
+ }
+
+ context = context || document;
+ results = results || [];
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( documentIsHTML && !seed ) {
+
+ // Shortcuts
+ if ( (match = rquickExpr.exec( selector )) ) {
+ // Speed-up: Sizzle("#ID")
+ if ( (m = match[1]) ) {
+ if ( nodeType === 9 ) {
+ elem = context.getElementById( m );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document (jQuery #6963)
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE, Opera, and Webkit return items
+ // by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+ } else {
+ // Context is not a document
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+ contains( context, elem ) && elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Speed-up: Sizzle("TAG")
+ } else if ( match[2] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
+ return results;
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
+ }
+ }
+
+ // QSA path
+ if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+ nid = old = expando;
+ newContext = context;
+ newSelector = nodeType === 9 && selector;
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ groups = tokenize( selector );
+
+ if ( (old = context.getAttribute("id")) ) {
+ nid = old.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", nid );
+ }
+ nid = "[id='" + nid + "'] ";
+
+ i = groups.length;
+ while ( i-- ) {
+ groups[i] = nid + toSelector( groups[i] );
+ }
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
+ newSelector = groups.join(",");
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch(qsaError) {
+ } finally {
+ if ( !old ) {
+ context.removeAttribute("id");
+ }
+ }
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+function createCache() {
+ var keys = [];
+
+ function cache( key, value ) {
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
+ // Only keep the most recent entries
+ delete cache[ keys.shift() ];
+ }
+ return (cache[ key + " " ] = value);
+ }
+ return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+ fn[ expando ] = true;
+ return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+ var div = document.createElement("div");
+
+ try {
+ return !!fn( div );
+ } catch (e) {
+ return false;
+ } finally {
+ // Remove from its parent by default
+ if ( div.parentNode ) {
+ div.parentNode.removeChild( div );
+ }
+ // release memory in IE
+ div = null;
+ }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+ var arr = attrs.split("|"),
+ i = attrs.length;
+
+ while ( i-- ) {
+ Expr.attrHandle[ arr[i] ] = handler;
+ }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+ var cur = b && a,
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+ ( ~b.sourceIndex || MAX_NEGATIVE ) -
+ ( ~a.sourceIndex || MAX_NEGATIVE );
+
+ // Use IE sourceIndex if available on both nodes
+ if ( diff ) {
+ return diff;
+ }
+
+ // Check if b follows a
+ if ( cur ) {
+ while ( (cur = cur.nextSibling) ) {
+ if ( cur === b ) {
+ return -1;
+ }
+ }
+ }
+
+ return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+ return markFunction(function( argument ) {
+ argument = +argument;
+ return markFunction(function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ (j = matchIndexes[i]) ] ) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+ return context && typeof context.getElementsByTagName !== strundefined && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+ var hasCompare,
+ doc = node ? node.ownerDocument || node : preferredDoc,
+ parent = doc.defaultView;
+
+ // If no document and documentElement is available, return
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+ return document;
+ }
+
+ // Set our document
+ document = doc;
+ docElem = doc.documentElement;
+
+ // Support tests
+ documentIsHTML = !isXML( doc );
+
+ // Support: IE>8
+ // If iframe document is assigned to "document" variable and if iframe has been reloaded,
+ // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
+ // IE6-8 do not support the defaultView property so parent will be undefined
+ if ( parent && parent !== parent.top ) {
+ // IE11 does not have attachEvent, so all must suffer
+ if ( parent.addEventListener ) {
+ parent.addEventListener( "unload", function() {
+ setDocument();
+ }, false );
+ } else if ( parent.attachEvent ) {
+ parent.attachEvent( "onunload", function() {
+ setDocument();
+ });
+ }
+ }
+
+ /* Attributes
+ ---------------------------------------------------------------------- */
+
+ // Support: IE<8
+ // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
+ support.attributes = assert(function( div ) {
+ div.className = "i";
+ return !div.getAttribute("className");
+ });
+
+ /* getElement(s)By*
+ ---------------------------------------------------------------------- */
+
+ // Check if getElementsByTagName("*") returns only elements
+ support.getElementsByTagName = assert(function( div ) {
+ div.appendChild( doc.createComment("") );
+ return !div.getElementsByTagName("*").length;
+ });
+
+ // Check if getElementsByClassName can be trusted
+ support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
+ div.innerHTML = "";
+
+ // Support: Safari<4
+ // Catch class over-caching
+ div.firstChild.className = "i";
+ // Support: Opera<10
+ // Catch gEBCN failure to find non-leading classes
+ return div.getElementsByClassName("i").length === 2;
+ });
+
+ // Support: IE<10
+ // Check if getElementById returns elements by name
+ // The broken getElementById methods don't pick up programatically-set names,
+ // so use a roundabout getElementsByName test
+ support.getById = assert(function( div ) {
+ docElem.appendChild( div ).id = expando;
+ return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
+ });
+
+ // ID find and filter
+ if ( support.getById ) {
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
+ var m = context.getElementById( id );
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ };
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ return elem.getAttribute("id") === attrId;
+ };
+ };
+ } else {
+ // Support: IE6/7
+ // getElementById is not reliable as a find shortcut
+ delete Expr.find["ID"];
+
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+ return node && node.value === attrId;
+ };
+ };
+ }
+
+ // Tag
+ Expr.find["TAG"] = support.getElementsByTagName ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== strundefined ) {
+ return context.getElementsByTagName( tag );
+ }
+ } :
+ function( tag, context ) {
+ var elem,
+ tmp = [],
+ i = 0,
+ results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ };
+
+ // Class
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+ if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
+ return context.getElementsByClassName( className );
+ }
+ };
+
+ /* QSA/matchesSelector
+ ---------------------------------------------------------------------- */
+
+ // QSA and matchesSelector support
+
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ rbuggyMatches = [];
+
+ // qSa(:focus) reports false when true (Chrome 21)
+ // We allow this because of a bug in IE8/9 that throws an error
+ // whenever `document.activeElement` is accessed on an iframe
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
+ // See http://bugs.jquery.com/ticket/13378
+ rbuggyQSA = [];
+
+ if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( div ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explicitly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // http://bugs.jquery.com/ticket/12359
+ div.innerHTML = "";
+
+ // Support: IE8, Opera 10-12
+ // Nothing should be selected when empty strings follow ^= or $= or *=
+ if ( div.querySelectorAll("[t^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+ }
+
+ // Support: IE8
+ // Boolean attributes and "value" are not treated correctly
+ if ( !div.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here and will not see later tests
+ if ( !div.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+ });
+
+ assert(function( div ) {
+ // Support: Windows 8 Native Apps
+ // The type and name attributes are restricted during .innerHTML assignment
+ var input = doc.createElement("input");
+ input.setAttribute( "type", "hidden" );
+ div.appendChild( input ).setAttribute( "name", "D" );
+
+ // Support: IE8
+ // Enforce case-sensitivity of name attribute
+ if ( div.querySelectorAll("[name=d]").length ) {
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here and will not see later tests
+ if ( !div.querySelectorAll(":enabled").length ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+ div.querySelectorAll("*,:x");
+ rbuggyQSA.push(",.*:");
+ });
+ }
+
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector) )) ) {
+
+ assert(function( div ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call( div, "div" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( div, "[s!='']:x" );
+ rbuggyMatches.push( "!=", pseudos );
+ });
+ }
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+ /* Contains
+ ---------------------------------------------------------------------- */
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+ // Element contains another
+ // Purposefully does not implement inclusive descendent
+ // As in, an element does not contain itself
+ contains = hasCompare || rnative.test( docElem.contains ) ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && (
+ adown.contains ?
+ adown.contains( bup ) :
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+ ));
+ } :
+ function( a, b ) {
+ if ( b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ /* Sorting
+ ---------------------------------------------------------------------- */
+
+ // Document order sorting
+ sortOrder = hasCompare ?
+ function( a, b ) {
+
+ // Flag for duplicate removal
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ // Sort on method existence if only one input has compareDocumentPosition
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ if ( compare ) {
+ return compare;
+ }
+
+ // Calculate position if both inputs belong to the same document
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+ a.compareDocumentPosition( b ) :
+
+ // Otherwise we know they are disconnected
+ 1;
+
+ // Disconnected nodes
+ if ( compare & 1 ||
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+ // Choose the first element that is related to our preferred document
+ if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+ return -1;
+ }
+ if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+ return 1;
+ }
+
+ // Maintain original order
+ return sortInput ?
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+ 0;
+ }
+
+ return compare & 4 ? -1 : 1;
+ } :
+ function( a, b ) {
+ // Exit early if the nodes are identical
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ var cur,
+ i = 0,
+ aup = a.parentNode,
+ bup = b.parentNode,
+ ap = [ a ],
+ bp = [ b ];
+
+ // Parentless nodes are either documents or disconnected
+ if ( !aup || !bup ) {
+ return a === doc ? -1 :
+ b === doc ? 1 :
+ aup ? -1 :
+ bup ? 1 :
+ sortInput ?
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+ 0;
+
+ // If the nodes are siblings, we can do a quick check
+ } else if ( aup === bup ) {
+ return siblingCheck( a, b );
+ }
+
+ // Otherwise we need full lists of their ancestors for comparison
+ cur = a;
+ while ( (cur = cur.parentNode) ) {
+ ap.unshift( cur );
+ }
+ cur = b;
+ while ( (cur = cur.parentNode) ) {
+ bp.unshift( cur );
+ }
+
+ // Walk down the tree looking for a discrepancy
+ while ( ap[i] === bp[i] ) {
+ i++;
+ }
+
+ return i ?
+ // Do a sibling check if the nodes have a common ancestor
+ siblingCheck( ap[i], bp[i] ) :
+
+ // Otherwise nodes in our document sort first
+ ap[i] === preferredDoc ? -1 :
+ bp[i] === preferredDoc ? 1 :
+ 0;
+ };
+
+ return doc;
+};
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ if ( support.matchesSelector && documentIsHTML &&
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
+
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || support.disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle( expr, document, null, [elem] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+ // Set document vars if needed
+ if ( ( context.ownerDocument || context ) !== document ) {
+ setDocument( context );
+ }
+ return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+ fn( elem, name, !documentIsHTML ) :
+ undefined;
+
+ return val !== undefined ?
+ val :
+ support.attributes || !documentIsHTML ?
+ elem.getAttribute( name ) :
+ (val = elem.getAttributeNode(name)) && val.specified ?
+ val.value :
+ null;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ duplicates = [],
+ j = 0,
+ i = 0;
+
+ // Unless we *know* we can detect duplicates, assume their presence
+ hasDuplicate = !support.detectDuplicates;
+ sortInput = !support.sortStable && results.slice( 0 );
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem === results[ i ] ) {
+ j = duplicates.push( i );
+ }
+ }
+ while ( j-- ) {
+ results.splice( duplicates[ j ], 1 );
+ }
+ }
+
+ // Clear input after sorting to release objects
+ // See https://github.com/jquery/sizzle/pull/225
+ sortInput = null;
+
+ return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( !nodeType ) {
+ // If no nodeType, this is expected to be an array
+ while ( (node = elem[i++]) ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (jQuery #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+
+ return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ attrHandle: {},
+
+ find: {},
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( runescape, funescape );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
+ // nth-* requires argument
+ if ( !match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var excess,
+ unquoted = !match[5] && match[2];
+
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ // Accept quoted arguments as-is
+ if ( match[3] && match[4] !== undefined ) {
+ match[2] = match[4];
+
+ // Strip excess characters from unquoted arguments
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ match[0] = match[0].slice( 0, excess );
+ match[2] = unquoted.slice( 0, excess );
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+
+ "TAG": function( nodeNameSelector ) {
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+ return nodeNameSelector === "*" ?
+ function() { return true; } :
+ function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ className + " " ];
+
+ return pattern ||
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+ classCache( className, function( elem ) {
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
+ });
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.slice( -check.length ) === check :
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+ false;
+ };
+ },
+
+ "CHILD": function( type, what, argument, first, last ) {
+ var simple = type.slice( 0, 3 ) !== "nth",
+ forward = type.slice( -4 ) !== "last",
+ ofType = what === "of-type";
+
+ return first === 1 && last === 0 ?
+
+ // Shortcut for :nth-*(n)
+ function( elem ) {
+ return !!elem.parentNode;
+ } :
+
+ function( elem, context, xml ) {
+ var cache, outerCache, node, diff, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType;
+
+ if ( parent ) {
+
+ // :(first|last|only)-(child|of-type)
+ if ( simple ) {
+ while ( dir ) {
+ node = elem;
+ while ( (node = node[ dir ]) ) {
+ if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ // Reverse direction for :only-* (if we haven't yet done so)
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+ return true;
+ }
+
+ start = [ forward ? parent.firstChild : parent.lastChild ];
+
+ // non-xml :nth-child(...) stores cache data on `parent`
+ if ( forward && useCache ) {
+ // Seek `elem` from a previously-cached index
+ outerCache = parent[ expando ] || (parent[ expando ] = {});
+ cache = outerCache[ type ] || [];
+ nodeIndex = cache[0] === dirruns && cache[1];
+ diff = cache[0] === dirruns && cache[2];
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+ // Fallback to seeking `elem` from the start
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ // When found, cache indexes on `parent` and break
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
+ outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
+
+ // Use previously-cached element index if available
+ } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+ diff = cache[1];
+
+ // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ } else {
+ // Use the same loop as above to seek `elem` from the start
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+ }
+
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset, then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction(function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf.call( seed, matched[i] );
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
+ }
+ }) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+ // Potentially complex pseudos
+ "not": markFunction(function( selector ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction(function( seed, matches, context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( (elem = unmatched[i]) ) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) :
+ function( elem, context, xml ) {
+ input[0] = elem;
+ matcher( input, null, xml, results );
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // http://www.w3.org/TR/selectors/#lang-pseudo
+ "lang": markFunction( function( lang ) {
+ // lang value must be a valid identifier
+ if ( !ridentifier.test(lang || "") ) {
+ Sizzle.error( "unsupported lang: " + lang );
+ }
+ lang = lang.replace( runescape, funescape ).toLowerCase();
+ return function( elem ) {
+ var elemLang;
+ do {
+ if ( (elemLang = documentIsHTML ?
+ elem.lang :
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+ }
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+ return false;
+ };
+ }),
+
+ // Miscellaneous
+ "target": function( elem ) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice( 1 ) === elem.id;
+ },
+
+ "root": function( elem ) {
+ return elem === docElem;
+ },
+
+ "focus": function( elem ) {
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+ },
+
+ // Boolean properties
+ "enabled": function( elem ) {
+ return elem.disabled === false;
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true;
+ },
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ // Contents
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+ // but not by others (comment: 8; processing instruction: 7; etc.)
+ // nodeType < 6 works because attributes (2) do not appear as children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ if ( elem.nodeType < 6 ) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ // Element/input types
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "text": function( elem ) {
+ var attr;
+ return elem.nodeName.toLowerCase() === "input" &&
+ elem.type === "text" &&
+
+ // Support: IE<8
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+ },
+
+ // Position-in-collection
+ "first": createPositionalPseudo(function() {
+ return [ 0 ];
+ }),
+
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
+ return [ length - 1 ];
+ }),
+
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ }),
+
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 0;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 1;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ })
+ }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+ Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+ Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+function tokenize( selector, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, preFilters,
+ cached = tokenCache[ selector + " " ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice( match[0].length ) || soFar;
+ }
+ groups.push( (tokens = []) );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ // Cast descendant combinators to space
+ type: match[0].replace( rtrim, " " )
+ });
+ soFar = soFar.slice( matched.length );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ (match = preFilters[ type ]( match ))) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ type: type,
+ matches: match
+ });
+ soFar = soFar.slice( matched.length );
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+}
+
+function toSelector( tokens ) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+ for ( ; i < len; i++ ) {
+ selector += tokens[i].value;
+ }
+ return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ checkNonElements = base && dir === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var oldCache, outerCache,
+ newCache = [ dirruns, doneName ];
+
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+ if ( xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ if ( matcher( elem, context, xml ) ) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
+ if ( (oldCache = outerCache[ dir ]) &&
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+ // Assign to newCache so results back-propagate to previous elements
+ return (newCache[ 2 ] = oldCache[ 2 ]);
+ } else {
+ // Reuse newcache so results back-propagate to previous elements
+ outerCache[ dir ] = newCache;
+
+ // A match means we're done; a fail means we have to keep checking
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ };
+}
+
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[i]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( (elem = unmatched[i]) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction(function( seed, results, context, xml ) {
+ var temp, i, elem,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ temp = condense( matcherOut, postMap );
+ postFilter( temp, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = temp.length;
+ while ( i-- ) {
+ if ( (elem = temp[i]) ) {
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ }
+ }
+ }
+
+ if ( seed ) {
+ if ( postFinder || preFilter ) {
+ if ( postFinder ) {
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) ) {
+ // Restore matcherIn since elem is not yet a final match
+ temp.push( (matcherIn[i] = elem) );
+ }
+ }
+ postFinder( null, (matcherOut = []), temp, xml );
+ }
+
+ // Move matched elements from seed to results to keep them synchronized
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) &&
+ (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+
+ seed[temp] = !(results[temp] = elem);
+ }
+ }
+ }
+
+ // Add elements to results, through postFinder if defined
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ });
+}
+
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[0].type ],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf.call( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+ } else {
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[j].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && toSelector(
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+ ).replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && toSelector( tokens )
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, outermost ) {
+ var elem, j, matcher,
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ setMatched = [],
+ contextBackup = outermostContext,
+ // We must always have either seed elements or outermost context
+ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+ len = elems.length;
+
+ if ( outermost ) {
+ outermostContext = context !== document && context;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+ // Support: IE<9, Safari
+ // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
+ for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+ if ( byElement && elem ) {
+ j = 0;
+ while ( (matcher = elementMatchers[j++]) ) {
+ if ( matcher( elem, context, xml ) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+ // They will have gone through all possible matchers
+ if ( (elem = !matcher && elem) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // Apply set filters to unmatched elements
+ matchedCount += i;
+ if ( bySet && i !== matchedCount ) {
+ j = 0;
+ while ( (matcher = setMatchers[j++]) ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !(unmatched[i] || setMatched[i]) ) {
+ setMatched[i] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ selector + " " ];
+
+ if ( !cached ) {
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !group ) {
+ group = tokenize( selector );
+ }
+ i = group.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( group[i] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+ }
+ return cached;
+};
+
+function multipleContexts( selector, contexts, results ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results );
+ }
+ return results;
+}
+
+function select( selector, context, results, seed ) {
+ var i, tokens, token, type, find,
+ match = tokenize( selector );
+
+ if ( !seed ) {
+ // Try to minimize operations if there is only one group
+ if ( match.length === 1 ) {
+
+ // Take a shortcut and set the context if the root selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ support.getById && context.nodeType === 9 && documentIsHTML &&
+ Expr.relative[ tokens[1].type ] ) {
+
+ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+ if ( !context ) {
+ return results;
+ }
+ selector = selector.slice( tokens.shift().value.length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+ while ( i-- ) {
+ token = tokens[i];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ (type = token.type) ] ) {
+ break;
+ }
+ if ( (find = Expr.find[ type ]) ) {
+ // Search, expanding context for leading sibling combinators
+ if ( (seed = find(
+ token.matches[0].replace( runescape, funescape ),
+ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+ )) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && toSelector( tokens );
+ if ( !selector ) {
+ push.apply( results, seed );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function
+ // Provide `match` to avoid retokenization if we modified the selector above
+ compile( selector, match )(
+ seed,
+ context,
+ !documentIsHTML,
+ results,
+ rsibling.test( selector ) && testContext( context.parentNode ) || context
+ );
+ return results;
+}
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome<14
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+ // Should return 1, but returns 4 (following)
+ return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+ div.innerHTML = "";
+ return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
+ if ( !isXML ) {
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+ }
+ });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+ div.innerHTML = "";
+ div.firstChild.setAttribute( "value", "" );
+ return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+ addHandle( "value", function( elem, name, isXML ) {
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+ return elem.defaultValue;
+ }
+ });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+ return div.getAttribute("disabled") == null;
+}) ) {
+ addHandle( booleans, function( elem, name, isXML ) {
+ var val;
+ if ( !isXML ) {
+ return elem[ name ] === true ? name.toLowerCase() :
+ (val = elem.getAttributeNode( name )) && val.specified ?
+ val.value :
+ null;
+ }
+ });
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
+
+
+
+var risSimple = /^.[^:#\[\.,]*$/;
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep( elements, function( elem, i ) {
+ /* jshint -W018 */
+ return !!qualifier.call( elem, i, elem ) !== not;
+ });
+
+ }
+
+ if ( qualifier.nodeType ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( elem === qualifier ) !== not;
+ });
+
+ }
+
+ if ( typeof qualifier === "string" ) {
+ if ( risSimple.test( qualifier ) ) {
+ return jQuery.filter( qualifier, elements, not );
+ }
+
+ qualifier = jQuery.filter( qualifier, elements );
+ }
+
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
+ });
+}
+
+jQuery.filter = function( expr, elems, not ) {
+ var elem = elems[ 0 ];
+
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 && elem.nodeType === 1 ?
+ jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+ jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ }));
+};
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var i,
+ len = this.length,
+ ret = [],
+ self = this;
+
+ if ( typeof selector !== "string" ) {
+ return this.pushStack( jQuery( selector ).filter(function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ }) );
+ }
+
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, self[ i ], ret );
+ }
+
+ // Needed because $( selector, context ) becomes $( context ).find( selector )
+ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+ ret.selector = this.selector ? this.selector + " " + selector : selector;
+ return ret;
+ },
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector || [], false) );
+ },
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector || [], true) );
+ },
+ is: function( selector ) {
+ return !!winnow(
+ this,
+
+ // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ typeof selector === "string" && rneedsContext.test( selector ) ?
+ jQuery( selector ) :
+ selector || [],
+ false
+ ).length;
+ }
+});
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+ // A simple way to check for HTML strings
+ // Prioritize #id over to avoid XSS via location.hash (#9521)
+ // Strict HTML recognition (#11290: must start with <)
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+ init = jQuery.fn.init = function( selector, context ) {
+ var match, elem;
+
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = rquickExpr.exec( selector );
+ }
+
+ // Match html or make sure no context is specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ context = context instanceof jQuery ? context[0] : context;
+
+ // scripts is true for back-compat
+ // Intentionally let the error be thrown if parseHTML is not present
+ jQuery.merge( this, jQuery.parseHTML(
+ match[1],
+ context && context.nodeType ? context.ownerDocument || context : document,
+ true
+ ) );
+
+ // HANDLE: $(html, props)
+ if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+ for ( match in context ) {
+ // Properties of context are called as methods if possible
+ if ( jQuery.isFunction( this[ match ] ) ) {
+ this[ match ]( context[ match ] );
+
+ // ...and otherwise set as attributes
+ } else {
+ this.attr( match, context[ match ] );
+ }
+ }
+ }
+
+ return this;
+
+ // HANDLE: $(#id)
+ } else {
+ elem = document.getElementById( match[2] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || rootjQuery ).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(DOMElement)
+ } else if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return typeof rootjQuery.ready !== "undefined" ?
+ rootjQuery.ready( selector ) :
+ // Execute immediately if ready is not present
+ selector( jQuery );
+ }
+
+ if ( selector.selector !== undefined ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ };
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+ // methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.extend({
+ dir: function( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
+ }
+ matched.push( elem );
+ }
+ }
+ return matched;
+ },
+
+ sibling: function( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
+ }
+ }
+
+ return matched;
+ }
+});
+
+jQuery.fn.extend({
+ has: function( target ) {
+ var targets = jQuery( target, this ),
+ l = targets.length;
+
+ return this.filter(function() {
+ var i = 0;
+ for ( ; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
+
+ for ( ; i < l; i++ ) {
+ for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
+ // Always skip document fragments
+ if ( cur.nodeType < 11 && (pos ?
+ pos.index(cur) > -1 :
+
+ // Don't pass non-elements to Sizzle
+ cur.nodeType === 1 &&
+ jQuery.find.matchesSelector(cur, selectors)) ) {
+
+ matched.push( cur );
+ break;
+ }
+ }
+ }
+
+ return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+ }
+
+ // index in selector
+ if ( typeof elem === "string" ) {
+ return indexOf.call( jQuery( elem ), this[ 0 ] );
+ }
+
+ // Locate the position of the desired element
+ return indexOf.call( this,
+
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[ 0 ] : elem
+ );
+ },
+
+ add: function( selector, context ) {
+ return this.pushStack(
+ jQuery.unique(
+ jQuery.merge( this.get(), jQuery( selector, context ) )
+ )
+ );
+ },
+
+ addBack: function( selector ) {
+ return this.add( selector == null ?
+ this.prevObject : this.prevObject.filter(selector)
+ );
+ }
+});
+
+function sibling( cur, dir ) {
+ while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
+ return cur;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return elem.contentDocument || jQuery.merge( [], elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var matched = jQuery.map( this, fn, until );
+
+ if ( name.slice( -5 ) !== "Until" ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ matched = jQuery.filter( selector, matched );
+ }
+
+ if ( this.length > 1 ) {
+ // Remove duplicates
+ if ( !guaranteedUnique[ name ] ) {
+ jQuery.unique( matched );
+ }
+
+ // Reverse order for parents* and prev-derivatives
+ if ( rparentsprev.test( name ) ) {
+ matched.reverse();
+ }
+ }
+
+ return this.pushStack( matched );
+ };
+});
+var rnotwhite = (/\S+/g);
+
+
+
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+ var object = optionsCache[ options ] = {};
+ jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
+ object[ flag ] = true;
+ });
+ return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ * options: an optional list of space-separated options that will change how
+ * the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ * once: will ensure the callback list can only be fired once (like a Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback added
+ * after the list has been fired right away with the latest "memorized"
+ * values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+ // Convert options from String-formatted to Object-formatted if needed
+ // (we check in cache first)
+ options = typeof options === "string" ?
+ ( optionsCache[ options ] || createOptions( options ) ) :
+ jQuery.extend( {}, options );
+
+ var // Last fire value (for non-forgettable lists)
+ memory,
+ // Flag to know if list was already fired
+ fired,
+ // Flag to know if list is currently firing
+ firing,
+ // First callback to fire (used internally by add and fireWith)
+ firingStart,
+ // End of the loop when firing
+ firingLength,
+ // Index of currently firing callback (modified by remove if needed)
+ firingIndex,
+ // Actual callback list
+ list = [],
+ // Stack of fire calls for repeatable lists
+ stack = !options.once && [],
+ // Fire callbacks
+ fire = function( data ) {
+ memory = options.memory && data;
+ fired = true;
+ firingIndex = firingStart || 0;
+ firingStart = 0;
+ firingLength = list.length;
+ firing = true;
+ for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+ if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+ memory = false; // To prevent further calls using add
+ break;
+ }
+ }
+ firing = false;
+ if ( list ) {
+ if ( stack ) {
+ if ( stack.length ) {
+ fire( stack.shift() );
+ }
+ } else if ( memory ) {
+ list = [];
+ } else {
+ self.disable();
+ }
+ }
+ },
+ // Actual Callbacks object
+ self = {
+ // Add a callback or a collection of callbacks to the list
+ add: function() {
+ if ( list ) {
+ // First, we save the current length
+ var start = list.length;
+ (function add( args ) {
+ jQuery.each( args, function( _, arg ) {
+ var type = jQuery.type( arg );
+ if ( type === "function" ) {
+ if ( !options.unique || !self.has( arg ) ) {
+ list.push( arg );
+ }
+ } else if ( arg && arg.length && type !== "string" ) {
+ // Inspect recursively
+ add( arg );
+ }
+ });
+ })( arguments );
+ // Do we need to add the callbacks to the
+ // current firing batch?
+ if ( firing ) {
+ firingLength = list.length;
+ // With memory, if we're not firing then
+ // we should call right away
+ } else if ( memory ) {
+ firingStart = start;
+ fire( memory );
+ }
+ }
+ return this;
+ },
+ // Remove a callback from the list
+ remove: function() {
+ if ( list ) {
+ jQuery.each( arguments, function( _, arg ) {
+ var index;
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+ list.splice( index, 1 );
+ // Handle firing indexes
+ if ( firing ) {
+ if ( index <= firingLength ) {
+ firingLength--;
+ }
+ if ( index <= firingIndex ) {
+ firingIndex--;
+ }
+ }
+ }
+ });
+ }
+ return this;
+ },
+ // Check if a given callback is in the list.
+ // If no argument is given, return whether or not list has callbacks attached.
+ has: function( fn ) {
+ return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+ },
+ // Remove all callbacks from the list
+ empty: function() {
+ list = [];
+ firingLength = 0;
+ return this;
+ },
+ // Have the list do nothing anymore
+ disable: function() {
+ list = stack = memory = undefined;
+ return this;
+ },
+ // Is it disabled?
+ disabled: function() {
+ return !list;
+ },
+ // Lock the list in its current state
+ lock: function() {
+ stack = undefined;
+ if ( !memory ) {
+ self.disable();
+ }
+ return this;
+ },
+ // Is it locked?
+ locked: function() {
+ return !stack;
+ },
+ // Call all callbacks with the given context and arguments
+ fireWith: function( context, args ) {
+ if ( list && ( !fired || stack ) ) {
+ args = args || [];
+ args = [ context, args.slice ? args.slice() : args ];
+ if ( firing ) {
+ stack.push( args );
+ } else {
+ fire( args );
+ }
+ }
+ return this;
+ },
+ // Call all the callbacks with the given arguments
+ fire: function() {
+ self.fireWith( this, arguments );
+ return this;
+ },
+ // To know if the callbacks have already been called at least once
+ fired: function() {
+ return !!fired;
+ }
+ };
+
+ return self;
+};
+
+
+jQuery.extend({
+
+ Deferred: function( func ) {
+ var tuples = [
+ // action, add listener, listener list, final state
+ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+ [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+ [ "notify", "progress", jQuery.Callbacks("memory") ]
+ ],
+ state = "pending",
+ promise = {
+ state: function() {
+ return state;
+ },
+ always: function() {
+ deferred.done( arguments ).fail( arguments );
+ return this;
+ },
+ then: function( /* fnDone, fnFail, fnProgress */ ) {
+ var fns = arguments;
+ return jQuery.Deferred(function( newDefer ) {
+ jQuery.each( tuples, function( i, tuple ) {
+ var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+ // deferred[ done | fail | progress ] for forwarding actions to newDefer
+ deferred[ tuple[1] ](function() {
+ var returned = fn && fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise()
+ .done( newDefer.resolve )
+ .fail( newDefer.reject )
+ .progress( newDefer.notify );
+ } else {
+ newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+ }
+ });
+ });
+ fns = null;
+ }).promise();
+ },
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
+ }
+ },
+ deferred = {};
+
+ // Keep pipe for back-compat
+ promise.pipe = promise.then;
+
+ // Add list-specific methods
+ jQuery.each( tuples, function( i, tuple ) {
+ var list = tuple[ 2 ],
+ stateString = tuple[ 3 ];
+
+ // promise[ done | fail | progress ] = list.add
+ promise[ tuple[1] ] = list.add;
+
+ // Handle state
+ if ( stateString ) {
+ list.add(function() {
+ // state = [ resolved | rejected ]
+ state = stateString;
+
+ // [ reject_list | resolve_list ].disable; progress_list.lock
+ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+ }
+
+ // deferred[ resolve | reject | notify ]
+ deferred[ tuple[0] ] = function() {
+ deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+ return this;
+ };
+ deferred[ tuple[0] + "With" ] = list.fireWith;
+ });
+
+ // Make the deferred a promise
+ promise.promise( deferred );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+
+ // All done!
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( subordinate /* , ..., subordinateN */ ) {
+ var i = 0,
+ resolveValues = slice.call( arguments ),
+ length = resolveValues.length,
+
+ // the count of uncompleted subordinates
+ remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+ // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+ deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+ // Update function for both resolve and progress values
+ updateFunc = function( i, contexts, values ) {
+ return function( value ) {
+ contexts[ i ] = this;
+ values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+ if ( values === progressValues ) {
+ deferred.notifyWith( contexts, values );
+ } else if ( !( --remaining ) ) {
+ deferred.resolveWith( contexts, values );
+ }
+ };
+ },
+
+ progressValues, progressContexts, resolveContexts;
+
+ // add listeners to Deferred subordinates; treat others as resolved
+ if ( length > 1 ) {
+ progressValues = new Array( length );
+ progressContexts = new Array( length );
+ resolveContexts = new Array( length );
+ for ( ; i < length; i++ ) {
+ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+ resolveValues[ i ].promise()
+ .done( updateFunc( i, resolveContexts, resolveValues ) )
+ .fail( deferred.reject )
+ .progress( updateFunc( i, progressContexts, progressValues ) );
+ } else {
+ --remaining;
+ }
+ }
+ }
+
+ // if we're not waiting on anything, resolve the master
+ if ( !remaining ) {
+ deferred.resolveWith( resolveContexts, resolveValues );
+ }
+
+ return deferred.promise();
+ }
+});
+
+
+// The deferred used on DOM ready
+var readyList;
+
+jQuery.fn.ready = function( fn ) {
+ // Add the callback
+ jQuery.ready.promise().done( fn );
+
+ return this;
+};
+
+jQuery.extend({
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+
+ // Abort if there are pending holds or we're already ready
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+ return;
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger("ready").off("ready");
+ }
+ }
+});
+
+/**
+ * The ready event handler and self cleanup method
+ */
+function completed() {
+ document.removeEventListener( "DOMContentLoaded", completed, false );
+ window.removeEventListener( "load", completed, false );
+ jQuery.ready();
+}
+
+jQuery.ready.promise = function( obj ) {
+ if ( !readyList ) {
+
+ readyList = jQuery.Deferred();
+
+ // Catch cases where $(document).ready() is called after the browser event has already occurred.
+ // we once tried to use readyState "interactive" here, but it caused issues like the one
+ // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+ if ( document.readyState === "complete" ) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ setTimeout( jQuery.ready );
+
+ } else {
+
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed, false );
+ }
+ }
+ return readyList.promise( obj );
+};
+
+// Kick off the DOM ready check even if the user does not
+jQuery.ready.promise();
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ len = elems.length,
+ bulk = key == null;
+
+ // Sets many values
+ if ( jQuery.type( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+ }
+
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
+
+ if ( !jQuery.isFunction( value ) ) {
+ raw = true;
+ }
+
+ if ( bulk ) {
+ // Bulk operations run against the entire set
+ if ( raw ) {
+ fn.call( elems, value );
+ fn = null;
+
+ // ...except when executing function values
+ } else {
+ bulk = fn;
+ fn = function( elem, key, value ) {
+ return bulk.call( jQuery( elem ), value );
+ };
+ }
+ }
+
+ if ( fn ) {
+ for ( ; i < len; i++ ) {
+ fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+ }
+ }
+ }
+
+ return chainable ?
+ elems :
+
+ // Gets
+ bulk ?
+ fn.call( elems ) :
+ len ? fn( elems[0], key ) : emptyGet;
+};
+
+
+/**
+ * Determines whether an object can have data
+ */
+jQuery.acceptData = function( owner ) {
+ // Accepts only:
+ // - Node
+ // - Node.ELEMENT_NODE
+ // - Node.DOCUMENT_NODE
+ // - Object
+ // - Any
+ /* jshint -W018 */
+ return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+function Data() {
+ // Support: Android < 4,
+ // Old WebKit does not have Object.preventExtensions/freeze method,
+ // return new empty object instead with no [[set]] accessor
+ Object.defineProperty( this.cache = {}, 0, {
+ get: function() {
+ return {};
+ }
+ });
+
+ this.expando = jQuery.expando + Math.random();
+}
+
+Data.uid = 1;
+Data.accepts = jQuery.acceptData;
+
+Data.prototype = {
+ key: function( owner ) {
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return the key for a frozen object.
+ if ( !Data.accepts( owner ) ) {
+ return 0;
+ }
+
+ var descriptor = {},
+ // Check if the owner object already has a cache key
+ unlock = owner[ this.expando ];
+
+ // If not, create one
+ if ( !unlock ) {
+ unlock = Data.uid++;
+
+ // Secure it in a non-enumerable, non-writable property
+ try {
+ descriptor[ this.expando ] = { value: unlock };
+ Object.defineProperties( owner, descriptor );
+
+ // Support: Android < 4
+ // Fallback to a less secure definition
+ } catch ( e ) {
+ descriptor[ this.expando ] = unlock;
+ jQuery.extend( owner, descriptor );
+ }
+ }
+
+ // Ensure the cache object
+ if ( !this.cache[ unlock ] ) {
+ this.cache[ unlock ] = {};
+ }
+
+ return unlock;
+ },
+ set: function( owner, data, value ) {
+ var prop,
+ // There may be an unlock assigned to this node,
+ // if there is no entry for this "owner", create one inline
+ // and set the unlock as though an owner entry had always existed
+ unlock = this.key( owner ),
+ cache = this.cache[ unlock ];
+
+ // Handle: [ owner, key, value ] args
+ if ( typeof data === "string" ) {
+ cache[ data ] = value;
+
+ // Handle: [ owner, { properties } ] args
+ } else {
+ // Fresh assignments by object are shallow copied
+ if ( jQuery.isEmptyObject( cache ) ) {
+ jQuery.extend( this.cache[ unlock ], data );
+ // Otherwise, copy the properties one-by-one to the cache object
+ } else {
+ for ( prop in data ) {
+ cache[ prop ] = data[ prop ];
+ }
+ }
+ }
+ return cache;
+ },
+ get: function( owner, key ) {
+ // Either a valid cache is found, or will be created.
+ // New caches will be created and the unlock returned,
+ // allowing direct access to the newly created
+ // empty data object. A valid owner object must be provided.
+ var cache = this.cache[ this.key( owner ) ];
+
+ return key === undefined ?
+ cache : cache[ key ];
+ },
+ access: function( owner, key, value ) {
+ var stored;
+ // In cases where either:
+ //
+ // 1. No key was specified
+ // 2. A string key was specified, but no value provided
+ //
+ // Take the "read" path and allow the get method to determine
+ // which value to return, respectively either:
+ //
+ // 1. The entire cache object
+ // 2. The data stored at the key
+ //
+ if ( key === undefined ||
+ ((key && typeof key === "string") && value === undefined) ) {
+
+ stored = this.get( owner, key );
+
+ return stored !== undefined ?
+ stored : this.get( owner, jQuery.camelCase(key) );
+ }
+
+ // [*]When the key is not a string, or both a key and value
+ // are specified, set or extend (existing objects) with either:
+ //
+ // 1. An object of properties
+ // 2. A key and value
+ //
+ this.set( owner, key, value );
+
+ // Since the "set" path can have two possible entry points
+ // return the expected data based on which path was taken[*]
+ return value !== undefined ? value : key;
+ },
+ remove: function( owner, key ) {
+ var i, name, camel,
+ unlock = this.key( owner ),
+ cache = this.cache[ unlock ];
+
+ if ( key === undefined ) {
+ this.cache[ unlock ] = {};
+
+ } else {
+ // Support array or space separated string of keys
+ if ( jQuery.isArray( key ) ) {
+ // If "name" is an array of keys...
+ // When data is initially created, via ("key", "val") signature,
+ // keys will be converted to camelCase.
+ // Since there is no way to tell _how_ a key was added, remove
+ // both plain key and camelCase key. #12786
+ // This will only penalize the array argument path.
+ name = key.concat( key.map( jQuery.camelCase ) );
+ } else {
+ camel = jQuery.camelCase( key );
+ // Try the string as a key before any manipulation
+ if ( key in cache ) {
+ name = [ key, camel ];
+ } else {
+ // If a key with the spaces exists, use it.
+ // Otherwise, create an array by matching non-whitespace
+ name = camel;
+ name = name in cache ?
+ [ name ] : ( name.match( rnotwhite ) || [] );
+ }
+ }
+
+ i = name.length;
+ while ( i-- ) {
+ delete cache[ name[ i ] ];
+ }
+ }
+ },
+ hasData: function( owner ) {
+ return !jQuery.isEmptyObject(
+ this.cache[ owner[ this.expando ] ] || {}
+ );
+ },
+ discard: function( owner ) {
+ if ( owner[ this.expando ] ) {
+ delete this.cache[ owner[ this.expando ] ];
+ }
+ }
+};
+var data_priv = new Data();
+
+var data_user = new Data();
+
+
+
+/*
+ Implementation Summary
+
+ 1. Enforce API surface and semantic compatibility with 1.9.x branch
+ 2. Improve the module's maintainability by reducing the storage
+ paths to a single mechanism.
+ 3. Use the same single mechanism to support "private" and "user" data.
+ 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+ 5. Avoid exposing implementation details on user objects (eg. expando properties)
+ 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+*/
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+ rmultiDash = /([A-Z])/g;
+
+function dataAttr( elem, key, data ) {
+ var name;
+
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+ // Only convert to a number if it doesn't change the string
+ +data + "" === data ? +data :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ data_user.set( elem, key, data );
+ } else {
+ data = undefined;
+ }
+ }
+ return data;
+}
+
+jQuery.extend({
+ hasData: function( elem ) {
+ return data_user.hasData( elem ) || data_priv.hasData( elem );
+ },
+
+ data: function( elem, name, data ) {
+ return data_user.access( elem, name, data );
+ },
+
+ removeData: function( elem, name ) {
+ data_user.remove( elem, name );
+ },
+
+ // TODO: Now that all calls to _data and _removeData have been replaced
+ // with direct calls to data_priv methods, these can be deprecated.
+ _data: function( elem, name, data ) {
+ return data_priv.access( elem, name, data );
+ },
+
+ _removeData: function( elem, name ) {
+ data_priv.remove( elem, name );
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ var i, name, data,
+ elem = this[ 0 ],
+ attrs = elem && elem.attributes;
+
+ // Gets all values
+ if ( key === undefined ) {
+ if ( this.length ) {
+ data = data_user.get( elem );
+
+ if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
+ i = attrs.length;
+ while ( i-- ) {
+ name = attrs[ i ].name;
+
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = jQuery.camelCase( name.slice(5) );
+ dataAttr( elem, name, data[ name ] );
+ }
+ }
+ data_priv.set( elem, "hasDataAttrs", true );
+ }
+ }
+
+ return data;
+ }
+
+ // Sets multiple values
+ if ( typeof key === "object" ) {
+ return this.each(function() {
+ data_user.set( this, key );
+ });
+ }
+
+ return access( this, function( value ) {
+ var data,
+ camelKey = jQuery.camelCase( key );
+
+ // The calling jQuery object (element matches) is not empty
+ // (and therefore has an element appears at this[ 0 ]) and the
+ // `value` parameter was not undefined. An empty jQuery object
+ // will result in `undefined` for elem = this[ 0 ] which will
+ // throw an exception if an attempt to read a data cache is made.
+ if ( elem && value === undefined ) {
+ // Attempt to get data from the cache
+ // with the key as-is
+ data = data_user.get( elem, key );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // Attempt to get data from the cache
+ // with the key camelized
+ data = data_user.get( elem, camelKey );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // Attempt to "discover" the data in
+ // HTML5 custom data-* attrs
+ data = dataAttr( elem, camelKey, undefined );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // We tried really hard, but the data doesn't exist.
+ return;
+ }
+
+ // Set the data...
+ this.each(function() {
+ // First, attempt to store a copy or reference of any
+ // data that might've been store with a camelCased key.
+ var data = data_user.get( this, camelKey );
+
+ // For HTML5 data-* attribute interop, we have to
+ // store property names with dashes in a camelCase form.
+ // This might not apply to all properties...*
+ data_user.set( this, camelKey, value );
+
+ // *... In the case of properties that might _actually_
+ // have dashes, we need to also store a copy of that
+ // unchanged property.
+ if ( key.indexOf("-") !== -1 && data !== undefined ) {
+ data_user.set( this, key, value );
+ }
+ });
+ }, null, value, arguments.length > 1, null, true );
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ data_user.remove( this, key );
+ });
+ }
+});
+
+
+jQuery.extend({
+ queue: function( elem, type, data ) {
+ var queue;
+
+ if ( elem ) {
+ type = ( type || "fx" ) + "queue";
+ queue = data_priv.get( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !queue || jQuery.isArray( data ) ) {
+ queue = data_priv.access( elem, type, jQuery.makeArray(data) );
+ } else {
+ queue.push( data );
+ }
+ }
+ return queue || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ startLength = queue.length,
+ fn = queue.shift(),
+ hooks = jQuery._queueHooks( elem, type ),
+ next = function() {
+ jQuery.dequeue( elem, type );
+ };
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ startLength--;
+ }
+
+ if ( fn ) {
+
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift( "inprogress" );
+ }
+
+ // clear up the last queue stop function
+ delete hooks.stop;
+ fn.call( elem, next, hooks );
+ }
+
+ if ( !startLength && hooks ) {
+ hooks.empty.fire();
+ }
+ },
+
+ // not intended for public consumption - generates a queueHooks object, or returns the current one
+ _queueHooks: function( elem, type ) {
+ var key = type + "queueHooks";
+ return data_priv.get( elem, key ) || data_priv.access( elem, key, {
+ empty: jQuery.Callbacks("once memory").add(function() {
+ data_priv.remove( elem, [ type + "queue", key ] );
+ })
+ });
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ var setter = 2;
+
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ setter--;
+ }
+
+ if ( arguments.length < setter ) {
+ return jQuery.queue( this[0], type );
+ }
+
+ return data === undefined ?
+ this :
+ this.each(function() {
+ var queue = jQuery.queue( this, type, data );
+
+ // ensure a hooks for this queue
+ jQuery._queueHooks( this, type );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, obj ) {
+ var tmp,
+ count = 1,
+ defer = jQuery.Deferred(),
+ elements = this,
+ i = this.length,
+ resolve = function() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ };
+
+ if ( typeof type !== "string" ) {
+ obj = type;
+ type = undefined;
+ }
+ type = type || "fx";
+
+ while ( i-- ) {
+ tmp = data_priv.get( elements[ i ], type + "queueHooks" );
+ if ( tmp && tmp.empty ) {
+ count++;
+ tmp.empty.add( resolve );
+ }
+ }
+ resolve();
+ return defer.promise( obj );
+ }
+});
+var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHidden = function( elem, el ) {
+ // isHidden might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+ return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+ };
+
+var rcheckableType = (/^(?:checkbox|radio)$/i);
+
+
+
+(function() {
+ var fragment = document.createDocumentFragment(),
+ div = fragment.appendChild( document.createElement( "div" ) );
+
+ // #11217 - WebKit loses check when the name is after the checked attribute
+ div.innerHTML = "";
+
+ // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
+ // old WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+ // Support: IE9-IE11+
+ div.innerHTML = "";
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+})();
+var strundefined = typeof undefined;
+
+
+
+support.focusinBubbles = "onfocusin" in window;
+
+
+var
+ rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|contextmenu)|click/,
+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+ return true;
+}
+
+function returnFalse() {
+ return false;
+}
+
+function safeActiveElement() {
+ try {
+ return document.activeElement;
+ } catch ( err ) { }
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+ global: {},
+
+ add: function( elem, types, handler, data, selector ) {
+
+ var handleObjIn, eventHandle, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = data_priv.get( elem );
+
+ // Don't attach events to noData or text/comment nodes (but allow plain objects)
+ if ( !elemData ) {
+ return;
+ }
+
+ // Caller can pass in an object of custom data in lieu of the handler
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ selector = handleObjIn.selector;
+ }
+
+ // Make sure that the handler has a unique ID, used to find/remove it later
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure and main handler, if this is the first
+ if ( !(events = elemData.events) ) {
+ events = elemData.events = {};
+ }
+ if ( !(eventHandle = elemData.handle) ) {
+ eventHandle = elemData.handle = function( e ) {
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
+ jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+ };
+ }
+
+ // Handle multiple events separated by a space
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[t] ) || [];
+ type = origType = tmp[1];
+ namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+ // There *must* be a type, no attaching namespace-only handlers
+ if ( !type ) {
+ continue;
+ }
+
+ // If event changes its type, use the special event handlers for the changed type
+ special = jQuery.event.special[ type ] || {};
+
+ // If selector defined, determine special event api type, otherwise given type
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+
+ // Update special based on newly reset type
+ special = jQuery.event.special[ type ] || {};
+
+ // handleObj is passed to all event handlers
+ handleObj = jQuery.extend({
+ type: type,
+ origType: origType,
+ data: data,
+ handler: handler,
+ guid: handler.guid,
+ selector: selector,
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+ namespace: namespaces.join(".")
+ }, handleObjIn );
+
+ // Init the event handler queue if we're the first
+ if ( !(handlers = events[ type ]) ) {
+ handlers = events[ type ] = [];
+ handlers.delegateCount = 0;
+
+ // Only use addEventListener if the special events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add to the element's handler list, delegates in front
+ if ( selector ) {
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
+ } else {
+ handlers.push( handleObj );
+ }
+
+ // Keep track of which events have ever been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ },
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, selector, mappedTypes ) {
+
+ var j, origCount, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = data_priv.hasData( elem ) && data_priv.get( elem );
+
+ if ( !elemData || !(events = elemData.events) ) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[t] ) || [];
+ type = origType = tmp[1];
+ namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+ // Unbind all events (on this namespace, if provided) for the element
+ if ( !type ) {
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+ }
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+ handlers = events[ type ] || [];
+ tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+ // Remove matching events
+ origCount = j = handlers.length;
+ while ( j-- ) {
+ handleObj = handlers[ j ];
+
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
+ ( !handler || handler.guid === handleObj.guid ) &&
+ ( !tmp || tmp.test( handleObj.namespace ) ) &&
+ ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+ handlers.splice( j, 1 );
+
+ if ( handleObj.selector ) {
+ handlers.delegateCount--;
+ }
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+ }
+
+ // Remove generic event handler if we removed something and no more handlers exist
+ // (avoids potential for endless recursion during removal of special event handlers)
+ if ( origCount && !handlers.length ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ delete elemData.handle;
+ data_priv.remove( elem, "events" );
+ }
+ },
+
+ trigger: function( event, data, elem, onlyHandlers ) {
+
+ var i, cur, tmp, bubbleType, ontype, handle, special,
+ eventPath = [ elem || document ],
+ type = hasOwn.call( event, "type" ) ? event.type : event,
+ namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+ cur = tmp = elem = elem || document;
+
+ // Don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // focus/blur morphs to focusin/out; ensure we're not firing them right now
+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+ return;
+ }
+
+ if ( type.indexOf(".") >= 0 ) {
+ // Namespaced trigger; create a regexp to match event type in handle()
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ namespaces.sort();
+ }
+ ontype = type.indexOf(":") < 0 && "on" + type;
+
+ // Caller can pass in a jQuery.Event object, Object, or just an event type string
+ event = event[ jQuery.expando ] ?
+ event :
+ new jQuery.Event( type, typeof event === "object" && event );
+
+ // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+ event.isTrigger = onlyHandlers ? 2 : 3;
+ event.namespace = namespaces.join(".");
+ event.namespace_re = event.namespace ?
+ new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+ null;
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ if ( !event.target ) {
+ event.target = elem;
+ }
+
+ // Clone any incoming data and prepend the event, creating the handler arg list
+ data = data == null ?
+ [ event ] :
+ jQuery.makeArray( data, [ event ] );
+
+ // Allow special events to draw outside the lines
+ special = jQuery.event.special[ type ] || {};
+ if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+ return;
+ }
+
+ // Determine event propagation path in advance, per W3C events spec (#9951)
+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+ bubbleType = special.delegateType || type;
+ if ( !rfocusMorph.test( bubbleType + type ) ) {
+ cur = cur.parentNode;
+ }
+ for ( ; cur; cur = cur.parentNode ) {
+ eventPath.push( cur );
+ tmp = cur;
+ }
+
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
+ if ( tmp === (elem.ownerDocument || document) ) {
+ eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+ }
+ }
+
+ // Fire handlers on the event path
+ i = 0;
+ while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+ event.type = i > 1 ?
+ bubbleType :
+ special.bindType || type;
+
+ // jQuery handler
+ handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
+ if ( handle ) {
+ handle.apply( cur, data );
+ }
+
+ // Native handler
+ handle = ontype && cur[ ontype ];
+ if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
+ event.result = handle.apply( cur, data );
+ if ( event.result === false ) {
+ event.preventDefault();
+ }
+ }
+ }
+ event.type = type;
+
+ // If nobody prevented the default action, do it now
+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+ if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
+ jQuery.acceptData( elem ) ) {
+
+ // Call a native DOM method on the target with the same name name as the event.
+ // Don't do default actions on window, that's where global variables be (#6170)
+ if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
+
+ // Don't re-trigger an onFOO event when we call its FOO() method
+ tmp = elem[ ontype ];
+
+ if ( tmp ) {
+ elem[ ontype ] = null;
+ }
+
+ // Prevent re-triggering of the same event, since we already bubbled it above
+ jQuery.event.triggered = type;
+ elem[ type ]();
+ jQuery.event.triggered = undefined;
+
+ if ( tmp ) {
+ elem[ ontype ] = tmp;
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ dispatch: function( event ) {
+
+ // Make a writable jQuery.Event from the native event object
+ event = jQuery.event.fix( event );
+
+ var i, j, ret, matched, handleObj,
+ handlerQueue = [],
+ args = slice.call( arguments ),
+ handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
+ special = jQuery.event.special[ event.type ] || {};
+
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
+ args[0] = event;
+ event.delegateTarget = this;
+
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+ return;
+ }
+
+ // Determine handlers
+ handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+ // Run delegates first; they may want to stop propagation beneath us
+ i = 0;
+ while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+ event.currentTarget = matched.elem;
+
+ j = 0;
+ while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+ // Triggered event must either 1) have no namespace, or
+ // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+ if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+ event.handleObj = handleObj;
+ event.data = handleObj.data;
+
+ ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+ .apply( matched.elem, args );
+
+ if ( ret !== undefined ) {
+ if ( (event.result = ret) === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ }
+
+ // Call the postDispatch hook for the mapped type
+ if ( special.postDispatch ) {
+ special.postDispatch.call( this, event );
+ }
+
+ return event.result;
+ },
+
+ handlers: function( event, handlers ) {
+ var i, matches, sel, handleObj,
+ handlerQueue = [],
+ delegateCount = handlers.delegateCount,
+ cur = event.target;
+
+ // Find delegate handlers
+ // Black-hole SVG
-
\ No newline at end of file
+
+
+ <%= link_to "Create new Constraint", solutions_constraints_path %>
\ No newline at end of file
diff --git a/tutor/app/views/solutions_constraints/new.html.erb b/tutor/app/views/solutions_constraints/new.html.erb
new file mode 100644
index 00000000..b4dd62db
--- /dev/null
+++ b/tutor/app/views/solutions_constraints/new.html.erb
@@ -0,0 +1,3 @@
+
New mooo
+
+<%= render 'form' %>
\ No newline at end of file
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index 480589ae..f4005e4d 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -29,7 +29,7 @@
resources :solutions
resources :problems
resources :topics
- resources :solutions_constraints
+
# Example resource route with options:
# resources :products do
@@ -55,6 +55,13 @@
resources :model_answers do
post "model_answers/new"
end
+ resources :solutions_constraints do
+ collection do
+ post "new"
+ end
+ end
+
+
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
diff --git a/tutor/db/development.sqlite3 b/tutor/db/development.sqlite3
index d19c0b1d72718ca09796e9cf12d0309b4ca00b82..16f9168c6518c0aa49ad1fcc1826ba2aa4fd9b2e 100644
GIT binary patch
delta 4675
zcmbVQZERat8NSDMlBP}K?xTbuN+Q%%ZK__MbI*4-v^ZYtv}qG3aheZMz8W`QPMpMc
zl0}2KQYH9<*tk+ILWnX1;tyL_M@lB7vHn0H_yN--v_H_X-w4KpplDJX&UHrawS6KG
zk@LsTbKmoRJn#FS>q4QSP-uAblW=XbVHi&yEgpYlZX$63vI`WNRB~bw3nFqJlJgd7
ztwh>$6XuP~!YOOw6oRL6OPvWiNUkT7Oy*+qD+3#o@tM@%bYEgaOs-x{<)-^PRx=~!
z#Ly)ep=dFhj7DO&o&ujWo>GUG{-V*7x9pc+XkPG6!U!Uy^`V5Iav$bm@puPJr}?#>
zd_1{4czwBRIG)N5MAKcDr!!dO2J%DKX3)g)4cI@hK0kls#(Kmow%2{(?7@i^g&b?5
zW+ovR3u4336Eka_BmLczaAWw&)tfh2)*R`bnIGwyyS6;k6Hj)p%c0nGv@>hvv)#G$
zCH`XnTy%2Dtd7F9iMU{gBKGT}?QI9HVT3T$kfHf0Vx!Tg>0C5BJQM96q4~MBx%qf(
zHkXWKQ(|r;zZglUiA*QD7p|w##lelvz7caMhE_MGV)pph`Tw2+Xzpjn%>n(ta!?#^
z37D{`hvX~UZsVjpUJv~>4*19YnH&=3t$(voX*Ui-O`dWInV|A%BwQ+gz
z67OBQYGU(NEBKsoQi(mR{_VNVQ=Si42qL-8hkXQTd`Nb!!r6@&pXj=R%&Dox$(P_l
z%v>4TSi9KG2lI(ozGG-0-?6$ron2fS=}z#n+YLw1ypQ{2`uc_%Gs1bS)C5WMwBvH{6W6S
zXPZDwG|6*4;erVJ`){1|Qq2ex6j$3;QYs-Y29K%KxHHj+MiZHA?hr0jhw81kh?Eec>(-d)g-$S=27v9rQ=xephW#ML{4%sQBjBe4=GkouX|BDI~RMtft<0
zW^M-bZhgXjEgA|TYs770Wlv7Hav{cOvU8o!loRR%1IfBJ>5
zvDG(JYT8e+k-LxWzx);Z5-2FqvmvsGv^ziYEfjGm8L6QGk^SS3ET7v##jRBdlngRl
z{M%c8w<+aVpAu;aj_nU0x12s`48f$pnjlpvnY2&uwffvRgsKDu1)<2!l(Pw=T0vQm
zGK<@9?X~!_#~|mLDdE~y>v4N;@7s-@C!9)3v;H8OHOw~JO>c*9HvX#VyWuYbX)GACufE!{`}J1P5U>+9pV)n&$J@t(aj+YC7DR&e
zktgb!BN1@B(V0F2wrZCqRwfp*&b_C>XPm@2uvX8WtZPOH+-`QhdKP@IA(flSOpUFi
za`}}-=Y@0N8@u0X1HTPzK~Q@nWQ2bj9twxHpD6sZX|pd_Zy@)cAB|osJ(X}xr*f&4
zY%88!%vGmCX&(|yHHG^R(ib?~rd4j!Tm1rBoatMwg!F;KjiPd+UNxoU`g=JqA&tgv
zpdCb7Jdvq;klPPc^;e;lkluiEcMN>qSs(L@Oduw8BglQqMV!~iK%1vYfe6vB+kIqb
z9DL{-S*rD=(9e8?)J@DengM4$>s*a$q#5I?T}z1bl?pmit3Veq7cSzwQBFV987L&;
za%Tyg2z&YDP^}KV^%CMX?WWtboBn*NqA6=ypGt^xXA=lt#1J#xno|*%kevbuy<2+%
zgpA;db0iV?Vr}5PKn)1ly~p3%{Yh^i6L3Z&;D@^>l7ZXjrVrF3q}qns!MKk+59$n1
zUmuMIbe;-z{eqftr8H4Ob_#*_U-n{N}c-^boX^Y>kK0Zi>=3Hu3J)VaXnjI9E8(eL04}C
znj$D)sJih`r%*x1MEA3VOIMnL&ix8HV*2fXD8@u=?UlO@A=k)K87J!Qi=FmzIufd}
jw2=}^y~{a;3c9*a>DM+^X~)j}3OZ7+*IMfssVe;&FxWn2
delta 4570
zcmbVPYfM|$9lyus5yImpO&ii`8K}#mlq%+&d)~BDF-}5&1Ptcgl}Ess7>p^HIi9NF
zD4#d2yAoHLrlnOkbzj<~MuKXuM%uJ#`?7qiCT;2ZZR)hO(=+1bqcx)tLM*(R$#vF#@wtN&p@pCVxy@iY5Uhw@xVrcu8{7;QfwiV
zVME=E8%x&pkx18-**57Nb;a8Mqx+ow*_
z|0@K!nHIBn43-E|r1Qr`?CvBf<^>CBVSP2ai2Z{k_Oclvdeb703%exNTfFcmoKDZfnG5pGrftv)Ff-a
z5E>25T7#=}Vv=;d%gEo+)ZTsuUR41*3o4E1Xm+l|@Zn)_k1
z0ul>KG(p}+a^HUXfQe(u>)PA#sO*xhtB{(33
zI+f+#*l6Mqnr;DLh9tx~2jskMQU#~*btp1E(Fq~XZX?#@vSWt3}
zKl_OKdde`a1J_DVs@3ke!_9*hBS=Cf?ChN}uNV3M>Aet2a_;UoJVi?|WKs>J!{eD#
z!7LoAt}~u4_%IY*UC!vGVo8N2aLNf6300LEA@-x6*B3jOUSq~w^2-2D$5i_v5VQ~l7AOi*a={qe=35T$`rZRiV#
zJ^$c;Vk;d|Li;xlf*#w5G3Ab?v?NDJU>kq*f|rd{q_k{C8Ns&mQKyFu8PsnTYS|#f
z%Khn=p2lXBBYj8|&fpuYbdy08+u_q2h28F9<~T>{eHN7~;7P3En+;aAyF&LrP(vE(G*k|`zJu)g%WqxvFJ6X!c
zglG+`C<(=Wf3L+8J)){zpGU6BczbW}JB>vp6jPkvhYpV)!7!!V`Eer`^W3oNy<2>P<$@3(+NZa1v0CkZ;pL1s#e8IUfT~Y%=s*6GUm5Vsax^J|r%(GXp;MOcd2T
zyh4RBsdgOaXc9cjO0O(Nb3X1=F3OX8_MQA0|X1s8E{Zvx@*SZ!k!a_k~ISx|Mq>Phgn;T#S7o~`z8
z_)
z@59%M;?>wC>J6vyRjp@4%B@GfW-nW%MB8VQFtrsrouzcBZbkhqK-8?GPPUBBp+1mO
zJ;jCP+$*C~HAc14F=7yJJuZeIfVQP1
Date: Mon, 21 Apr 2014 20:22:55 +0200
Subject: [PATCH 136/526] Issue #216 Fixed documentation
---
tutor/app/controllers/application_controller.rb | 4 ++--
tutor/app/models/lecturer.rb | 2 +-
tutor/app/models/student.rb | 2 +-
tutor/app/models/teaching_assistant.rb | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tutor/app/controllers/application_controller.rb b/tutor/app/controllers/application_controller.rb
index e7b5eb1e..d303835a 100644
--- a/tutor/app/controllers/application_controller.rb
+++ b/tutor/app/controllers/application_controller.rb
@@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :update_sanitized_params, if: :devise_controller?
- # [User Authentication Advanced - Story 5.9, 5.11, 5.12, 5.16]
+ # [User Authentication Advanced - Story 5.9, 5.10, 5.11, 5.14, 5.15]
# Permits some fields to be passed through sign up forms to update the lecturer,
# student, and teaching_assistant models
# Parameters: None
@@ -33,7 +33,7 @@ def update_sanitized_params
end
end
- # [User Authentication Advanced - Story 5.9, 5.11, 5.12, 5.16]
+ # [User Authentication Advanced - Story 5.9, 5.10, 5.11, 5.14, 5.15]
# Checks if a user is signed-in in order to be used in authentication over different pages
# where they are redirected to homepage if they aren't authenticated
# Parameters: None
diff --git a/tutor/app/models/lecturer.rb b/tutor/app/models/lecturer.rb
index dcd4a28c..a6212275 100644
--- a/tutor/app/models/lecturer.rb
+++ b/tutor/app/models/lecturer.rb
@@ -37,7 +37,7 @@ class Lecturer < ActiveRecord::Base
#Methods
- # [User Authentication Advanced - Story 5.9, 5.11, 5.12, 5.16]
+ # [User Authentication Advanced - Story 5.9, 5.10, 5.11, 5.14, 5.15]
# Checks if the email is already registered in tables: Student and TeachingAssistant
# before registering the email for table: Lecturer
# Parameters: None
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index ce42ede8..77db215e 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -32,7 +32,7 @@ class Student < ActiveRecord::Base
#Methods
- # [User Authentication Advanced - Story 5.9, 5.11, 5.12, 5.16]
+ # [User Authentication Advanced - Story 5.9, 5.10, 5.11, 5.14, 5.15]
# Checks if the email is already registered in tables: Lecturer and TeachingAssistant
# before registering the email for table: Student
# Parameters: None
diff --git a/tutor/app/models/teaching_assistant.rb b/tutor/app/models/teaching_assistant.rb
index 20bb9967..87aec822 100644
--- a/tutor/app/models/teaching_assistant.rb
+++ b/tutor/app/models/teaching_assistant.rb
@@ -38,7 +38,7 @@ class TeachingAssistant < ActiveRecord::Base
#Methods
- # [User Authentication Advanced - Story 5.9, 5.11, 5.12, 5.16]
+ # [User Authentication Advanced - Story 5.9, 5.10, 5.11, 5.14, 5.15]
# Checks if the email is already registered in tables: Lecturer and Student
# before registering the email for table: TeachingAssistant
# Parameters: None
From 1449c5b2993653439f0dd5a39b928d9f061e919a Mon Sep 17 00:00:00 2001
From: serag
Date: Mon, 21 Apr 2014 21:00:37 +0200
Subject: [PATCH 137/526] Issue #206 Modified Controllers and added primative
views
---
Coolsoft-14 | 1 -
1 file changed, 1 deletion(-)
delete mode 160000 Coolsoft-14
diff --git a/Coolsoft-14 b/Coolsoft-14
deleted file mode 160000
index 37221f72..00000000
--- a/Coolsoft-14
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 37221f725d7016bbe114f1c23f3e0d313ca01a4c
From 8e5f175ec106de5ae95aac36d8038845bb7598d3 Mon Sep 17 00:00:00 2001
From: serag
Date: Mon, 21 Apr 2014 21:15:52 +0200
Subject: [PATCH 138/526] Issue #206 Modified Controllers and added primative
views
---
tutor/app/controllers/lecturers_controller.rb | 4 ++--
tutor/app/controllers/students_controller.rb | 4 ++--
tutor/app/controllers/teaching_assistants_controller.rb | 4 ++--
tutor/app/views/lecturers/show.html.erb | 2 +-
tutor/app/views/students/show.html.erb | 2 +-
tutor/app/views/teaching_assistants/show.html.erb | 2 +-
tutor/config/routes.rb | 4 ++--
7 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/tutor/app/controllers/lecturers_controller.rb b/tutor/app/controllers/lecturers_controller.rb
index 096e7bdd..a64d7975 100644
--- a/tutor/app/controllers/lecturers_controller.rb
+++ b/tutor/app/controllers/lecturers_controller.rb
@@ -1,7 +1,7 @@
class LecturersController < ApplicationController
- def index
- end
def show
@lecturer = Lecturer.find(params[:id])
end
+ def index
+ end
end
\ No newline at end of file
diff --git a/tutor/app/controllers/students_controller.rb b/tutor/app/controllers/students_controller.rb
index bd7f3e35..84bf342d 100644
--- a/tutor/app/controllers/students_controller.rb
+++ b/tutor/app/controllers/students_controller.rb
@@ -1,7 +1,7 @@
class StudentsController < ApplicationController
- def index
- end
def show
@student = Student.find(params[:id])
end
+ def index
+ end
end
\ No newline at end of file
diff --git a/tutor/app/controllers/teaching_assistants_controller.rb b/tutor/app/controllers/teaching_assistants_controller.rb
index f07c2afe..10e2e7c9 100644
--- a/tutor/app/controllers/teaching_assistants_controller.rb
+++ b/tutor/app/controllers/teaching_assistants_controller.rb
@@ -1,7 +1,7 @@
class TeachingAssistantsController < ApplicationController
- def index
- end
def show
@teaching_assistant = TeachingAssistant.find(params[:id])
end
+ def index
+ end
end
\ No newline at end of file
diff --git a/tutor/app/views/lecturers/show.html.erb b/tutor/app/views/lecturers/show.html.erb
index b5386660..256accc2 100644
--- a/tutor/app/views/lecturers/show.html.erb
+++ b/tutor/app/views/lecturers/show.html.erb
@@ -1,7 +1,7 @@
- CoolSoft - Java Tutor
+ CoolSoft - Java Tutor | <%= @lecturer.id%>'s Profile
<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/solutions/alert.js.erb b/tutor/app/views/solutions/alert.js.erb
deleted file mode 100644
index 31d535dc..00000000
--- a/tutor/app/views/solutions/alert.js.erb
+++ /dev/null
@@ -1,8 +0,0 @@
-<% if @solution.save %>
- alert('Your Solution has been submitted successfully');
-<% end %>
-<% if !@solution.save %>
- alert('Blank submissions are not allowed');
-<% end %>
-
-
From 683d7a99076e31d0e821f2c8dc6bf678edec1e78 Mon Sep 17 00:00:00 2001
From: Khaled
Date: Tue, 22 Apr 2014 07:19:21 +0200
Subject: [PATCH 152/526] Issue #193 Fixed documentation
---
tutor/app/models/debugger.rb | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/tutor/app/models/debugger.rb b/tutor/app/models/debugger.rb
index 7acbcf4d..0435b37f 100644
--- a/tutor/app/models/debugger.rb
+++ b/tutor/app/models/debugger.rb
@@ -10,10 +10,12 @@ class Debugger < ActiveRecord::Base
#Methods
# [Debugger: View Variables - Story 3.7]
- # Returns a list of all variables in the class with
- # their values
+ # Fetches the variables found in the class and returns
+ # a list of all variables in the class with their
+ # associated values
# Parameters: None
- # Returns: An Array
+ # Returns:
+ # An array. It contains the list of variables and their values
# Author: Khaled Helmy
def get_variables
method_arguments = []
@@ -42,10 +44,12 @@ def get_variables
end
# [Debugger: View Variables - Story 3.7]
- # Return the list of instance and static variables from within
- # static methods
+ # Return the list of instance and static variables of the
+ # class from within static methods
# Parameters: None
- # Returns: An Array
+ # Returns:
+ # An array. It contains the list of instance and static
+ # variables and their associated values
# Author: Khaled Helmy
def get_class_variables
result = []
@@ -79,10 +83,11 @@ def get_class_variables
end
# [Debugger: View Variables - Story 3.7]
- # Takes a variable and evaluates its value
+ # Takes an object and evaluates its value
# Parameters:
- # variable: A String containing a variable assignment
- # Returns: An Array
+ # variable: a string containing an instance object
+ # Returns:
+ # An array. It contains the values inside an object
# Author: Khaled Helmy
def get_value variable
result = []
@@ -105,8 +110,9 @@ def get_value variable
# Takes a line containing an object assignment and extracts
# the object name
# Parameters:
- # variable: A String containing an object assignment
- # Returns: A String
+ # variable: A string containing an object assignment
+ # Returns:
+ # A string. It contains the object name
# Author: Khaled Helmy
def get_name variable
name = variable.split(" = ").first
From 8fd5e9bc9e6343f54e502d3306c5c1cfadf6224c Mon Sep 17 00:00:00 2001
From: Mohab
Date: Tue, 22 Apr 2014 08:58:19 +0200
Subject: [PATCH 153/526] Issue #203 Editing duplicate recommendation
---
tutor/app/assets/javascripts/tracks.js | 13 +++++++++----
tutor/app/controllers/tracks_controller.rb | 7 +++++--
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/tutor/app/assets/javascripts/tracks.js b/tutor/app/assets/javascripts/tracks.js
index fedf2dad..ac2d5643 100644
--- a/tutor/app/assets/javascripts/tracks.js
+++ b/tutor/app/assets/javascripts/tracks.js
@@ -24,11 +24,16 @@ function fill(data, problem_id, recommender_id){
elem.append("
");
$.each(data, function (i , datum){
datum = data[i];
- temp = "
From de18ce119e459b3df37739788a33603ebe3c0c23 Mon Sep 17 00:00:00 2001
From: mohamedsaeed93
Date: Tue, 22 Apr 2014 11:48:19 +0200
Subject: [PATCH 158/526] Issue #194, Adding documentation
---
.../assets/javascripts/solutions.js.coffee | 9 +++++++-
tutor/app/controllers/solutions_controller.rb | 15 +-----------
tutor/app/models/solution.rb | 23 ++++++++-----------
tutor/app/views/solutions/_new.html.erb | 11 +++------
4 files changed, 21 insertions(+), 37 deletions(-)
diff --git a/tutor/app/assets/javascripts/solutions.js.coffee b/tutor/app/assets/javascripts/solutions.js.coffee
index 69cabf82..29cc87c1 100644
--- a/tutor/app/assets/javascripts/solutions.js.coffee
+++ b/tutor/app/assets/javascripts/solutions.js.coffee
@@ -7,7 +7,6 @@ root = exports ? this
# none
# Returns: none
# Author: Rami Khalil (Temporary)
-
root.toggleDebug = () ->
$('#debugButton').prop 'hidden', !$('#debugButton').prop 'hidden'
$('#compileButton').prop 'hidden', !$('#compileButton').prop 'hidden'
@@ -71,6 +70,14 @@ root.previous = () ->
root.stop = () ->
toggleDebug()
+# [Compiler: Validate - Story 3.5]
+# submits a solution in the form without refreshing
+# using ajax showing an alert box for success and failure scenarios
+# Parameters:
+# problem_id: the id of the problem being solved
+# Returns: a json object containing two arrays one for the errors
+# of the current code and the other containing success messages
+# Author: MOHAMEDSAEED
@validate_code = (problem_id) ->
code = $('#solution_code').val()
mins = parseInt($('#mins').text())
diff --git a/tutor/app/controllers/solutions_controller.rb b/tutor/app/controllers/solutions_controller.rb
index 2c7b3235..8cd4a435 100644
--- a/tutor/app/controllers/solutions_controller.rb
+++ b/tutor/app/controllers/solutions_controller.rb
@@ -2,7 +2,6 @@ class SolutionsController < ApplicationController
# [Code Editor: Write Code - Story 3.3]
# submits a solution for a problem that the student chose
- # and show an alert box for success and failure scenarios
# Parameters:
# solution_params: submitted from the form_for
# Returns: none
@@ -13,24 +12,12 @@ def create
solution.student_id = current_student.id
solution.length = solution.code.length
testcases = solution.problem.test_cases
+ solution.status = 0
#response_message = Solution.validate(solution.code , testcases , file)
response_message = {:success => ["Success"], :failure => ["Failure"]}
#solution.status = response_message[:status]
solution.save
render json: response_message
- #end
end
-
- # [Code Editor: Write Code - Story 3.3]
- # Fills the ID of the problem , code from the form_for
- # Parameters:
- # code: The written code for the problem
- # problem_id: Hidden field for problem id
- # Returns: none
- # Author: MOHAMEDSAEED
- # private
- # def solution_params
- # params.require(:solution).permit(:code , :problem_id)
- # end
end
\ No newline at end of file
diff --git a/tutor/app/models/solution.rb b/tutor/app/models/solution.rb
index 6214992a..5a08ac11 100644
--- a/tutor/app/models/solution.rb
+++ b/tutor/app/models/solution.rb
@@ -7,22 +7,17 @@ class Solution < ActiveRecord::Base
belongs_to :student
belongs_to :problem
-
-
-
- #Scoops
-
#Methods
# [Compiler: Validate - Story 3.5]
- # checks the validity of a submitted solution
- # and show the #compilation, runtime and logic errors if exist
+ # Checks the validity of a submitted solution
+ # and show the runtime and logic errors if exist
# Parameters:
# code: the code written in the editor from the form_for
# testcases: the testcases for the given problem
# file: the name of the file which is compiled successfully
- # without errors
+ # without errors
# Returns: a hash response containing status for the solution,
- # solution errors or success message.
+ # solution errors or success message.
# Author: MOHAMEDSAEED
def self.validate(code, testcases, file)
response = {status: 0, success: [], failure: []}
@@ -31,7 +26,7 @@ def self.validate(code, testcases, file)
testcases.each do |testcase|
input = testcase.input
expected_output = testcase.output
- runtime_check = Executer.execute(file , input)
+ runtime_check = Executer.execute(file, input)
if(runtime_check)
output = Executer.get_output()
if output != expected_output?
@@ -42,7 +37,7 @@ def self.validate(code, testcases, file)
response[:status] = 5
end
else
- response[:success] << "Your Solution is correct , Passed"
+ response[:success] << "Your Solution is correct, Passed"
unless(response[:status] == 4 | 5)
response[:status] = 1
end
@@ -64,13 +59,13 @@ def self.validate(code, testcases, file)
# [Compiler: Validate - Story 3.5]
# Parameters:
# s_id : the id of the current Student
- # p_id : the id of the current Problem
+ # p_id : the id of the current Problem
# Returns: the number of trials the student made for this problem
# Author: MOHAMEDSAEED
def self.get_num_of_trials(s_id , p_id)
num_of_trials = Solution.distinct.count(:all,
- :conditions => [" student_id = ? AND problem_id = ? AND status != ? " ,
- s_id , p_id , 3])
+ :conditions => ["student_id = ? AND problem_id = ? AND status != ?",
+ s_id, p_id, 3])
end
#Constants
diff --git a/tutor/app/views/solutions/_new.html.erb b/tutor/app/views/solutions/_new.html.erb
index 96c2565a..33aff5c0 100644
--- a/tutor/app/views/solutions/_new.html.erb
+++ b/tutor/app/views/solutions/_new.html.erb
@@ -1,17 +1,12 @@
-
-
<%= flash[:success] %>
-
<%= flash[:alert] %>
-
Time spent:0:00
<%= form_for :solution,
:url => { :controller => "solutions", :action => "create" },
- :html => {:method => :post} , remote: true do |f| %>
- <%= @code = f.text_area :code, placeholder: "Write your code here and then click submit",
+ :html => {:method => :post}, remote: true do |f| %>
+ <%= f.text_area :code, placeholder: "Write your code here and then click submit",
class: "editor" %>
- <%= f.hidden_field :problem_id, value: params[:id] %>
@@ -46,7 +41,7 @@
Output response
-
+
<% end %>
\ No newline at end of file
From a6cf63c46b5efd859178e51c516b6785cf7e782e Mon Sep 17 00:00:00 2001
From: ahmed93
Date: Tue, 22 Apr 2014 11:52:43 +0200
Subject: [PATCH 159/526] Issue #188 adding some ajax to send arrays to
controller
---
.../javascripts/solutions_constraints.js | 173 +++++++++++++++++-
.../solutions_constraints_controller.rb | 28 ++-
.../_edit_method.html.erb | 47 +++++
.../_edit_variable.html.erb | 19 ++
.../solutions_constraints/_form.html.erb | 114 ++----------
.../views/solutions_constraints/create.js.erb | 1 -
.../views/solutions_constraints/edit.html.erb | 2 +-
.../views/solutions_constraints/new.html.erb | 2 +-
8 files changed, 274 insertions(+), 112 deletions(-)
create mode 100644 tutor/app/views/solutions_constraints/_edit_method.html.erb
create mode 100644 tutor/app/views/solutions_constraints/_edit_variable.html.erb
delete mode 100644 tutor/app/views/solutions_constraints/create.js.erb
diff --git a/tutor/app/assets/javascripts/solutions_constraints.js b/tutor/app/assets/javascripts/solutions_constraints.js
index 24f83d18..838fddd8 100644
--- a/tutor/app/assets/javascripts/solutions_constraints.js
+++ b/tutor/app/assets/javascripts/solutions_constraints.js
@@ -1,3 +1,170 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://coffeescript.org/
+// # Place all the behaviors and hooks related to the matching controller here.
+// # All this logic will automatically be available in application.js.
+// # You can use CoffeeScript in this file: http://coffeescript.org/
+
+var type = new Array();
+var param_name = new Array();
+
+function add_params(field)
+{
+ var tmp_type = document.getElementById("params_type").value;
+ var tmp_name = document.getElementById("params_name").value;
+
+ if (tmp_name != "" && tmp_type != "") {
+ document.getElementById("params_type").style.border= "";
+ document.getElementById("params_name").style.border= "";
+ type[type.length] = tmp_type;
+ document.getElementById("params_type").value = "";
+ param_name[param_name.length] = tmp_name;
+ document.getElementById("params_name").value = "";
+
+ document.getElementById("parameter").innerHTML = "
Paramters Constraints
";
+ for (var i = 0; i < type.length; i++) {
+ $('#parameter').append("
- <%= f.submit "Save Changes", class: "btn btn-default"%>
-
+ <%= button_tag "Save Changes", type: "button", class: "btn btn-large btn-success", onclick:"submitParams();"%>
<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/solutions_constraints/create.js.erb b/tutor/app/views/solutions_constraints/create.js.erb
deleted file mode 100644
index df2ca465..00000000
--- a/tutor/app/views/solutions_constraints/create.js.erb
+++ /dev/null
@@ -1 +0,0 @@
-$('body').append('<%= @comment.text %>');
\ No newline at end of file
diff --git a/tutor/app/views/solutions_constraints/edit.html.erb b/tutor/app/views/solutions_constraints/edit.html.erb
index cc1a9a5e..eb8f486a 100644
--- a/tutor/app/views/solutions_constraints/edit.html.erb
+++ b/tutor/app/views/solutions_constraints/edit.html.erb
@@ -1,3 +1,3 @@
<%= link_to "<< Back to list", :controller => 'solutions_constraints', :action => 'index' %>
Edit Constraints
-<%= render "form" %>
\ No newline at end of file
+<%= render "edit_method" %>
\ No newline at end of file
diff --git a/tutor/app/views/solutions_constraints/new.html.erb b/tutor/app/views/solutions_constraints/new.html.erb
index b4dd62db..a0932b48 100644
--- a/tutor/app/views/solutions_constraints/new.html.erb
+++ b/tutor/app/views/solutions_constraints/new.html.erb
@@ -1,3 +1,3 @@
-
New mooo
+
New Method/Variable Constraints
<%= render 'form' %>
\ No newline at end of file
From 8341d99959a2556c6ebd4099b090d7bd8f851beb Mon Sep 17 00:00:00 2001
From: Mohab
Date: Tue, 22 Apr 2014 12:33:48 +0200
Subject: [PATCH 160/526] Issue #200 Editing student model
---
tutor/app/models/student.rb | 13 +++++++++++++
tutor/config/routes.rb | 1 +
2 files changed, 14 insertions(+)
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index 72116f09..a563300e 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -75,5 +75,18 @@ def getProblemsStatus
end
return res
end
+
+ def getClassMatesRecommendations
+ recommended_problems = Recommendation.where(:student_id => self.id)
+ recommended_problems_hash = Hash.new
+ recommended_problems.each do |problem|
+ recommended_problems_hash[problem.id] = Hash.new
+ recommender_name = Student.where(:id => problem.recommender_id).recommender_name
+ problem_title = Problem.where(:id => problem.id).title
+ recommended_problems_hash[problem.id]['recommender_name '] = recommender_name
+ recommended_problems_hash[problem.id]['ptoblem_title'] = problem.title
+ end
+ return recommended_problems_hash
+ end
end
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index e9d7079c..9d8935e4 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -29,6 +29,7 @@
resources :solutions
resources :problems
resources :topics
+ resources :profile
# Example resource route with options:
# resources :products do
From 6e0f5af90d230220953ff059b8d76372eb6f3826 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Tue, 22 Apr 2014 12:54:07 +0200
Subject: [PATCH 161/526] changing in the posts controller and in the views of
the edit and show
---
tutor/Gemfile.lock | 2 --
tutor/app/controllers/posts_controller.rb | 4 ++--
tutor/app/views/posts/edit.html.erb | 4 ++--
tutor/app/views/posts/show.html.erb | 2 +-
4 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/tutor/Gemfile.lock b/tutor/Gemfile.lock
index 43582f98..fa0d2aac 100644
--- a/tutor/Gemfile.lock
+++ b/tutor/Gemfile.lock
@@ -29,7 +29,6 @@ GEM
atomic (1.1.16)
bcrypt (3.1.7)
builder (3.1.4)
- chartkick (1.2.4)
coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
@@ -132,7 +131,6 @@ PLATFORMS
ruby
DEPENDENCIES
- chartkick
coffee-rails (~> 4.0.0)
composite_primary_keys (~> 6.0.1)
devise
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index 234d28ea..7aed2717 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -64,8 +64,8 @@ def update
flash[:notice] = "Post successfully updated"
redirect_to(:action => 'show' ,:id => @post.id)
else
- if @new_post.errors.any?
- flash[:notice] = @new_post.errors.full_messages.first
+ if @post.errors.any?
+ flash[:notice] = @post.errors.full_messages.first
end
render :action => 'edit'
end
diff --git a/tutor/app/views/posts/edit.html.erb b/tutor/app/views/posts/edit.html.erb
index 2b66ea55..c2d3227a 100644
--- a/tutor/app/views/posts/edit.html.erb
+++ b/tutor/app/views/posts/edit.html.erb
@@ -12,12 +12,12 @@
<%= form_for :post, url: {action: "update", :id => @post.id} do |f| %>
<% end %>
\ No newline at end of file
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index 9d44a4c7..866b78f8 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -13,6 +13,7 @@
post 'courses/new' => 'courses#new'
get 'courses/sign_up'
post 'posts/new' => 'posts#new'
+ post '/posts/:id' => 'posts#update'
# You can have the root of your site routed with "root"
root 'site#index'
From d4ebec049bca164f79e071149dd7827f76d5facd Mon Sep 17 00:00:00 2001
From: Mussab ElDash
Date: Tue, 22 Apr 2014 13:44:32 +0200
Subject: [PATCH 166/526] Update solutions.js.coffee
---
tutor/app/assets/javascripts/solutions.js.coffee | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/tutor/app/assets/javascripts/solutions.js.coffee b/tutor/app/assets/javascripts/solutions.js.coffee
index 09ab84de..92f994d5 100644
--- a/tutor/app/assets/javascripts/solutions.js.coffee
+++ b/tutor/app/assets/javascripts/solutions.js.coffee
@@ -34,10 +34,20 @@ IndexNumber = 0
return
return
+# [Debugger: Debug - Story 3.6]
+# Starts the Spinner
+# Parameters: noe
+# Returns: none
+# Author: Mussab ElDash
@start_spin = ->
$('#spinner').attr "class" , "spinner"
return
+# [Debugger: Debug - Story 3.6]
+# Stops the Spinner
+# Parameters: noe
+# Returns: none
+# Author: Mussab ElDash
@stop_spin = ->
$('#spinner').attr "class" , ""
return
From 2f387a205862cea96d1efe7f93c57dc2a73ba538 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Tue, 22 Apr 2014 13:47:34 +0200
Subject: [PATCH 167/526] Adding documentation and indentation for my methods
and views
---
tutor/app/controllers/posts_controller.rb | 18 ++++++++++++
tutor/app/views/posts/edit.html.erb | 2 +-
tutor/app/views/posts/show.html.erb | 36 +++++++++++------------
3 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index 7aed2717..3c52e2af 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -18,6 +18,14 @@ def show
@replies = @post.replies.order("created_at desc")
end
+ # [Edit Post - Story 1.18]
+ # Description: This action takes the passed post id
+ # to be passed to the Edit form.
+ # Parameters:
+ # params[:id]: The post id
+ # Returns:
+ # none
+ # Author: Ahmed Atef
def edit
@post = Post.find(params[:id])
end
@@ -58,6 +66,16 @@ def create
end
end
+ # [Edit Post - Story 1.18]
+ # Description: This action takes the passed parameters from
+ # the edit post form, updates the passed post parameters.If the
+ # update fails the user is redirected to the form
+ # Parameters:
+ # topic_params[]: A list that has all fields entered by the user to in the
+ # Edit_post_form
+ # Returns:
+ # flash[:notice]: A message indicating the success or failure of the creation
+ # Author: Ahmed Atef
def update
@post = Post.find(params[:id])
if @post.update_attributes(post_params)
diff --git a/tutor/app/views/posts/edit.html.erb b/tutor/app/views/posts/edit.html.erb
index 947070d5..435a258e 100644
--- a/tutor/app/views/posts/edit.html.erb
+++ b/tutor/app/views/posts/edit.html.erb
@@ -1,4 +1,4 @@
-
diff --git a/tutor/app/views/posts/show.html.erb b/tutor/app/views/posts/show.html.erb
index 085d8497..7172e590 100644
--- a/tutor/app/views/posts/show.html.erb
+++ b/tutor/app/views/posts/show.html.erb
@@ -1,28 +1,28 @@
<% if current_lecturer %>
<% @userID = current_lecturer.id %>
- <% end %>
+ <% end %>
<% if current_student %>
<% @userID = current_student.id %>
<% end %>
<%if current_teaching_assistant %>
<% @userID = current_teaching_assistant.id %>
<%end%>
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
From 1c12dd810d3a2301f5aa188f4edeee206d52a0f5 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Tue, 22 Apr 2014 20:47:23 +0200
Subject: [PATCH 200/526] Issue #200 Inserting test records in seeds
---
tutor/db/seeds.rb | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index aa0556ef..63fb3d71 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -117,6 +117,11 @@
Attempt.create(failure: true)
Attempt.create(failure: true)
Attempt.create(failure: true)
+
+puts("#-----------------------Recommendations-----------------------")
+ Recommendation.create(problem_id:1, student_id:1, recommender_id:2)
+ Recommendation.create(problem_id:2, student_id:1, recommender_id:2)
+ Recommendation.create(problem_id:5, student_id:1, recommender_id:2)
puts("# -------------------------------------------------------")
From d8565a667464c83f0954b1bbde74dfa6c404449e Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Tue, 22 Apr 2014 20:56:38 +0200
Subject: [PATCH 201/526] Issue #223 query logic
---
tutor/app/models/course.rb | 28 +++++++++++++++++++++++++
tutor/app/models/lecturer.rb | 6 ++++++
tutor/app/models/post.rb | 27 ++++++++++++++++++++++++
tutor/app/models/student.rb | 28 +++++++++++++++++++++++++
tutor/app/models/teaching_assistant.rb | 28 +++++++++++++++++++++++++
tutor/app/models/topic.rb | 29 ++++++++++++++++++++++++++
6 files changed, 146 insertions(+)
diff --git a/tutor/app/models/course.rb b/tutor/app/models/course.rb
index d5655e6a..91c39fd5 100644
--- a/tutor/app/models/course.rb
+++ b/tutor/app/models/course.rb
@@ -45,4 +45,32 @@ def self.simple_search(keyword)
where("name LIKE ? or code LIKE ?", "%#{keyword}%" , "%#{keyword}%") if keyword.present?
end
+ # [Advanced Search - Story 1.23]
+ # search for courses
+ # Parameters: hash of search options
+ # Returns: A hash with search results according to the keyword and other options
+ # Author: Ahmed Elassuty
+ def self.search(params)
+ if params[:keyword].present?
+ case params[:options]
+ when "exactly match"
+ tire.search do
+ query { string "name:#{params[:keyword]}" }
+ end
+ when "includes"
+ tire.search do
+ query { string "name:*#{params[:keyword]}*" }
+ end
+ when "starts with"
+ tire.search do
+ query { string "name:#{params[:keyword]}*" }
+ end
+ when "ends with"
+ tire.search do
+ query { string "name:*#{params[:keyword]}" }
+ end
+ end
+ end
+ end
+
end
diff --git a/tutor/app/models/lecturer.rb b/tutor/app/models/lecturer.rb
index dbb139e9..8dfd2ef4 100644
--- a/tutor/app/models/lecturer.rb
+++ b/tutor/app/models/lecturer.rb
@@ -33,6 +33,12 @@ class Lecturer < ActiveRecord::Base
#Scoops
#Methods
+
+ # [Advanced Search - Story 1.23]
+ # search for lecturers
+ # Parameters: hash of search options
+ # Returns: A hash with search results according to the keyword and other options
+ # Author: Ahmed Elassuty
def self.search(params)
if params[:keyword].present?
case params[:options]
diff --git a/tutor/app/models/post.rb b/tutor/app/models/post.rb
index e9cc4cc9..0afbb25e 100644
--- a/tutor/app/models/post.rb
+++ b/tutor/app/models/post.rb
@@ -16,4 +16,31 @@ class Post < ActiveRecord::Base
#Methods
+ # [Advanced Search - Story 1.23]
+ # search for posts
+ # Parameters: hash of search options
+ # Returns: A hash with search results according to the keyword and other options
+ # Author: Ahmed Elassuty
+ def self.search(params)
+ if params[:keyword].present?
+ case params[:options]
+ when "exactly match"
+ tire.search do
+ query { string "content:#{params[:keyword]}" }
+ end
+ when "includes"
+ tire.search do
+ query { string "content:*#{params[:keyword]}*" }
+ end
+ when "starts with"
+ tire.search do
+ query { string "content:#{params[:keyword]}*" }
+ end
+ when "ends with"
+ tire.search do
+ query { string "content:*#{params[:keyword]}" }
+ end
+ end
+ end
+ end
end
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index 7a1f27f0..4f898efc 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -82,5 +82,33 @@ def getProblemsStatus
end
return res
end
+
+ # [Advanced Search - Story 1.23]
+ # search for students
+ # Parameters: hash of search options
+ # Returns: A hash with search results according to the keyword and other options
+ # Author: Ahmed Elassuty
+ def self.search(params)
+ if params[:keyword].present?
+ case params[:options]
+ when "exactly match"
+ tire.search do
+ query { string "name:#{params[:keyword]}" }
+ end
+ when "includes"
+ tire.search do
+ query { string "name:*#{params[:keyword]}*" }
+ end
+ when "starts with"
+ tire.search do
+ query { string "name:#{params[:keyword]}*" }
+ end
+ when "ends with"
+ tire.search do
+ query { string "name:*#{params[:keyword]}" }
+ end
+ end
+ end
+ end
end
diff --git a/tutor/app/models/teaching_assistant.rb b/tutor/app/models/teaching_assistant.rb
index 6e766568..4df262c2 100644
--- a/tutor/app/models/teaching_assistant.rb
+++ b/tutor/app/models/teaching_assistant.rb
@@ -31,4 +31,32 @@ class TeachingAssistant < ActiveRecord::Base
#Scoops
#Methods
+
+ # [Advanced Search - Story 1.23]
+ # search for students
+ # Parameters: hash of search options
+ # Returns: A hash with search results according to the keyword and other options
+ # Author: Ahmed Elassuty
+ def self.search(params)
+ if params[:keyword].present?
+ case params[:options]
+ when "exactly match"
+ tire.search do
+ query { string "name:#{params[:keyword]}" }
+ end
+ when "includes"
+ tire.search do
+ query { string "name:*#{params[:keyword]}*" }
+ end
+ when "starts with"
+ tire.search do
+ query { string "name:#{params[:keyword]}*" }
+ end
+ when "ends with"
+ tire.search do
+ query { string "name:*#{params[:keyword]}" }
+ end
+ end
+ end
+ end
end
diff --git a/tutor/app/models/topic.rb b/tutor/app/models/topic.rb
index a63cd235..f16c23dc 100644
--- a/tutor/app/models/topic.rb
+++ b/tutor/app/models/topic.rb
@@ -13,4 +13,33 @@ class Topic < ActiveRecord::Base
belongs_to :course
belongs_to :owner, class_name: "Lecturer", foreign_key: :lecturer_id
+ #Methods
+
+ # [Advanced Search - Story 1.23]
+ # search for topics
+ # Parameters: hash of search options
+ # Returns: A hash with search results according to the keyword and other options
+ # Author: Ahmed Elassuty
+ def self.search(params)
+ if params[:keyword].present?
+ case params[:options]
+ when "exactly match"
+ tire.search do
+ query { string "title:#{params[:keyword]}" }
+ end
+ when "includes"
+ tire.search do
+ query { string "title:*#{params[:keyword]}*" }
+ end
+ when "starts with"
+ tire.search do
+ query { string "title:#{params[:keyword]}*" }
+ end
+ when "ends with"
+ tire.search do
+ query { string "title:*#{params[:keyword]}" }
+ end
+ end
+ end
+ end
end
From 9ef63be41ac0376088c498edd85de4b18b610bae Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Tue, 22 Apr 2014 20:57:19 +0200
Subject: [PATCH 202/526] Issue #223 search views
---
.../views/utilities/_advanced_search.html.erb | 63 +++++++++----------
.../app/views/utilities/_result_form.html.erb | 2 +-
.../views/utilities/advanced_search.js.erb | 8 ++-
3 files changed, 39 insertions(+), 34 deletions(-)
diff --git a/tutor/app/views/utilities/_advanced_search.html.erb b/tutor/app/views/utilities/_advanced_search.html.erb
index 82d1cc66..3796d1ea 100644
--- a/tutor/app/views/utilities/_advanced_search.html.erb
+++ b/tutor/app/views/utilities/_advanced_search.html.erb
@@ -11,44 +11,43 @@
+
<% end %>
\ No newline at end of file
From d555a4a0bafdaa6f9d028a6a289bd3169c836174 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Tue, 22 Apr 2014 22:33:51 +0200
Subject: [PATCH 205/526] fixed the button bug, added documentation,woked on
indentation.
---
.../assets/javascripts/teaching_assistants.js | 0
.../teaching_assistants_controller.rb | 36 +++++++++-------
tutor/app/views/courses/edit.html.erb | 4 --
.../views/teaching_assistants/new.html.erb | 41 ++++++++++++-------
tutor/config/routes.rb | 1 +
5 files changed, 50 insertions(+), 32 deletions(-)
create mode 100644 tutor/app/assets/javascripts/teaching_assistants.js
diff --git a/tutor/app/assets/javascripts/teaching_assistants.js b/tutor/app/assets/javascripts/teaching_assistants.js
new file mode 100644
index 00000000..e69de29b
diff --git a/tutor/app/controllers/teaching_assistants_controller.rb b/tutor/app/controllers/teaching_assistants_controller.rb
index 4a8eab61..cb4d8e59 100644
--- a/tutor/app/controllers/teaching_assistants_controller.rb
+++ b/tutor/app/controllers/teaching_assistants_controller.rb
@@ -1,8 +1,21 @@
class TeachingAssistantsController < ApplicationController
-
+# [Add TA - Story 1.4]
+# this action renders the form and sets the value for checkbox
+# Parameters:
+# check : contains the value from the previous instance of the form
+# Returns: None
+# Author: Muhammad Mamdouh
def new
+ if(@checkbox == nil)
+ @checkbox = true
+ end
+ @checkbox = !params[:check]
end
-
+# [Add TA - Story 1.5,1.6]
+# Adds the TA selected from the dropdown list in the view to the course and to the lecturer's history
+# Parameters: teaching_assistant_id , course_id
+# Returns: None
+# Author: Muhammad Mamdouh
def create
begin
@teaching_assistant = TeachingAssistant.find_by_id(params[:teaching_assistant][:id])
@@ -16,21 +29,16 @@ def create
That or something went terribly wrong on our side. Either way lamo2a5za.'
redirect_to :action => 'new'
end
-
-
end
-
-
+# [Add TA - Story /]
+# lists the TAs added to the course.
+# Parameters: course_id
+# Returns:
+# @course
+# @course_teaching_assistants
+# Author: Muhammad Mamdouh
def index
@course = Course.find(params[:course_id])
@course_teaching_assistants = @course.TAs.order('name')
end
-
-
-
-
-
-
-
-
end
diff --git a/tutor/app/views/courses/edit.html.erb b/tutor/app/views/courses/edit.html.erb
index d0ff2964..d2f8c6a3 100644
--- a/tutor/app/views/courses/edit.html.erb
+++ b/tutor/app/views/courses/edit.html.erb
@@ -20,10 +20,6 @@
:course_id => @course.id}, class: "btn btn-success" , style: "float: left; margin-left: 15px", :method => :get%>
+ <%= p.hidden_field :title, value: @problem.title %>
+<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/_failure_options.html.erb b/tutor/app/views/problems/_failure_options.html.erb
index 27410fa3..616f8d6c 100644
--- a/tutor/app/views/problems/_failure_options.html.erb
+++ b/tutor/app/views/problems/_failure_options.html.erb
@@ -1,3 +1 @@
-
-<%= button_to 'Abort and Delete Problem', problem_destroy_problem_path(:problem_id => @problem.id), method: :get, :confirm => 'Are you sure you want to delete this problem?' %>
<%= button_to 'Save as Incomplete', track_path(:id => @problem.track_id), method: :get %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/_flash.html.erb b/tutor/app/views/problems/_flash.html.erb
new file mode 100644
index 00000000..beb8b998
--- /dev/null
+++ b/tutor/app/views/problems/_flash.html.erb
@@ -0,0 +1,3 @@
+<% if flash[:notice] %>
+
<%= flash[:notice] %>
+<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/_title.html.erb b/tutor/app/views/problems/_title.html.erb
new file mode 100644
index 00000000..71dbe155
--- /dev/null
+++ b/tutor/app/views/problems/_title.html.erb
@@ -0,0 +1,8 @@
+
<%= @problem.title %>
+<%= form_for :Problem, url: problem_path(@problem), method: :patch, remote: true do |p| %>
+
+ <%= p.text_field :title %>
+ <%= p.hidden_field :description, value: @problem.description %>
+ <%= p.submit('update title') %>
+
+<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/edit.html.erb b/tutor/app/views/problems/edit.html.erb
index e8bba23e..1b0932f0 100644
--- a/tutor/app/views/problems/edit.html.erb
+++ b/tutor/app/views/problems/edit.html.erb
@@ -1,24 +1,27 @@
-
<%= render partial: "test_cases/index" %>
<%= render partial: "model_answers/new" %>
@@ -26,6 +29,8 @@ and a paragraph to view the problem description of the instance variable @proble
<%= render partial: "problems/failure_options" %>
-<% if flash[:notice] %>
-
<%= flash[:notice] %>
-<% end %>
+
+ <% if flash[:notice] %>
+
<%= flash[:notice] %>
+ <% end %>
+
diff --git a/tutor/app/views/problems/update.js.erb b/tutor/app/views/problems/update.js.erb
new file mode 100644
index 00000000..1709cc5c
--- /dev/null
+++ b/tutor/app/views/problems/update.js.erb
@@ -0,0 +1,4 @@
+$('#div1').html("<%= escape_javascript(render 'problems/title') %>");
+$('#div2').html("<%= escape_javascript(render 'problems/description') %>");
+
+$('#div4').html("<%= escape_javascript(render 'problems/flash') %>");
\ No newline at end of file
diff --git a/tutor/db/development.sqlite3 b/tutor/db/development.sqlite3
index cdf0f15783ba35b3bc67b2141177f8cabc9605b4..7bbdae58d1ea289a53d9aa5fad548589ab99060e 100644
GIT binary patch
delta 385
zcmZp8z|-)6XM!}N%S0JxMwg8V+x-}MHcR-wJHT;)fj@!o0Pls(f(nOtMH_RO#TY<<
zmx002(YKKm$Yh-UOqNky&`80^z{i8Jp`F7@Hdy8X(IUS{WHy85-)DnV1@ynMCja
zjZ{W6vM95lBr`t`Zn8Cs(S}wACRT
Date: Tue, 22 Apr 2014 23:25:04 +0200
Subject: [PATCH 214/526] Issue #221 prepare autocomplete
---
tutor/app/assets/javascripts/application.js | 6 +++++-
tutor/app/controllers/utilities_controller.rb | 17 +++++++++++++++++
tutor/app/views/layouts/application.html.erb | 2 +-
tutor/config/routes.rb | 1 +
4 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/tutor/app/assets/javascripts/application.js b/tutor/app/assets/javascripts/application.js
index 0649b784..ec7edd09 100644
--- a/tutor/app/assets/javascripts/application.js
+++ b/tutor/app/assets/javascripts/application.js
@@ -14,4 +14,8 @@
//= require jquery_ujs
//= require turbolinks
//= require_tree .
-//= require jquery.tokeninput
\ No newline at end of file
+//= require jquery.tokeninput
+
+$(document).ready(function () {
+ $("#search_txt_bar").tokenInput("/utilities/auto_complete");
+});
\ No newline at end of file
diff --git a/tutor/app/controllers/utilities_controller.rb b/tutor/app/controllers/utilities_controller.rb
index 3dfd88c9..efccdbc0 100644
--- a/tutor/app/controllers/utilities_controller.rb
+++ b/tutor/app/controllers/utilities_controller.rb
@@ -16,6 +16,11 @@ def simple_search
end
end
+ # [Advanced Search - Story 1.23]
+ # search for users and courses and topics
+ # Parameters: search options
+ # Returns: A hashes with search results according to the keyword
+ # Author: Ahmed Elassuty
def advanced_search
if params[:lecturers].present?
@lecturers = Lecturer.search(params)
@@ -40,4 +45,16 @@ def advanced_search
format.js
end
end
+
+ # [Simple Search - Story 1.22]
+ # auto complete search keyword for users and courses
+ # Parameters: search
+ # Returns: A hashes with search results according to the keyword
+ # Author: Ahmed Elassuty
+ def auto_complete
+ @objects = Lecturer.simple_search(params[:q]).take(1)
+ respond_to do |format|
+ format.json {render :template => 'utilities/auto_complete',:formats => [],:handlers => [:json_builder],:layout=>false}
+ end
+ end
end
diff --git a/tutor/app/views/layouts/application.html.erb b/tutor/app/views/layouts/application.html.erb
index 37165e56..27101bab 100644
--- a/tutor/app/views/layouts/application.html.erb
+++ b/tutor/app/views/layouts/application.html.erb
@@ -7,7 +7,7 @@
CoolSoft - Java Tutor
- <%= stylesheet_link_tag "application", "bootstrap", :media => "all"%>
+ <%= stylesheet_link_tag "application", "bootstrap","token-input", :media => "all"%>
<%= javascript_include_tag "application","bootstrap", "jquery"%>
<%= csrf_meta_tags%>
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index c4ba2652..8c0132ce 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -2,6 +2,7 @@
get "utilities/simple_search"
get "utilities/advanced_search"
+ get "utilities/auto_complete"
devise_for :teaching_assistants
devise_for :students
devise_for :lecturers
From 902979c53246983595626ecdb3863bb83df10906 Mon Sep 17 00:00:00 2001
From: AbdullRahman ElHusseini
Date: Tue, 22 Apr 2014 23:26:14 +0200
Subject: [PATCH 215/526] Issue #208 documentation and fixing indentation
---
tutor/app/controllers/problems_controller.rb | 6 +++---
tutor/app/views/problems/_flash.html.erb | 2 +-
tutor/app/views/problems/_title.html.erb | 1 -
tutor/app/views/problems/edit.html.erb | 6 +++---
4 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/tutor/app/controllers/problems_controller.rb b/tutor/app/controllers/problems_controller.rb
index e085aadc..f8366479 100644
--- a/tutor/app/controllers/problems_controller.rb
+++ b/tutor/app/controllers/problems_controller.rb
@@ -91,11 +91,11 @@ def update
format.html {redirect_to :action => "edit", :id => @problem.id}
format.js
end
- else
+ else
flash.keep[:notice] = "Update paramater is empty"
respond_to do |format|
format.html {redirect_to :action => "edit", :id => @problem.id}
- format.js
+ format.js
end
end
end
@@ -121,7 +121,7 @@ def done
flash.keep[:notice] = ""
redirect_to :controller => "tracks", :action => "show", :id => @problem.track_id
end
- end
+ end
# [Add Problem - 4.4]
# Passes the input of the form as paramaters for create action to use it
diff --git a/tutor/app/views/problems/_flash.html.erb b/tutor/app/views/problems/_flash.html.erb
index beb8b998..ff4bdef0 100644
--- a/tutor/app/views/problems/_flash.html.erb
+++ b/tutor/app/views/problems/_flash.html.erb
@@ -1,3 +1,3 @@
<% if flash[:notice] %>
-
<%= flash[:notice] %>
+
<%= flash[:notice] %>
<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/_title.html.erb b/tutor/app/views/problems/_title.html.erb
index 71dbe155..5de7580c 100644
--- a/tutor/app/views/problems/_title.html.erb
+++ b/tutor/app/views/problems/_title.html.erb
@@ -4,5 +4,4 @@
<%= p.text_field :title %>
<%= p.hidden_field :description, value: @problem.description %>
<%= p.submit('update title') %>
-
<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/edit.html.erb b/tutor/app/views/problems/edit.html.erb
index 1b0932f0..b9d28715 100644
--- a/tutor/app/views/problems/edit.html.erb
+++ b/tutor/app/views/problems/edit.html.erb
@@ -11,7 +11,7 @@ and a paragraph to view the problem description of the instance variable @proble
<% end %>
-
+
<%= @problem.description %>
<%= form_for :Problem, url: problem_path(@problem), method: :patch, remote: true do |p| %>
@@ -21,7 +21,7 @@ and a paragraph to view the problem description of the instance variable @proble
<%= p.hidden_field :title, value: @problem.title %>
<% end %>
-
+
<%= render partial: "test_cases/index" %>
<%= render partial: "model_answers/new" %>
@@ -33,4 +33,4 @@ and a paragraph to view the problem description of the instance variable @proble
<% if flash[:notice] %>
<%= flash[:notice] %>
<% end %>
-
+
From 45568f4bd54eca59aba41318b93e3eb359158496 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Tue, 22 Apr 2014 23:26:27 +0200
Subject: [PATCH 216/526] generated acknowledgement controllers , routes and
added a basic form
---
.../javascripts/acknowledgements.js.coffee | 3 +++
.../stylesheets/acknowledgements.css.scss | 3 +++
.../acknowledgements_controller.rb | 27 +++++++++++++++++++
tutor/app/helpers/acknowledgements_helper.rb | 2 ++
tutor/app/views/acknowledgements/new.html.erb | 19 +++++++++++++
tutor/app/views/courses/edit.html.erb | 7 ++++-
tutor/config/routes.rb | 1 +
.../acknowledgements_controller_test.rb | 7 +++++
.../helpers/acknowledgements_helper_test.rb | 4 +++
9 files changed, 72 insertions(+), 1 deletion(-)
create mode 100644 tutor/app/assets/javascripts/acknowledgements.js.coffee
create mode 100644 tutor/app/assets/stylesheets/acknowledgements.css.scss
create mode 100644 tutor/app/controllers/acknowledgements_controller.rb
create mode 100644 tutor/app/helpers/acknowledgements_helper.rb
create mode 100644 tutor/app/views/acknowledgements/new.html.erb
create mode 100644 tutor/test/controllers/acknowledgements_controller_test.rb
create mode 100644 tutor/test/helpers/acknowledgements_helper_test.rb
diff --git a/tutor/app/assets/javascripts/acknowledgements.js.coffee b/tutor/app/assets/javascripts/acknowledgements.js.coffee
new file mode 100644
index 00000000..24f83d18
--- /dev/null
+++ b/tutor/app/assets/javascripts/acknowledgements.js.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/tutor/app/assets/stylesheets/acknowledgements.css.scss b/tutor/app/assets/stylesheets/acknowledgements.css.scss
new file mode 100644
index 00000000..c90441b1
--- /dev/null
+++ b/tutor/app/assets/stylesheets/acknowledgements.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the Acknowledgements controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/tutor/app/controllers/acknowledgements_controller.rb b/tutor/app/controllers/acknowledgements_controller.rb
new file mode 100644
index 00000000..1f849a08
--- /dev/null
+++ b/tutor/app/controllers/acknowledgements_controller.rb
@@ -0,0 +1,27 @@
+class AcknowledgementsController < ApplicationController
+
+ def new
+ end
+
+ def create
+ end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+end
diff --git a/tutor/app/helpers/acknowledgements_helper.rb b/tutor/app/helpers/acknowledgements_helper.rb
new file mode 100644
index 00000000..cb65d0dd
--- /dev/null
+++ b/tutor/app/helpers/acknowledgements_helper.rb
@@ -0,0 +1,2 @@
+module AcknowledgementsHelper
+end
diff --git a/tutor/app/views/acknowledgements/new.html.erb b/tutor/app/views/acknowledgements/new.html.erb
new file mode 100644
index 00000000..fa9926bb
--- /dev/null
+++ b/tutor/app/views/acknowledgements/new.html.erb
@@ -0,0 +1,19 @@
+
Acknowledge A student
+
+
+<% if flash[:notice] -%>
+
<%= flash[:notice] %>
+<% end %>
+
+
+<%= form_for :acknowledgement, url: {action: "create"} do |f| %>
+
+
+<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/courses/edit.html.erb b/tutor/app/views/courses/edit.html.erb
index 2a259c5f..81e97872 100644
--- a/tutor/app/views/courses/edit.html.erb
+++ b/tutor/app/views/courses/edit.html.erb
@@ -16,7 +16,12 @@
-
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index 378532f4..9e1aa367 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -12,6 +12,7 @@
# get 'products/index'
post 'solutions/compile_solution' => 'problems#show'
post 'courses/new' => 'courses#new'
+ post 'courses/share' => 'courses#share'
get 'courses/sign_up'
post 'solutions/execute' => 'problems#show'
post 'debuggers/:id' => 'debuggers#start'
From fab5932fd7095e27ea15cad506fdac7a1be56399 Mon Sep 17 00:00:00 2001
From: Nadine Adel
Date: Wed, 23 Apr 2014 02:43:40 +0200
Subject: [PATCH 246/526] Issue #183 editing view new
---
.../controllers/model_answers_controller.rb | 94 +++++++++++++++----
tutor/app/views/model_answers/_new.html.erb | 19 ----
tutor/app/views/model_answers/new.html.erb | 37 ++++++++
tutor/app/views/problems/edit.html.erb | 2 +-
4 files changed, 113 insertions(+), 39 deletions(-)
delete mode 100644 tutor/app/views/model_answers/_new.html.erb
create mode 100644 tutor/app/views/model_answers/new.html.erb
diff --git a/tutor/app/controllers/model_answers_controller.rb b/tutor/app/controllers/model_answers_controller.rb
index f1f15621..f8b0349e 100644
--- a/tutor/app/controllers/model_answers_controller.rb
+++ b/tutor/app/controllers/model_answers_controller.rb
@@ -1,41 +1,92 @@
class ModelAnswersController < ApplicationController
+ @@problemid = nil
# [Add answer story 4.6]
# It creates the new answer.
# Parameters:
+ # @problem:To fetch the problem to which the answer is added.
+ # @@problemid :this is a global variable to save the id of the problem to which the answer is added to be able to use
+ # it in another views.
# @answer: the new answer the user enters.
# @answers: All the previous answers that had been entered before.
# Return : none
# Author: Nadine Adel
def new
- @answers = ModelAnswer.all
- @answer = ModelAnswer.new
+ @problem = Problem.find(params[:problem_id])
+ @@problemid = params[:problem_id]
+ session[:problem_id] = params[:problem_id]
+ if(@new_answer == nil)
+ @new_answer =ModelAnswer.new
+ end
end
# [Add answer story 4.6]
- # The new answer is saved.
+ # The new answer is saved and check that the user is a lecturer or TA.
# Parameters:
- # @answer:answer provided by the user.
+ # @new_answer:answer provided by the user.
+ # @problems:The problem to which the answer is linked.
# Returns: Returns a message if the answer is added and another message if answer was not added.
# Author: Nadine Adel
def create
+ @new_answer = ModelAnswer.new
+ @new_answer.title = post_params[:title]
+ @new_answer.answer = post_params[:answer]
+ @new_answer.problem_id = session[:problem_id]
+ @problems =Problem.find_by_id(session[:problem_id])
if lecturer_signed_in?
- @answer = ModelAnswer.new(post_params)
- @answer.owner_id = current_lecturer.id
- @answer.owner_type = "lecturer"
+ @new_answer.owner_id = current_lecturer.id
+ @new_answer.owner_type = "lecturer"
elsif teaching_assistant_signed_in?
- @answer = ModelAnswer.new(post_params)
- @answer.owner_id = current_teaching_assistant.id
- @answer.owner_type = "teaching assistant"
+ @new_answer.owner_id = current_teaching_assistant.id
+ @new_answer.owner_type = "teaching assistant"
end
- if @answer.save
- flash[:notice] = "Your Answer is now added"
- redirect_to :controller => 'problems', :action => 'edit', :id => @answer.problem_id
+ if @new_answer.save
+ flash[:success_creation]= "Answer added."
+ @problems.model_answers << @new_answer
+ redirect_to :controller => 'model_answers', :action => 'edit', :id => @new_answer.id
else
- flash[:notice] = "Your Answer can not be added"
- redirect_to :controller => 'problems', :action => 'edit', :id => @answer.problem_id
+ render :action=>'new' , :problem_id => post_params[:problem_id]
end
end
+ # [Edit answer story 4.7]
+ # Answer that has been created before is edited
+ # Parameters:
+ # @answer:answerthat is being edited.
+ # @problem:The problem to which the answer is linked.
+ # @tips:Tips that are linked to the answer being edited.
+ # @tips_check:used to check the type of Hint.
+ # @hints:Hints that are linked to the answer being edited.
+ # @hints_check:used to check the type of Hint.
+ # Returns: Returns a message if the answer is edited and another message if answer was not edited.
+ # Author: Nadine Adel
+
+ def edit
+ @answer = ModelAnswer.find(params[:id])
+ @problem = Problem.find(@answer.problem_id)
+ @tips = @answer.hints
+ @tips_check = @answer.hints
+ @hints = @answer.hints
+ @hints_check = @answer.hints
+ end
+
+ # [Edit answer story 4.7]
+ # Answer is updated in the database.
+ # Parameters:
+ # @answer:answer that is being updated.
+ # Returns: None.
+ # Author: Nadine Adel
+
+ def update
+ @answer = ModelAnswer.find(params[:id])
+ if @answer.update_attributes(post_params)
+ flash[:notice] = "Your Answer is now updated"
+ redirect_to :controller => 'problems', :action => 'edit', :id => @@problemid
+ else
+ session[:errorsupdate] = @answer.errors.full_messages
+ redirect_to :back
+ end
+ end
+
# [Add answer story 4.6]
# It shows answer that was entered before.
# Parameters:
@@ -44,26 +95,31 @@ def create
# Author: Nadine Adel
def show
@answer = ModelAnswer.find(params[:problem_id])
+
end
# [Add answer story 4.6]
# It shows all the answers that are saved in the database.
# Parameters:
- # @answers:previous answer that are saved in the database.
- # Return : none
+ # @answers:previous answers that are saved in the database.
+ # @problem:problem to which the current answer is added.
+ # Returns : none
# Author: Nadine Adel
def index
+ @problem =Problem.find_by_id(params[:id])
@answers = ModelAnswer.all
end
# [Add answer story 4.6]
# It requires the attributes from the form that we are interested in.
# Parameters:
- # @answer:the answer that the user wants to add.
+ # None
# Return : none
# Author: Nadine Adel
private
def post_params
- params.require(:model_answer).permit(:answer, :problem_id)
+ params.require(:model_answer).permit(:title,:answer,:problem_id)
end
+
+
end
\ No newline at end of file
diff --git a/tutor/app/views/model_answers/_new.html.erb b/tutor/app/views/model_answers/_new.html.erb
deleted file mode 100644
index c2f3721f..00000000
--- a/tutor/app/views/model_answers/_new.html.erb
+++ /dev/null
@@ -1,19 +0,0 @@
-<%= form_for :model_answer, url: model_answers_path do |f| %>
-
-<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/model_answers/new.html.erb b/tutor/app/views/model_answers/new.html.erb
new file mode 100644
index 00000000..f1003869
--- /dev/null
+++ b/tutor/app/views/model_answers/new.html.erb
@@ -0,0 +1,37 @@
+
+<%= form_for :model_answer, url: model_answers_path do |f| %>
+
+<% if @new_answer.errors.any? %>
+
+
<%= pluralize(@new_answer.errors.count, "error") %> prohibited this course from being saved:
+
+ <% @new_answer.errors.full_messages.each do |msg| %>
+
Output:
- <% if flash[:exp] %>
+ <% if flash[:exp] || flash[:exp_2] %>
@@ -73,6 +73,11 @@
<%= flash[:msg] %>
+ <% if flash[:msg_2] %>
+ <% flash[:msg_2].each do |message|%>
+
<%= message%>
+ <% end %>
+ <% end %>
@@ -80,6 +85,11 @@
<%= flash[:exp] %>
+ <% if flash[:exp_2] %>
+ <% flash[:exp_2].each do |message|%>
+
<%= message %>
+ <% end %>
+ <% end %>
<% else %>
@@ -95,13 +105,14 @@
-->
- <% if flash[:compiler_success] %>
- <% flash[:compiler_success].each do |message|%>
+
<%= flash[:compiler_success] %>
+ <% if flash[:compiler_success_2] %>
+ <% flash[:compiler_success_2].each do |message|%>
<%= message %>
<% end %>
<% end %>
- <% if flash[:compiler_fail] %>
- <% flash[:compiler_fail].each do |message|%>
+ <% if flash[:compiler_fail_2] %>
+ <% flash[:compiler_fail_2].each do |message|%>
<%= message %>
<% end %>
<% end %>
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index 5d0cbbcb..961f80eb 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -69,8 +69,8 @@
TestCase.create(output: "hello World 1", input:"x = 0")
TestCase.create(output: "hello World 2", input:"x = 1")
TestCase.create(output: "hello World 3", input:"x = 2")
- TestCase.create(output: "5", input:"10 2")
- TestCase.create(output: "2.5", input:"5 2")
+ TestCase.create(output: "5\n", input:"10 2")
+ TestCase.create(output: "2.5\n", input:"5 2")
TestCase.create(output: "x", input:"10 0")
puts("# -----------------------Method Parameters---------------------------")
From 389043cc80a2ab33e16df69ac39061f1d7ccb293 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Wed, 23 Apr 2014 14:22:10 +0200
Subject: [PATCH 266/526] Issue #200 Adding documentation and Editing routes
---
tutor/app/models/student.rb | 6 ++++++
tutor/app/views/layouts/_right_side_bar.html.erb | 5 +++++
tutor/config/routes.rb | 1 -
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index a011587b..d7ea4803 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -76,6 +76,12 @@ def getProblemsStatus
return res
end
+ # [Get Recommended Problems - Story 5.6]
+ # Gets the recommended problems for this student by classmates
+ # Parameters: none
+ # Returns: A hash with 'problem_id' as a key and a value of a hash containing
+ # 'recommender_name' and 'problem_title'
+ # Author: Mohab Ghanim
def getClassMatesRecommendations
recommended_problems = Recommendation.where(:student_id => self.id)
recommended_problems_hash = Hash.new
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 0f7bb300..0609fe55 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -4,6 +4,11 @@
# Author: Ahmed Elassuty
-->
+
<% if student_signed_in? %>
<% recommended_problems = current_student.getClassMatesRecommendations
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index 9d8935e4..e9d7079c 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -29,7 +29,6 @@
resources :solutions
resources :problems
resources :topics
- resources :profile
# Example resource route with options:
# resources :products do
From 7daf6b24ffd23add3f2b8500d4491c2b12d929c3 Mon Sep 17 00:00:00 2001
From: mohamedsaeed93
Date: Wed, 23 Apr 2014 14:36:58 +0200
Subject: [PATCH 267/526] fixing indentations
---
tutor/app/assets/javascripts/solutions.js.coffee | 1 +
tutor/app/controllers/solutions_controller.rb | 13 -------------
tutor/app/models/solution.rb | 13 ++-----------
tutor/app/views/solutions/_new.html.erb | 4 ----
4 files changed, 3 insertions(+), 28 deletions(-)
diff --git a/tutor/app/assets/javascripts/solutions.js.coffee b/tutor/app/assets/javascripts/solutions.js.coffee
index df4fce9f..e9085bb1 100644
--- a/tutor/app/assets/javascripts/solutions.js.coffee
+++ b/tutor/app/assets/javascripts/solutions.js.coffee
@@ -145,6 +145,7 @@ index_number = 0
index_number = 0;
variables = null;
+#To be Used when changing to ajax
# [Compiler: Validate - Story 3.5]
# submits a solution in the form without refreshing
# using ajax showing an alert box for success and failure scenarios
diff --git a/tutor/app/controllers/solutions_controller.rb b/tutor/app/controllers/solutions_controller.rb
index 573824e5..a8a10532 100644
--- a/tutor/app/controllers/solutions_controller.rb
+++ b/tutor/app/controllers/solutions_controller.rb
@@ -14,19 +14,6 @@ def create
redirect_to :back and return
end
submit_no_ajax
- # solution = Solution.new({problem_id: params[:problem_id], code: params[:code],
- # time: params[:time]})
- # solution.student_id = current_student.id
- # solution.length = solution.code.length
- # testcases = solution.problem.test_cases
- # solution.status = 0
- # solution.save
- # #file = @solution.file_name
- # #response_message = Solution.validate(solution.code , testcases , file)
- # response_message = {:success => ["Success"], :failure => ["Failure"]}
- # #solution.status = response_message[:status]
- # #solution.save
- # render json: response_message
elsif params[:commit] == 'Compile'
compile_solution
redirect_to :back and return
diff --git a/tutor/app/models/solution.rb b/tutor/app/models/solution.rb
index 73678a7d..93994d40 100644
--- a/tutor/app/models/solution.rb
+++ b/tutor/app/models/solution.rb
@@ -12,8 +12,7 @@ class Solution < ActiveRecord::Base
# Checks the validity of a submitted solution
# and show the runtime and logic errors if exist
# Parameters:
- # code: the code written in the editor from the form_for
- # testcases: the testcases for the given problem
+ # problem_id: id of the problem being answered
# file: the name of the file which is compiled successfully
# without errors
# Returns: a hash response containing status for the solution,
@@ -22,8 +21,6 @@ class Solution < ActiveRecord::Base
def self.validate(file, problem_id)
response = {status: 0, success: [], runtime_error: [] ,runtime_error_exp: [] , logic_error: []}
testcases = Problem.find_by_id(problem_id).test_cases
- #compile_result = Compiler.compile(code)
- #if(compile_result[:sucess])
testcases.each do |testcase|
input = testcase.input
expected_output = testcase.output
@@ -46,17 +43,11 @@ def self.validate(file, problem_id)
response[:status] = 4
response[:runtime_error] << runtime_error[:error]
response[:runtime_error_exp] << runtime_error[:explanation]
- #response[:runtime_error] = runtime_error
end
end
if response[:status] == 1
response[:success] << "Your Solution is correct, Passed"
end
- #else
- #compile_message = Compiler.compileFeedback(compile_result)
- #response[:status] = 2
- #response[:failure] << compile_message
- #end
return response
end
@@ -130,7 +121,7 @@ def class_file_name(prepend_path = false, append_extension = false)
STATUS_COMPILED_WITHOUT_ERRORS = 3
STATUS_EXECUTED_WITH_RUNTIME_ERRORS = 4
STATUS_EXECUTED_WITH_LOGIC_ERRORS = 5
-
JAVA_PATH = 'students_solutions/Java/'
CLASS_PATH = 'students_solutions/Class/'
+
end
\ No newline at end of file
diff --git a/tutor/app/views/solutions/_new.html.erb b/tutor/app/views/solutions/_new.html.erb
index 21a3570a..2a4a4c3e 100644
--- a/tutor/app/views/solutions/_new.html.erb
+++ b/tutor/app/views/solutions/_new.html.erb
@@ -101,10 +101,6 @@
Console:
+<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/layouts/application.html.erb b/tutor/app/views/layouts/application.html.erb
index 27101bab..3a6dd1b1 100644
--- a/tutor/app/views/layouts/application.html.erb
+++ b/tutor/app/views/layouts/application.html.erb
@@ -13,35 +13,38 @@
-
-
-
\ No newline at end of file
From 279ea8e69164f69a04c9b5ff35c679d06bf8ab9f Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Wed, 23 Apr 2014 19:22:43 +0200
Subject: [PATCH 291/526] Fixed indentation in the method destroy
---
tutor/app/controllers/problems_controller.rb | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/tutor/app/controllers/problems_controller.rb b/tutor/app/controllers/problems_controller.rb
index 929994d1..edd45a7e 100644
--- a/tutor/app/controllers/problems_controller.rb
+++ b/tutor/app/controllers/problems_controller.rb
@@ -92,10 +92,11 @@ def new
# flash[:notice]: A message indicating the success of the deletion
# Author: Ahmed Atef
def destroy
- @track = Problem.find_by_id(params[:id]).track_id
- if Problem.find_by_id(params[:id]).destroy
- flash[:notice] = "Problem successfully Deleted"
- redirect_to(:controller => 'tracks' , :action => 'show' ,:id => @track)
- end
+ @track = Problem.find_by_id(params[:id]).track_id
+ if Problem.find_by_id(params[:id]).destroy
+ flash[:notice] = "Problem successfully Deleted"
+ redirect_to(:controller => 'tracks' , :action => 'show' ,:id => @track)
+ end
end
+
end
\ No newline at end of file
From fc5ac6fb171c1aab5dbf73109b6ebc2c00f80124 Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Wed, 23 Apr 2014 19:26:40 +0200
Subject: [PATCH 292/526] Issue #223 remove unneeded spaces
---
tutor/app/models/concerns/searchable.rb | 3 +--
tutor/app/models/course.rb | 10 +++++-----
tutor/app/models/lecturer.rb | 8 ++++----
tutor/app/models/post.rb | 8 ++++----
tutor/app/models/student.rb | 8 ++++----
tutor/app/models/teaching_assistant.rb | 8 ++++----
tutor/app/models/topic.rb | 8 ++++----
7 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/tutor/app/models/concerns/searchable.rb b/tutor/app/models/concerns/searchable.rb
index 827f1f05..88552233 100644
--- a/tutor/app/models/concerns/searchable.rb
+++ b/tutor/app/models/concerns/searchable.rb
@@ -7,11 +7,10 @@ module Searchable
# Returns: A hash with search results according to the keyword
# Author: Ahmed Elassuty
-
#class Methods
module ClassMethods
def simple_search(keyword)
- self.where("name LIKE ? or email LIKE ?", "%#{keyword}%" , "%#{keyword}%") if keyword.present?
+ self.where("name LIKE ? or email LIKE ?", "%#{keyword}%", "%#{keyword}%") if keyword.present?
end
end
diff --git a/tutor/app/models/course.rb b/tutor/app/models/course.rb
index 91c39fd5..451911e8 100644
--- a/tutor/app/models/course.rb
+++ b/tutor/app/models/course.rb
@@ -42,7 +42,7 @@ def can_edit(user)
# Returns: A hash with search results according to the keyword
# Author: Ahmed Elassuty
def self.simple_search(keyword)
- where("name LIKE ? or code LIKE ?", "%#{keyword}%" , "%#{keyword}%") if keyword.present?
+ where("name LIKE ? or code LIKE ?", "%#{keyword}%", "%#{keyword}%") if keyword.present?
end
# [Advanced Search - Story 1.23]
@@ -54,19 +54,19 @@ def self.search(params)
if params[:keyword].present?
case params[:options]
when "exactly match"
- tire.search do
+ tire.search do
query { string "name:#{params[:keyword]}" }
end
when "includes"
- tire.search do
+ tire.search do
query { string "name:*#{params[:keyword]}*" }
end
when "starts with"
- tire.search do
+ tire.search do
query { string "name:#{params[:keyword]}*" }
end
when "ends with"
- tire.search do
+ tire.search do
query { string "name:*#{params[:keyword]}" }
end
end
diff --git a/tutor/app/models/lecturer.rb b/tutor/app/models/lecturer.rb
index 8dfd2ef4..c6682757 100644
--- a/tutor/app/models/lecturer.rb
+++ b/tutor/app/models/lecturer.rb
@@ -43,19 +43,19 @@ def self.search(params)
if params[:keyword].present?
case params[:options]
when "exactly match"
- tire.search do
+ tire.search do
query { string "name:#{params[:keyword]}" }
end
when "includes"
- tire.search do
+ tire.search do
query { string "name:*#{params[:keyword]}*" }
end
when "starts with"
- tire.search do
+ tire.search do
query { string "name:#{params[:keyword]}*" }
end
when "ends with"
- tire.search do
+ tire.search do
query { string "name:*#{params[:keyword]}" }
end
end
diff --git a/tutor/app/models/post.rb b/tutor/app/models/post.rb
index 4525f378..85ac2e15 100644
--- a/tutor/app/models/post.rb
+++ b/tutor/app/models/post.rb
@@ -25,19 +25,19 @@ def self.search(params)
if params[:keyword].present?
case params[:options]
when "exactly match"
- tire.search do
+ tire.search do
query { string "title:#{params[:keyword]}" }
end
when "includes"
- tire.search do
+ tire.search do
query { string "title:*#{params[:keyword]}*" }
end
when "starts with"
- tire.search do
+ tire.search do
query { string "title:#{params[:keyword]}*" }
end
when "ends with"
- tire.search do
+ tire.search do
query { string "title:*#{params[:keyword]}" }
end
end
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index 4f898efc..94b9e00d 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -92,19 +92,19 @@ def self.search(params)
if params[:keyword].present?
case params[:options]
when "exactly match"
- tire.search do
+ tire.search do
query { string "name:#{params[:keyword]}" }
end
when "includes"
- tire.search do
+ tire.search do
query { string "name:*#{params[:keyword]}*" }
end
when "starts with"
- tire.search do
+ tire.search do
query { string "name:#{params[:keyword]}*" }
end
when "ends with"
- tire.search do
+ tire.search do
query { string "name:*#{params[:keyword]}" }
end
end
diff --git a/tutor/app/models/teaching_assistant.rb b/tutor/app/models/teaching_assistant.rb
index 9945f9a2..e4e60100 100644
--- a/tutor/app/models/teaching_assistant.rb
+++ b/tutor/app/models/teaching_assistant.rb
@@ -41,19 +41,19 @@ def self.search(params)
if params[:keyword].present?
case params[:options]
when "exactly match"
- tire.search do
+ tire.search do
query { string "name:#{params[:keyword]}" }
end
when "includes"
- tire.search do
+ tire.search do
query { string "name:*#{params[:keyword]}*" }
end
when "starts with"
- tire.search do
+ tire.search do
query { string "name:#{params[:keyword]}*" }
end
when "ends with"
- tire.search do
+ tire.search do
query { string "name:*#{params[:keyword]}" }
end
end
diff --git a/tutor/app/models/topic.rb b/tutor/app/models/topic.rb
index f16c23dc..ea9ce72b 100644
--- a/tutor/app/models/topic.rb
+++ b/tutor/app/models/topic.rb
@@ -24,19 +24,19 @@ def self.search(params)
if params[:keyword].present?
case params[:options]
when "exactly match"
- tire.search do
+ tire.search do
query { string "title:#{params[:keyword]}" }
end
when "includes"
- tire.search do
+ tire.search do
query { string "title:*#{params[:keyword]}*" }
end
when "starts with"
- tire.search do
+ tire.search do
query { string "title:#{params[:keyword]}*" }
end
when "ends with"
- tire.search do
+ tire.search do
query { string "title:*#{params[:keyword]}" }
end
end
From 1b1377ae5b2a4e06fa735c5506daeada834d721d Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Wed, 23 Apr 2014 19:31:44 +0200
Subject: [PATCH 293/526] Issue #223 follow conventions
---
tutor/app/controllers/utilities_controller.rb | 3 ++-
.../views/utilities/_advanced_search.html.erb | 16 ++++++++--------
tutor/app/views/utilities/_result_form.html.erb | 9 +++++----
.../app/views/utilities/_simple_search.html.erb | 15 ++++++++-------
.../app/views/utilities/advanced_search.html.erb | 3 +--
tutor/app/views/utilities/simple_search.html.erb | 2 +-
6 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/tutor/app/controllers/utilities_controller.rb b/tutor/app/controllers/utilities_controller.rb
index efccdbc0..2e4daac1 100644
--- a/tutor/app/controllers/utilities_controller.rb
+++ b/tutor/app/controllers/utilities_controller.rb
@@ -1,5 +1,5 @@
class UtilitiesController < ApplicationController
-
+
# [Simple Search - Story 1.22]
# search for users and courses
# Parameters: search
@@ -57,4 +57,5 @@ def auto_complete
format.json {render :template => 'utilities/auto_complete',:formats => [],:handlers => [:json_builder],:layout=>false}
end
end
+
end
diff --git a/tutor/app/views/utilities/_advanced_search.html.erb b/tutor/app/views/utilities/_advanced_search.html.erb
index b13971d4..4829c59e 100644
--- a/tutor/app/views/utilities/_advanced_search.html.erb
+++ b/tutor/app/views/utilities/_advanced_search.html.erb
@@ -4,7 +4,7 @@
- <% unless @lecturers.present? or @teaching_assisstants.present? or @courses.present? or @students.present?%>
+ <% unless @lecturers.present? or @teaching_assisstants.present?
+ or @courses.present? or @students.present? %>
No Result match
<% else %>
- <% if @lecturers.present?%>
+ <% if @lecturers.present? %>
<%= render "result_form" , objects: @lecturers %>
- <%end%>
- <% if @students.present?%>
+ <% end %>
+ <% if @students.present? %>
<%= render "result_form" , objects: @students %>
- <%end%>
+ <% end %>
<% if @teaching_assisstants.present? %>
\ No newline at end of file
diff --git a/tutor/app/views/utilities/simple_search.html.erb b/tutor/app/views/utilities/simple_search.html.erb
index 8de4fb67..d5b51d60 100644
--- a/tutor/app/views/utilities/simple_search.html.erb
+++ b/tutor/app/views/utilities/simple_search.html.erb
@@ -2,5 +2,5 @@
\ No newline at end of file
From bc73f2c635779cb2465e8e47692632b7ed9b3a4c Mon Sep 17 00:00:00 2001
From: mohamedsaeed93
Date: Wed, 23 Apr 2014 19:40:51 +0200
Subject: [PATCH 294/526] Issue #194, fixing indentation after reopening
---
tutor/app/assets/javascripts/solutions.js.coffee | 10 +++++-----
tutor/app/models/solution.rb | 16 ++++++++--------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/tutor/app/assets/javascripts/solutions.js.coffee b/tutor/app/assets/javascripts/solutions.js.coffee
index c3d0aaf9..c97b9cf4 100644
--- a/tutor/app/assets/javascripts/solutions.js.coffee
+++ b/tutor/app/assets/javascripts/solutions.js.coffee
@@ -145,11 +145,11 @@ index_number = 0
index_number = 0;
variables = null;
-#To be Used when changing to ajax in order not to refresh page
+# To be Used when changing to ajax in order not to refresh page
# [Compiler: Validate - Story 3.5]
-# submits a solution in the form without refreshing
+# submits a solution in the form without refreshing
# using ajax showing an alert box for success and failure scenarios
-# Parameters:
+# Parameters:
# problem_id: the id of the problem being solved
# Returns: a json object containing two arrays one for the errors
# of the current code and the other containing success messages
@@ -158,7 +158,7 @@ index_number = 0
code = $('#solution_code').val()
mins = parseInt($('#mins').text())
secs = parseInt($('#secs').text())
- time = mins*60 + secs
+ time = mins*60 + secseol
start_spin()
$.ajax
type: "POST"
@@ -175,7 +175,7 @@ index_number = 0
errors.html("")
for i in data["failure"]
errors.append("#{i} ")
- if code.length isnt 0
+ if code.length isnt 0
alert 'Solution has been submitted successfully'
else
alert 'Blank submissions are not allowed'
diff --git a/tutor/app/models/solution.rb b/tutor/app/models/solution.rb
index 455d2b49..fce31995 100644
--- a/tutor/app/models/solution.rb
+++ b/tutor/app/models/solution.rb
@@ -9,9 +9,9 @@ class Solution < ActiveRecord::Base
#Methods
# [Compiler: Validate - Story 3.5]
- # Checks the validity of a submitted solution
+ # Checks the validity of a submitted solution
# and show the runtime and logic errors if exist
- # Parameters:
+ # Parameters:
# problem_id: id of the problem being answered
# file: the name of the file which is compiled successfully
# without errors
@@ -22,22 +22,22 @@ def self.validate(file, problem_id)
response = {status: 0, success: [], runtime_error: [],runtime_error_exp: [],
logic_error: []}
testcases = Problem.find_by_id(problem_id).test_cases
- testcases.each do |testcase|
+ testcases.each do |testcase|
input = testcase.input
- expected_output = testcase.output
+ expected_output = testcase.output
runtime_check = Executer.execute(file, input, problem_id)
if(runtime_check)
- output = Executer.get_output()
+ output = Executer.get_output()
if (output != expected_output)
response[:logic_error] << "Logic error: for input: " +
input + " ,expected output: " +
- expected_output + " but your output was: " + output
+ expected_output + " but your output was: " + output
unless response[:status] == 4
response[:status] = 5
end
else
unless(response[:status] == 4 | 5)
- response[:status] = 1
+ response[:status] = 1
end
end
else
@@ -55,7 +55,7 @@ def self.validate(file, problem_id)
end
# [Compiler: Validate - Story 3.5]
- # Parameters:
+ # Parameters:
# s_id : the id of the current Student
# p_id : the id of the current Problem
# Returns: the number of trials the student made for this problem
From 0649dcf39310aa785ff9ae55ce584a073ebac616 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Wed, 23 Apr 2014 19:43:11 +0200
Subject: [PATCH 295/526] Fixed indentation in show post view
---
tutor/app/views/posts/show.html.erb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tutor/app/views/posts/show.html.erb b/tutor/app/views/posts/show.html.erb
index 858f2b82..d72626bd 100644
--- a/tutor/app/views/posts/show.html.erb
+++ b/tutor/app/views/posts/show.html.erb
@@ -2,7 +2,7 @@
<% else %>
The discusstion board is deactivated
From b97d324effdae6b2fe25e7f46e0959d88bb4fa65 Mon Sep 17 00:00:00 2001
From: mohamedsaeed93
Date: Wed, 23 Apr 2014 20:08:45 +0200
Subject: [PATCH 297/526] Issue 194, fixing indentation once more
---
tutor/app/controllers/solutions_controller.rb | 2 +-
tutor/app/models/solution.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tutor/app/controllers/solutions_controller.rb b/tutor/app/controllers/solutions_controller.rb
index 8b609610..61d59400 100644
--- a/tutor/app/controllers/solutions_controller.rb
+++ b/tutor/app/controllers/solutions_controller.rb
@@ -111,5 +111,5 @@ def solution_params
def input
params.require(:solution).permit(:input)
end
-
+
end
\ No newline at end of file
diff --git a/tutor/app/models/solution.rb b/tutor/app/models/solution.rb
index fce31995..0997d481 100644
--- a/tutor/app/models/solution.rb
+++ b/tutor/app/models/solution.rb
@@ -128,5 +128,5 @@ def class_file_name(prepend_path = false, append_extension = false)
STATUS_EXECUTED_WITH_LOGIC_ERRORS = 5
JAVA_PATH = 'students_solutions/Java/'
CLASS_PATH = 'students_solutions/Class/'
-
+
end
\ No newline at end of file
From c7ab886d46de745a5c86e4bd23437c2b8a339fff Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Wed, 23 Apr 2014 20:13:03 +0200
Subject: [PATCH 298/526] changed routes
---
tutor/config/routes.rb | 65 +++++++++++++++++++++++++-----------------
1 file changed, 39 insertions(+), 26 deletions(-)
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index 1056ca82..6d1a9cd3 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -1,43 +1,38 @@
Tutor::Application.routes.draw do
+ devise_for :teaching_assistants
+ devise_for :students
+ devise_for :lecturers
+
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# Example of regular route:
# get 'products/:id' => 'catalog#view'
+ # get 'products/index'
+ post 'solutions/compile_solution' => 'problems#show'
+ post 'courses/new' => 'courses#new'
+ get 'courses/sign_up'
+ post 'solutions/execute' => 'problems#show'
+ post 'debuggers/:id' => 'debuggers#start'
# You can have the root of your site routed with "root"
-
root 'site#index'
- resources :tracks do
- post 'getProblems', on: :member
- end
- resources :problems_by_tas
- resources :solutions
- resources :problems
- resources :discussion_boards do
- post 'toggle', on: :member
- end
- post 'courses/new' => 'courses#new'
- resources :courses do
- post 'topics/new' => 'topics#new'
- resources :teaching_assistants
- post 'teaching_assistants/new' => 'teaching_assistants#new'
- resources :topics
- end
- resources :model_answers do
- post "model_answers/new"
- end
- resources :test_cases
- devise_for :teaching_assistants
- devise_for :students
- devise_for :lecturers
+
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
+ resources :courses
+ resources :test_cases
+ resources :model_answers
+ resources :problems_by_tas
+ resources :solutions
+ resources :problems
+ resources :topics
+ resources :facebook
# Example resource route with options:
# resources :products do
@@ -50,7 +45,19 @@
# get 'sold'
# end
# end
-
+ resources :tracks do
+ member do
+ get 'getProblems'
+ end
+ end
+ resources :discussion_boards do
+ member do
+ post 'toggle'
+ end
+ end
+ resources :model_answers do
+ post "model_answers/new"
+ end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
@@ -64,6 +71,12 @@
# get 'recent', on: :collection
# end
# end
+ resources :courses do
+ post 'topics/new' => 'topics#new'
+ resources :topics
+ resources :teaching_assistants
+ post 'teaching_assistants/new' => 'teaching_assistants#new'
+ end
# Example resource route with concerns:
# concern :toggleable do
@@ -79,4 +92,4 @@
# resources :products
# end
-end
\ No newline at end of file
+end
From 36b7d1790d9e2ffdf34ef4d4201ab5a217d29cdc Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Wed, 23 Apr 2014 20:14:40 +0200
Subject: [PATCH 299/526] Issue #223 layout modification
---
tutor/app/assets/stylesheets/application.css | 12 +++++-------
tutor/app/views/layouts/_right_side_bar.html.erb | 2 +-
tutor/app/views/layouts/application.html.erb | 16 +++++++---------
tutor/vendor/assets/stylesheets/bootstrap.css | 1 -
4 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/tutor/app/assets/stylesheets/application.css b/tutor/app/assets/stylesheets/application.css
index 348e58a1..c1518ed1 100644
--- a/tutor/app/assets/stylesheets/application.css
+++ b/tutor/app/assets/stylesheets/application.css
@@ -18,18 +18,16 @@
}
.side-right {
- margin-top:70px;
+ margin-top:80px;
height:auto;
- margin-right:1.5%;
+ margin-right:0.5%;
}
.main-content {
- margin-top:70px;
+ margin-top:80px;
margin-bottom:70px;
- height:auto;
- width:76%;
- margin-left:2%;
- margin-bottom: 100px;
+ width:78%;
+ margin-left:1%;
}
.footer {
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 100ecf78..4748d18c 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -3,5 +3,5 @@
# General layout for right side bar
# Author: Ahmed Elassuty
-->
-
+
\ No newline at end of file
diff --git a/tutor/app/views/layouts/application.html.erb b/tutor/app/views/layouts/application.html.erb
index 4d711eda..19c281b2 100644
--- a/tutor/app/views/layouts/application.html.erb
+++ b/tutor/app/views/layouts/application.html.erb
@@ -28,12 +28,12 @@
<% end %>
u61Xd*
z)iYPy{4!ESw*%i+p%fz|+5sQ5ZBJOX6r-Ime!Ldth}DP@ZXEAG55TSyEV@r*{6={4
zL@TO-Pfk!M7joPGfRAT+;ZG3~-?ZtAc@2+c
z)rN|<)`R_f|VhZeu7bGUxY?vSD4f4W5QwXN>$Kdhv{nl7yue^d2E_s*`>WxN%
zp?*Q>SRwx#Uxja-*#u`VZGum)l~12kCyVu{^jVt@<#+f!%E24u=X;=2n1(rVrn)y#
zHfVH)!x&MJ#u*N;vO7ETO*9reiJRoPUlLw#iOe{365~*Exyxb~xjW;rGbHDBvCbum
zv0THkc82Z}i`6PgEF&4GI_aYa8p6zAzt`pR21Wx%{lm^^{n(+VM(0R>D}Q=4O8Po_
zA~mOc&9uud9H}|ba;Pt%b&hel>Gd@VwNN^-4%ONi%j6ix5(LS(JrqUSIgWF>R+@=x
z7}o7%9g!ZfhN_a~vM{@Z?%@uqX6TrMZ1!?oXG0|!*hTh_c7}%eJ$&2
zg{D0$>v6b9kt;e`Ce+VYiPy3ahr*$eJ;O)pLUsL2pfXhJ>x$OXa8%#eKAf>_R!LCk$dX#5}(#sSco3UjrifCc_S)=JM%~JSYI=gU87J1
zv|Y=!OfmKHtNV#~dRr|17uzCu>DwpoN^-No#Iq!vEi8hcKU-S9`h~wd8LUneaO0Y5
z?uq6IQVs5dC!Z@r#qw`cKe?!fo6i;Cv4RFTbAMun
zZ)Q2eiXZ$SGDS_mhBQc2>EX|AyP(r^vwWjfluGO4^@KZtvmR*
z;}BfE$s+ohkC2$j^f>W1u_7V
Date: Wed, 23 Apr 2014 21:19:45 +0200
Subject: [PATCH 308/526] Issue #223 follow conventions
---
tutor/app/controllers/utilities_controller.rb | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tutor/app/controllers/utilities_controller.rb b/tutor/app/controllers/utilities_controller.rb
index 2e4daac1..2f31e5a1 100644
--- a/tutor/app/controllers/utilities_controller.rb
+++ b/tutor/app/controllers/utilities_controller.rb
@@ -54,7 +54,8 @@ def advanced_search
def auto_complete
@objects = Lecturer.simple_search(params[:q]).take(1)
respond_to do |format|
- format.json {render :template => 'utilities/auto_complete',:formats => [],:handlers => [:json_builder],:layout=>false}
+ format.json {render :template => 'utilities/auto_complete',
+ :formats => [], :handlers => [:json_builder], :layout=>false}
end
end
From 88fe8ec1a9191f00c4ece9fd41f71db86713a465 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Wed, 23 Apr 2014 21:28:04 +0200
Subject: [PATCH 309/526] removed unprofessional message
---
tutor/app/controllers/teaching_assistants_controller.rb | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tutor/app/controllers/teaching_assistants_controller.rb b/tutor/app/controllers/teaching_assistants_controller.rb
index cb4d8e59..722f3d31 100644
--- a/tutor/app/controllers/teaching_assistants_controller.rb
+++ b/tutor/app/controllers/teaching_assistants_controller.rb
@@ -25,8 +25,7 @@ def create
flash[:notice]='TA added!'
redirect_to :action => 'index'
rescue
- flash[:notice]='Error! TA is probably already added to the course.
- That or something went terribly wrong on our side. Either way lamo2a5za.'
+ flash[:notice]='Error! TA is already added to the course.'
redirect_to :action => 'new'
end
end
From 248100c0ae13b895fc5ba9564dcf0b50e787560d Mon Sep 17 00:00:00 2001
From: Mohab
Date: Wed, 23 Apr 2014 21:33:50 +0200
Subject: [PATCH 310/526] Issue #246 deleting empty files
---
tutor/config/routes.rb | 1 -
1 file changed, 1 deletion(-)
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index 9d8935e4..e9d7079c 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -29,7 +29,6 @@
resources :solutions
resources :problems
resources :topics
- resources :profile
# Example resource route with options:
# resources :products do
From c13d662b4ba1a6f705ace58f929ef96265fee44f Mon Sep 17 00:00:00 2001
From: Mohab
Date: Wed, 23 Apr 2014 21:52:55 +0200
Subject: [PATCH 311/526] Issue #246 deleting empty files
---
tutor/.gitignore | 39 -------------------
.../app/assets/javascripts/profile.js.coffee | 3 --
tutor/app/assets/stylesheets/profile.css.scss | 3 --
3 files changed, 45 deletions(-)
delete mode 100644 tutor/.gitignore
delete mode 100644 tutor/app/assets/javascripts/profile.js.coffee
delete mode 100644 tutor/app/assets/stylesheets/profile.css.scss
diff --git a/tutor/.gitignore b/tutor/.gitignore
deleted file mode 100644
index 4ea75899..00000000
--- a/tutor/.gitignore
+++ /dev/null
@@ -1,39 +0,0 @@
-# Ignore bundler config.
-/.bundle
-/vendor/bundle
-
-# Ignore the default SQLite database.
-/db/*.sqlite3
-/db/*.sqlite3-journal
-
-# Ignore all logfiles and tempfiles.
-/log
-/log/*.log
-/tmp
-*~
-
-# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
-.rvmrc
-
-.DS_Store
-/public/system
-/public/uploads/*
-*.rbc
-capybara-*.html
-.rspec
-/coverage/
-/spec/tmp
-**.orig
-rerun.txt
-pickle-email-*.html
-/config/initializers/secret_token.rb
-/config/secrets.yml
-
-# Ignoring migration files
-/db/migrate
-
-# These should all be checked in to normalise the environment:
-Gemfile.lock, .ruby-version, .ruby-gemset
-
-# Ignoring generated model diagram
-models.svg
diff --git a/tutor/app/assets/javascripts/profile.js.coffee b/tutor/app/assets/javascripts/profile.js.coffee
deleted file mode 100644
index 24f83d18..00000000
--- a/tutor/app/assets/javascripts/profile.js.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/tutor/app/assets/stylesheets/profile.css.scss b/tutor/app/assets/stylesheets/profile.css.scss
deleted file mode 100644
index 22ee5087..00000000
--- a/tutor/app/assets/stylesheets/profile.css.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-// Place all the styles related to the Profile controller here.
-// They will automatically be included in application.css.
-// You can use Sass (SCSS) here: http://sass-lang.com/
From 5f4f823aecf64ef2f9badfbef1e4abc4ff094ed0 Mon Sep 17 00:00:00 2001
From: MohabGhanim
Date: Wed, 23 Apr 2014 21:54:52 +0200
Subject: [PATCH 312/526] Issue #246 reverting .gitignore
From 31bc0e13215596efb2d7ecd5eff44be5942abd9f Mon Sep 17 00:00:00 2001
From: Nadine Adel
Date: Wed, 23 Apr 2014 21:57:10 +0200
Subject: [PATCH 313/526] Issue 183 ranaming variable
---
tutor/app/views/model_answers/_index.html.erb | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tutor/app/views/model_answers/_index.html.erb b/tutor/app/views/model_answers/_index.html.erb
index ead62f8c..a7e42f0b 100644
--- a/tutor/app/views/model_answers/_index.html.erb
+++ b/tutor/app/views/model_answers/_index.html.erb
@@ -1,11 +1,11 @@
From 629ba65c3c8c336784adeaa78c8b68aa522f2b8b Mon Sep 17 00:00:00 2001
From: Mohab
Date: Wed, 23 Apr 2014 22:01:32 +0200
Subject: [PATCH 314/526] Issue #246 removing extra spaces
---
tutor/app/models/student.rb | 2 --
tutor/app/views/layouts/_right_side_bar.html.erb | 8 ++++++--
tutor/db/seeds.rb | 2 +-
tutor/test/controllers/profile_controller_test.rb | 9 ---------
4 files changed, 7 insertions(+), 14 deletions(-)
delete mode 100644 tutor/test/controllers/profile_controller_test.rb
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index 634d3260..c4b3ff98 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -84,11 +84,9 @@ def getProblemsStatus
# Author: Mohab Ghanim (Modified from Rami Khalil's Story 3.9)
def get_next_problems_to_solve
next_problems_to_solve = Hash.new
-
courses.each do |course|
course.topics.each do |topic|
level = TrackProgression.get_progress(self.id, topic.id)
-
topic.tracks.each do |track|
if(track.difficulty == level)
track.problems.each do |problem|
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 3250649b..ec9fb915 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -3,7 +3,12 @@
# General layout for right side bar
# Author: Ahmed Elassuty
-->
-
+
+
<% if student_signed_in? %>
<% next_problems_to_solve = current_student.get_next_problems_to_solve
if next_problems_to_solve != nil then %>
@@ -22,5 +27,4 @@
<% end %>
<% end %>
-
\ No newline at end of file
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index 316b56e7..9fbe767f 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -101,7 +101,7 @@
puts("# -----------------------TrackProgression---------------------------")
TrackProgression.create(level: 2, student_id: 1, topic_id: 1)
- TrackProgression.create(level: 3, student_id: 1, topic_id: 2)
+ TrackProgression.create(level: 0, student_id: 1, topic_id: 2)
puts("# -------------------------------------------------------")
diff --git a/tutor/test/controllers/profile_controller_test.rb b/tutor/test/controllers/profile_controller_test.rb
deleted file mode 100644
index 242bcc3f..00000000
--- a/tutor/test/controllers/profile_controller_test.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'test_helper'
-
-class ProfileControllerTest < ActionController::TestCase
-
- # test "the truth" do
- # assert true
- # end
-
-end
From 1e71c3aaec82db14f0720ffe924d5122bebe66d3 Mon Sep 17 00:00:00 2001
From: Khaled
Date: Wed, 23 Apr 2014 22:05:13 +0200
Subject: [PATCH 315/526] Issue #216 Fixed conventions
---
tutor/db/schema.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/db/schema.rb b/tutor/db/schema.rb
index 248638f8..b21dcc71 100644
--- a/tutor/db/schema.rb
+++ b/tutor/db/schema.rb
@@ -362,4 +362,4 @@
t.datetime "updated_at"
end
-end
\ No newline at end of file
+end
From a51b599d6b0bc129af5ec38f2295a8c813e284ca Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Wed, 23 Apr 2014 22:08:10 +0200
Subject: [PATCH 316/526] adding notifications
---
.../teaching_assistants_controller.rb | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/tutor/app/controllers/teaching_assistants_controller.rb b/tutor/app/controllers/teaching_assistants_controller.rb
index 722f3d31..ab58452b 100644
--- a/tutor/app/controllers/teaching_assistants_controller.rb
+++ b/tutor/app/controllers/teaching_assistants_controller.rb
@@ -19,11 +19,20 @@ def new
def create
begin
@teaching_assistant = TeachingAssistant.find_by_id(params[:teaching_assistant][:id])
- @course = Course.find_by_id(params[:course_id])
- @course.TAs << @teaching_assistant
- current_lecturer.worked_with << @teaching_assistant
- flash[:notice]='TA added!'
- redirect_to :action => 'index'
+ if params[:teaching_assistant][:id] == ''
+ flash[:notice] = 'Error! you need to select a TA'
+ redirect_to :action => 'new'
+ else
+ @course = Course.find_by_id(params[:course_id])
+ @course.TAs << @teaching_assistant
+ flash[:notice]='TA added!'
+ @notification = NotificationMail.new
+ @notification.subject = 'Invitation to join tutor'
+ @notification.email = @teaching_assistant.email
+ @notification.content = 'You have been added to a course on Tutor!'
+ @notification.save
+ redirect_to :action => 'index'
+ end
rescue
flash[:notice]='Error! TA is already added to the course.'
redirect_to :action => 'new'
From 450912d2190b8dd92a304c92d3453d266b2a70c1 Mon Sep 17 00:00:00 2001
From: Khaled
Date: Wed, 23 Apr 2014 22:13:47 +0200
Subject: [PATCH 317/526] Issue #143 Fixed documentation
---
tutor/app/controllers/courses_controller.rb | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tutor/app/controllers/courses_controller.rb b/tutor/app/controllers/courses_controller.rb
index 6f3fb15b..694d10e6 100644
--- a/tutor/app/controllers/courses_controller.rb
+++ b/tutor/app/controllers/courses_controller.rb
@@ -161,13 +161,13 @@ def update
end
# [Share Performance - Story 5.2, 5.13]
- # Description: Updates the database with the value of whether to share
+ # Updates the database with the value of whether to share
# performance or not and it redirects to an error page if an error
# occurs
# Parameters:
# params[:id]: The course id
# params[:value]: The decision of the student whether to share his
- # performance or not
+ # performance or not
# Returns: none
# Author: Khaled Helmy
def share
@@ -193,7 +193,7 @@ def course_params
end
# [Share Performance - Story 5.2, 5.13]
- # Description: Fetches the sharing status for each course that the current
+ # Fetches the sharing status for each course that the current
# signed in student is subscribing to in the database, appends them in
# a list and returns that list
# Parameters: none
@@ -218,12 +218,12 @@ def find_state courses
end
# [Share Performance - Story 5.2, 5.13]
- # Description: Converts a string consisting of either "true" or "false"
+ # Converts a string consisting of either "true" or "false"
# into the corresponding boolean value
# Parameters:
# value: String consisting of "true" or "false" to be converted to boolean
# Returns:
- # Boolean
+ # A boolean converted from a string
# Author: Khaled Helmy
def to_boolean value
if value == "true"
From 91d4577923bf0c4574e1227d0b343f9092f28b46 Mon Sep 17 00:00:00 2001
From: Khaled
Date: Wed, 23 Apr 2014 22:21:29 +0200
Subject: [PATCH 318/526] Issue #193 Fixed conventions
---
tutor/app/models/debugger.rb | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tutor/app/models/debugger.rb b/tutor/app/models/debugger.rb
index e2fe25de..d61386f5 100644
--- a/tutor/app/models/debugger.rb
+++ b/tutor/app/models/debugger.rb
@@ -165,9 +165,9 @@ def self.change_class_name(student_id, problem_id, code)
# [Debugger: View Variables - Story 3.7]
# Takes a line containing an object assignment and extracts
# the object name
- # Parameters:
+ # Parameters:
# variable: A string containing an object assignment
- # Returns:
+ # Returns:
# A string. It contains the object name
# Author: Khaled Helmy
def get_name variable
@@ -177,9 +177,9 @@ def get_name variable
# [Debugger: View Variables - Story 3.7]
# Takes an object and evaluates its value
- # Parameters:
+ # Parameters:
# variable: a string containing an instance object
- # Returns:
+ # Returns:
# An array. It contains the values inside an object
# Author: Khaled Helmy
def get_value variable
@@ -204,7 +204,7 @@ def get_value variable
# Return the list of instance and static variables of the
# class from within static methods
# Parameters: none
- # Returns:
+ # Returns:
# An array. It contains the list of instance and static
# variables and their associated values
# Author: Khaled Helmy
@@ -242,11 +242,11 @@ def get_class_variables
end
# [Debugger: View Variables - Story 3.7]
- # Fetches the variables found in the class and returns
- # a list of all variables in the class with their
+ # Fetches the variables found in the class and returns
+ # a list of all variables in the class with their
# associated values
# Parameters: none
- # Returns:
+ # Returns:
# An array. It contains the list of variables and their values
# Author: Khaled Helmy
def get_variables
From a78931e37de66e499eabb9b078b78840eece4ec6 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Wed, 23 Apr 2014 22:22:36 +0200
Subject: [PATCH 319/526] Issue #246 removing line
---
tutor/db/seeds.rb | 1 -
1 file changed, 1 deletion(-)
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index 23ea7ed9..ec0ee8ff 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -123,7 +123,6 @@
Attempt.create(failure: true)
Attempt.create(failure: true)
Attempt.create(failure: true)
->>>>>>> 9f7a6eaedbbd7f2e4949ff654b51b31f498dc8af
puts("# -------------------------------------------------------")
From 953df93802b42667ed815faf8afc7d4cbc7c0e40 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Wed, 23 Apr 2014 22:45:10 +0200
Subject: [PATCH 320/526] Issue #200 fixing long line
---
tutor/app/models/student.rb | 2 +-
tutor/app/views/layouts/_right_side_bar.html.erb | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index 763f3eee..4e8a1ada 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -94,4 +94,4 @@ def getClassMatesRecommendations
end
return recommended_problems_hash
end
-end
+end
\ No newline at end of file
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 0609fe55..28403f85 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -21,7 +21,8 @@
<%= value["recommender_name"] %>
From 798cd92268dc61712a22aed8c2f247f467fbb21f Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Wed, 23 Apr 2014 23:40:10 +0200
Subject: [PATCH 328/526] Fixed commas as Mamdou7's comment
---
tutor/app/views/problems/edit.html.erb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/views/problems/edit.html.erb b/tutor/app/views/problems/edit.html.erb
index 88abb8a7..d96726d8 100644
--- a/tutor/app/views/problems/edit.html.erb
+++ b/tutor/app/views/problems/edit.html.erb
@@ -10,5 +10,5 @@ and a paragraph to view the problem description of the instance variable @proble
<%= flash[:notice] %>
<% end %>
<%= button_to "Delete Problem", {:action => 'destroy'}, method: :delete,
- class: 'btn btn-primary',:id => params[:id] ,
+ class: 'btn btn-primary', :id =>params[:id] ,
:confirm => "Are you sure you want to delete this problem ??" %>
\ No newline at end of file
From 1b4227c60f9ed71ccad8cb941dbc497d3b7d8c66 Mon Sep 17 00:00:00 2001
From: AmirGeorge
Date: Wed, 23 Apr 2014 23:41:22 +0200
Subject: [PATCH 329/526] changed interval to 2 days
---
tutor/config/schedule.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/config/schedule.rb b/tutor/config/schedule.rb
index 141ce37c..bcaf7f11 100644
--- a/tutor/config/schedule.rb
+++ b/tutor/config/schedule.rb
@@ -1,6 +1,6 @@
# for this to work type this the terminal before starting server:
# whenever --update-crontab sendReminders
set :environment, 'development'
-every 1.minute do
+every 2.days do
runner "Student.send_reminder_mails"
end
\ No newline at end of file
From 765b4f4da6e4230d5277030b8735adacec58469c Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Wed, 23 Apr 2014 23:46:48 +0200
Subject: [PATCH 330/526] added a space
---
tutor/app/views/problems/edit.html.erb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/views/problems/edit.html.erb b/tutor/app/views/problems/edit.html.erb
index d96726d8..4fa1c94b 100644
--- a/tutor/app/views/problems/edit.html.erb
+++ b/tutor/app/views/problems/edit.html.erb
@@ -10,5 +10,5 @@ and a paragraph to view the problem description of the instance variable @proble
<%= flash[:notice] %>
<% end %>
<%= button_to "Delete Problem", {:action => 'destroy'}, method: :delete,
- class: 'btn btn-primary', :id =>params[:id] ,
+ class: 'btn btn-primary', :id => params[:id],
:confirm => "Are you sure you want to delete this problem ??" %>
\ No newline at end of file
From fe1bba02c655aded19e3a958afb5ddcba5039880 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Wed, 23 Apr 2014 23:50:18 +0200
Subject: [PATCH 331/526] fixing indentation
---
tutor/app/views/posts/show.html.erb | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/tutor/app/views/posts/show.html.erb b/tutor/app/views/posts/show.html.erb
index d72626bd..9bbf1f5b 100644
--- a/tutor/app/views/posts/show.html.erb
+++ b/tutor/app/views/posts/show.html.erb
@@ -1,17 +1,17 @@
-
- <% end %>
- <% else %>
- No Replies in this post yet .
+ <%= @post.content %>
+
+ <% unless @replies.blank? %>
+ <% @replies.each do |reply| %>
+
+ <%= reply.content %>
+
+
<% end %>
+ <% else %>
+ No Replies in this post yet .
+ <% end %>
\ No newline at end of file
From dc3d0a17880519668c5df0370c1f22f8cfda9a81 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Wed, 23 Apr 2014 23:51:51 +0200
Subject: [PATCH 332/526] fixing tab
---
tutor/app/views/problems/edit.html.erb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tutor/app/views/problems/edit.html.erb b/tutor/app/views/problems/edit.html.erb
index 4fa1c94b..b1838fec 100644
--- a/tutor/app/views/problems/edit.html.erb
+++ b/tutor/app/views/problems/edit.html.erb
@@ -10,5 +10,5 @@ and a paragraph to view the problem description of the instance variable @proble
<%= flash[:notice] %>
<% end %>
<%= button_to "Delete Problem", {:action => 'destroy'}, method: :delete,
- class: 'btn btn-primary', :id => params[:id],
- :confirm => "Are you sure you want to delete this problem ??" %>
\ No newline at end of file
+ class: 'btn btn-primary', :id => params[:id],
+ :confirm => "Are you sure you want to delete this problem ??" %>
\ No newline at end of file
From acbe75c6fbe6e9ab6cb02ee80f47223959abb156 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Wed, 23 Apr 2014 23:53:57 +0200
Subject: [PATCH 333/526] Issue #246 remove end
---
tutor/app/views/layouts/_right_side_bar.html.erb | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 3a0df550..6e96f4f5 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -27,8 +27,7 @@
<% end %>
<% end %>
- <% end %>
-
From c8ab564c32f4bc02d7c7e70a1e6b7a1c27915eb4 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Thu, 24 Apr 2014 00:29:39 +0200
Subject: [PATCH 341/526] Issue #203 fixing indentation
---
tutor/app/assets/javascripts/tracks.js | 133 +++++++++++++-----------
tutor/app/assets/stylesheets/tracks.css | 17 ++-
2 files changed, 79 insertions(+), 71 deletions(-)
diff --git a/tutor/app/assets/javascripts/tracks.js b/tutor/app/assets/javascripts/tracks.js
index 38d6f2ed..d13dcd44 100644
--- a/tutor/app/assets/javascripts/tracks.js
+++ b/tutor/app/assets/javascripts/tracks.js
@@ -1,68 +1,77 @@
-// # [Recommendation to students]
-// # Author: Mohab Ghanim
-
-function showdialog(problem_id, recommender_id){
- $.ajax({
- type: "GET",
- url: '/tracks/show_classmates/' + problem_id,
- datatype: 'json',
- success: function(json){
- fill(json, problem_id, recommender_id)}
- });
-}
+ // [Recommendation to students]
+ // Shows the dialog containing names of students
+ // who can recieve recommendation and a button to send recommendation
+ // Parameters:
+ // problem_id : id of problem
+ // recommender_id : id of student recommending the problem
+ // Returns: calls the function which fills the dialog with student names
+ // Author: Mohab Ghanim
+ function showdialog(problem_id, recommender_id){
+ $.ajax({
+ type: "GET",
+ url: '/tracks/show_classmates/' + problem_id,
+ datatype: 'json',
+ success: function(json){
+ fill(json, problem_id, recommender_id)}
+ });
+ }
-function fill(data, problem_id, recommender_id){
- elem = $('#container');
- elem.html("");
- if(Object.keys(data).length == 0){
- elem.html("
No classmates to recommend this problem to
");
+ // [Recommendation to students]
+ // Fills the dialog with student names and recommend buttons
+ // Parameters:
+ // problem_id : id of problem
+ // recommender_id : id of student recommending the problem
+ // data : data returned from the above method
+ // Returns: appends html in /tracks/id
+ // Author: Mohab Ghanim
+ function fill(data, problem_id, recommender_id){
+ elem = $('#container');
+ elem.html("");
+ if(Object.keys(data).length == 0){
+ elem.html("
We miss you at our Tutors website, <%= @user.name %>
-
- Your beloved Tutors website has missed you !
-
-
- To login to the site, just follow this link: <%= @url %>.
-
-
- <%= suggestion = @user.get_a_system_suggested_problem
- if suggestion != nil then
- link_to "And if you are still up to it can you solve this problem ? ;) ", suggestion
- end %>
-
>
-
Hoping to see you soon and have a great day!
-
+
+
+
+
+
We miss you at our Tutors website, <%= @user.name %>
+
+ Your beloved Tutors website has missed you !
+
+
+ To login to the site, just follow this link: <%= @url %>.
+
+
+ <%= suggestion = @user.get_a_system_suggested_problem
+ if suggestion != nil then
+ link_to "And if you are still up to it can you solve this problem ? ;) ", suggestion
+ end %>
+
>
+
Hoping to see you soon and have a great day!
+
\ No newline at end of file
diff --git a/tutor/config/environments/development.rb b/tutor/config/environments/development.rb
index 256ec4cd..e545369f 100644
--- a/tutor/config/environments/development.rb
+++ b/tutor/config/environments/development.rb
@@ -1,43 +1,41 @@
Tutor::Application.configure do
- # Settings specified here will take precedence over those in config/application.rb.
-
- # In the development environment your application's code is reloaded on
- # every request. This slows down response time but is perfect for development
- # since you don't have to restart the web server when you make code changes.
- config.cache_classes = false
-
- # Do not eager load code on boot.
- config.eager_load = false
-
- # Show full error reports and disable caching.
- config.consider_all_requests_local = true
- config.action_controller.perform_caching = false
-
- # Print deprecation notices to the Rails logger.
- config.active_support.deprecation = :log
-
- # Raise an error on page load if there are pending migrations
- config.active_record.migration_error = :page_load
-
- # Debug mode disables concatenation and preprocessing of assets.
- # This option may cause significant delays in view rendering with a large
- # number of complex assets.
- config.assets.debug = true
-
- # Configuring mailing options in Development environment
- config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
- config.action_mailer.delivery_method = :smtp
- config.action_mailer.perform_deliveries = true
- config.action_mailer.raise_delivery_errors = true
- config.action_mailer.smtp_settings = {
- :address => "smtp.gmail.com",
- :port => 587,
- :domain => "gmail.com",
- :user_name => "CoolSoft14@gmail.com",
- :password => "coolsoftwillrockandwin",
- :authentication => 'plain',
- :enable_starttls_auto => true
- }
-
+ # Settings specified here will take precedence over those in config/application.rb.
+ # In the development environment your application's code is reloaded on
+ # every request. This slows down response time but is perfect for development
+ # since you don't have to restart the web server when you make code changes.
+ config.cache_classes = false
+
+ # Do not eager load code on boot.
+ config.eager_load = false
+
+ # Show full error reports and disable caching.
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
+
+ # Print deprecation notices to the Rails logger.
+ config.active_support.deprecation = :log
+
+ # Raise an error on page load if there are pending migrations
+ config.active_record.migration_error = :page_load
+
+ # Debug mode disables concatenation and preprocessing of assets.
+ # This option may cause significant delays in view rendering with a large
+ # number of complex assets.
+ config.assets.debug = true
+
+ # Configuring mailing options in Development environment
+ config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
+ config.action_mailer.delivery_method = :smtp
+ config.action_mailer.perform_deliveries = true
+ config.action_mailer.raise_delivery_errors = true
+ config.action_mailer.smtp_settings = {
+ :address => "smtp.gmail.com",
+ :port => 587,
+ :domain => "gmail.com",
+ :user_name => "CoolSoft14@gmail.com",
+ :password => "coolsoftwillrockandwin",
+ :authentication => 'plain',
+ :enable_starttls_auto => true
+ }
end
\ No newline at end of file
From ad37af37670a1904e8bf853f2f771cec850d8171 Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Thu, 24 Apr 2014 00:56:48 +0200
Subject: [PATCH 347/526] Issue #223 fix conventions
---
tutor/app/views/layouts/application.html.erb | 2 +-
tutor/app/views/utilities/_no_result.html.erb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tutor/app/views/layouts/application.html.erb b/tutor/app/views/layouts/application.html.erb
index 19c281b2..6ea64d6b 100644
--- a/tutor/app/views/layouts/application.html.erb
+++ b/tutor/app/views/layouts/application.html.erb
@@ -63,7 +63,7 @@
\ No newline at end of file
diff --git a/tutor/app/views/utilities/_no_result.html.erb b/tutor/app/views/utilities/_no_result.html.erb
index 23e02182..eabbfaa3 100644
--- a/tutor/app/views/utilities/_no_result.html.erb
+++ b/tutor/app/views/utilities/_no_result.html.erb
@@ -1,3 +1,3 @@
-
No Results match
+
No Results match
\ No newline at end of file
From 14c777b14e39c44520c26e2f3dff132d20421b85 Mon Sep 17 00:00:00 2001
From: AmirGeorge
Date: Thu, 24 Apr 2014 00:58:30 +0200
Subject: [PATCH 348/526] removed extra indent
---
tutor/app/views/system_reminders/reminder_email.html.erb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tutor/app/views/system_reminders/reminder_email.html.erb b/tutor/app/views/system_reminders/reminder_email.html.erb
index 31c20a3a..2d739ee5 100644
--- a/tutor/app/views/system_reminders/reminder_email.html.erb
+++ b/tutor/app/views/system_reminders/reminder_email.html.erb
@@ -16,7 +16,7 @@
if suggestion != nil then
link_to "And if you are still up to it can you solve this problem ? ;) ", suggestion
end %>
- >
+
Hoping to see you soon and have a great day!
-
\ No newline at end of file
+
From 75e443ebd979510873b8dae260e906c2915909d5 Mon Sep 17 00:00:00 2001
From: serag
Date: Thu, 24 Apr 2014 00:58:43 +0200
Subject: [PATCH 349/526] Issue #206 final point mixed with statistics of Mahdi
---
tutor/app/views/lecturers/show.html.erb | 4 ----
tutor/app/views/students/show.html.erb | 4 ++--
tutor/app/views/teaching_assistants/show.html.erb | 4 ----
3 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/tutor/app/views/lecturers/show.html.erb b/tutor/app/views/lecturers/show.html.erb
index 762e6590..db7c3295 100644
--- a/tutor/app/views/lecturers/show.html.erb
+++ b/tutor/app/views/lecturers/show.html.erb
@@ -9,7 +9,6 @@
+ <%= p.hidden_field :title, value: @problem.title %>
+
<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/_failure_options.html.erb b/tutor/app/views/problems/_failure_options.html.erb
index 616f8d6c..d935cf31 100644
--- a/tutor/app/views/problems/_failure_options.html.erb
+++ b/tutor/app/views/problems/_failure_options.html.erb
@@ -1 +1 @@
-<%= button_to 'Save as Incomplete', track_path(:id => @problem.track_id), method: :get %>
\ No newline at end of file
+<%= button_to 'Save as Incomplete', track_path(:id => @problem.track_id), method: :get %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/_title.html.erb b/tutor/app/views/problems/_title.html.erb
index 5de7580c..78b34469 100644
--- a/tutor/app/views/problems/_title.html.erb
+++ b/tutor/app/views/problems/_title.html.erb
@@ -1,7 +1,8 @@
<%= @problem.title %>
<%= form_for :Problem, url: problem_path(@problem), method: :patch, remote: true do |p| %>
- <%= p.text_field :title %>
- <%= p.hidden_field :description, value: @problem.description %>
- <%= p.submit('update title') %>
+ <%= p.text_field :title %>
+ <%= p.hidden_field :description, value: @problem.description %>
+ <%= p.submit('update title') %>
+
<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/problems/done.js.erb b/tutor/app/views/problems/done.js.erb
new file mode 100644
index 00000000..7aacef6d
--- /dev/null
+++ b/tutor/app/views/problems/done.js.erb
@@ -0,0 +1 @@
+$('#div1').html("<%= escape_javascript(render 'problems/flash') %>");
\ No newline at end of file
diff --git a/tutor/app/views/problems/edit.html.erb b/tutor/app/views/problems/edit.html.erb
index b9d28715..dc15ceda 100644
--- a/tutor/app/views/problems/edit.html.erb
+++ b/tutor/app/views/problems/edit.html.erb
@@ -1,36 +1,30 @@
-
-
<%= p.description %>
-
+ <% if @can_edit %>
+
+ <% end %>
<% end %>
-<% if true %>
+<% if @can_edit %>
<% end %>
\ No newline at end of file
From 0a9fed75cfa52b887770f6eec731064035c750bd Mon Sep 17 00:00:00 2001
From: Mohab
Date: Thu, 24 Apr 2014 01:33:32 +0200
Subject: [PATCH 358/526] Issue #203 fixing indentation
---
tutor/app/controllers/tracks_controller.rb | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tutor/app/controllers/tracks_controller.rb b/tutor/app/controllers/tracks_controller.rb
index 62a0c0b9..45ac3738 100644
--- a/tutor/app/controllers/tracks_controller.rb
+++ b/tutor/app/controllers/tracks_controller.rb
@@ -99,9 +99,11 @@ def show_classmates
end
# [Recommendatio to students - Story 5.7]
- # Inserts a record in recommendation table
+ # Inserts a record in the recommendation table containing the id of the problem,
+ # the id of the students recommending the problem, the id of the student recieving
+ # the recommendation
# Parameters: none
- # Returns: json
+ # Returns: none
# Author: Mohab Ghanim
def insert_recommendation
problem_id = params[:p_id]
From 7bbe4af379a80c4bdf0a8ed654594bff6219f201 Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Thu, 24 Apr 2014 01:33:45 +0200
Subject: [PATCH 359/526] Issue #223 fix conventions
---
tutor/app/views/utilities/_simple_search.html.erb | 3 ++-
tutor/app/views/utilities/advanced_search.js.erb | 1 -
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tutor/app/views/utilities/_simple_search.html.erb b/tutor/app/views/utilities/_simple_search.html.erb
index 18021f9c..2a1e0e8d 100644
--- a/tutor/app/views/utilities/_simple_search.html.erb
+++ b/tutor/app/views/utilities/_simple_search.html.erb
@@ -1,7 +1,8 @@
- <% unless @lecturers.present? or @teaching_assisstants.present? or @courses.present? or @students.present? %>
+ <% unless @lecturers.present? or @teaching_assisstants.present?\
+ or @courses.present? or @students.present? %>
No Result match
diff --git a/tutor/app/views/utilities/advanced_search.js.erb b/tutor/app/views/utilities/advanced_search.js.erb
index d922c1a6..62887224 100644
--- a/tutor/app/views/utilities/advanced_search.js.erb
+++ b/tutor/app/views/utilities/advanced_search.js.erb
@@ -4,7 +4,6 @@ $("#advanced_search_result").append("<%=escape_javascript( render 'result_form',
$("#advanced_search_result").append("<%=escape_javascript( render 'result_form', objects: @courses)%>");
$("#advanced_search_result").append("<%=escape_javascript( render 'result_form', objects: @topics)%>");
$("#advanced_search_result").append("<%=escape_javascript( render 'result_form', objects: @posts)%>");
-console.log("asd");
if ( $("#advanced_search_result").children().length == 0 ) {
$("#advanced_search_result").html("<%=escape_javascript( render 'no_result')%>");
}
\ No newline at end of file
From e38580f199eedd94babf4e97529414b96b1d2035 Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Thu, 24 Apr 2014 01:34:52 +0200
Subject: [PATCH 360/526] Issue #223 fix conventions
---
tutor/app/models/lecturer.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/models/lecturer.rb b/tutor/app/models/lecturer.rb
index 030bd5f7..67494fec 100644
--- a/tutor/app/models/lecturer.rb
+++ b/tutor/app/models/lecturer.rb
@@ -2,7 +2,7 @@ class Lecturer < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
- :recoverable, :rememberable, :trackable, :validatable
+ :recoverable, :rememberable, :trackable, :validatable
#Elasticsearch
include Tire::Model::Search
From a2a506c547d072ce6ac728cc2eaacb0a09fa795f Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 01:38:51 +0200
Subject: [PATCH 361/526] fixing indentation
---
.../acknowledgements_controller.rb | 22 +++++++++----------
tutor/app/views/acknowledgements/new.html.erb | 2 +-
2 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/tutor/app/controllers/acknowledgements_controller.rb b/tutor/app/controllers/acknowledgements_controller.rb
index 87f933a4..2eb015f0 100644
--- a/tutor/app/controllers/acknowledgements_controller.rb
+++ b/tutor/app/controllers/acknowledgements_controller.rb
@@ -3,9 +3,8 @@ class AcknowledgementsController < ApplicationController
# Description: This action takes the passed course id and assings
# the respective course to an instance variable.
# Parameters:
- # params[:course_id]: The current course id
- # Returns:
- # none
+ # params[:course_id]: The current course id
+ # Returns: none
# Author: Muhammad Mamdouh
def new
@course = Course.find(params[:course_id])
@@ -18,11 +17,10 @@ def new
# creation fails the user is redirected to the form
# with an appropriate message.
# Parameters:
- # array "students" which has the students selected
- # the ID of the course
- # the description of the acknowledgement.
- # Returns:
- # flash[:notice]: A message indicating the success or failure of the creation
+ # array "students" which has the students selected
+ # the ID of the course
+ # the description of the acknowledgement.
+ # Returns: A message indicating the success or failure of the creation
# Author: Muhammad Mamdouh
def create
if params[:students] == nil
@@ -38,10 +36,10 @@ def create
if @student == nil
flash[:notice]= "Please choose a student to acknowledge."
else
- flash[:notice] = "Acknowledgement successfully created"
- @student.acknowledgements << @acknowledgement
- current_lecturer.acknowledgements << @acknowledgement
- @course.acknowledgements << @acknowledgement
+ flash[:notice] = "Acknowledgement successfully created"
+ @student.acknowledgements << @acknowledgement
+ current_lecturer.acknowledgements << @acknowledgement
+ @course.acknowledgements << @acknowledgement
end
else
flash[:notice] = "Acknowledgement failed."
diff --git a/tutor/app/views/acknowledgements/new.html.erb b/tutor/app/views/acknowledgements/new.html.erb
index 8734ff50..8ca78f9e 100644
--- a/tutor/app/views/acknowledgements/new.html.erb
+++ b/tutor/app/views/acknowledgements/new.html.erb
@@ -2,7 +2,7 @@
<% if flash[:notice] -%>
-
<%= render partial: "hints/give" %>
From d6f3a5da470ce8c727ae52364de269991893c01c Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 01:43:04 +0200
Subject: [PATCH 363/526] fixing indentation
---
tutor/app/controllers/acknowledgements_controller.rb | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tutor/app/controllers/acknowledgements_controller.rb b/tutor/app/controllers/acknowledgements_controller.rb
index 2eb015f0..e71b7db6 100644
--- a/tutor/app/controllers/acknowledgements_controller.rb
+++ b/tutor/app/controllers/acknowledgements_controller.rb
@@ -3,7 +3,7 @@ class AcknowledgementsController < ApplicationController
# Description: This action takes the passed course id and assings
# the respective course to an instance variable.
# Parameters:
- # params[:course_id]: The current course id
+ # params[:course_id]: The current course id
# Returns: none
# Author: Muhammad Mamdouh
def new
@@ -17,9 +17,9 @@ def new
# creation fails the user is redirected to the form
# with an appropriate message.
# Parameters:
- # array "students" which has the students selected
- # the ID of the course
- # the description of the acknowledgement.
+ # array "students" which has the students selected
+ # the ID of the course
+ # the description of the acknowledgement.
# Returns: A message indicating the success or failure of the creation
# Author: Muhammad Mamdouh
def create
From 905e3dfe8666840fe9dc5763f0a3025fb081c032 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Thu, 24 Apr 2014 01:56:54 +0200
Subject: [PATCH 364/526] Issue #203 fixing indentation
---
tutor/app/assets/javascripts/tracks.js | 142 ++++++++++-----------
tutor/app/controllers/tracks_controller.rb | 2 +-
2 files changed, 72 insertions(+), 72 deletions(-)
diff --git a/tutor/app/assets/javascripts/tracks.js b/tutor/app/assets/javascripts/tracks.js
index d13dcd44..a12fffd3 100644
--- a/tutor/app/assets/javascripts/tracks.js
+++ b/tutor/app/assets/javascripts/tracks.js
@@ -1,77 +1,77 @@
- // [Recommendation to students]
- // Shows the dialog containing names of students
- // who can recieve recommendation and a button to send recommendation
- // Parameters:
- // problem_id : id of problem
- // recommender_id : id of student recommending the problem
- // Returns: calls the function which fills the dialog with student names
- // Author: Mohab Ghanim
- function showdialog(problem_id, recommender_id){
- $.ajax({
- type: "GET",
- url: '/tracks/show_classmates/' + problem_id,
- datatype: 'json',
- success: function(json){
- fill(json, problem_id, recommender_id)}
- });
- }
+// [Recommendation to students]
+// Shows the dialog containing names of students
+// who can recieve recommendation and a button to send recommendation
+// Parameters:
+// problem_id : id of problem
+// recommender_id : id of student recommending the problem
+// Returns: calls the function which fills the dialog with student names
+// Author: Mohab Ghanim
+function showdialog(problem_id, recommender_id){
+ $.ajax({
+ type: "GET",
+ url: '/tracks/show_classmates/' + problem_id,
+ datatype: 'json',
+ success: function(json){
+ fill(json, problem_id, recommender_id)}
+ });
+}
- // [Recommendation to students]
- // Fills the dialog with student names and recommend buttons
- // Parameters:
- // problem_id : id of problem
- // recommender_id : id of student recommending the problem
- // data : data returned from the above method
- // Returns: appends html in /tracks/id
- // Author: Mohab Ghanim
- function fill(data, problem_id, recommender_id){
- elem = $('#container');
- elem.html("");
- if(Object.keys(data).length == 0){
- elem.html("
");
- $.each(data, function (i , datum){
- datum = data[i];
- temp = "
" + datum['student_name'] +
- "" +
- "
"
- elem.append(temp);
- });
- elem.append("
");
+// [Recommendation to students]
+// Fills the dialog with student names and recommend buttons
+// Parameters:
+// problem_id : id of problem
+// recommender_id : id of student recommending the problem
+// data : data returned from the above method
+// Returns: appends html in /tracks/id
+// Author: Mohab Ghanim
+function fill(data, problem_id, recommender_id){
+ elem = $('#container');
+ elem.html("");
+ if(Object.keys(data).length == 0){
+ elem.html("
");
+ $.each(data, function (i , datum){
+ datum = data[i];
+ temp = "
" + datum['student_name'] +
+ "" +
+ "
"
+ elem.append(temp);
+ });
+ elem.append("
");
+ $('.classmates_list').bPopup();
+}
- // [Recommendation to students]
- // sends problem id , recommender id, student getting recommendation id
- // to the controller to be inserted in the database
- // Parameters:
- // problem_id : id of problem
- // recommender_id : id of student recommending the problem
- // student_id : id of student recieving the problem
- // Returns: none
- // Author: Mohab Ghanim
- function recommend(problem_id, recommender_id, student_id){
+// [Recommendation to students]
+// sends problem id , recommender id, student getting recommendation id
+// to the controller to be inserted in the database
+// Parameters:
+// problem_id : id of problem
+// recommender_id : id of student recommending the problem
+// student_id : id of student recieving the problem
+// Returns: none
+// Author: Mohab Ghanim
+function recommend(problem_id, recommender_id, student_id){
- $.ajax({
- type: "POST",
- url: '/tracks/insert_recommendation/',
- data: { p_id : problem_id,
- r_id : recommender_id,
- s_id : student_id
- }
- });
- showdialog(problem_id, recommender_id);
+ $.ajax({
+ type: "POST",
+ url: '/tracks/insert_recommendation/',
+ data: { p_id : problem_id,
+ r_id : recommender_id,
+ s_id : student_id
+ }
+ });
+ showdialog(problem_id, recommender_id);
- }
+}
diff --git a/tutor/app/controllers/tracks_controller.rb b/tutor/app/controllers/tracks_controller.rb
index 45ac3738..bf83e644 100644
--- a/tutor/app/controllers/tracks_controller.rb
+++ b/tutor/app/controllers/tracks_controller.rb
@@ -98,7 +98,7 @@ def show_classmates
render json: students_receiving_recommendation
end
- # [Recommendatio to students - Story 5.7]
+ # [Recommendation to students - Story 5.7]
# Inserts a record in the recommendation table containing the id of the problem,
# the id of the students recommending the problem, the id of the student recieving
# the recommendation
From bc224e35028267c231413be8a181531957e7223e Mon Sep 17 00:00:00 2001
From: Mohab
Date: Thu, 24 Apr 2014 02:03:42 +0200
Subject: [PATCH 365/526] Issue #203 fixing documentation errors
---
tutor/app/controllers/tracks_controller.rb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tutor/app/controllers/tracks_controller.rb b/tutor/app/controllers/tracks_controller.rb
index bf83e644..36a39113 100644
--- a/tutor/app/controllers/tracks_controller.rb
+++ b/tutor/app/controllers/tracks_controller.rb
@@ -69,7 +69,7 @@ def create
end
# [Recommendatio to students - Story 5.7]
- # Gets students who can be recommende by problem of id :id
+ # Gets students who can be recommended by problem of id :id
# Parameters: none
# Returns: json containing a Hash of classmates
# Author: Mohab Ghanim
@@ -100,8 +100,8 @@ def show_classmates
# [Recommendation to students - Story 5.7]
# Inserts a record in the recommendation table containing the id of the problem,
- # the id of the students recommending the problem, the id of the student recieving
- # the recommendation
+ # the id of the students recommending the problem, the id of the student recieving
+ # the recommendation
# Parameters: none
# Returns: none
# Author: Mohab Ghanim
From adea8de9db3525fbdbd918a17fdcb83955a7b9ed Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Thu, 24 Apr 2014 02:07:13 +0200
Subject: [PATCH 366/526] Issue #223 fix conventions
---
tutor/app/views/utilities/advanced_search.js.erb | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tutor/app/views/utilities/advanced_search.js.erb b/tutor/app/views/utilities/advanced_search.js.erb
index 62887224..110f6d28 100644
--- a/tutor/app/views/utilities/advanced_search.js.erb
+++ b/tutor/app/views/utilities/advanced_search.js.erb
@@ -1,9 +1,9 @@
-$("#advanced_search_result").html("<%=escape_javascript( render 'result_form', objects: @lecturers)%>");
-$("#advanced_search_result").append("<%=escape_javascript( render 'result_form', objects: @teaching_assistants)%>");
-$("#advanced_search_result").append("<%=escape_javascript( render 'result_form', objects: @students)%>");
-$("#advanced_search_result").append("<%=escape_javascript( render 'result_form', objects: @courses)%>");
-$("#advanced_search_result").append("<%=escape_javascript( render 'result_form', objects: @topics)%>");
-$("#advanced_search_result").append("<%=escape_javascript( render 'result_form', objects: @posts)%>");
+$("#advanced_search_result").html("<%=escape_javascript(render 'result_form', objects: @lecturers)%>");
+$("#advanced_search_result").append("<%=escape_javascript(render 'result_form', objects: @teaching_assistants)%>");
+$("#advanced_search_result").append("<%=escape_javascript(render 'result_form', objects: @students)%>");
+$("#advanced_search_result").append("<%=escape_javascript(render 'result_form', objects: @courses)%>");
+$("#advanced_search_result").append("<%=escape_javascript(render 'result_form', objects: @topics)%>");
+$("#advanced_search_result").append("<%=escape_javascript(render 'result_form', objects: @posts)%>");
if ( $("#advanced_search_result").children().length == 0 ) {
$("#advanced_search_result").html("<%=escape_javascript( render 'no_result')%>");
}
\ No newline at end of file
From 1f0b597f531353405c1262104a76668711b55f18 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 02:12:04 +0200
Subject: [PATCH 367/526] fixing indentation
---
tutor/app/controllers/acknowledgements_controller.rb | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tutor/app/controllers/acknowledgements_controller.rb b/tutor/app/controllers/acknowledgements_controller.rb
index e71b7db6..f363a62d 100644
--- a/tutor/app/controllers/acknowledgements_controller.rb
+++ b/tutor/app/controllers/acknowledgements_controller.rb
@@ -3,7 +3,7 @@ class AcknowledgementsController < ApplicationController
# Description: This action takes the passed course id and assings
# the respective course to an instance variable.
# Parameters:
- # params[:course_id]: The current course id
+ # params[:course_id]: The current course id
# Returns: none
# Author: Muhammad Mamdouh
def new
@@ -17,9 +17,9 @@ def new
# creation fails the user is redirected to the form
# with an appropriate message.
# Parameters:
- # array "students" which has the students selected
- # the ID of the course
- # the description of the acknowledgement.
+ # array "students" which has the students selected
+ # the ID of the course
+ # the description of the acknowledgement.
# Returns: A message indicating the success or failure of the creation
# Author: Muhammad Mamdouh
def create
From fb5516181ce9f0b46892b03f0e04e349fac8c45d Mon Sep 17 00:00:00 2001
From: Ahmed ELAssuty
Date: Thu, 24 Apr 2014 02:13:06 +0200
Subject: [PATCH 368/526] Issue #223 fix conventions
---
tutor/app/views/layouts/application.html.erb | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/tutor/app/views/layouts/application.html.erb b/tutor/app/views/layouts/application.html.erb
index 6ea64d6b..1f1b435c 100644
--- a/tutor/app/views/layouts/application.html.erb
+++ b/tutor/app/views/layouts/application.html.erb
@@ -28,10 +28,9 @@
<% end %>
@@ -27,4 +31,6 @@
<%= render partial: "model_answers/new" %>
<%= render partial: "problems/success_options" %>
-<%= render partial: "problems/failure_options" %>
\ No newline at end of file
+<% if @problem.model_answers.empty? || @problem.test_cases.empty? %>
+ <%= render partial: "problems/failure_options" %>
+<% end %>
\ No newline at end of file
diff --git a/tutor/db/development.sqlite3 b/tutor/db/development.sqlite3
index 49fa27ac2d303e2a7eefae38fd476a39053ff4ea..8c0986898a3a56d6fe5e34828815e6e6d86306a4 100644
GIT binary patch
delta 1170
zcmaJ=O-vI(7~Sbqaog?=4MqNJfEKBSu*}TY&=SB32#W|8z@uIy
z9M+qh{5fcX#BAcl1Mwz_2?RZek$5%n1ZTG`EmVcwWOtLd^S<}qyqRC-=9jrAHDF-z
zOa~ZP>3V7y@_4lBx9V#OUO7YGTs8bSpjs;Of`-m32hL
zu&9ScEKnWG3N?SUfI2hg2N!A}#YAexQZp6n4*t?~qEhp*A5>c({NU2VYPY9}LC;Vt
zcb)&n&+?VrCk}bmJky@0)%sG-GZ%HU3{wtReHnxxb7c@w!YhoC51L>4d;Ux4qN7?$;{6j7E{xgaGQ
z!C}Ngufc8r2H~Dr@)>kEot<#cHvAI$x`Q633L%DJGoFoMBb}mVVhfbD=ABBiAgYR@
zD+T(0kXXROc*_bTMlzW+S2jUKqeR0*7AU5wMheRd>U2Ss3DIQh=_aUiWLA`$>sz40
zn;$?kA#1v>Si4&Q^|~Op!=OI?J-1_v-{9sJdSEq^x$M!ID-x+#IAOopNTjxQuy~*-
zg(XQ)v8byDPI6tzBATjERY|lbgnO3w9p;ZH{{D
zd#j@nxFFhK&~LPjHdejeACZfN6(B1WTHA3)sPu&s1N$-Vz^7TRjo~eH6S>ekKF!y2
zTiheA&CcsAH`m3w7<;d?^(OR~a#MjyiY6WemERFLk3>(o81Ft6CG?nbi-II#T~R3x
z?Vr#bnO*KY)Kzjw7b)ttebg2EoYCS~Gu_T3R{a~t&qWyI8MCAvUUcyc??KPe23oUC
azvX;xCtC$_#SWG@SuZe*faQz9U*Hc1Dh^x#
delta 342
zcmZozz}v8ZcY-uy&_o$$#-NP}EB)9MCHR<48K*lMGK)-B_E#5S6Xa%AXUxq{NzI8*
z%quQWEh^@i9Oqxj$h7%}zx!E!LlY}wLn|XgJxg;VLqqfF5A+!oru)e<+L$sK85o-A
z8kp!B87m;EGB7hWh07Qz7#Uib7+M*c=$V>Zm{?eD-!IGP+9blk%g?|+pWlu*g6|Gr
z6`us}8D9R)iUQwxw)3xL{HnyP$TDL(`vpd4pqL-a_8C_g6_}=Pyu~O!{rojX(dnnI
zF$!+~dX14kl7oqF7XyDR-!7oSb$rZ?KxGN`Op4p@*)gdxaxn4VW#E6$e|NKBz(xM;
zcm0{v1-7$HVEW6yow0z4*+77ePmzIdJAVv67ynki96m*$A-sIs71uF6p2)1oCo-Mg
Zf!UUge;NN}{=-12Q@q
Date: Thu, 24 Apr 2014 02:15:06 +0200
Subject: [PATCH 370/526] Issue #203 fixing documentation again
---
tutor/app/assets/javascripts/tracks.js | 22 +++++++++++-----------
tutor/app/controllers/tracks_controller.rb | 2 +-
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/tutor/app/assets/javascripts/tracks.js b/tutor/app/assets/javascripts/tracks.js
index a12fffd3..ccc98c77 100644
--- a/tutor/app/assets/javascripts/tracks.js
+++ b/tutor/app/assets/javascripts/tracks.js
@@ -1,9 +1,9 @@
// [Recommendation to students]
// Shows the dialog containing names of students
-// who can recieve recommendation and a button to send recommendation
+// who can recieve recommendation and a button to send recommendation
// Parameters:
-// problem_id : id of problem
-// recommender_id : id of student recommending the problem
+// problem_id : id of problem
+// recommender_id : id of student recommending the problem
// Returns: calls the function which fills the dialog with student names
// Author: Mohab Ghanim
function showdialog(problem_id, recommender_id){
@@ -19,9 +19,9 @@ function showdialog(problem_id, recommender_id){
// [Recommendation to students]
// Fills the dialog with student names and recommend buttons
// Parameters:
-// problem_id : id of problem
-// recommender_id : id of student recommending the problem
-// data : data returned from the above method
+// problem_id : id of problem
+// recommender_id : id of student recommending the problem
+// data : data returned from the above method
// Returns: appends html in /tracks/id
// Author: Mohab Ghanim
function fill(data, problem_id, recommender_id){
@@ -54,12 +54,12 @@ function fill(data, problem_id, recommender_id){
}
// [Recommendation to students]
-// sends problem id , recommender id, student getting recommendation id
-// to the controller to be inserted in the database
+// Sends problem id , recommender id, student getting recommendation id
+// to the controller to be inserted in the database
// Parameters:
-// problem_id : id of problem
-// recommender_id : id of student recommending the problem
-// student_id : id of student recieving the problem
+// problem_id : id of problem
+// recommender_id : id of student recommending the problem
+// student_id : id of student recieving the problem
// Returns: none
// Author: Mohab Ghanim
function recommend(problem_id, recommender_id, student_id){
diff --git a/tutor/app/controllers/tracks_controller.rb b/tutor/app/controllers/tracks_controller.rb
index 36a39113..6e59f535 100644
--- a/tutor/app/controllers/tracks_controller.rb
+++ b/tutor/app/controllers/tracks_controller.rb
@@ -69,7 +69,7 @@ def create
end
# [Recommendatio to students - Story 5.7]
- # Gets students who can be recommended by problem of id :id
+ # Gets students who can be recommended a problem of id :id
# Parameters: none
# Returns: json containing a Hash of classmates
# Author: Mohab Ghanim
From c0c4bd3a148932c4b231a4390d41fed085a3721c Mon Sep 17 00:00:00 2001
From: ahmed93
Date: Thu, 24 Apr 2014 02:20:43 +0200
Subject: [PATCH 371/526] Issue #188 fixing condiftions
---
tutor/app/assets/javascripts/solutions_constraints.js | 4 ++--
.../controllers/solutions_constraints_controller.rb | 8 ++++----
.../solutions_constraints/_edit_variable.html.erb | 11 +++--------
3 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/tutor/app/assets/javascripts/solutions_constraints.js b/tutor/app/assets/javascripts/solutions_constraints.js
index 78e1d948..f1040a3e 100644
--- a/tutor/app/assets/javascripts/solutions_constraints.js
+++ b/tutor/app/assets/javascripts/solutions_constraints.js
@@ -179,11 +179,11 @@ function testingValidation(errorArray,method,name){
errorArray.push("Enter method name and return type ..");
}
};
- if(method == ""){
+ if(method == "" && name != ""){
document.getElementById("_constrain_method_name").style.border= "";
document.getElementById("_constrain_method_return").style.border= "red 1px solid";
errorArray.push("Enter method return type ..");
- }else if(name == ""){
+ }else if(name == "" && method != ""){
document.getElementById("_constrain_method_name").style.border= "red 1px solid";
document.getElementById("_constrain_method_return").style.border= "";
errorArray.push("Enter method name ..");
diff --git a/tutor/app/controllers/solutions_constraints_controller.rb b/tutor/app/controllers/solutions_constraints_controller.rb
index 4dd0bdf9..f7835de9 100644
--- a/tutor/app/controllers/solutions_constraints_controller.rb
+++ b/tutor/app/controllers/solutions_constraints_controller.rb
@@ -24,20 +24,20 @@ def create
parameters.parameter = value[:name]
parameters.params_type = value[:type]
parameters.save
- constarint.method_parameter << parameters
+ constarint.parameters << parameters
end
end
constarint.save
end
+
if var_cons.present?
var_cons.each do |index,value|
variable = VariableConstraint.new
- variable.variable_name = value[:name]
- variable.variable_type = value[:type]
+ variable.variable_name = var_cons[index][:name]
+ variable.variable_type = var_cons[index][:type]
variable.save
end
end
-
render json: true
end
diff --git a/tutor/app/views/solutions_constraints/_edit_variable.html.erb b/tutor/app/views/solutions_constraints/_edit_variable.html.erb
index 47464e84..ca27359c 100644
--- a/tutor/app/views/solutions_constraints/_edit_variable.html.erb
+++ b/tutor/app/views/solutions_constraints/_edit_variable.html.erb
@@ -1,19 +1,14 @@
-<%= form_for :@constrain do |f| %>
+<%= form_for :@variables do |f| %>
<% end %>
From 7468cbe52c0d5ef66991009f7065c2e1f91bacfa Mon Sep 17 00:00:00 2001
From: MohabGhanim
Date: Thu, 24 Apr 2014 02:31:54 +0200
Subject: [PATCH 377/526] Issue #203 fixing documentation again and again
---
tutor/app/assets/javascripts/tracks.js | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tutor/app/assets/javascripts/tracks.js b/tutor/app/assets/javascripts/tracks.js
index ccc98c77..a1681fb1 100644
--- a/tutor/app/assets/javascripts/tracks.js
+++ b/tutor/app/assets/javascripts/tracks.js
@@ -2,8 +2,8 @@
// Shows the dialog containing names of students
// who can recieve recommendation and a button to send recommendation
// Parameters:
-// problem_id : id of problem
-// recommender_id : id of student recommending the problem
+// problem_id: id of problem
+// recommender_id: id of student recommending the problem
// Returns: calls the function which fills the dialog with student names
// Author: Mohab Ghanim
function showdialog(problem_id, recommender_id){
@@ -19,9 +19,9 @@ function showdialog(problem_id, recommender_id){
// [Recommendation to students]
// Fills the dialog with student names and recommend buttons
// Parameters:
-// problem_id : id of problem
-// recommender_id : id of student recommending the problem
-// data : data returned from the above method
+// problem_id: id of problem
+// recommender_id: id of student recommending the problem
+// data: data returned from the above method
// Returns: appends html in /tracks/id
// Author: Mohab Ghanim
function fill(data, problem_id, recommender_id){
@@ -57,9 +57,9 @@ function fill(data, problem_id, recommender_id){
// Sends problem id , recommender id, student getting recommendation id
// to the controller to be inserted in the database
// Parameters:
-// problem_id : id of problem
-// recommender_id : id of student recommending the problem
-// student_id : id of student recieving the problem
+// problem_id: id of problem
+// recommender_id: id of student recommending the problem
+// student_id: id of student recieving the problem
// Returns: none
// Author: Mohab Ghanim
function recommend(problem_id, recommender_id, student_id){
From fa2bc9c653f76821db19f144bec3ba7a20960432 Mon Sep 17 00:00:00 2001
From: MohabGhanim
Date: Thu, 24 Apr 2014 02:33:58 +0200
Subject: [PATCH 378/526] Issue #203 removing space
---
tutor/app/assets/javascripts/tracks.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/assets/javascripts/tracks.js b/tutor/app/assets/javascripts/tracks.js
index a1681fb1..73572a12 100644
--- a/tutor/app/assets/javascripts/tracks.js
+++ b/tutor/app/assets/javascripts/tracks.js
@@ -45,7 +45,7 @@ function fill(data, problem_id, recommender_id){
}else {
temp += ">recommend";
}
- temp += "" +
+ temp += "" +
""
elem.append(temp);
});
From 0ef9f143ac6a3d2c6fc3f6c215285f43b70728fe Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 02:34:49 +0200
Subject: [PATCH 379/526] fixing indentation
---
tutor/app/views/teaching_assistants/new.html.erb | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tutor/app/views/teaching_assistants/new.html.erb b/tutor/app/views/teaching_assistants/new.html.erb
index 73db0aa8..342c3f68 100644
--- a/tutor/app/views/teaching_assistants/new.html.erb
+++ b/tutor/app/views/teaching_assistants/new.html.erb
@@ -18,7 +18,7 @@
<% end %>
-
<%= button_to "Back", {:controller => 'courses', :action =>'index'}, class: "btn btn-success", style: "float:right; margin-top:-50px", :method => :get %>
\ No newline at end of file
From 749a1a4cbefcc920f01e61cb8a039f3dd9c2a232 Mon Sep 17 00:00:00 2001
From: Nadine Adel
Date: Thu, 24 Apr 2014 02:36:01 +0200
Subject: [PATCH 380/526] Issue #183 fixing documentation
---
.../controllers/model_answers_controller.rb | 47 ++++++++++---------
1 file changed, 24 insertions(+), 23 deletions(-)
diff --git a/tutor/app/controllers/model_answers_controller.rb b/tutor/app/controllers/model_answers_controller.rb
index 81203bf7..3ac46a8f 100644
--- a/tutor/app/controllers/model_answers_controller.rb
+++ b/tutor/app/controllers/model_answers_controller.rb
@@ -3,10 +3,10 @@ class ModelAnswersController < ApplicationController
# [Add answer story 4.6]
# It creates the new answer.
# Parameters:
- # @problem:To fetch the problem to which the answer is added.
- # @answer: the new answer the user enters.
- # @answers: All the previous answers that had been entered before.
- # Return : none
+ # @problem:To fetch the problem to which the answer is added.
+ # @answer: the new answer the user enters.
+ # @answers: All the previous answers that had been entered before.
+ # Returns : none
# Author: Nadine Adel
def new
@problem = Problem.find(params[:problem_id])
@@ -19,9 +19,10 @@ def new
# [Add answer story 4.6]
# The new answer is saved and check that the user is a lecturer or TA.
# Parameters:
- # @new_answer:answer provided by the user.
- # @problems:The problem to which the answer is linked.
- # Returns: Returns a message if the answer is added and another message if answer was not added.
+ # @new_answer:answer provided by the user.
+ # @problems:The problem to which the answer is linked.
+ # Returns:
+ # Returns a message if the answer is added and another message if answer was not added.
# Author: Nadine Adel
def create
@new_answer = ModelAnswer.new
@@ -48,13 +49,14 @@ def create
# [Edit answer story 4.7]
# Answer that has been created before is edited
# Parameters:
- # @answer:answerthat is being edited.
- # @problem:The problem to which the answer is linked.
- # @tips:Tips that are linked to the answer being edited.
- # @tips_check:used to check the type of Hint.
- # @hints:Hints that are linked to the answer being edited.
- # @hints_check:used to check the type of Hint.
- # Returns: Returns a message if the answer is edited and another message if answer was not edited.
+ # @answer:answerthat is being edited.
+ # @problem:The problem to which the answer is linked.
+ # @tips:Tips that are linked to the answer being edited.
+ # @tips_check:used to check the type of Hint.
+ # @hints:Hints that are linked to the answer being edited.
+ # @hints_check:used to check the type of Hint.
+ # Returns:
+ # Returns a message if the answer is edited and another message if answer was not edited.
# Author: Nadine Adel
def edit
@answer = ModelAnswer.find(params[:id])
@@ -68,7 +70,7 @@ def edit
# [Edit answer story 4.7]
# Answer is updated in the database.
# Parameters:
- # @answer:answer that is being updated.
+ # @answer:answer that is being updated.
# Returns: None.
# Author: Nadine Adel
def update
@@ -85,8 +87,8 @@ def update
# [Add answer story 4.6]
# It shows answer that was entered before.
# Parameters:
- # @answer:previous answer.
- # Return : none
+ # @answer:previous answer.
+ # Returns : None.
# Author: Nadine Adel
def show
@answer = ModelAnswer.find(params[:problem_id])
@@ -95,9 +97,9 @@ def show
# [Add answer story 4.6]
# It shows all the answers that are saved in the database.
# Parameters:
- # @answers:previous answers that are saved in the database.
- # @problem:problem to which the current answer is added.
- # Returns : none
+ # @answers:previous answers that are saved in the database.
+ # @problem:problem to which the current answer is added.
+ # Returns : None
# Author: Nadine Adel
def index
@problem =Problem.find_by_id(params[:id])
@@ -106,9 +108,8 @@ def index
# [Add answer story 4.6]
# It requires the attributes from the form that we are interested in.
- # Parameters:
- # None
- # Return : none
+ # Parameters:None.
+ # Returns : None.
# Author: Nadine Adel
private
def post_params
From c859bcb377c18e8570907fa2692849ae84e6ec46 Mon Sep 17 00:00:00 2001
From: AbdullRahman ElHusseini
Date: Thu, 24 Apr 2014 02:38:48 +0200
Subject: [PATCH 381/526] Issue #208 Updating seeds after database changes
---
tutor/db/seeds.rb | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index 8eadba45..0ca20e64 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -82,11 +82,11 @@
puts("# -----------------------Problems---------------------------")
- Problem.create(title:"Problem 1", description:"This will be very hard Problem")
- Problem.create(title:"Problem 2", description:"This is very hard Problem" )
- Problem.create(title:"Problem 3", description:"This wont be a hard Problem")
- Problem.create(title:"Problem 4", description:"This will be very easy Problem")
- Problem.create(title:"Problem 5", description:"This is very easy Problem")
+ Problem.create(title:"Problem 1", description:"This will be very hard Problem", track_id: 1)
+ Problem.create(title:"Problem 2", description:"This is very hard Problem", track_id: 1)
+ Problem.create(title:"Problem 3", description:"This wont be a hard Problem", track_id: 1)
+ Problem.create(title:"Problem 4", description:"This will be very easy Problem", track_id: 2)
+ Problem.create(title:"Problem 5", description:"This is very easy Problem", track_id: 2)
puts("# -----------------------Tracks---------------------------")
Track.create(title: "Track 1" , difficulty: 0)
From f343d85a7bca54780953fd2907e316e5bc352ce9 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 02:48:24 +0200
Subject: [PATCH 382/526] fixing indentation
---
tutor/app/views/teaching_assistants/index.html.erb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tutor/app/views/teaching_assistants/index.html.erb b/tutor/app/views/teaching_assistants/index.html.erb
index 8a9b0466..5b5880b8 100644
--- a/tutor/app/views/teaching_assistants/index.html.erb
+++ b/tutor/app/views/teaching_assistants/index.html.erb
@@ -1,9 +1,9 @@
The Course's Teaching Assistants
-<% if flash[:notice] -%>
-
<%= flash[:notice] %>
-<% end %>
+ <% if flash[:notice] -%>
+
<%= flash[:notice] %>
+ <% end %>
From 1d34711bc79f8c27dd8c9fc02f067bad2f394e24 Mon Sep 17 00:00:00 2001
From: ahmed93
Date: Thu, 24 Apr 2014 02:49:57 +0200
Subject: [PATCH 383/526] Database fixing relations and seeds missing
parameters
---
tutor/Gemfile.lock | 5 +++++
tutor/app/models/lecturer.rb | 2 +-
tutor/app/models/method_constraint.rb | 2 +-
tutor/db/schema.rb | 2 +-
tutor/db/seeds.rb | 21 +++++++++------------
5 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/tutor/Gemfile.lock b/tutor/Gemfile.lock
index fa0d2aac..63d729da 100644
--- a/tutor/Gemfile.lock
+++ b/tutor/Gemfile.lock
@@ -29,6 +29,7 @@ GEM
atomic (1.1.16)
bcrypt (3.1.7)
builder (3.1.4)
+ chronic (0.10.2)
coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
@@ -126,6 +127,9 @@ GEM
raindrops (~> 0.7)
warden (1.2.3)
rack (>= 1.0)
+ whenever (0.9.2)
+ activesupport (>= 2.3.4)
+ chronic (>= 0.6.3)
PLATFORMS
ruby
@@ -144,3 +148,4 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
unicorn
+ whenever
diff --git a/tutor/app/models/lecturer.rb b/tutor/app/models/lecturer.rb
index a9ba664d..84ecb1b5 100644
--- a/tutor/app/models/lecturer.rb
+++ b/tutor/app/models/lecturer.rb
@@ -15,7 +15,7 @@ class Lecturer < ActiveRecord::Base
has_many :topics
has_many :tracks, as: :owner
- has_many :problems, as: :ownerm
+ has_many :problems, as: :owner
has_many :model_answers, as: :owner
has_many :method_constraints, as: :owner
has_many :method_parameters, as: :owner
diff --git a/tutor/app/models/method_constraint.rb b/tutor/app/models/method_constraint.rb
index f13ce249..0b0a952b 100644
--- a/tutor/app/models/method_constraint.rb
+++ b/tutor/app/models/method_constraint.rb
@@ -6,7 +6,7 @@ class MethodConstraint < ActiveRecord::Base
belongs_to :model_answer
belongs_to :owner, polymorphic: true
- has_many :method_parameter, dependent: :destroy
+ has_many :parameters, class_name:"MethodParameter", dependent: :destroy
#Scoops
diff --git a/tutor/db/schema.rb b/tutor/db/schema.rb
index d498fcd2..0a4e42ab 100644
--- a/tutor/db/schema.rb
+++ b/tutor/db/schema.rb
@@ -152,7 +152,6 @@
t.string "method_name"
t.string "method_return"
t.integer "model_answer_id"
- t.integer "method_constraint_id"
t.integer "owner_id"
t.string "owner_type"
t.datetime "created_at"
@@ -162,6 +161,7 @@
create_table "method_parameters", force: true do |t|
t.string "parameter"
t.string "params_type"
+ t.integer "method_constraint_id"
t.integer "model_answer_id"
t.integer "owner_id"
t.string "owner_type"
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index b4e4c909..e3eb97c4 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -38,10 +38,10 @@
DiscussionBoard.create(title:"DiscussionBoard3", activated: true)
puts("# --------------------------Posts------------------------------")
- Post.create(content: "The Main Objective is to be a winner", views_count: 20)
- Post.create(content: "It is very hard to keep in this life, be happy", views_count: 100)
- Post.create(content: "Post3")
- Post.create(content: "Post4")
+ Post.create(title:"My 1st Post", content: "The Main Objective is to be a winner", views_count: 20)
+ Post.create(title:"My 2nd Post", content: "It is very hard to keep in this life, be happy", views_count: 100)
+ Post.create(title:"My 3th Post", content: "Post3")
+ Post.create(title:"My 4th Post", content: "Post4")
puts("# --------------------------Replies---------------------------")
Reply.create(content: "Reply1")
@@ -108,7 +108,7 @@
puts("# -----------------------TrackProgression---------------------------")
TrackProgression.create(level: 0, student_id: 1, topic_id: 1)
TrackProgression.create(level: 2, student_id: 1, topic_id: 2)
-
+
puts("# -----------------------Attempts---------------------------")
Attempt.create(success: true)
Attempt.create(failure: true)
@@ -128,7 +128,7 @@
Recommendation.create(problem_id:1, student_id:1, recommender_id:2)
Recommendation.create(problem_id:2, student_id:1, recommender_id:2)
Recommendation.create(problem_id:5, student_id:1, recommender_id:2)
-
+
puts("# -------------------------------------------------------")
puts("**************************************************************")
@@ -169,6 +169,8 @@
# since the table has key on (student_id and course_id)then the array will always be 1 elemet [0]
Student.find_by_id(2).courses << Course.find_by_id(2)
CourseStudent.where(student_id:2, course_id:2)[0].update(share: true)
+ Student.find_by_id(1).courses << Course.find_by_id(2)
+ CourseStudent.where(student_id:1, course_id:2)[0].update(share: true)
puts("# -----------------------Problems---------------------------")
Problem.find_by_id(3).test_cases << TestCase.first
@@ -227,9 +229,4 @@
DiscussionBoard.first.posts << Post.first
DiscussionBoard.first.posts << Post.find_by_id(2)
-puts("# -----------------------Solution---------------------------")
- Student.first.solutions << Solution.first
- Student.first.solutions << Solution.find_by_id(2)
- Student.first.solutions << Solution.find_by_id(3)
-
-puts("# ---------------------------------------------------------")
+puts("# ---------------------------------------------------------")
\ No newline at end of file
From caa63c26aec12ec50eacc4a42a6d96e031dc6dbd Mon Sep 17 00:00:00 2001
From: Nadine Adel
Date: Thu, 24 Apr 2014 02:54:06 +0200
Subject: [PATCH 384/526] Issue #183 Documentation
---
.../controllers/model_answers_controller.rb | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/tutor/app/controllers/model_answers_controller.rb b/tutor/app/controllers/model_answers_controller.rb
index 3ac46a8f..72c3a055 100644
--- a/tutor/app/controllers/model_answers_controller.rb
+++ b/tutor/app/controllers/model_answers_controller.rb
@@ -3,9 +3,9 @@ class ModelAnswersController < ApplicationController
# [Add answer story 4.6]
# It creates the new answer.
# Parameters:
- # @problem:To fetch the problem to which the answer is added.
- # @answer: the new answer the user enters.
- # @answers: All the previous answers that had been entered before.
+ # @problem:To fetch the problem to which the answer is added.
+ # @answer: the new answer the user enters.
+ # @answers: All the previous answers that had been entered before.
# Returns : none
# Author: Nadine Adel
def new
@@ -19,10 +19,10 @@ def new
# [Add answer story 4.6]
# The new answer is saved and check that the user is a lecturer or TA.
# Parameters:
- # @new_answer:answer provided by the user.
- # @problems:The problem to which the answer is linked.
+ # @new_answer:answer provided by the user.
+ # @problems:The problem to which the answer is linked.
# Returns:
- # Returns a message if the answer is added and another message if answer was not added.
+ # Returns a message if the answer is added and another message if answer was not added.
# Author: Nadine Adel
def create
@new_answer = ModelAnswer.new
@@ -49,14 +49,14 @@ def create
# [Edit answer story 4.7]
# Answer that has been created before is edited
# Parameters:
- # @answer:answerthat is being edited.
- # @problem:The problem to which the answer is linked.
- # @tips:Tips that are linked to the answer being edited.
- # @tips_check:used to check the type of Hint.
- # @hints:Hints that are linked to the answer being edited.
- # @hints_check:used to check the type of Hint.
+ # @answer:answerthat is being edited.
+ # @problem:The problem to which the answer is linked.
+ # @tips:Tips that are linked to the answer being edited.
+ # @tips_check:used to check the type of Hint.
+ # @hints:Hints that are linked to the answer being edited.
+ # @hints_check:used to check the type of Hint.
# Returns:
- # Returns a message if the answer is edited and another message if answer was not edited.
+ # Returns a message if the answer is edited and another message if answer was not edited.
# Author: Nadine Adel
def edit
@answer = ModelAnswer.find(params[:id])
@@ -70,7 +70,7 @@ def edit
# [Edit answer story 4.7]
# Answer is updated in the database.
# Parameters:
- # @answer:answer that is being updated.
+ # @answer:answer that is being updated.
# Returns: None.
# Author: Nadine Adel
def update
@@ -87,7 +87,7 @@ def update
# [Add answer story 4.6]
# It shows answer that was entered before.
# Parameters:
- # @answer:previous answer.
+ # @answer:previous answer.
# Returns : None.
# Author: Nadine Adel
def show
@@ -97,8 +97,8 @@ def show
# [Add answer story 4.6]
# It shows all the answers that are saved in the database.
# Parameters:
- # @answers:previous answers that are saved in the database.
- # @problem:problem to which the current answer is added.
+ # @answers:previous answers that are saved in the database.
+ # @problem:problem to which the current answer is added.
# Returns : None
# Author: Nadine Adel
def index
From 97e039da755c4db0eb806565c05b5de455de3b17 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 02:55:32 +0200
Subject: [PATCH 385/526] fixing indentation
---
tutor/app/views/teaching_assistants/new.html.erb | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/tutor/app/views/teaching_assistants/new.html.erb b/tutor/app/views/teaching_assistants/new.html.erb
index 342c3f68..0768e185 100644
--- a/tutor/app/views/teaching_assistants/new.html.erb
+++ b/tutor/app/views/teaching_assistants/new.html.erb
@@ -23,12 +23,11 @@
<% end %>
- <% if @checkbox == true %>
- <% str = "Show only TAs I worked with" %>
- <% else %>
- <% str = "Show All TAs" , @checkbox = nil%>
- <% end %>
-
+ <% if @checkbox == true %>
+ <% str = "Show only TAs I worked with" %>
+ <% else %>
+ <% str = "Show All TAs" , @checkbox = nil%>
+ <% end %>
From 8929f97563a591ad989a41c0a4583704ef1aec73 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 02:57:11 +0200
Subject: [PATCH 386/526] fixing indentation
---
tutor/app/controllers/teaching_assistants_controller.rb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tutor/app/controllers/teaching_assistants_controller.rb b/tutor/app/controllers/teaching_assistants_controller.rb
index ee28ed5d..a4c4ebc8 100644
--- a/tutor/app/controllers/teaching_assistants_controller.rb
+++ b/tutor/app/controllers/teaching_assistants_controller.rb
@@ -21,9 +21,9 @@ def new
def create
begin
@teaching_assistant = TeachingAssistant.find_by_id(params[:teaching_assistant][:id])
- if params[:teaching_assistant][:id] == ''
- flash[:notice] = 'Error! you need to select a TA'
- redirect_to :action => 'new'
+ if params[:teaching_assistant][:id] == ''
+ flash[:notice] = 'Error! you need to select a TA'
+ redirect_to :action => 'new'
else
@course = Course.find_by_id(params[:course_id])
@course.TAs << @teaching_assistant
From 52ca7a322fb411b415f6c5326873132fa85b9c8e Mon Sep 17 00:00:00 2001
From: AbdullRahman ElHusseini
Date: Thu, 24 Apr 2014 03:00:08 +0200
Subject: [PATCH 387/526] Issue #208 fixing seeds
---
tutor/db/development.sqlite3 | Bin 217088 -> 217088 bytes
tutor/db/seeds.rb | 10 +++++-----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tutor/db/development.sqlite3 b/tutor/db/development.sqlite3
index 8c0986898a3a56d6fe5e34828815e6e6d86306a4..641983506b1375066a805be87d6fde69365137e5 100644
GIT binary patch
delta 331
zcmZozz}v8ZcY-uy>O>i5#?*}onf{E-&8Pg^Px&)$KjqJ4rNG6^`Eu@&
z9h?{C5ulgjT
Date: Thu, 24 Apr 2014 03:02:57 +0200
Subject: [PATCH 388/526] Issue #208 delete db development file
---
tutor/db/development.sqlite3 | Bin 217088 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 tutor/db/development.sqlite3
diff --git a/tutor/db/development.sqlite3 b/tutor/db/development.sqlite3
deleted file mode 100644
index 641983506b1375066a805be87d6fde69365137e5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 217088
zcmeI5eQ+D;dDwTcAVKg0E1m8R($O+k)SY?oouK{10`#0Mh~i08Ohj2LelS
zPx#XAf)r)D9zeR8Ox#X0lRp|~8hbiP(@tlaOp>YF+Wq!)8aJKkN8+Y`IGwR4ZQM>`
zJ09Cf{V~&Lcd?6I?1B<`A2~@6?gV1rXZLxZ=l8z*e(k&OyK-$&H56u}q18$TBM^rO
zk|fSB3_%Pj1VKpfulphYGyI4;NAQ>Q{2uTVbe#Iui6M|u^moj2MEb|{59sfVzdojn
z{^2MYH%9(p?7OkT@Rx`FMfA7He@$K>evSB|Us<$0eI%BAeTr<~Q0o=tj`dZnDrKXk
zDVknv)Qg&;D@L(d()FE&Rw){dTT0zM;pw^M`FvrXSzTJVwmQ!&ES;NwjhTK(Ez``E
zC1%>yHO;&@9TwSis`XSX`3l%LImkw(R#L03q9YG$lyzB%6?S;)?Z)9)a%zhF+$p29
zUR7NE?vJOs5f$=h7w7vtQ7hAcqcDGdewn$tyl^?cyvAIbUt{vCg)0k7aN*_or2?~b
z1^%rrF22l6*Gn~Jn%ORC<*kzTA}>iP2<%$e7rL!z>V~R7V(d2In)ODbs+8(*x|2!)
zJ(b4#G*c-V3Y=8hglp8gp=>Ied5zZCP^(H&tyzM;s5TYI7MeGXin6IGK}#!2v!od{
zrEUZwcX$;|CcTK=VB3qnh|8J+=2nU&&}SNMs5R60R?|EP1S|Ejw%arX;Ru*>^RMPt
z7YoeHjF)+6cI!`rzLRutvEM39sVTK}MJo=lT30vgMYUcmH(Dm2E(6yn)@xI_rDUnM{)R8di?q0z-A{>##qkTVdw?y6;?GQ*_b7|sxc8--
zm1Z_(fEu9EbhxE`_uIa_PbRFQul*U@du6?~3B`q8aemN!-a6q2@^W969i0Hn=E(Nz
zR%KAg&so0ew#$0aP)cRUo|{FeuvEwdkb@IlTm6-kd!=0g>~X#6Q;(>bX#;VXs8j9C
zcq};wra`n&U+kfA57C4l>>g+O&2sJvZ&4C%XW-0Kdtoe=ynTx7ke&+GiCH&V6)2Ca
zwtyW5&cZ!cDRw1r*njSLC~>=4(0{Jk#u%j6pEQmoe#gy1!Zy)PgwfGh^3*A^ecqP{
z&b9rqkA>rQPWML@Am@)eAWpTf#$(CWX|fX!0qfL%A!Hqq2dxvNk3Ixj_v9d4M`XgX
z+FuS4N1*$C1{WQP%{MV(m5c35KEBR5?tSP6#KQ@@a({FIhJEn|
zI!l$BTG#FGs87SR9e5xYLpuxuy9V!K4`5%(AB#ZW?KIgwZIytnx(Zy2dU*?aHpQB{
zsg=xIKo0~^T}=Kud(h=}NfuCIVg(>(>v1}Do3zWV!*()1(1M6Rq4rd6bs3;%Ep(2;
zcd|1E-_N!`Jpq4)=-(yipV0q@{v-O|!%zGm0VIF~kN^@u0!RP}AOR$R1dsp{KmvdL
z1P%>FQasCvtjO~m3m^Va)Cu8oY*rG*>>;WfBJeUN@jRbB6micHxGa~EIEswW>?rs%
zME{oA|NlDuZTjEAPy8SOB!C2v01`j~NB{{S0VIF~kN^@u0)M>(o}yBuzwbZP3vxRD
zQ8&o#{Znp`$aTB_ktjvSS@ZcnN&ia%{>KjzKmter2_OL^fCP{L5$WQ&XhgsJ5(^_^HuD
z)G_-sJvvT<0yr5K!l~&ek0vOIgcZJ2b734X`}ZG+9%Ot%kXFmj){+
zz)Bf9l^CZ^kOnN9Q7o5qMUNjIqh?6&a!>kLe3VL()=E^=Xxxmr(NxPiH8w&`lA6-2
zs){}okHI<3hHmK5XNDo7z^Y8t*btoFT`h!4MkxVe4XhwUjZ@%_vnUKTL4w=v0wz>E
zLLH0S3psRig*ovbKIZd(So9A+NB{{S0VIF~kN^@u0!RP}AOR$R1dzaEOaS};k8$Fn
zYe)bIAOR$R1dsp{Kmter2_OL^fCRb(%>F->_`d|q`@aBx@Ph=901`j~NB{{S0VIF~
zkN^@u0!ZKyC-8IBC^1P#;)Im%ZpbSLvHw}vQgsIYx2M-L#ujWG9(-Fqm*!X@n-d31
zZbrJ=IY&Fs2et1sf*P{vT#n}jcCh3o*{_@90=gUZ5WBPKtiTI$h~19F?EgpTADZj`
z|L_q{U^E{IAOR$R1dsp{Kmter2_OL^fCP{L67Uj;Mko?i1R$w++*}4ALjS<*|Np>y
z3jRg{NB{{S0VIF~kN^@u0!RP}AOR$R1RiYy!%;F$Mk3K@JRUcn|C97jp#T49`-Ijb
z0VIF~kN^@u0!RP}AOR$R1dsp{Kmwrz+~@z;{}1JZfk*%eAOR$R1dsp{Kmter2_OL^
zfCL@~0`BvF-2d-!NKW(t2_OL^fCP{L51(5`91dNB{{S0VIF~kN^@u0!RP}AOR#W
zn1I>;r|4%0`giCG{J{?rKmter2_OL^fCP{L5aePh`Wvl<6_+x_pBK>jrgC8V-1dsp{Kmter
z2_OL^fCP{L5{Yg
ziU0cOB{5oz1dsp{Kmter2_OL^fCP{L5^xE$Yvi-m0X*r<=P$R1-~gWNPE7^+M4XuB
zB`G8II%)#L3-EwU5%X|SDH|)7A8Ly1e=7IVpeT+|K-~*Q-~mqI6?v
z?Z%dVSG>Bk&YxYav8HZnB?A^P)dK;M
zx#jtMVV)`E&o0h0(*gN3^WyZjqM56oPBYsjt-MvzUW7N~Qq0no0<*NbxR`3kBC+Hv
z5a(&NUQzC}>gw&5QVeJc1W?_mSCEeYpWl7L7we^(@-keR>TEKxy1WLDb?ZhW=Yp~8X83HO(YOh8tcx^6g2BbW4X!XMM4L&Q{oCjahH47tK7>ODHqMPVl}o+7DoY7<&52C<6z2
z`43HlTS2D>1n3E9Tt%tNGQ%0yDEQ18pR|RfaaJK1i(AVWEj;
zRWSxC*bgJ~`9B@`F%kJO^@Zq#p_@a0HvDg5OCysbUyt7&9UmJT&m_J@-+aQ#26Xoc
zAkb#opNS=3c!BItR_Rb~RFtApQH_SCdw&o6O9`*&KqbX~?#}i{+J7UKOr^+9tZQSf
zX?EKbO|z`@9>x0Y^a|f|OFN17XJg69N%9`_2VwZZuEGGMS(E7_{kB=52Qn(O9x)Ro
zP8WF>xS8{?S;XRgEhoq>;^8czz~Y2HqEh9Ug2wo>s?a>YlK|wRFecng8TOYfSo#U}^
z#*Ww@nUhgmgl6p=tms{Fs=d&mV#(X5$PO7o*ohJZUHIPj1&{lO)7;&!itFa~S9+yC;835b{qh5uY^X*x
zSelp0hPrKz9S&+2+iB~~5ReG_albRu8L`G8@1L^VhdgfR*4JUbn^xF?Tyr~oPJIFn
zZ8kKhe0syV=18fxih>cqnriJqW|qn@g6pfmYEbi4p^(;h6s^zq#!h`e*gGCjeEY>t
z+{(niFlC`~ie%mW@suB#8-5^cp>@8u@3{Zr>`hGx=CM6n0|N)Z_mRgSM}`dU_xgV`
zZdGEQSubn5O>?w7e1w0%WtyTZhI>iTXxvizp5K7(zLQ`TL!*DFUW4XRZ5?vZ0RMD#
zvtCrKrh@rYpxdT$jbgp7lv|o+M&Vr3_f()-(g(`=FIAg?mYVPKetD|Z8HHz5P~J{@
zs$@4mnsug?ByPx&Zq5yB(6}eLm)Z4#8*XNAJB3s2>CRXz`8q^=V^G9>sbD3QtLo{8
zwIfVRh*_bhrOfyLasK}k(A`BBkpL1v0!RP}AOR$R1dsp{KmthMi6(&W|3A^mkIo|j
zB!C2v01`j~NB{{S0VIF~kiZi{!0i81^aMfw7X1eN!4DEZ0!RP}AOR$R1dsp{Kmter
z2_S*TpTHF=PH?81`TS+Y*lJX+mNZzP30}F;8G&ax@f0hb;(3PWW<~g4NV6=Tm2!h6
zS0aNI^1;jabT-GzGCNpug&eGq3%g8~BrYcpmP|~1nHU>?iJ-qoe|+LKSoQC2;^@SG
znxMzOI=%zJ_(1|l00|%gB!C2v01`j~NZ`pNaB(b75YLeD>2-c)uw7b3&5
zvn)3&$!S64C0QISxj5?6H90^RJ1b_PlO<-wUMI_r#Ur^G_vv!ihjC*U7+#o_a+Y0!
zB+1fX$@vk`McY1}2pDB4Vso=xHZA0G0@pJtAbAtIlEgLA>`Jce!m2~HbfaaYn;N_(
zU#-75vvO^bSueq-GLt$bL|lX1z9naN1+#o6Ad$GV%w}cL?595E&xjXeJ`lrU_H(nG
zJj+XIR+0p+*DnP7{gO9_AKv~96|hp|)4a&?a)|wWT95@v7Tz3s_!y+n7&uPiJeka4
zCqdj&CMRa!j6Qq}Vn`bBko5#M*UK($43Ih^D`eOr^zVsl@b4i~Ii$Z2Nh!-&xtEPR
z5wK!L5VA$+?>}q=A^m?YoslwG7^UbRyO7v4G|kNCuQqg}H>Jcm7qsMZFcBd5jN6r*qx!T2
z=kmk35FM8d)o)9{hBr(@-kZ;M#I#Yhxh@zcN7$HZmw`RED<;ufiqeEV78qj-Bvo|-
zHd6-3Tcu`mx3U*uIU{qKY=AvX(cuJv%jPB$Byp1Z5t*2ze`n(JiLWIp^v#J&<3Aez
z!uYFWe?IohV{@b58U6g|x%hYEzY?Dx`QFIqN6y8*7yH%N!tf7=zc{=w^u3{989EpJ
zPV|?f7pNb-H*8QV5pyfb7HTmwiSCMg%5?A%Z6kt`&xEZkkeT%!?C^j
zZvjbRa-2Bc%U0cN0LF%91ISt8EDw`2%~^rHO5Vw=yg4s5o6BXEp98IKHn6fk!wG{d
zQDTRKpUdi&Y5S`p0oseBwE)BCF1<7|4@UvdYwWH(2q-$qg*t4yqvv9Ba%(RdWG*p`9#WZKmKHL#9?8nnU0VsW0qdyE4YU;|4om5r
zD2ZG@RF7ok$N`kfd{*$Z%xnObQd_d})V`I9a6jcZzAu-upwyA991c?|?cqMm6^24p
z@|69KrLJV<&;gW+P@_n_M!QF;Em@%tpp@s}b=RQ#V5u!xN$gvxn1*@SQm(Iz0;Z5t
zZOO{S0hDIgY&O$>PgzQB$;$Y?l?v$$l>IR4+L`R@GIb<3#=;7JS>B`Yhw1#RkQRk3
z+^&6!J(BCAU~QmQ$?T<eymn_Dh31k+7R?(vCgS3fRvp$tXNy_s~i)X@ZQ!ApV&q+N-?KrJjlVeQADkXiF={gcJ*5HEWC^k|MlLmawo87)1oBjvY9#9EC7_5Gu|y_y?0UE
zQ`vMTo8_{>R|G)4Et!M;0K7_iuPk_!!23f|$ddn{#Fos##tvR3z1IvqN`zcS=0nxn
z5^&^|2NN7{#wFNvzzde&3oH+>6A8Wf|E`Vj0t$q4@JhtPz3(7ht!TgQWntHPTc*0;_fTplqm`Zg`ZtZ~42udp{h
zB$vha|D6=XzeoTHAOR$R1dsp{Kmter2_OL^fCL_20%rf8n)oI`e=_l9_=6uLfCP{L
z51&K#>2w!!mJ>gTgb?)
z0K4zG50gETteoZLOzBK1U4EV~J&{!51>*vLx6Z%1RoM+!Ewk{1-m_zaV@_5!B^+$t!@_^PA8jV`9B~{x
zaUGkn92+scTrpY|rEc&&2c0M1LN*QCAqbwWjDnIgx_x=N+^BUOO)uU)TfKF+wz0O-
zQsfNolCdhlIJB&+bRf`#cLO8+SbjrtNgawX2=Jc$c387!X8+j
zEq6R7+7d3r#M=tDqbzXSTWaam^Bb^-fWEeSwsom|v9f#i+{O7ji@UYe+G}UI+sm(Q
z-@Uo9t?b-cP|WrJDEbcw`n&WW!yo)00VIF~kN^@u0!RP}AOR$R1dsp{Kmv~jfjE^U
ztuY$vFf~K+-jRaHA!;V>8#}=H|BptZqLoMh2_OL^fCP{L5fQ2N^P7c5Wm(~5
z&B!))PH(QAUD8+TH!oaGSLa$6x3ulG^p2>6#hS~pGVG@3tPJ3b)s%#+3~(fJlsMuz
zmd_vWtqV}d!^{7ic#0KI@t&9JGZ_(_+e323fHe=?#Q;`s2-ngTMJ($V&JCiDkvBl%*2V)>g@TRrcO`@Mz3%teESiXh3o`
z;@8M|HTIBut`l=v$&;=D2^bfHe+$tbNKP0I2g%8^TrMs1BA@HMJz;_LO04()6W=1}
zzek^iKlnicNB{{S0VIF~kN^@u0!RP}AOR%sh!S{%iWA53FjSDw7aC2qEEKj>oq_-D
zBc`J0Wle1wYNH-9Zos8ER%V4@Z(YiyGZH8BnNLP6{c%S>@6*qF^#_L~*mN!@N@8!M
z!|C#adR~%+EdNQ;Rv+)0&-v7I4^j`y8pt7I6q1zANja7m%>I9bzE99!g)jUd0VIF~
zkN^@u0!RP}AOR$R1dsp{KmzX>fmb3im_b73^O2AN2nmK6cvyHbICkJjK1RlfkvNPG
zgqCw+MBT@?eHLm*ZiEKDayoj$J+vZ`@Ck_Id-h
zO(I1FpQ?-LEYAsiaJ2xiMwZzu$DfB)2K5U@gGGDuYk?;X;lV1Xw_z|M|ZwG5h}$!IjcL11pMBmOC@{APpQZX0stS2(X=<0JFc(jP9)=lg{RH
znM|-BCkbgeBf&0xXX37g4I_j@CM}C1m=WY4q%$mREhnEDd60&Tz-7W_jKi*jvdD4S
zGqDG0kYJ*FHq-`zlLUc3GyEV8LQc%G!7egz0MBGWJTvql4Lq0tTL|{|dqD%6&51(h
zOw`p7nxislPV#L*=+2zy(>XaS$k{V6WYEo%1JZ&O;l+gD*a7S~m=z%@vS(m~V6R*a
zYxE0{oFO@iPs;);WQ8*@Ah4GW@YX>NvP}p{KAquUUjWJK|5I-g)SJ=i=2ed`kumP=9cI4g?XlsKf5^3xO=*WDw<|qoDS+Qs+DO5#xs>oMPrt(6qu#e
z#l@F%odgk^XKQ6nXAhS
zm-EYO%%%A?Ccj#^vakdiF3&Fk$sWzFntG|GOf%aht-MvzUW64~Q($serYW#Xa6Kq(
zRFrD5RM&SD&6^gz3w!SL$s0TMz%_Q5vD*yVQPz}_p;U?`W16YJFGH;<5KF6R9{7V(
zozopUmOOo$yg%V3+bn6|p`mCF*j~VMp)|yYt?d
z1*G0E)D5*b
z(auw`WHL$K7c8Hf4c*YKuj78ttgr()6Q0;=ZS#SSY^%zS4y9wubgo+^K*p%3dbtJF
z5v0m`qoh^dzZ}vz*EteP9zRarf8C~KXHmVIRrL?|G3$!oMQomZz})m!>*YqRS%qS5
znptl&s!FL2lm@^v3(;a#t*Jhw@CdPd>;2={PIjJ-C0CD=?FFm0w!VrE#UdoEV-Qp{
zm7
z`dmZ@0e<`hIv?*mA4^ISd4I~fXP|{|O&9TYHNwI;e|8ExdRV
zCu7ND$H@DXMbN4$%&9izTl#4~B|GpyT*BK%6?FsJovo^|>%F-KRp{n+q3>Uj)L!aL
z$C5fnc7{Avw_TCKjlQWVR?AE`EAd`&U{~W^OM@q;yFkP0^x)ZhsJ1Jd;3a0_^sKR}
zdk0&pUF)2%oBcz*ls0QU*O#EaQz1FPcgcZrLsi*Upn2bG>3U4|gc^?Np0NFtrtMF6
z7%OYvTd^HB_34&Y{pCK#EYX3S8IZMm``EfQO+%|dRliXx8x76tJv96^UFpl(&gfHL
z@P7P%`%|4`RxAE<3zq*~%DVISc|QXu_&^jw%ezWr-5$|^)(+&e4Ydkh)=HbfF7YNb
zJQaY_Yu4*9P}6JYGw0@C&95#Nn3;_kP}Zue+c4Ilngs_Gs@_2zz-t#Mec`pzTPF3s
zP+h4hIt-h5lcQAGR&^K(^jc$9?N)Qp8@P|O0GmVlv^}q8yiHl9UeTG#a;*;HXyLNxIqA?i+W~fJto~a_Rv8bak^{RO@~HRo5ui>q@z$
zX=W78HGNT4OVG+3AnU(WZTcwyQs3qM^3?6lbFt*dpzoFR6yQ!KH_KKlMVx>a_9&X2
zbKHyU;@1f_Zx}muQ|%9TCS%Dph;(H@qnMKMRKT@y_vB@|r-l=R7xQNS=1@_YhfXk9#%bbXQfk
zhC>49(Hg
z^btCm_+jFIC;o{3HvN^vuO|Lk;y)zHiIv1$LZJU5agzQ!^k?Wg{RaIv6aOgjw-fDz
zo_IPzB*y9Ap#OmWs=up@M@Rq(AOR$R1dsp{Kmter2_OL^@WCN47L6Yxtp^JH$yhXg
zm^6&(L^M8ShcP_MpP-}h6J)nz$_OmuJLaV+|1tkz|1o#mf6RVpA{syLs-N^6al&)n
zBktIEG(Jhzl^q8D9rcRXq-CQivTT3W7YD~alZX;iuFbip{f9^VhfnzqrNjQiL;geB
zf0*zePWTVUeP+q>m}RwtGBfHsl;We&c+v(l;**HObd;PTBUkOg0Y;$cKOu$)NUkGs
eKwt?eM<@;XPZpzQW{bw6#9>m`V}wt$5c&VB`S-p6
From e5ae3acb82f4099085d700a9f0cb6574eabe847f Mon Sep 17 00:00:00 2001
From: ahmed93
Date: Thu, 24 Apr 2014 03:05:43 +0200
Subject: [PATCH 389/526] fixing conventions
---
tutor/app/models/lecturer.rb | 3 +--
tutor/db/seeds.rb | 26 +++++++++++++-------------
2 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/tutor/app/models/lecturer.rb b/tutor/app/models/lecturer.rb
index 84ecb1b5..5695d539 100644
--- a/tutor/app/models/lecturer.rb
+++ b/tutor/app/models/lecturer.rb
@@ -12,7 +12,6 @@ class Lecturer < ActiveRecord::Base
has_many :posts, as: :owner, dependent: :destroy
has_many :replies, as: :owner, dependent: :destroy
-
has_many :topics
has_many :tracks, as: :owner
has_many :problems, as: :owner
@@ -28,4 +27,4 @@ class Lecturer < ActiveRecord::Base
#Methods
-end
+end
\ No newline at end of file
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index e3eb97c4..06667124 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -110,24 +110,24 @@
TrackProgression.create(level: 2, student_id: 1, topic_id: 2)
puts("# -----------------------Attempts---------------------------")
- Attempt.create(success: true)
+ Attempt.create(success: true)
+ Attempt.create(failure: true)
+ Attempt.create(success: true)
+ Attempt.create(failure: true)
+ Attempt.create(success: true)
+ Attempt.create(success: true)
+ Attempt.create(success: true)
+ Attempt.create(success: true)
+ Attempt.create(success: true)
+ Attempt.create(failure: true)
+ Attempt.create(failure: true)
+ Attempt.create(failure: true)
Attempt.create(failure: true)
- Attempt.create(success: true)
- Attempt.create(failure: true)
- Attempt.create(success: true)
- Attempt.create(success: true)
- Attempt.create(success: true)
- Attempt.create(success: true)
- Attempt.create(success: true)
- Attempt.create(failure: true)
- Attempt.create(failure: true)
- Attempt.create(failure: true)
- Attempt.create(failure: true)
puts("#-----------------------Recommendations-----------------------")
Recommendation.create(problem_id:1, student_id:1, recommender_id:2)
Recommendation.create(problem_id:2, student_id:1, recommender_id:2)
- Recommendation.create(problem_id:5, student_id:1, recommender_id:2)
+ Recommendation.create(problem_id:5, student_id:1, recommender_id:2)
puts("# -------------------------------------------------------")
From b2ee6f28a633624cd970c1db892092f964606121 Mon Sep 17 00:00:00 2001
From: Nadine Adel
Date: Thu, 24 Apr 2014 03:07:49 +0200
Subject: [PATCH 390/526] Issue #183 documentation
---
.../controllers/model_answers_controller.rb | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/tutor/app/controllers/model_answers_controller.rb b/tutor/app/controllers/model_answers_controller.rb
index 72c3a055..6dc45d7b 100644
--- a/tutor/app/controllers/model_answers_controller.rb
+++ b/tutor/app/controllers/model_answers_controller.rb
@@ -4,9 +4,9 @@ class ModelAnswersController < ApplicationController
# It creates the new answer.
# Parameters:
# @problem:To fetch the problem to which the answer is added.
- # @answer: the new answer the user enters.
+ # @answer: The new answer the user enters.
# @answers: All the previous answers that had been entered before.
- # Returns : none
+ # Returns : None
# Author: Nadine Adel
def new
@problem = Problem.find(params[:problem_id])
@@ -19,7 +19,7 @@ def new
# [Add answer story 4.6]
# The new answer is saved and check that the user is a lecturer or TA.
# Parameters:
- # @new_answer:answer provided by the user.
+ # @new_answer:Answer provided by the user.
# @problems:The problem to which the answer is linked.
# Returns:
# Returns a message if the answer is added and another message if answer was not added.
@@ -49,12 +49,12 @@ def create
# [Edit answer story 4.7]
# Answer that has been created before is edited
# Parameters:
- # @answer:answerthat is being edited.
- # @problem:The problem to which the answer is linked.
- # @tips:Tips that are linked to the answer being edited.
- # @tips_check:used to check the type of Hint.
- # @hints:Hints that are linked to the answer being edited.
- # @hints_check:used to check the type of Hint.
+ # @answer: Answer that is being edited.
+ # @problem: The problem to which the answer is linked.
+ # @tips: Tips that are linked to the answer being edited.
+ # @tips_check: Used to check the type of Hint.
+ # @hints: Hints that are linked to the answer being edited.
+ # @hints_check: Used to check the type of Hint.
# Returns:
# Returns a message if the answer is edited and another message if answer was not edited.
# Author: Nadine Adel
@@ -70,7 +70,7 @@ def edit
# [Edit answer story 4.7]
# Answer is updated in the database.
# Parameters:
- # @answer:answer that is being updated.
+ # @answer: Answer that is being updated.
# Returns: None.
# Author: Nadine Adel
def update
@@ -87,8 +87,8 @@ def update
# [Add answer story 4.6]
# It shows answer that was entered before.
# Parameters:
- # @answer:previous answer.
- # Returns : None.
+ # @answer: Previous answer.
+ # Returns: None.
# Author: Nadine Adel
def show
@answer = ModelAnswer.find(params[:problem_id])
@@ -97,9 +97,9 @@ def show
# [Add answer story 4.6]
# It shows all the answers that are saved in the database.
# Parameters:
- # @answers:previous answers that are saved in the database.
- # @problem:problem to which the current answer is added.
- # Returns : None
+ # @answers: Previous answers that are saved in the database.
+ # @problem: Problem to which the current answer is added.
+ # Returns: None
# Author: Nadine Adel
def index
@problem =Problem.find_by_id(params[:id])
@@ -108,8 +108,8 @@ def index
# [Add answer story 4.6]
# It requires the attributes from the form that we are interested in.
- # Parameters:None.
- # Returns : None.
+ # Parameters: None.
+ # Returns: None.
# Author: Nadine Adel
private
def post_params
From 3e81f61f8cc68ce68e6b094fbd37af1ea1a51df0 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 03:14:45 +0200
Subject: [PATCH 391/526] fixing indentation
---
.../views/teaching_assistants/index.html.erb | 26 +++++++++----------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/tutor/app/views/teaching_assistants/index.html.erb b/tutor/app/views/teaching_assistants/index.html.erb
index 5b5880b8..48418b5c 100644
--- a/tutor/app/views/teaching_assistants/index.html.erb
+++ b/tutor/app/views/teaching_assistants/index.html.erb
@@ -1,27 +1,27 @@
The Course's Teaching Assistants
- <% if flash[:notice] -%>
-
<%= flash[:notice] %>
- <% end %>
+ <% if flash[:notice] -%>
+
<%= flash[:notice] %>
+ <% end %>
-
+
-
Name
-
Email
-
+
Name
+
Email
+
- <% @course_teaching_assistants.each do |teaching_assistant| %>
-
+ <% @course_teaching_assistants.each do |teaching_assistant| %>
+
-
<%= teaching_assistant.name %>
-
<%= teaching_assistant.email %>
-
- <% end %>
+
<%= teaching_assistant.name %>
+
<%= teaching_assistant.email %>
+
+ <% end %>
<%= button_to "Back", {:controller => 'courses', :action => 'index'}, class: "btn btn-success", style: "float:right; margin-top:-50px", :method => :get %>
\ No newline at end of file
From b45dde16f342c1ab440a83876d3a8a076baef0c9 Mon Sep 17 00:00:00 2001
From: Nadine Adel
Date: Thu, 24 Apr 2014 03:15:20 +0200
Subject: [PATCH 392/526] Issue #183 documentation
---
tutor/app/controllers/model_answers_controller.rb | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tutor/app/controllers/model_answers_controller.rb b/tutor/app/controllers/model_answers_controller.rb
index 6dc45d7b..e1cd6e27 100644
--- a/tutor/app/controllers/model_answers_controller.rb
+++ b/tutor/app/controllers/model_answers_controller.rb
@@ -3,7 +3,7 @@ class ModelAnswersController < ApplicationController
# [Add answer story 4.6]
# It creates the new answer.
# Parameters:
- # @problem:To fetch the problem to which the answer is added.
+ # @problem: To fetch the problem to which the answer is added.
# @answer: The new answer the user enters.
# @answers: All the previous answers that had been entered before.
# Returns : None
@@ -19,10 +19,10 @@ def new
# [Add answer story 4.6]
# The new answer is saved and check that the user is a lecturer or TA.
# Parameters:
- # @new_answer:Answer provided by the user.
- # @problems:The problem to which the answer is linked.
+ # @new_answer: Answer provided by the user.
+ # @problems: The problem to which the answer is linked.
# Returns:
- # Returns a message if the answer is added and another message if answer was not added.
+ # A message if the answer is added and another message if answer was not added.
# Author: Nadine Adel
def create
@new_answer = ModelAnswer.new
@@ -56,7 +56,7 @@ def create
# @hints: Hints that are linked to the answer being edited.
# @hints_check: Used to check the type of Hint.
# Returns:
- # Returns a message if the answer is edited and another message if answer was not edited.
+ # A message if the answer is edited and another message if answer was not edited.
# Author: Nadine Adel
def edit
@answer = ModelAnswer.find(params[:id])
From 62b777e0b75ea9d94563f8babc946bca3c735e58 Mon Sep 17 00:00:00 2001
From: ahmed93
Date: Thu, 24 Apr 2014 03:18:24 +0200
Subject: [PATCH 393/526] adding line in lecturer
---
tutor/app/models/lecturer.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/tutor/app/models/lecturer.rb b/tutor/app/models/lecturer.rb
index 5695d539..4d4e5955 100644
--- a/tutor/app/models/lecturer.rb
+++ b/tutor/app/models/lecturer.rb
@@ -1,4 +1,5 @@
class Lecturer < ActiveRecord::Base
+
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
From 4c4ef7af38eff61716f92bd4809b3c76fed4fbad Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 03:19:16 +0200
Subject: [PATCH 394/526] fixing indentation
---
tutor/app/views/courses/edit.html.erb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/views/courses/edit.html.erb b/tutor/app/views/courses/edit.html.erb
index 46000367..24af501f 100644
--- a/tutor/app/views/courses/edit.html.erb
+++ b/tutor/app/views/courses/edit.html.erb
@@ -20,7 +20,7 @@
<%= button_to "Add a TA", {:controller => 'teaching_assistants', :action => 'new',
:course_id => @course.id}, class: "btn btn-success", style: "float: left; margin-left: 15px", :method => :get%>
<% if(lecturer_signed_in?) %>
diff --git a/tutor/config/environments/development.rb b/tutor/config/environments/development.rb
index 7752c5c1..6a2c1a10 100644
--- a/tutor/config/environments/development.rb
+++ b/tutor/config/environments/development.rb
@@ -1,10 +1,7 @@
Tutor::Application.configure do
# Settings specified here will take precedence over those in config/application.rb.
-<<<<<<< HEAD
-=======
->>>>>>> eece1025029484a4e8240f9fb6cc1a16a76e376f
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index daf01d93..ec755ac1 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -66,10 +66,10 @@
DiscussionBoard.create(title:"DiscussionBoard3", activated: true)
puts("# --------------------------Posts------------------------------")
- Post.create(content: "The Main Objective is to be a winner", views_count: 20)
- Post.create(content: "It is very hard to keep in this life, be happy", views_count: 100)
- Post.create(content: "Post3")
- Post.create(content: "Post4")
+ Post.create(title: "Hello", content: "The Main Objective is to be a winner", views_count: 20)
+ Post.create(title: "World", content: "It is very hard to keep in this life, be happy", views_count: 100)
+ Post.create(title: "Tile3", content: "Post3")
+ Post.create(title: "Title4", content: "Post4")
puts("# --------------------------Replies---------------------------")
Reply.create(content: "Reply1")
From b899bd1f4ff910817738981260c479d7ac65cd56 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Thu, 24 Apr 2014 04:06:47 +0200
Subject: [PATCH 406/526] Issue #246 editing .gitignore
---
tutor/.gitignore | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/.gitignore b/tutor/.gitignore
index 62eaaf0e..5830e151 100644
--- a/tutor/.gitignore
+++ b/tutor/.gitignore
@@ -40,4 +40,4 @@ models.svg
# Ignoring .java and .class files
/students_solutions/Java/*.java
-/students_solutions/Class/*.class
+/students_solutions/Class/*.class
\ No newline at end of file
From af29a9eae47e90add7b799fb42b772bbdd63a89f Mon Sep 17 00:00:00 2001
From: Mohab
Date: Thu, 24 Apr 2014 04:19:04 +0200
Subject: [PATCH 407/526] Issue #246 deleting .gitignore~
---
.gitignore~ | 25 -------------------------
1 file changed, 25 deletions(-)
delete mode 100644 .gitignore~
diff --git a/.gitignore~ b/.gitignore~
deleted file mode 100644
index 40c1a8fa..00000000
--- a/.gitignore~
+++ /dev/null
@@ -1,25 +0,0 @@
-.DS_Store
-*.rbc
-capybara-*.html
-.rspec
-/log
-/tmp
-/db/*.sqlite3
-/public/system
-/coverage/
-/spec/tmp
-**.orig
-rerun.txt
-pickle-email-*.html
-config/initializers/secret_token.rb
-config/secrets.yml
-
-## Environment normalisation:
-/.bundle
-/vendor/bundle
-
-# these should all be checked in to normalise the environment:
-# Gemfile.lock, .ruby-version, .ruby-gemset
-
-# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
-.rvmrc
From 6418ff9eb928401dff39bcb1e0a7de28fcf0981d Mon Sep 17 00:00:00 2001
From: Mohab
Date: Thu, 24 Apr 2014 04:27:17 +0200
Subject: [PATCH 408/526] Issue #246 removing brackets
---
tutor/app/models/student.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index 0d06888f..fa1b93cc 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -90,7 +90,7 @@ def get_next_problems_to_solve
course.topics.each do |topic|
level = TrackProgression.get_progress(self.id, topic.id)
topic.tracks.each do |track|
- if(track.difficulty == level)
+ if track.difficulty == level
track.problems.each do |problem|
if(!problem.is_solved_by_student(self.id))
key = course.name
From b4f889e259c8ab1de7914091493ef1171fddd740 Mon Sep 17 00:00:00 2001
From: AbdullRahman ElHusseini
Date: Thu, 24 Apr 2014 04:37:34 +0200
Subject: [PATCH 409/526] Issue #208 fixing seeds
---
tutor/db/seeds.rb | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index 0bdb7375..e6556d1e 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -213,4 +213,8 @@
Student.first.solutions << Solution.find_by_id(2)
Student.first.solutions << Solution.find_by_id(3)
-puts("# ---------------------------------------------------------")
+puts("# -----------------------TeachingAssistants---------------------------")
+ TeachingAssistant.first.courses << Course.first
+ TeachingAssistant.find_by_id(2).courses << Course.find_by_id(2)
+
+puts("# ---------------------------------------------------------")
\ No newline at end of file
From 2dcd3ec8bba2e28addd326a7c8abda34303ef848 Mon Sep 17 00:00:00 2001
From: MohabGhanim
Date: Thu, 24 Apr 2014 04:39:16 +0200
Subject: [PATCH 410/526] Issue #203 editing tags
---
tutor/app/views/layouts/_right_side_bar.html.erb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 6e96f4f5..24232988 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -11,8 +11,8 @@
-->
<% if student_signed_in? %>
- <% next_problems_to_solve = current_student.get_next_problems_to_solve
- if next_problems_to_solve != nil then %>
+ <% next_problems_to_solve = current_student.get_next_problems_to_solve %>
+ <% if next_problems_to_solve != nil then %>
Your Next Problems
<% next_problems_to_solve.each do |key , value| %>
@@ -53,4 +53,4 @@
<% end %>
<% end %>
-
\ No newline at end of file
+
From 9239925a1945b549e933ee61097321900b15f2ad Mon Sep 17 00:00:00 2001
From: AbdullRahman ElHusseini
Date: Thu, 24 Apr 2014 04:43:44 +0200
Subject: [PATCH 411/526] Issue #208 fixing indentation
---
tutor/app/controllers/problems_controller.rb | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/tutor/app/controllers/problems_controller.rb b/tutor/app/controllers/problems_controller.rb
index d109ef1e..1fde6448 100644
--- a/tutor/app/controllers/problems_controller.rb
+++ b/tutor/app/controllers/problems_controller.rb
@@ -21,7 +21,8 @@ def show
# Parameters:
# title: problem's title through permitCreate action
# description: problem's description through permitCreate action
- # Returns: Redirects to edit page on success, refreshes on failure
+ # Returns:
+ # Redirects to edit page on success, refreshes on failure
# Author: Abdullrahman Elhusseny
def create
p = Problem.new(problem_params)
@@ -65,9 +66,9 @@ def edit
# [Edit Problem - 4.5]
# Checks if a lecturer or TA is signed in and shows the problem's add page(title & description)
# on success and renders 404 on failure
- # Parameters:
- # none
- # Returns: Redirects to add page on success or 404 on failure
+ # Parameters: none
+ # Returns:
+ # Redirects to add page on success or 404 on failure
# Author: Abdullrahman Elhusseny
def new
if lecturer_signed_in? || teaching_assistant_signed_in?
@@ -81,7 +82,8 @@ def new
# Update the problem's title or description
# Parameters:
# problem_params: a problem's title & description
- # Returns: refreshes divisions in the page using AJAX without refreshing the whole page
+ # Returns:
+ # Refreshes divisions in the page using AJAX without refreshing the whole page
# Author: Abdullrahman Elhusseny
def update
@problem = Problem.find_by_id(params[:id])
@@ -121,7 +123,8 @@ def update
# Checks if problem is complete or not by checking the number of test cases and answers
# Parameters:
# problem_id: ID of the problem being edited
- # Returns: On success redirects to the track page, on failure redirects to the edit page
+ # Returns:
+ # On success redirects to the track page, on failure redirects to the edit page
# Author: Abdullrahman Elhusseny
def done
@problem = Problem.find_by_id(params[:problem_id])
@@ -141,7 +144,8 @@ def done
# Parameters:
# title: problem's title
# description: problem's description
- # Returns: params to create action
+ # Returns:
+ # Params to create action
# Author: Abdullrahman Elhusseny
private
def problem_params
From b6493b6c67db639bd8a0271861913763526b7efb Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 05:02:01 +0200
Subject: [PATCH 412/526] fixing documentation
---
tutor/app/controllers/teaching_assistants_controller.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tutor/app/controllers/teaching_assistants_controller.rb b/tutor/app/controllers/teaching_assistants_controller.rb
index a4c4ebc8..2a4ef672 100644
--- a/tutor/app/controllers/teaching_assistants_controller.rb
+++ b/tutor/app/controllers/teaching_assistants_controller.rb
@@ -13,7 +13,7 @@ def new
@checkbox = !params[:check]
end
-# [Add TA - Story 1.5,1.6]
+# [Add TA - Story 1.4,1.5,1.6]
# Adds the TA selected from the dropdown list in the view to the course and to the lecturer's history
# Parameters: teaching_assistant_id , course_id
# Returns: flash[:notice] that shows the result of trying to add the TA
@@ -41,7 +41,7 @@ def create
end
end
-# [Add TA - Story /]
+# [Add TA - Story 1.4, 1.5, 1.6]
# lists the TAs added to the course.
# Parameters: course_id
# Returns:
From c40d4a0b416c8449e752dcc5bc2e862bc4df6024 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 05:04:17 +0200
Subject: [PATCH 413/526] adding indentation
---
tutor/app/views/teaching_assistants/index.html.erb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tutor/app/views/teaching_assistants/index.html.erb b/tutor/app/views/teaching_assistants/index.html.erb
index edcbd01e..85e51404 100644
--- a/tutor/app/views/teaching_assistants/index.html.erb
+++ b/tutor/app/views/teaching_assistants/index.html.erb
@@ -9,15 +9,15 @@
-
+
Name
Email
-
+
<% @course_teaching_assistants.each do |teaching_assistant| %>
-
+
<%= teaching_assistant.name %>
<%= teaching_assistant.email %>
From 4d0c3d5bf914976bd4d6a4bb9e6ade4bc1cae92d Mon Sep 17 00:00:00 2001
From: MohabGhanim
Date: Thu, 24 Apr 2014 05:04:25 +0200
Subject: [PATCH 414/526] Issue #246 removing brackets
---
tutor/app/models/student.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index fa1b93cc..513374b8 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -38,7 +38,7 @@ def get_a_system_suggested_problem
topic.tracks.each do |track|
if(track.difficulty == level)
track.problems.each do |problem|
- if(!problem.is_solved_by_student(self.id))
+ if !problem.is_solved_by_student(self.id)
suggestions.add(problem)
break
end
From 52289e8209011010fe915725140f99e99931aa22 Mon Sep 17 00:00:00 2001
From: Muhammad Mamdouh
Date: Thu, 24 Apr 2014 05:11:28 +0200
Subject: [PATCH 415/526] adding indentation
---
.../teaching_assistants_controller.rb | 36 +++++++++----------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/tutor/app/controllers/teaching_assistants_controller.rb b/tutor/app/controllers/teaching_assistants_controller.rb
index 2a4ef672..602e80b0 100644
--- a/tutor/app/controllers/teaching_assistants_controller.rb
+++ b/tutor/app/controllers/teaching_assistants_controller.rb
@@ -1,11 +1,11 @@
class TeachingAssistantsController < ApplicationController
-# [Add TA - Story 1.4]
-# this action renders the form and sets the value for checkbox
-# Parameters:
-# check : contains the value from the previous instance of the form
-# Returns: None
-# Author: Muhammad Mamdouh
+ # [Add TA - Story 1.4]
+ # this action renders the form and sets the value for checkbox
+ # Parameters:
+ # check : contains the value from the previous instance of the form
+ # Returns: None
+ # Author: Muhammad Mamdouh
def new
if @checkbox == nil
@checkbox = true
@@ -13,11 +13,11 @@ def new
@checkbox = !params[:check]
end
-# [Add TA - Story 1.4,1.5,1.6]
-# Adds the TA selected from the dropdown list in the view to the course and to the lecturer's history
-# Parameters: teaching_assistant_id , course_id
-# Returns: flash[:notice] that shows the result of trying to add the TA
-# Author: Muhammad Mamdouh
+ # [Add TA - Story 1.4,1.5,1.6]
+ # Adds the TA selected from the dropdown list in the view to the course and to the lecturer's history
+ # Parameters: teaching_assistant_id , course_id
+ # Returns: flash[:notice] that shows the result of trying to add the TA
+ # Author: Muhammad Mamdouh
def create
begin
@teaching_assistant = TeachingAssistant.find_by_id(params[:teaching_assistant][:id])
@@ -41,13 +41,13 @@ def create
end
end
-# [Add TA - Story 1.4, 1.5, 1.6]
-# lists the TAs added to the course.
-# Parameters: course_id
-# Returns:
-# @course
-# @course_teaching_assistants
-# Author: Muhammad Mamdouh
+ # [Add TA - Story 1.4, 1.5, 1.6]
+ # lists the TAs added to the course.
+ # Parameters: course_id
+ # Returns:
+ # @course
+ # @course_teaching_assistants
+ # Author: Muhammad Mamdouh
def index
@course = Course.find(params[:course_id])
@course_teaching_assistants = @course.TAs.order('name')
From 56a9ef96791b6ac3c0216ac71ac0358446e32945 Mon Sep 17 00:00:00 2001
From: MohabGhanim
Date: Thu, 24 Apr 2014 05:12:50 +0200
Subject: [PATCH 416/526] Issue #246 removing brackets
---
tutor/app/models/student.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/models/student.rb b/tutor/app/models/student.rb
index 513374b8..8aec5ab1 100644
--- a/tutor/app/models/student.rb
+++ b/tutor/app/models/student.rb
@@ -92,7 +92,7 @@ def get_next_problems_to_solve
topic.tracks.each do |track|
if track.difficulty == level
track.problems.each do |problem|
- if(!problem.is_solved_by_student(self.id))
+ if !problem.is_solved_by_student(self.id)
key = course.name
key += " - " + topic.title
key += " - " + track.title
From 106143749c299ae61a2ad493eadad8cd98735552 Mon Sep 17 00:00:00 2001
From: Khaled
Date: Thu, 24 Apr 2014 09:21:31 +0200
Subject: [PATCH 417/526] Issue #216 Fixed coflict markers
---
tutor/app/models/lecturer.rb | 3 ---
1 file changed, 3 deletions(-)
diff --git a/tutor/app/models/lecturer.rb b/tutor/app/models/lecturer.rb
index c7399ffc..3ec5c3c0 100644
--- a/tutor/app/models/lecturer.rb
+++ b/tutor/app/models/lecturer.rb
@@ -37,7 +37,6 @@ class Lecturer < ActiveRecord::Base
#Methods
-<<<<<<< HEAD
# [User Authentication Advanced - Story 5.9, 5.10, 5.11, 5.14, 5.15]
# Checks if the email is already registered in tables: Student and TeachingAssistant
# before registering the email for table: Lecturer
@@ -50,6 +49,4 @@ def duplicate_email
end
end
-=======
->>>>>>> 7a2782c115057f5a1727019edd7769639fc15b87
end
\ No newline at end of file
From d1c508a8a403d643df1e76c479be44e8094b1a68 Mon Sep 17 00:00:00 2001
From: Khaled
Date: Thu, 24 Apr 2014 10:07:26 +0200
Subject: [PATCH 418/526] Issue #216 Fixed seeds.rb
---
tutor/db/seeds.rb | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index 524c3658..aaa8c59b 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -37,6 +37,18 @@
faculty: "Fac", university: "Uni", major: "Maj", semester: 6,
advising: true, probation: true)
s.save!
+ s = Student.new(email: '3@student.com', password: '123456789',
+ password_confirmation: '123456789', name: 'StudentIII',
+ confirmed_at: Time.now, dob: DateTime.now.to_date, gender: false,
+ faculty: "Fac", university: "Uni", major: "Maj", semester: 6,
+ advising: false, probation: true)
+ s.save!
+ s = Student.new(email: '4@student.com', password: '123456789',
+ password_confirmation: '123456789', name: 'StudentIV',
+ confirmed_at: Time.now, dob: DateTime.now.to_date, gender: true,
+ faculty: "Fac", university: "Uni", major: "Maj", semester: 8,
+ advising: true, probation: false)
+ s.save!
puts("# ---------------------------TeachingAssistants-----------------------------")
t = TeachingAssistant.new(email: '1@ta.com', password: '123456789',
From ebc356f8c815c1140535b342a15cdd94d7746ca3 Mon Sep 17 00:00:00 2001
From: ahmed93
Date: Thu, 24 Apr 2014 10:15:40 +0200
Subject: [PATCH 419/526] fixing seeds conventions
---
tutor/db/seeds.rb | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/tutor/db/seeds.rb b/tutor/db/seeds.rb
index eb129b9b..ff8839be 100644
--- a/tutor/db/seeds.rb
+++ b/tutor/db/seeds.rb
@@ -131,6 +131,11 @@
Recommendation.create(problem_id:2, student_id:1, recommender_id:2)
Recommendation.create(problem_id:5, student_id:1, recommender_id:2)
+puts("# ----------------- Track Progressions ----------------------")
+ TrackProgression.create(:level => 1, :student_id => 2, :topic_id => 1)
+ TrackProgression.create(:level => 1, :student_id => 3, :topic_id => 1)
+ TrackProgression.create(:level => 1, :student_id => 4, :topic_id => 1)
+
puts("# -------------------------------------------------------")
puts("**************************************************************")
@@ -234,14 +239,4 @@
DiscussionBoard.first.posts << Post.first
DiscussionBoard.first.posts << Post.find_by_id(2)
-puts("# ----------------- Track Progressions ----------------------")
- TrackProgression.create(:level => 1, :student_id => 2, :topic_id => 1)
- TrackProgression.create(:level => 1, :student_id => 3, :topic_id => 1)
- TrackProgression.create(:level => 1, :student_id => 4, :topic_id => 1)
-puts("# ---------------------------------------------------------")
-puts("# -----------------------Solution---------------------------")
- Student.first.solutions << Solution.first
- Student.first.solutions << Solution.find_by_id(2)
- Student.first.solutions << Solution.find_by_id(3)
-
puts("# ---------------------------------------------------------")
From ecb1273666ec58147d676e45dedc1934a978b646 Mon Sep 17 00:00:00 2001
From: serag
Date: Thu, 24 Apr 2014 10:41:38 +0200
Subject: [PATCH 420/526] Issue #206 removed useless tags from show.html.erb
---
tutor/app/views/lecturers/show.html.erb | 80 ++++++++---------
tutor/app/views/students/show.html.erb | 88 +++++++++----------
.../views/teaching_assistants/show.html.erb | 80 ++++++++---------
3 files changed, 112 insertions(+), 136 deletions(-)
diff --git a/tutor/app/views/lecturers/show.html.erb b/tutor/app/views/lecturers/show.html.erb
index db7c3295..7a17b52b 100644
--- a/tutor/app/views/lecturers/show.html.erb
+++ b/tutor/app/views/lecturers/show.html.erb
@@ -1,46 +1,38 @@
-
-
-
- CoolSoft - Java tutor | <%= @lecturer.id %>'s Profile
-
-
-
<%= image_tag(@lecturer.profile_image_url.to_s) if @lecturer.profile_image? %> <%= @lecturer.name %>'s Profile
\ No newline at end of file
diff --git a/tutor/app/views/teaching_assistants/show.html.erb b/tutor/app/views/teaching_assistants/show.html.erb
index a7cdddfd..1fedd543 100644
--- a/tutor/app/views/teaching_assistants/show.html.erb
+++ b/tutor/app/views/teaching_assistants/show.html.erb
@@ -1,4 +1,7 @@
-
<%= image_tag(@teaching_assistant.profile_image_url.to_s) if @teaching_assistant.profile_image? %> <%= @teaching_assistant.name %>'s Profile
\ No newline at end of file
diff --git a/tutor/app/views/teaching_assistants/show.html.erb b/tutor/app/views/teaching_assistants/show.html.erb
index 1fedd543..edfda86c 100644
--- a/tutor/app/views/teaching_assistants/show.html.erb
+++ b/tutor/app/views/teaching_assistants/show.html.erb
@@ -19,21 +19,34 @@
<% @courses.each do |c| %>
<%= link_to "About us"%>
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 8b03a53f..0ace203e 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -3,55 +3,61 @@
# General layout for right side bar
# Author: Ahmed Elassuty
-->
-
+
+
+ Navigation!!
+
+
- <% if student_signed_in? %>
-
- <% next_problems_to_solve = current_student.get_next_problems_to_solve %>
- <% if next_problems_to_solve != nil then %>
-
-
Your Next Problems
- <% next_problems_to_solve.each do |key , value| %>
-
\ No newline at end of file
diff --git a/tutor/app/views/layouts/application.html.erb b/tutor/app/views/layouts/application.html.erb
index 1f1b435c..0104fd37 100644
--- a/tutor/app/views/layouts/application.html.erb
+++ b/tutor/app/views/layouts/application.html.erb
@@ -45,7 +45,7 @@
\ No newline at end of file
diff --git a/tutor/app/views/model_answers/_index.html.erb b/tutor/app/views/model_answers/_index.html.erb
index 08f1228e..573cdc00 100644
--- a/tutor/app/views/model_answers/_index.html.erb
+++ b/tutor/app/views/model_answers/_index.html.erb
@@ -2,16 +2,16 @@
-
<%= link_to "About us"%>
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 29814900..58035bf4 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -3,7 +3,7 @@
# General layout for right side bar
# Author: Ahmed Elassuty
-->
-
<%= button_to "Back", {:controller => 'courses', :action => 'index'}, class: "btn btn-success" , style: "margin-left:
- 600px; margin-top: 250px", :method => :get%>
\ No newline at end of file
+ 600px; margin-top: 250px", :method => :get%>
+
+
+
\ No newline at end of file
diff --git a/tutor/app/views/courses/index.html.erb b/tutor/app/views/courses/index.html.erb
index 37388dff..4f2b3e4b 100644
--- a/tutor/app/views/courses/index.html.erb
+++ b/tutor/app/views/courses/index.html.erb
@@ -1,57 +1,61 @@
-<% if !@courses.any? %>
-
You have no courses
-<% end %>
-<% if current_lecturer %>
- <%= button_to "Create course", { :action => 'new', :controller => 'courses' }, {
- class: 'btn btn-primary'} %>
-<% end %>
-
-
-<% if flash[:success_creation] %>
-
\ No newline at end of file
From a9d09899b2a23226eacbd42c8a242ad068d37dc6 Mon Sep 17 00:00:00 2001
From: ahmed93
Date: Thu, 24 Apr 2014 21:17:24 +0200
Subject: [PATCH 490/526] fixing indentations
---
.../javascripts/solutions_constraints.js | 80 +++++++++----------
1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/tutor/app/assets/javascripts/solutions_constraints.js b/tutor/app/assets/javascripts/solutions_constraints.js
index 1483ac96..6217872e 100644
--- a/tutor/app/assets/javascripts/solutions_constraints.js
+++ b/tutor/app/assets/javascripts/solutions_constraints.js
@@ -1,17 +1,17 @@
-// # Place all the behaviors and hooks related to the matching controller here.
-// # All this logic will automatically be available in application.js.
-// # You can use CoffeeScript in this file: http://coffeescript.org/
+//# Place all the behaviors and hooks related to the matching controller here.
+//# All this logic will automatically be available in application.js.
+//# You can use CoffeeScript in this file: http://coffeescript.org/
var type = new Array();
var param_name = new Array();
var var_type = new Array();
var var_name = new Array();
-// # [Add Solutions' constraints - Story 4.14]
-// # Description: Adds the parameters from the text_fields to array
-// # Parameters: none
-// # Returns: none
-// # Author: Ahmed Mohamed Magdi
+//# [Add Solutions' constraints - Story 4.14]
+//# Description: Adds the parameters from the text_fields to array
+//# Parameters: none
+//# Returns: none
+//# Author: Ahmed Mohamed Magdi
function add_params(field) {
var tmp_type = document.getElementById("params_type").value;
var tmp_name = document.getElementById("params_name").value;
@@ -55,11 +55,11 @@ function add_params(field) {
}
}
-// # [Add Solutions' constraints - Story 4.14]
-// # Description: removes selected variable from method Contraints
-// # Parameters: none
-// # Returns: none
-// # Author: Ahmed Mohamed Magdi
+//# [Add Solutions' constraints - Story 4.14]
+//# Description: removes selected variable from method Contraints
+//# Parameters: none
+//# Returns: none
+//# Author: Ahmed Mohamed Magdi
function remove_params(field) {
var index = field.id.split("_")[1];
type.splice(index,1);
@@ -83,11 +83,11 @@ function remove_params(field) {
$('#parameter').append("");
}
-// # [Add Solutions' constraints - Story 4.14]
-// # Description: Adds the parameters from the text_fields to array
-// # Parameters: none
-// # Returns: none
-// # Author: Ahmed Mohamed Magdi
+//# [Add Solutions' constraints - Story 4.14]
+//# Description: Adds the parameters from the text_fields to array
+//# Parameters: none
+//# Returns: none
+//# Author: Ahmed Mohamed Magdi
function add_variable(field) {
var tmp_type = document.getElementById("variable_type").value;
var tmp_name = document.getElementById("variable_name").value;
@@ -131,11 +131,11 @@ function add_variable(field) {
}
}
-// # [Add Solutions' constraints - Story 4.14]
-// # Description: removes selected variable from Variable Contraints
-// # Parameters: none
-// # Returns: none
-// # Author: Ahmed Mohamed Magdi
+//# [Add Solutions' constraints - Story 4.14]
+//# Description: removes selected variable from Variable Contraints
+//# Parameters: none
+//# Returns: none
+//# Author: Ahmed Mohamed Magdi
function remove_variable(field) {
var index = field.id.split("_")[1];
var_type.splice(index,1);
@@ -159,24 +159,24 @@ function remove_variable(field) {
$('#variable').append("");
}
-// # [Add Solutions' constraints - Story 4.14]
-// # Description: for showing the error massages for the user
-// # Parameters:
-// # errorArray: array of Error, for multi error massage show
-// # Returns: none
-// # Author: Ahmed Mohamed Magdi
+//# [Add Solutions' constraints - Story 4.14]
+//# Description: for showing the error massages for the user
+//# Parameters:
+//# errorArray: array of Errors, for multi error massage show
+//# Returns: none
+//# Author: Ahmed Mohamed Magdi
function showErrorMessage(arrayOfErrors) {
for (var i = 0; i < arrayOfErrors.length; i++) {
$("#errors").append("
"+arrayOfErrors[i]+"
");
};
}
-// # [Add Solutions' constraints - Story 4.14]
-// # Description: Validates Data before sending it to the Server side
-// # Parameters:
-// # errorArray: array of Error, for multi error massage show
-// # Returns: none
-// # Author: Ahmed Mohamed Magdi
+//# [Add Solutions' constraints - Story 4.14]
+//# Description: Validates Data before sending it to the Server side
+//# Parameters:
+//# errorArray: array of Errors, for multi error massage show
+//# Returns: none
+//# Author: Ahmed Mohamed Magdi
function testingValidation(errorArray,method,name) {
if (type.length == 0 &&
var_type.length == 0 &&
@@ -206,11 +206,11 @@ function testingValidation(errorArray,method,name) {
return errorArray.length == 0;
}
-// # [Add Solutions' constraints - Story 4.14]
-// # Description: submits via ajax to the controller
-// # Parameters: none
-// # Returns: none
-// # Author: Ahmed Mohamed Magdi
+//# [Add Solutions' constraints - Story 4.14]
+//# Description: submits via ajax to the controller
+//# Parameters: none
+//# Returns: none
+//# Author: Ahmed Mohamed Magdi
function submitParams() {
$("#errors").html("");
errorArray = new Array();
From cb7e1b92090830a0048355233824558fd2e29d81 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Thu, 24 Apr 2014 21:20:58 +0200
Subject: [PATCH 491/526] Fixed conflicts in posts controller
---
tutor/app/controllers/posts_controller.rb | 7 +------
tutor/app/views/posts/edit.html.erb | 3 ++-
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index 6ef7e136..8cc453c3 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -12,12 +12,7 @@ def new
@discussion_board = DiscussionBoard.find_by_id(params[:discussion_board_id])
@new_post = Post.new
end
-
- def show
- @post = Post.find(params[:id])
- @replies = @post.replies.order("created_at desc")
- end
-
+
# [Edit Post - Story 1.18]
# Description: This action takes the passed post id
# to be passed to the Edit form.
diff --git a/tutor/app/views/posts/edit.html.erb b/tutor/app/views/posts/edit.html.erb
index e8f20b3d..f15e2146 100644
--- a/tutor/app/views/posts/edit.html.erb
+++ b/tutor/app/views/posts/edit.html.erb
@@ -29,7 +29,8 @@
<%= f.submit "Update Post", class: "btn btn-success" %>
From 6c90bdfae53f854c66454ceafe6f0c3f1e2bd070 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Thu, 24 Apr 2014 21:29:05 +0200
Subject: [PATCH 492/526] Fixing conflicts in problem controller
---
tutor/app/controllers/problems_controller.rb | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/tutor/app/controllers/problems_controller.rb b/tutor/app/controllers/problems_controller.rb
index 7389b747..d5ba96aa 100644
--- a/tutor/app/controllers/problems_controller.rb
+++ b/tutor/app/controllers/problems_controller.rb
@@ -84,7 +84,6 @@ def new
end
end
-<<<<<<< HEAD
# [Remove Problem - Story 4.18]
# This action takes the problem id, remove it from the database
# and then redirects the user to the show page of the track that had the problem
@@ -103,7 +102,6 @@ def destroy
end
end
-=======
# [Edit Problem - 4.5]
# Update the problem's title or description
# Parameters:
@@ -178,5 +176,5 @@ def done
def problem_params
params.require(:Problem).permit(:title, :description, :track_id)
end
->>>>>>> master
+
end
\ No newline at end of file
From ba340937815d4f7e41f6ee56b740da64ececf51e Mon Sep 17 00:00:00 2001
From: Mohab
Date: Thu, 24 Apr 2014 21:29:21 +0200
Subject: [PATCH 493/526] fixing TA problem
---
tutor/app/views/courses/index.html.erb | 2 +-
tutor/app/views/courses/new.html.erb | 2 +-
tutor/app/views/courses/show.html.erb | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tutor/app/views/courses/index.html.erb b/tutor/app/views/courses/index.html.erb
index 4f2b3e4b..0ce82820 100644
--- a/tutor/app/views/courses/index.html.erb
+++ b/tutor/app/views/courses/index.html.erb
@@ -4,7 +4,7 @@
<% end %>
diff --git a/tutor/app/views/courses/new.html.erb b/tutor/app/views/courses/new.html.erb
index fbacdd7f..70618fcf 100644
--- a/tutor/app/views/courses/new.html.erb
+++ b/tutor/app/views/courses/new.html.erb
@@ -65,4 +65,4 @@
<% end %>
-
+
\ No newline at end of file
diff --git a/tutor/app/views/courses/show.html.erb b/tutor/app/views/courses/show.html.erb
index a0032e2f..18f5a9e4 100644
--- a/tutor/app/views/courses/show.html.erb
+++ b/tutor/app/views/courses/show.html.erb
@@ -3,7 +3,7 @@
From ec0f151de3e86c484ff804465866889188e703fe Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Thu, 24 Apr 2014 22:39:12 +0200
Subject: [PATCH 515/526] conflicts with master
---
tutor/app/controllers/posts_controller.rb | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index c3844454..1adf7bbf 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -40,10 +40,11 @@ def edit
# flash[:notice]: A message indicating the success of the deletion
# Author: Ahmed Atef
def destroy
- @dis = Post.find_by_id(params[:id]).discussion_board_id
+ @disscusion_board = Post.find_by_id(params[:id]).discussion_board_id
if Post.find_by_id(params[:id]).destroy
flash[:notice] = "Post successfully Deleted"
- redirect_to(:controller => 'discussion_boards' , :action => 'show' ,:id => @dis)
+ redirect_to(:controller => 'discussion_boards' ,
+ :action => 'show' ,:id => @disscussion_board)
end
end
# [Add Post - Story 1.13]
From b2dec3e4ea61660009f901aabc751559edfebdc7 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Thu, 24 Apr 2014 22:47:49 +0200
Subject: [PATCH 516/526] fixed conflicts
---
tutor/config/routes.rb | 4 ----
1 file changed, 4 deletions(-)
diff --git a/tutor/config/routes.rb b/tutor/config/routes.rb
index 615ef930..8c167b04 100644
--- a/tutor/config/routes.rb
+++ b/tutor/config/routes.rb
@@ -17,15 +17,11 @@
post 'courses/new' => 'courses#new'
post 'courses/share' => 'courses#share'
get 'courses/sign_up'
-<<<<<<< HEAD
- post 'posts/new' => 'posts#new'
post '/posts/:id' => 'posts#update'
-=======
get 'tracks/show_classmates/:id' => 'tracks#show_classmates'
post 'tracks/insert_recommendation' => 'tracks#insert_recommendation'
post 'solutions/execute' => 'problems#show'
post 'debuggers/:id' => 'debuggers#start'
->>>>>>> 7eb9faa02cd949c47035b7b7f69f9e74a5f97b7d
# You can have the root of your site routed with "root"
root 'site#index'
From 5805c141ad31b33cb45c6ac5ce8fb89cb41534cf Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Fri, 25 Apr 2014 01:52:13 +0200
Subject: [PATCH 517/526] fixed indentaiton
---
tutor/app/controllers/posts_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index 8cf0bfe7..657ef770 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -60,7 +60,7 @@ def show
# and assigns it to the respective discussion board.If the
# creation fails the user is redirected to the form
# Parameters:
- # topic_params[]: A list that has all fields entered by the user to in the
+ # topic_params[]: A list that has all fields entered by the user to in the
# add_post_form
# Returns:
# flash[:notice]: A message indicating the success or failure of the creation
From 43ab6bb75ebf37f2ae63d0a0ffb855a0d31aa3da Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Fri, 25 Apr 2014 02:21:05 +0200
Subject: [PATCH 518/526] fixed redirect in destroy funtion and fixed button
delete post
---
tutor/app/controllers/posts_controller.rb | 7 ++++---
tutor/app/views/posts/edit.html.erb | 4 ++--
tutor/app/views/posts/show.html.erb | 24 -----------------------
3 files changed, 6 insertions(+), 29 deletions(-)
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index 657ef770..9e7558eb 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -35,11 +35,12 @@ def edit
# flash[:notice]: A message indicating the success of the deletion
# Author: Ahmed Atef
def destroy
- @disscusion_board = Post.find_by_id(params[:id]).discussion_board_id
+ @disscusion_board = DiscussionBoard.find_by_id
+ (Post.find_by_id(params[:id]).discussion_board_id)
if Post.find_by_id(params[:id]).destroy
flash[:notice] = "Post successfully Deleted"
redirect_to(:controller => 'discussion_boards' ,
- :action => 'show' ,:id => @disscussion_board)
+ :action => 'show' ,:id => @disscusion_board.course_id)
end
end
# [Add Post - Story 1.13]
@@ -93,7 +94,7 @@ def create
# update fails the user is redirected to the form
# Parameters:
# topic_params[]: A list that has all fields entered by the user to in the
- # Edit_post_form
+ # Edit_post_form
# Returns:
# flash[:notice]: A message indicating the success or failure of the creation
# Author: Ahmed Atef
diff --git a/tutor/app/views/posts/edit.html.erb b/tutor/app/views/posts/edit.html.erb
index 9748159e..76530768 100644
--- a/tutor/app/views/posts/edit.html.erb
+++ b/tutor/app/views/posts/edit.html.erb
@@ -36,6 +36,6 @@
<%= f.submit "Update Post", class: "btn btn-success" %>
<% end %>
- <%= button_to "Delete Post", {:action => 'destroy'}, method: :delete,
- class: 'btn btn-primary',:id => params[:id] , :confirm => "Are you sure??" %>
+ <%= button_to "Delete Post", {:action => 'destroy', :id => params[:id]}, method: :delete,
+ class: 'btn btn-primary', :confirm => "Are you sure??" %>
\ No newline at end of file
diff --git a/tutor/app/views/posts/show.html.erb b/tutor/app/views/posts/show.html.erb
index 5d4af1c5..6b06d14c 100644
--- a/tutor/app/views/posts/show.html.erb
+++ b/tutor/app/views/posts/show.html.erb
@@ -6,10 +6,6 @@
:id => DiscussionBoard.find_by_id(@post.discussion_board_id).course_id}, {
class: 'btn btn-primary'} %>
-<<<<<<< HEAD
-<<<<<<< HEAD
-=======
->>>>>>> 9f5d2de792278daa7a008d66fca60495ffe3465e
<% if current_lecturer %>
<% @userID = current_lecturer.id %>
<% end %>
@@ -38,24 +34,4 @@
<%= link_to "Edit Post", {:action => 'edit', :controller => 'posts'}, {
class: 'btn btn-primary',:id => @post.id} %>
<% end %>
-<<<<<<< HEAD
-=======
-
\ No newline at end of file
From cb2c59ab2a43d18d4ec0ce404f4570ce9d1aaf73 Mon Sep 17 00:00:00 2001
From: Mohab
Date: Fri, 25 Apr 2014 02:25:50 +0200
Subject: [PATCH 519/526] Placing System recommendations in right side bar
---
tutor/app/views/layouts/_right_side_bar.html.erb | 10 ++++++++++
tutor/app/views/layouts/application.html.erb | 1 -
.../app/views/problems/_system_recommendation.html.erb | 2 +-
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 58035bf4..08663f35 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -57,6 +57,16 @@
<% end %>
+
+
+
System Recommendations
+
+
+ <%= render "problems/system_recommendation" if student_signed_in? %>
+
+
+
+
<% end %>
\ No newline at end of file
diff --git a/tutor/app/views/layouts/application.html.erb b/tutor/app/views/layouts/application.html.erb
index fca81845..a69400de 100644
--- a/tutor/app/views/layouts/application.html.erb
+++ b/tutor/app/views/layouts/application.html.erb
@@ -50,7 +50,6 @@
<%= render "layouts/right_side_bar" %>
- <%= render "problems/system_recommendation" if student_signed_in? %>
<%= yield %>
diff --git a/tutor/app/views/problems/_system_recommendation.html.erb b/tutor/app/views/problems/_system_recommendation.html.erb
index 4682f010..afedfb52 100644
--- a/tutor/app/views/problems/_system_recommendation.html.erb
+++ b/tutor/app/views/problems/_system_recommendation.html.erb
@@ -1,7 +1,7 @@
<%
suggestion = current_student.get_a_system_suggested_problem
if suggestion != nil then
- concat link_to "Recommended problem: " + suggestion.title, suggestion
+ concat link_to suggestion.title, suggestion
%> <%
end
%>
\ No newline at end of file
From cc6a78d5e4639760868e61cdf7929cce975c4b85 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Fri, 25 Apr 2014 02:44:32 +0200
Subject: [PATCH 520/526] Fixed indentation and removed extra space
---
tutor/app/controllers/posts_controller.rb | 7 ++++---
tutor/app/views/posts/show.html.erb | 2 +-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index 9e7558eb..51924c1a 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -39,10 +39,11 @@ def destroy
(Post.find_by_id(params[:id]).discussion_board_id)
if Post.find_by_id(params[:id]).destroy
flash[:notice] = "Post successfully Deleted"
- redirect_to(:controller => 'discussion_boards' ,
- :action => 'show' ,:id => @disscusion_board.course_id)
+ redirect_to(:controller => 'discussion_boards',
+ :action => 'show', :id => @disscusion_board.course_id)
end
- end
+ end
+
# [Add Post - Story 1.13]
# Description: Displays the post that the user chose
# Parameters:
diff --git a/tutor/app/views/posts/show.html.erb b/tutor/app/views/posts/show.html.erb
index 6b06d14c..8d0756e0 100644
--- a/tutor/app/views/posts/show.html.erb
+++ b/tutor/app/views/posts/show.html.erb
@@ -32,6 +32,6 @@
<% if @post.owner_id == @userID %>
<%= link_to "Edit Post", {:action => 'edit', :controller => 'posts'}, {
- class: 'btn btn-primary',:id => @post.id} %>
+ class: 'btn btn-primary',:id => @post.id} %>
<% end %>
\ No newline at end of file
From 81b057ceaa5eeae28d65fa7cb054ef46a436d7f0 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Fri, 25 Apr 2014 02:46:58 +0200
Subject: [PATCH 521/526] removed extra tabs
---
tutor/app/views/posts/show.html.erb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/views/posts/show.html.erb b/tutor/app/views/posts/show.html.erb
index 8d0756e0..7f06d3b2 100644
--- a/tutor/app/views/posts/show.html.erb
+++ b/tutor/app/views/posts/show.html.erb
@@ -32,6 +32,6 @@
<% if @post.owner_id == @userID %>
<%= link_to "Edit Post", {:action => 'edit', :controller => 'posts'}, {
- class: 'btn btn-primary',:id => @post.id} %>
+ class: 'btn btn-primary',:id => @post.id} %>
<% end %>
\ No newline at end of file
From 2546e0cfaf6625965473fa8d02654cc359db3f9e Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Fri, 25 Apr 2014 02:57:07 +0200
Subject: [PATCH 522/526] Fixed wrong indentation
---
tutor/app/views/posts/edit.html.erb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/views/posts/edit.html.erb b/tutor/app/views/posts/edit.html.erb
index 76530768..2a22740a 100644
--- a/tutor/app/views/posts/edit.html.erb
+++ b/tutor/app/views/posts/edit.html.erb
@@ -36,6 +36,6 @@
<%= f.submit "Update Post", class: "btn btn-success" %>
<% end %>
- <%= button_to "Delete Post", {:action => 'destroy', :id => params[:id]}, method: :delete,
+ <%= button_to "Delete Post", {:action => 'destroy', :id => params[:id]}, method: :delete,
class: 'btn btn-primary', :confirm => "Are you sure??" %>
\ No newline at end of file
From 0ad4ae7ffae9a1db0c99911619c922e478510f81 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Fri, 25 Apr 2014 03:07:36 +0200
Subject: [PATCH 523/526] Fixed indentation and removed extra spaces
---
tutor/app/controllers/posts_controller.rb | 14 +++++++-------
tutor/app/views/discussion_boards/show.html.erb | 4 ++--
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index 51924c1a..ab30d6ca 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -35,13 +35,13 @@ def edit
# flash[:notice]: A message indicating the success of the deletion
# Author: Ahmed Atef
def destroy
- @disscusion_board = DiscussionBoard.find_by_id
- (Post.find_by_id(params[:id]).discussion_board_id)
- if Post.find_by_id(params[:id]).destroy
- flash[:notice] = "Post successfully Deleted"
- redirect_to(:controller => 'discussion_boards',
- :action => 'show', :id => @disscusion_board.course_id)
- end
+ @disscusion_board = DiscussionBoard.find_by_id
+ (Post.find_by_id(params[:id]).discussion_board_id)
+ if Post.find_by_id(params[:id]).destroy
+ flash[:notice] = "Post successfully Deleted"
+ redirect_to(:controller => 'discussion_boards',
+ :action => 'show', :id => @disscusion_board.course_id)
+ end
end
# [Add Post - Story 1.13]
diff --git a/tutor/app/views/discussion_boards/show.html.erb b/tutor/app/views/discussion_boards/show.html.erb
index 07d27796..7733d2f5 100644
--- a/tutor/app/views/discussion_boards/show.html.erb
+++ b/tutor/app/views/discussion_boards/show.html.erb
@@ -1,7 +1,7 @@
<% if flash[:notice] %>
-
<%= flash[:notice] %>
- <% end %>
+
<%= flash[:notice] %>
+ <% end %>
<% if @discussionBoard.activated == true %>
<% end %>
<% if @discussionBoard.activated == true %>
From a88cf2bbb80bfa10188b6fc0221679640f80ebe0 Mon Sep 17 00:00:00 2001
From: Ahmed Atef
Date: Fri, 25 Apr 2014 03:37:11 +0200
Subject: [PATCH 525/526] removed extra tab
---
tutor/app/controllers/posts_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb
index ab30d6ca..afb13e76 100644
--- a/tutor/app/controllers/posts_controller.rb
+++ b/tutor/app/controllers/posts_controller.rb
@@ -95,7 +95,7 @@ def create
# update fails the user is redirected to the form
# Parameters:
# topic_params[]: A list that has all fields entered by the user to in the
- # Edit_post_form
+ # Edit_post_form
# Returns:
# flash[:notice]: A message indicating the success or failure of the creation
# Author: Ahmed Atef
From aecc976236f2f297fefb21b79ab28c50f9545f32 Mon Sep 17 00:00:00 2001
From: MohabGhanim
Date: Fri, 25 Apr 2014 05:27:11 +0300
Subject: [PATCH 526/526] putting spaces before and after the equal
---
tutor/app/views/layouts/_right_side_bar.html.erb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tutor/app/views/layouts/_right_side_bar.html.erb b/tutor/app/views/layouts/_right_side_bar.html.erb
index 08663f35..bd94c82c 100644
--- a/tutor/app/views/layouts/_right_side_bar.html.erb
+++ b/tutor/app/views/layouts/_right_side_bar.html.erb
@@ -61,7 +61,7 @@
System Recommendations
-
+
<%= render "problems/system_recommendation" if student_signed_in? %>
@@ -69,4 +69,4 @@
<% end %>
-
\ No newline at end of file
+