% if asset['thumb_url'] is not None:
diff --git a/cms/templates/import.html b/cms/templates/import.html
index 42def2d512..84e136fef9 100644
--- a/cms/templates/import.html
+++ b/cms/templates/import.html
@@ -11,21 +11,23 @@
Import
- Importing a new course will delete all course content currently associated with your course
- and replace it with the contents of the uploaded file.
+
+ Importing a new course will delete all content currently associated with your course
+ and replace it with the contents of the uploaded file.
File uploads must be zip files containing, at a minimum, a course.xml file.
Please note that if your course has any problems with auto-generated url_name nodes,
re-importing your course could cause the loss of student data associated with those problems.
+ %if allow_actions:
+ %endif
% for user in staff:
-
${user.username}
${user.email}
+ %if allow_actions :
-
+ %if request_user_id != user.id:
+
+ %endif
+ %endif
% endfor
diff --git a/cms/templates/registration/activation_complete.html b/cms/templates/registration/activation_complete.html
index 30e731e8cc..8cc3dc8c56 100644
--- a/cms/templates/registration/activation_complete.html
+++ b/cms/templates/registration/activation_complete.html
@@ -3,28 +3,24 @@
<%namespace name='static' file='../static_content.html'/>
+<%block name="content">
- %if not already_active:
- Activation Complete!
- %else:
- Account already active!
- %endif
-
-
-
+
+
%if not already_active:
- Thanks for activating your account.
+ Thanks for activating your account.
%else:
This account has already been activated.
%endif
-
+
%if user_logged_in:
- Visit your dashboard to see your courses.
+ Visit your dashboard to see your courses.
%else:
You can now login.
%endif
+%block>
diff --git a/cms/templates/signup.html b/cms/templates/signup.html
index 93acdfad71..150658b75e 100644
--- a/cms/templates/signup.html
+++ b/cms/templates/signup.html
@@ -1,4 +1,6 @@
<%inherit file="base.html" />
+<%! from django.core.urlresolvers import reverse %>
+
<%block name="title">Sign up%block>
<%block name="bodyclass">no-header%block>
@@ -82,7 +84,7 @@
submit_data,
function(json) {
if(json.success) {
- $('#register').html(json.value);
+ location.href = "${reverse('index')}";
} else {
$('#register_error').html(json.value).stop().slideDown(150);
}
diff --git a/cms/templates/unit.html b/cms/templates/unit.html
index 0f4f999599..3a184d65ba 100644
--- a/cms/templates/unit.html
+++ b/cms/templates/unit.html
@@ -108,9 +108,7 @@
${subsection.display_name}
-
- ${units.enum_units(subsection, actions=False, selected=unit.location)}
-
+ ${units.enum_units(subsection, actions=False, selected=unit.location)}
diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html
index 6e56c4f591..2b9b2c7884 100644
--- a/cms/templates/widgets/header.html
+++ b/cms/templates/widgets/header.html
@@ -10,7 +10,7 @@
${context_course.display_name}
- Courseware
- - Pages
+ - Pages
- Assets
- Users
- Import
diff --git a/cms/templates/widgets/metadata-edit.html b/cms/templates/widgets/metadata-edit.html
index f960ecfebd..069db424da 100644
--- a/cms/templates/widgets/metadata-edit.html
+++ b/cms/templates/widgets/metadata-edit.html
@@ -1,10 +1,26 @@
% if metadata:
+<%
+ import hashlib
+ hlskey = hashlib.md5(module.location.url()).hexdigest()
+%>
% endif
diff --git a/cms/templates/widgets/source-edit.html b/cms/templates/widgets/source-edit.html
new file mode 100644
index 0000000000..f0922831e1
--- /dev/null
+++ b/cms/templates/widgets/source-edit.html
@@ -0,0 +1,112 @@
+<%
+ import hashlib
+ hlskey = hashlib.md5(module.location.url()).hexdigest()
+%>
+
+
+
+
+
+ High Level Source Editing
+
+
+
+
+
+
+
+
+
diff --git a/cms/templates/widgets/units.html b/cms/templates/widgets/units.html
index 13bf73fec6..fe955baafe 100644
--- a/cms/templates/widgets/units.html
+++ b/cms/templates/widgets/units.html
@@ -18,7 +18,7 @@ This def will enumerate through a passed in subsection and list all of the units
- ${unit.display_name}
+ ${unit.display_name}
% if actions:
diff --git a/common/djangoapps/external_auth/views.py b/common/djangoapps/external_auth/views.py
index 5cf21ca68d..520cd95c0b 100644
--- a/common/djangoapps/external_auth/views.py
+++ b/common/djangoapps/external_auth/views.py
@@ -215,6 +215,52 @@ def ssl_dn_extract_info(dn):
else:
return None
return (user, email, fullname)
+
+
+def ssl_get_cert_from_request(request):
+ """
+ Extract user information from certificate, if it exists, returning (user, email, fullname).
+ Else return None.
+ """
+ certkey = "SSL_CLIENT_S_DN" # specify the request.META field to use
+
+ cert = request.META.get(certkey, '')
+ if not cert:
+ cert = request.META.get('HTTP_' + certkey, '')
+ if not cert:
+ try:
+ # try the direct apache2 SSL key
+ cert = request._req.subprocess_env.get(certkey, '')
+ except Exception:
+ return ''
+
+ return cert
+
+ (user, email, fullname) = ssl_dn_extract_info(cert)
+ return (user, email, fullname)
+
+
+def ssl_login_shortcut(fn):
+ """
+ Python function decorator for login procedures, to allow direct login
+ based on existing ExternalAuth record and MIT ssl certificate.
+ """
+ def wrapped(*args, **kwargs):
+ if not settings.MITX_FEATURES['AUTH_USE_MIT_CERTIFICATES']:
+ return fn(*args, **kwargs)
+ request = args[0]
+ cert = ssl_get_cert_from_request(request)
+ if not cert: # no certificate information - show normal login window
+ return fn(*args, **kwargs)
+
+ (user, email, fullname) = ssl_dn_extract_info(cert)
+ return external_login_or_signup(request,
+ external_id=email,
+ external_domain="ssl:MIT",
+ credentials=cert,
+ email=email,
+ fullname=fullname)
+ return wrapped
@csrf_exempt
@@ -234,17 +280,7 @@ def ssl_login(request):
Else continues on with student.views.index, and no authentication.
"""
- certkey = "SSL_CLIENT_S_DN" # specify the request.META field to use
-
- cert = request.META.get(certkey, '')
- if not cert:
- cert = request.META.get('HTTP_' + certkey, '')
- if not cert:
- try:
- # try the direct apache2 SSL key
- cert = request._req.subprocess_env.get(certkey, '')
- except Exception:
- cert = None
+ cert = ssl_get_cert_from_request(request)
if not cert:
# no certificate information - go onward to main index
diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py
index 61f91893a7..d97741613c 100644
--- a/common/lib/capa/capa/responsetypes.py
+++ b/common/lib/capa/capa/responsetypes.py
@@ -63,7 +63,7 @@ class StudentInputError(Exception):
class LoncapaResponse(object):
- '''
+ """
Base class for CAPA responsetypes. Each response type (ie a capa question,
which is part of a capa problem) is represented as a subclass,
which should provide the following methods:
@@ -89,7 +89,7 @@ class LoncapaResponse(object):
- required_attributes : list of required attributes (each a string) on the main response XML stanza
- hint_tag : xhtml tag identifying hint associated with this response inside hintgroup
- '''
+ """
__metaclass__ = abc.ABCMeta # abc = Abstract Base Class
response_tag = None
@@ -164,6 +164,8 @@ class LoncapaResponse(object):
- renderer : procedure which produces HTML given an ElementTree
'''
tree = etree.Element('span') # render ourself as a + our content
+ if self.xml.get('inline',''): # problem author can make this span display:inline
+ tree.set('class','inline')
for item in self.xml:
item_xhtml = renderer(item) # call provided procedure to do the rendering
if item_xhtml is not None: tree.append(item_xhtml)
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index f6054c494d..4e6a27c14e 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -618,12 +618,14 @@ class CapaModule(XModule):
if self.closed():
event_info['failure'] = 'closed'
self.system.track_function('reset_problem_fail', event_info)
- return "Problem is closed"
+ return {'success': False,
+ 'error': "Problem is closed"}
if not self.lcp.done:
event_info['failure'] = 'not_done'
self.system.track_function('reset_problem_fail', event_info)
- return "Refresh the page and make an attempt before resetting."
+ return {'success': False,
+ 'error': "Refresh the page and make an attempt before resetting."}
self.lcp.do_reset()
if self.rerandomize in ["always", "onreset"]:
diff --git a/common/lib/xmodule/xmodule/js/src/html/display.coffee b/common/lib/xmodule/xmodule/js/src/html/display.coffee
index 05e2ddab28..c1e3d8f8ea 100644
--- a/common/lib/xmodule/xmodule/js/src/html/display.coffee
+++ b/common/lib/xmodule/xmodule/js/src/html/display.coffee
@@ -1,8 +1,9 @@
class @HTMLModule
constructor: (@element) ->
- @el = $(@element)
- @setCollapsibles()
+ @el = $(@element)
+ @setCollapsibles()
+ MathJax.Hub.Queue ["Typeset", MathJax.Hub, @el[0]]
$: (selector) ->
$(selector, @el)
diff --git a/common/lib/xmodule/xmodule/templates/html/latex_html.yaml b/common/lib/xmodule/xmodule/templates/html/latex_html.yaml
new file mode 100644
index 0000000000..e3962d60a6
--- /dev/null
+++ b/common/lib/xmodule/xmodule/templates/html/latex_html.yaml
@@ -0,0 +1,23 @@
+---
+metadata:
+ display_name: E-text Written in LaTeX
+ source_processor_url: https://qisx.mit.edu:5443/latex2edx
+ source_code: |
+ \subsection{Example of E-text in LaTeX}
+
+ It is very convenient to write complex equations in LaTeX.
+
+ \begin{equation}
+ x = \frac{-b\pm\sqrt{b^2-4*a*c}}{2a}
+ \end{equation}
+
+ Seize the moment.
+
+data: |
+
+ Example: E-text page
+
+ It is very convenient to write complex equations in LaTeX.
+
+
+children: []
diff --git a/common/lib/xmodule/xmodule/templates/problem/latex_problem.yaml b/common/lib/xmodule/xmodule/templates/problem/latex_problem.yaml
new file mode 100644
index 0000000000..6b31c4af3e
--- /dev/null
+++ b/common/lib/xmodule/xmodule/templates/problem/latex_problem.yaml
@@ -0,0 +1,218 @@
+---
+metadata:
+ display_name: Problem Written in LaTeX
+ source_processor_url: https://qisx.mit.edu:5443/latex2edx
+ source_code: |
+ % Nearly any kind of edX problem can be authored using Latex as
+ % the source language. Write latex as usual, including equations. The
+ % key new feature is the \edXabox{} macro, which specifies an "Answer
+ % Box" that queries students for a response, and specifies what the
+ % epxected (correct) answer is.
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \subsection{Example "option" problem}
+
+ Where is the earth?
+
+ \edXabox{options='up','down' expect='down'}
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \subsection{Example "symbolic" problem}
+
+ What is Einstein's equation for the energy equivalent of a mass $m$?
+
+ \edXabox{type='symbolic' size='90' expect='m*c^2' }
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \subsection{Example "numerical" problem}
+
+ Estimate the energy savings (in J/y) if all the people
+ ($3\times 10^8$) in the U.~S. switched from U.~S. code to low flow
+ shower heads.
+
+ \edXinline{Energy saved = }\edXabox{expect="0.52" type="numerical" tolerance='0.02' inline='1' } %
+ \edXinline{~EJ/year}
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \subsection{Example "multiple choice" problem}
+
+ What color is a bannana?
+
+ \edXabox{ type="multichoice" expect="Yellow" options="Red","Green","Yellow","Blue" }
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \subsection{Example "string response" problem}
+
+ In what U.S. state is Detroit located?
+
+ \edXabox{ type="string" expect="Michigan" options="ci" }
+
+ An explanation of the answer can be provided by using the edXsolution
+ macro. Click on "Show Answer" to see the solution.
+
+ \begin{edXsolution}
+ Detroit is near Canada, but it is actually in the United States.
+ \end{edXsolution}
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \subsection{Example "custom response" problem}
+
+ This problem demonstrates the use of a custom python script used for
+ checking the answer.
+
+ \begin{edXscript}
+ def sumtest(expect,ans):
+ (a1,a2) = map(float,eval(ans))
+ return (a1+a2)==10
+ \end{edXscript}
+
+ Enter a python list of two numbers which sum to 10, eg [9,1]:
+
+ \edXabox{expect="[1,9]" type="custom" cfn="sumtest"}
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \subsection{Example image}
+
+ Include image by using the edXxml macro:
+
+ \edXxml{ }
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \subsection{Example show/hide explanation}
+
+ Extra explanations can be tucked away behind a "showhide" toggle flag:
+
+ \edXshowhide{sh1}{More explanation}{This is a hidden explanation. It
+ can contain equations: $\alpha = \frac{2}{\sqrt{1+\gamma}}$ }
+
+ This is some text after the showhide example.
+
+data: |
+
+
+
+
+ Example "option" problem
+
+
+ Where is the earth?
+
+
+
+
+
+
+ Example "symbolic" problem
+
+
+ What is Einstein's equation for the energy equivalent of a mass [mathjaxinline]m[/mathjaxinline]?
+
+
+
+
+
+
+ Example "numerical" problem
+
+
+ Estimate the energy savings (in J/y) if all the people ([mathjaxinline]3\times 10^8[/mathjaxinline]) in the U. S. switched from U. S. code to low flow shower heads.
+
+ Energy saved =
+
+
+
+
+
+ EJ/year
+
+
+ Example "multiple choice" problem
+
+
+ What color is a bannana?
+
+
+
+
+ Red
+
+
+ Green
+
+
+ Yellow
+
+
+ Blue
+
+
+
+
+
+ Example "string response" problem
+
+
+ In what U.S. state is Detroit located?
+
+
+
+
+
+
+ An explanation of the answer can be provided by using the edXsolution macro:
+
+
+ Answer:
+ Detroit is near Canada, but it is actually in the United States.
+
+
+
+ Example "custom response" problem
+
+
+ This problem demonstrates the use of a custom python script used for checking the answer.
+
+
+ Enter a python list of two numbers which sum to 10, eg [9,1]:
+
+
+
+
+
+
+ Example image
+
+
+ Include image by using the edXxml macro:
+
+
+
+
+ Example show/hide explanation
+
+
+ Extra explanations can be tucked away behind a "showhide" toggle flag:
+
+
+
+
+ | More explanation [show] |
+
+
+ |
+
+ This is a hidden explanation. It can contain equations: [mathjaxinline]\alpha = \frac{2}{\sqrt {1+\gamma }}[/mathjaxinline]
+
+ This is some text after the showhide example.
+ |
+
+
+
+
+
+
+children: []
diff --git a/common/lib/xmodule/xmodule/templates/problem/problem_with_hint.yaml b/common/lib/xmodule/xmodule/templates/problem/problem_with_hint.yaml
new file mode 100644
index 0000000000..876060e578
--- /dev/null
+++ b/common/lib/xmodule/xmodule/templates/problem/problem_with_hint.yaml
@@ -0,0 +1,96 @@
+---
+metadata:
+ display_name: Problem with Adaptive Hint
+ source_processor_url: https://qisx.mit.edu:5443/latex2edx
+ source_code: |
+ \subsection{Problem With Adaptive Hint}
+
+ % Adaptive hints are messages provided to students which depend on
+ % student input. These hints are produced using a script embedded
+ % within the problem (written in Python).
+ %
+ % Here is an example. This example uses LaTeX as a high-level
+ % soure language for the problem. The problem can also be coded
+ % directly in XML.
+
+ This problem demonstrates a question with hints, based on using the
+ {\tt hintfn} method.
+
+ \begin{edXscript}
+ def test_str(expect, ans):
+ print expect, ans
+ ans = ans.strip("'")
+ ans = ans.strip('"')
+ return expect == ans.lower()
+
+ def hint_fn(answer_ids, student_answers, new_cmap, old_cmap):
+ aid = answer_ids[0]
+ ans = str(student_answers[aid]).lower()
+ print 'hint_fn called, ans=', ans
+ hint = ''
+ if 'java' in ans:
+ hint = 'that is only good for drinking'
+ elif 'perl' in ans:
+ hint = 'not that rich'
+ elif 'pascal' in ans:
+ hint = 'that is a beatnick language'
+ elif 'fortran' in ans:
+ hint = 'those were the good days'
+ elif 'clu' in ans:
+ hint = 'you must be invariant'
+ if hint:
+ hint = "Hint: {0}".format(hint)
+ new_cmap.set_hint_and_mode(aid,hint,'always')
+ \end{edXscript}
+
+ What is the best programming language that exists today? You may
+ enter your answer in upper or lower case, with or without quotes.
+
+ \edXabox{type="custom" cfn='test_str' expect='python' hintfn='hint_fn'}
+
+data: |
+
+
+
+
+ Problem With Adaptive Hint
+
+
+ This problem demonstrates a question with hints, based on using the hintfn method.
+
+
+ What is the best programming language that exists today? You may enter your answer in upper or lower case, with or without quotes.
+
+
+
+
+
+
+
+
+children: []
diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py
index 3309f6270c..a53f2db7da 100644
--- a/common/lib/xmodule/xmodule/x_module.py
+++ b/common/lib/xmodule/xmodule/x_module.py
@@ -369,6 +369,9 @@ class ResourceTemplates(object):
return []
for template_file in resource_listdir(__name__, dirname):
+ if not template_file.endswith('.yaml'):
+ log.warning("Skipping unknown template file %s" % template_file)
+ continue
template_content = resource_string(__name__, os.path.join(dirname, template_file))
template = yaml.load(template_content)
templates.append(Template(**template))
diff --git a/common/static/js/vendor/CodeMirror/stex.js b/common/static/js/vendor/CodeMirror/stex.js
new file mode 100644
index 0000000000..7d9495f9f7
--- /dev/null
+++ b/common/static/js/vendor/CodeMirror/stex.js
@@ -0,0 +1,182 @@
+/*
+ * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de)
+ * Licence: MIT
+ */
+
+CodeMirror.defineMode("stex", function(cmCfg, modeCfg)
+{
+ function pushCommand(state, command) {
+ state.cmdState.push(command);
+ }
+
+ function peekCommand(state) {
+ if (state.cmdState.length>0)
+ return state.cmdState[state.cmdState.length-1];
+ else
+ return null;
+ }
+
+ function popCommand(state) {
+ if (state.cmdState.length>0) {
+ var plug = state.cmdState.pop();
+ plug.closeBracket();
+ }
+ }
+
+ function applyMostPowerful(state) {
+ var context = state.cmdState;
+ for (var i = context.length - 1; i >= 0; i--) {
+ var plug = context[i];
+ if (plug.name=="DEFAULT")
+ continue;
+ return plug.styleIdentifier();
+ }
+ return null;
+ }
+
+ function addPluginPattern(pluginName, cmdStyle, brackets, styles) {
+ return function () {
+ this.name=pluginName;
+ this.bracketNo = 0;
+ this.style=cmdStyle;
+ this.styles = styles;
+ this.brackets = brackets;
+
+ this.styleIdentifier = function(content) {
+ if (this.bracketNo<=this.styles.length)
+ return this.styles[this.bracketNo-1];
+ else
+ return null;
+ };
+ this.openBracket = function(content) {
+ this.bracketNo++;
+ return "bracket";
+ };
+ this.closeBracket = function(content) {
+ };
+ };
+ }
+
+ var plugins = new Array();
+
+ plugins["importmodule"] = addPluginPattern("importmodule", "tag", "{[", ["string", "builtin"]);
+ plugins["documentclass"] = addPluginPattern("documentclass", "tag", "{[", ["", "atom"]);
+ plugins["usepackage"] = addPluginPattern("documentclass", "tag", "[", ["atom"]);
+ plugins["begin"] = addPluginPattern("documentclass", "tag", "[", ["atom"]);
+ plugins["end"] = addPluginPattern("documentclass", "tag", "[", ["atom"]);
+
+ plugins["DEFAULT"] = function () {
+ this.name="DEFAULT";
+ this.style="tag";
+
+ this.styleIdentifier = function(content) {
+ };
+ this.openBracket = function(content) {
+ };
+ this.closeBracket = function(content) {
+ };
+ };
+
+ function setState(state, f) {
+ state.f = f;
+ }
+
+ function normal(source, state) {
+ if (source.match(/^\\[a-zA-Z@]+/)) {
+ var cmdName = source.current();
+ cmdName = cmdName.substr(1, cmdName.length-1);
+ var plug;
+ if (plugins.hasOwnProperty(cmdName)) {
+ plug = plugins[cmdName];
+ } else {
+ plug = plugins["DEFAULT"];
+ }
+ plug = new plug();
+ pushCommand(state, plug);
+ setState(state, beginParams);
+ return plug.style;
+ }
+
+ // escape characters
+ if (source.match(/^\\[$&%#{}_]/)) {
+ return "tag";
+ }
+
+ // white space control characters
+ if (source.match(/^\\[,;!\/]/)) {
+ return "tag";
+ }
+
+ var ch = source.next();
+ if (ch == "%") {
+ // special case: % at end of its own line; stay in same state
+ if (!source.eol()) {
+ setState(state, inCComment);
+ }
+ return "comment";
+ }
+ else if (ch=='}' || ch==']') {
+ plug = peekCommand(state);
+ if (plug) {
+ plug.closeBracket(ch);
+ setState(state, beginParams);
+ } else
+ return "error";
+ return "bracket";
+ } else if (ch=='{' || ch=='[') {
+ plug = plugins["DEFAULT"];
+ plug = new plug();
+ pushCommand(state, plug);
+ return "bracket";
+ }
+ else if (/\d/.test(ch)) {
+ source.eatWhile(/[\w.%]/);
+ return "atom";
+ }
+ else {
+ source.eatWhile(/[\w-_]/);
+ return applyMostPowerful(state);
+ }
+ }
+
+ function inCComment(source, state) {
+ source.skipToEnd();
+ setState(state, normal);
+ return "comment";
+ }
+
+ function beginParams(source, state) {
+ var ch = source.peek();
+ if (ch == '{' || ch == '[') {
+ var lastPlug = peekCommand(state);
+ var style = lastPlug.openBracket(ch);
+ source.eat(ch);
+ setState(state, normal);
+ return "bracket";
+ }
+ if (/[ \t\r]/.test(ch)) {
+ source.eat(ch);
+ return null;
+ }
+ setState(state, normal);
+ lastPlug = peekCommand(state);
+ if (lastPlug) {
+ popCommand(state);
+ }
+ return normal(source, state);
+ }
+
+ return {
+ startState: function() { return { f:normal, cmdState:[] }; },
+ copyState: function(s) { return { f: s.f, cmdState: s.cmdState.slice(0, s.cmdState.length) }; },
+
+ token: function(stream, state) {
+ var t = state.f(stream, state);
+ var w = stream.current();
+ return t;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-stex", "stex");
+CodeMirror.defineMIME("text/x-latex", "stex");
diff --git a/common/static/js/vendor/mustache.js b/common/static/js/vendor/mustache.js
new file mode 100644
index 0000000000..aab62f9ddc
--- /dev/null
+++ b/common/static/js/vendor/mustache.js
@@ -0,0 +1,613 @@
+/*!
+ * mustache.js - Logic-less {{mustache}} templates with JavaScript
+ * http://github.com/janl/mustache.js
+ */
+
+var Mustache;
+
+(function (exports) {
+ if (typeof module !== "undefined") {
+ module.exports = exports; // CommonJS
+ } else if (typeof define === "function") {
+ define(exports); // AMD
+ } else {
+ Mustache = exports; //
%block>
-<%include file="../signup_modal.html" />
\ No newline at end of file
+<%include file="../signup_modal.html" />
+<%include file="../forgot_password_modal.html" />
\ No newline at end of file
|