the initial version

master
Igor Minar 14 years ago
commit 3f2cce0120

5
.gitignore vendored

@ -0,0 +1,5 @@
**/.DS_Store
nbproject
manifest.mf
build.xml

@ -0,0 +1,146 @@
# angular-seed — the seed for <angular/> apps
This project is an application skeleton for a typical [angular](http://angularjs.org/) web app. You
can use it to quickly bootstrap your angular webapp projects and dev environment for these projects.
The seed contains angular libraries, test libraries and a bunch of scripts all preconfigured for
instant web development gratification. Just clone the repo (or download the zip/tarball), start up
our (or yours) webserver and you are ready to develop and test your application.
The seed app doesn't do much, just shows how to wire two controllers and views together. You can
check it out by opening app/index.html in your browser (might not work file `file://` scheme in
certain browsers, see note below).
_Note: While angular is client-side-only technology and it's possible to create angular webapps that
don't require a backend server at all, we recommend hosting the project files using a local
webserver during development to avoid issues with security restrictions (sandbox) in browsers. The
sandbox implementation varies between browsers, but quite often prevents things like cookies, xhr,
etc to function properly when an html page is opened via `file://` scheme instead of `http://`._
## How to use angular-seed
Clone the angular-seed repository and start hacking...
### Running the app during development
You can pick one of these options:
* serve this repository with your webserver
* install node.js and run `scripts/web-server.js`
Then navigate your browser to `http://localhost:<port>/app/index.html` to see the app running in
your browser.
### Running the app in production
This really depends on how complex is your app and the overall infrastructure of your system, but
the general rule is that all you need in production are all the files under the `app/` directory.
Everything else should be omitted.
angular apps are really just a bunch of static html, css and js files that just need to be hosted
somewhere, where they can be accessed by browsers.
If your angular app is talking to the backend server via xhr or other means, you need to figure
out what is the best way to host the static files to comply with the same origin policy if
applicable. Usually this is done by hosting the files by the backend server or through
reverse-proxying the backend server(s) and a webserver(s).
### Running unit tests
We recommend using [jasmine](http://pivotal.github.com/jasmine/) and
[JsTestDriver](http://code.google.com/p/js-test-driver/) for your unit tests/specs, but you are free
to use whatever works for you.
Requires java and a local or remote browser.
* start `scripts/test-server.sh`
* navigate your browser to `http://localhost:9876/`
* click on one of the capture links (preferably the "strict" one)
* run `scripts/test.sh`
### Continuous unit testing
Requires ruby and [watchr](https://github.com/mynyml/watchr) gem.
* start JSTD server and capture a browser as described above
* start watchr as `watchr scripts/watchr.rb`
* in a different window/tab/editor `tail -f logs/jstd.log`
* edit files in `app/` or `src/` and save them
* watch the log to see updates
There are many other ways to achieve the same effect. Feel free to use them if you prefer them over
watchr.
### End to end testing
angular ships with a baked-in end-to-end test runner that understands angular, your app and allows
you to write your tests with jasmine-like BDD syntax.
Requires a webserver, node.js or your backend server that hosts the angular static files.
* create your end-to-end tests in `test/e2e/scenarios.js`
* serve your project directory with your http/backend server or node.js + `scripts/web-server.js`
* open `http://localhost:port/test/e2e/runner.html` in your browser
### Receiving updates from upstream
When we upgrade angular-seed's repo with newer angular or testing library code, you can just
fetch the changes and merge them into your project with git.
## Directory Layout
app/ --> all of the files to be used in production
css/ --> css files
app.css --> default stylesheet
img/ --> image files
js/ --> javascript files
controllers.js --> application controllers
filters.js --> custom angular filters
services.js --> custom angular services
widgets.js --> custom angular widgets
lib/ --> angular and 3rd party javascript libraries
angular/
angular.js --> the latest angular js
angular.min.js --> the latest minified angular js
angular-ie-compat.js --> angular patch for IE 6&7 compatibility
version.txt --> version number
partials/ --> angular view partials (partial html templates)
partial1.html
partial2.html
jsTestDriver.conf --> config file for JsTestDriver
logs/ --> JSTD and other logs go here (git-ignored)
scripts/ --> handy shell/js/ruby scripts
test-server.sh --> starts JSTD server
test.sh --> runs all unit tests
watchr.rb --> config script for continuous testing with watchr
web-server.js --> simple development webserver based on node.js
test/ --> test source files and libraries
e2e/ -->
runner.html --> end-to-end test runner (open in your browser to run)
scenarios.js --> end-to-end specs
lib/
angular/ --> angular testing libraries
angular-mocks.js --> mocks that replace certain angular services in tests
angular-scenario.js --> angular's scenario (end-to-end) test runner library
version.txt --> version file
jasmine/ --> Pivotal's Jasmine - an elegant BDD-style testing framework
jasmine-jstd-adapter/ --> bridge between JSTD and Jasmine
jstestdriver/ --> JSTD - JavaScript test runner
unit/ --> unit level specs/tests
controllersSpec.js --> specs for controllers
## Contact
For more information on angular please check out http://angularjs.org/

@ -0,0 +1,30 @@
/* app css stylesheet */
.menu {
list-style: none;
border-bottom: 0.1em solid black;
margin-bottom: 2em;
padding: 0 0 0.5em;
}
.menu:before {
content: "[";
}
.menu:after {
content: "]";
}
.menu > li {
display: inline;
}
.menu > li:before {
content: "|";
padding-right: 0.3em;
}
.menu > li:nth-child(1):before {
content: "";
padding: 0;
}

@ -0,0 +1,21 @@
<!doctype html>
<html xmlns:ng="http://angularjs.org/">
<head>
<title>my angular app</title>
<link rel="stylesheet" href="css/app.css"/>
</head>
<body style="display:none" ng:show="true">
<ul class="menu">
<li><a href="#/view1">view1</a></li>
<li><a href="#/view2">view2</a></li>
</ul>
<ng:include src="$route.current.template" scope="$route.current.scope"></ng:include>
<script src="lib/angular/angular.js" ng:autobind></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/widgets.js"></script>
</body>
</html>

@ -0,0 +1,10 @@
/* App Controllers */
function MyCtrl1() {}
MyCtrl1.$inject = [];
function MyCtrl2() {
}
MyCtrl1.$inject = [];

@ -0,0 +1 @@
/* http://docs.angularjs.org/#!angular.filter */

@ -0,0 +1,21 @@
/* http://docs.angularjs.org/#!angular.service */
/**
* App service which is responsible for the main configuration of the app.
*/
angular.service('myAngularApp', function($route, $location, $window) {
$route.when('/view1', {template: 'partials/partial1.html', controller: MyCtrl1});
$route.when('/view2', {template: 'partials/partial2.html', controller: MyCtrl2});
$route.onChange(function() {
if ($location.hash === '') {
$location.updateHash('/view1');
this.$eval();
} else {
$route.current.scope.params = $route.current.params;
$window.scrollTo(0,0);
}
});
}, {$inject:['$route', '$location', '$window'], $creation: 'eager'});

@ -0,0 +1 @@
/* http://docs.angularjs.org/#!angular.widget */

@ -0,0 +1,32 @@
/*
Content-Type: multipart/related; boundary="_"
--_
Content-Location:img0
Content-Transfer-Encoding:base64
R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrSLoc/AG8FeUUIN+sGebWAnbKSJodqqlsOxJtqYooU9vvk+vcJIcTkg+QAAA7
--_
Content-Location:img1
Content-Transfer-Encoding:base64
R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrCLTcoM29yN6k9socs91e5X3EyJloipYrO4ohTMqA0Fn2XVNswJe+H+SXAAA7
--_
Content-Location:img2
Content-Transfer-Encoding:base64
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
--_--
*/
(function(){
var jsUri = document.location.href.replace(/\/[^/]+(#.*)?$/, '/') + document.getElementById('ng-ie-compat').src;
var css = '#ng-callout .ng-arrow-left{*background-image:url("mhtml:' + jsUri + '!img0")}#ng-callout .ng-arrow-right{*background-image:url("mhtml:' + jsUri + '!img1")}.ng-input-indicator-wait {*background-image:url("mhtml:' + jsUri + '!img2")}'
var s = document.createElement('style');
s.setAttribute('type', 'text/css');
if (s.styleSheet) {
s.styleSheet.cssText = css;
} else {
s.appendChild(document.createTextNode(css));
}
document.getElementsByTagName('head')[0].appendChild(s);
})();

File diff suppressed because it is too large Load Diff

@ -0,0 +1,106 @@
(function(H,Y,ub){function u(a,b,c){var d;if(a)if(J(a))for(d in a)d!="prototype"&&d!=fc&&d!=gc&&a.hasOwnProperty(d)&&b.call(c,a[d],d);else if(a.forEach)a.forEach(b,c);else if(T(a)&&wa(a.length))for(d=0;d<a.length;d++)b.call(c,a[d],d);else for(d in a)b.call(c,a[d],d);return a}function $a(a,b,c){var d=[],e;for(e in a)d.push(e);d.sort();for(e=0;e<d.length;e++)b.call(c,a[d[e]],d[e]);return d}function ab(a){if(a instanceof na)if(a.stack)a=a.stack;else if(a.sourceURL)a=a.message+"\n"+a.sourceURL+":"+a.line;
return a}function D(a){u(arguments,function(b){b!==a&&u(b,function(c,d){a[d]=c})});return a}function hc(a,b){return D(new (D(function(){},{prototype:a})),b)}function F(){}function oa(a){return a}function bb(a){return function(){return a}}function ga(a,b,c){var d;return a[b]||(d=a[b]=function(e,f,g){e=(c||oa)(e);if(E(f)){E(d[e])&&u(d[e],function(h,i){if(i.charAt(0)=="$"&&ba(f[i]))f[i]=h});d[e]=D(f,g||{})}return d[e]})}function ic(a){if(a)if(I(a)){var b=Y.createElement("div");b.innerHTML=a;a=new pa(b.childNodes)}else if(!(a instanceof
pa)&&Ja(a))a=new pa(a);return a}function ba(a){return typeof a==qa}function E(a){return typeof a!=qa}function T(a){return a!=y&&typeof a==vb}function I(a){return typeof a==jc}function wa(a){return typeof a==kc}function ha(a){return a instanceof Array}function J(a){return typeof a==ia}function xa(a){return I(a)?a.replace(/^\s*/,"").replace(/\s*$/,""):a}function Ja(a){return a&&(a.nodeName||a instanceof pa||cb&&a instanceof cb)}function db(a,b){this.html=a;this.get=Q(b)=="unsafe"?bb(a):function(){var c=
[];lc(a,wb(c));return c.join("")}}function mc(a,b,c){var d=[];u(a,function(e,f,g){d.push(b.call(c,e,f,g))});return d}function xb(a,b){for(var c=0;c<a.length;c++)if(b===a[c])return true;return false}function Ka(a,b){for(var c=0;c<a.length;c++)if(b===a[c])return c;return-1}function nc(a){if(a)switch(a.nodeName){case "OPTION":case "PRE":case "TITLE":return true}return false}function U(a,b){if(b)if(ha(a)){for(;b.length;)b.pop();for(var c=0;c<a.length;c++)b.push(U(a[c]))}else{u(b,function(d,e){delete b[e]});
for(c in a)b[c]=U(a[c])}else if(b=a)if(ha(a))b=U(a,[]);else if(a instanceof Date)b=new Date(a.getTime());else if(T(a))b=U(a,{});return b}function La(a,b){if(a==b)return true;var c=typeof a,d;if(c==typeof b&&c=="object")if(a instanceof Array){if((c=a.length)==b.length){for(d=0;d<c;d++)if(!La(a[d],b[d]))return false;return true}}else{c={};for(d in a){if(d.charAt(0)!=="$"&&!J(a[d])&&!La(a[d],b[d]))return false;c[d]=true}for(d in b)if(!c[d]&&d.charAt(0)!=="$"&&!J(b[d]))return false;return true}return false}
function oc(a){return(a=a&&a[0]&&a[0].nodeName)&&a.charAt(0)!="#"&&!xb(["TR","COL","COLGROUP","TBODY","THEAD","TFOOT"],a)}function ra(a,b,c){for(;!oc(a);)a=a.parent()||A(Y.body);if(a[0].$NG_ERROR!==c)if(a[0].$NG_ERROR=c){a.addClass(b);a.attr(b,c)}else{a.removeClass(b);a.removeAttr(b)}}function Ma(a,b,c){return a.concat(Na.call(b,c,b.length))}function M(a,b){var c=arguments.length>2?Na.call(arguments,2,arguments.length):[];return typeof b==ia?c.length?function(){return arguments.length?b.apply(a,c.concat(Na.call(arguments,
0,arguments.length))):b.apply(a,c)}:function(){return arguments.length?b.apply(a,arguments):b.call(a)}:b}function ya(a){if(a&&a.length!==0){a=Q(""+a);a=!(a=="f"||a=="0"||a=="false"||a=="no"||a=="n"||a=="[]")}else a=false;return a}function yb(a,b){var c=new zb(eb,Ab,K,Z),d=A(a);return c.compile(d)(d,b)}function fb(a){var b={},c,d;u((a||"").split("&"),function(e){if(e){c=e.split("=");d=unescape(c[0]);b[d]=E(c[1])?unescape(c[1]):true}});return b}function Bb(a){var b=[];u(a,function(c,d){b.push(escape(d)+
(c===true?"":"="+escape(c)))});return b.length?b.join("&"):""}function pc(a,b){var c=a.getElementsByTagName("script"),d;b=D({ie_compat_id:"ng-ie-compat"},b);for(var e=0;e<c.length;e++)if(d=(c[e].src||"").match(qc)){b.base_url=d[1];b.ie_compat=d[1]+"angular-ie-compat"+(d[2]||"")+".js";D(b,fb(d[6]));Oa(A(c[e]),function(f,g){if(/^ng:/.exec(g)){g=g.substring(3).replace(/-/g,"_");if(g=="autobind")f=true;b[g]=f}})}return b}function $(a,b){var c=[];gb(c,a,b?"\n ":y,[]);return c.join("")}function sa(a,b){function c(h){if(I(h)&&
h.length===Cb)return hb.toDate(h);else if(ha(h)||T(h))u(h,function(i,j){h[j]=c(i)});return h}if(!a)return a;var d,e,f;try{if(b&&JSON&&JSON.parse){d=JSON.parse(a);return c(d)}e=Pa(a,true);f=e.primary();e.assertAllConsumed();return f()}catch(g){Db("fromJson error: ",a,g);throw g;}}function gb(a,b,c,d){if(T(b)){if(b===H){a.push("WINDOW");return}if(b===Y){a.push("DOCUMENT");return}if(xb(d,b)){a.push("RECURSION");return}d.push(b)}if(b===y)a.push(Qa);else if(b instanceof RegExp)a.push(B.String.quoteUnicode(b.toString()));
else if(J(b))return;else if(typeof b==rc)a.push(""+b);else if(wa(b))isNaN(b)?a.push(Qa):a.push(""+b);else if(I(b))return a.push(B.String.quoteUnicode(b));else if(T(b))if(ha(b)){a.push("[");for(var e=b.length,f=false,g=0;g<e;g++){var h=b[g];f&&a.push(",");!(h instanceof RegExp)&&(J(h)||ba(h))?a.push(Qa):gb(a,h,c,d);f=true}a.push("]")}else if(b instanceof Date)a.push(B.String.quoteUnicode(B.Date.toString(b)));else{a.push("{");c&&a.push(c);e=false;f=c?c+" ":false;g=[];for(h in b)b[h]!==V&&g.push(h);
g.sort();for(h=0;h<g.length;h++){var i=g[h],j=b[i];if(typeof j!=ia){if(e){a.push(",");c&&a.push(c)}a.push(B.String.quote(i));a.push(":");gb(a,j,f,d);e=true}}a.push("}")}T(b)&&d.pop()}function ib(a){this.paths=[];this.children=[];this.inits=[];this.priority=a;this.newScope=false}function sc(a){for(var b;a&&!(b=a.data(jb));)a=a.parent();return b}function zb(a,b,c,d){this.markup=a;this.attrMarkup=b;this.directives=c;this.widgets=d}function Eb(a,b){var c,d=a[0].childNodes||[],e;for(c=0;c<d.length;c++){var f=
e=d[c];Ba(f)=="#text"||b(A(e),c)}}function Oa(a,b){var c,d=a[0].attributes||[],e,f,g={};for(c=0;c<d.length;c++){e=d[c];f=e.name;e=e.value;if(ka&&f=="href")e=decodeURIComponent(a[0].getAttribute(f,2));g[f]=e}$a(g,b)}function Ca(a,b,c){if(!b)return a;for(var d=b.split("."),e,f=a,g=d.length,h=0;h<g;h++){e=d[h];if(!e.match(/^[\$\w][\$\w\d]*$/))throw"Expression '"+b+"' is not a valid expression for accesing variables.";if(a){f=a;a=a[e]}if(ba(a)&&e.charAt(0)=="$"){var i=B.Global.typeOf(f);if(e=(i=B[i.charAt(0).toUpperCase()+
i.substring(1)])?i[[e.substring(1)]]:V)return a=M(f,e,f)}}if(!c&&J(a))return M(f,a);return a}function Ra(a,b,c){b=b.split(".");for(var d=0;b.length>1;d++){var e=b.shift(),f=a[e];if(!f){f={};a[e]=f}a=f}return a[b.shift()]=c}function Fb(a){var b=Gb[a];if(b)return b;var c="var l, fn, t;\n";u(a.split("."),function(d){d=Hb[d]?'["'+d+'"]':"."+d;c+="if(!s) return s;\nl=s;\ns=s"+d+';\nif(typeof s=="function" && !(s instanceof RegExp)) s = function(){ return l'+d+".apply(l, arguments); };\n";if(d.charAt(1)==
"$"){d=d.substr(2);c+='if(!s) {\n t = angular.Global.typeOf(l);\n fn = (angular[t.charAt(0).toUpperCase() + t.substring(1)]||{})["'+d+'"];\n if (fn) s = function(){ return fn.apply(l, [l].concat(Array.prototype.slice.call(arguments, 0, arguments.length))); };\n}\n'}});c+="return s;";b=Function("s",c);b.toString=function(){return c};return Gb[a]=b}function ta(a){if(typeof a===ia)return a;var b=Ib[a];if(!b){b=Pa(a);var c=b.statements();b.assertAllConsumed();b=Ib[a]=D(function(){return c(this)},{fnSelf:c})}return b}
function ua(a,b,c){function d(){}a=d.prototype=a||{};var e=new d,f={sorted:[]};D(e,{"this":e,$id:tc++,$parent:a,$bind:M(e,M,e),$get:M(e,Ca,e),$set:M(e,Ra,e),$eval:function(g){var h=typeof g,i,j,k;if(h==qa){g=0;for(h=f.sorted.length;g<h;g++){k=f.sorted[g];j=k.length;for(i=0;i<j;i++)e.$tryEval(k[i].fn,k[i].handler)}}else if(h===ia)return g.call(e);else if(h==="string")return ta(g).call(e)},$tryEval:function(g,h){var i=typeof g;try{if(i==ia)return g.call(e);else if(i=="string")return ta(g).call(e)}catch(j){(e.$log||
{error:Db}).error(j);if(J(h))h(j);else if(h)ra(h,Sa,E(j)?ab(j):j);else J(e.$exceptionHandler)&&e.$exceptionHandler(j)}},$watch:function(g,h,i,j){function k(o){var m=p.call(e),r=t;if(o||r!==m){t=m;e.$tryEval(function(){return h.call(e,m,r)},i)}}var p=ta(g),t=p.call(e);h=ta(h);e.$onEval(Jb,k);if(ba(j))j=true;j&&k(true)},$onEval:function(g,h,i){if(!wa(g)){i=h;h=g;g=0}var j=f[g];if(!j){j=f[g]=[];j.priority=g;f.sorted.push(j);f.sorted.sort(function(k,p){return k.priority-p.priority})}j.push({fn:ta(h),
handler:i})},$become:function(g){if(J(g)){e.constructor=g;u(g.prototype,function(h,i){e[i]=M(e,h)});e.$inject.apply(e,Ma([g,e],arguments,1));J(g.prototype.init)&&e.init()}},$new:function(g){var h=ua(e);h.$become.apply(e,Ma([g],arguments,1));e.$onEval(h.$eval);return h}});if(!a.$root){e.$root=e;e.$parent=e;(e.$inject=Kb(e,b,c))()}return e}function Kb(a,b,c){b=b||kb;c=c||{};a=a||{};return function d(e,f){var g,h,i;if(I(e)){if(!c.hasOwnProperty(e)){h=b[e];if(!h)throw"Unknown provider for '"+e+"'.";c[e]=
d(h,a)}g=c[e]}else if(ha(e)){g=[];u(e,function(j){g.push(d(j))})}else if(J(e)){g=d(e.$inject||[]);g=e.apply(f,Ma(g,arguments,2))}else if(T(e))u(b,function(j,k){i=j.$creation;i=="eager"&&d(k);i=="eager-published"&&Ra(e,k,d(k))});else g=d(a);return g}}function uc(a,b){function c(v){return v.indexOf(n)!=-1}function d(){return m+1<a.length?a.charAt(m+1):false}function e(v){return"0"<=v&&v<="9"}function f(v){return"a"<=v&&v<="z"||"A"<=v&&v<="Z"||"_"==v||v=="$"}function g(v){return v=="-"||v=="+"||e(v)}
function h(v,N,C){C=C||m;throw na("Lexer Error: "+v+" at column"+(E(N)?"s "+N+"-"+m+" ["+a.substring(N,C)+"]":" "+C)+" in expression ["+a+"].");}function i(){for(var v="",N=m;m<a.length;){var C=Q(a.charAt(m));if(C=="."||e(C))v+=C;else{var X=d();if(C=="e"&&g(X))v+=C;else if(g(C)&&X&&e(X)&&v.charAt(v.length-1)=="e")v+=C;else if(g(C)&&(!X||!e(X))&&v.charAt(v.length-1)=="e")h("Invalid exponent");else break}m++}v=1*v;t.push({index:N,text:v,json:true,fn:function(){return v}})}function j(){for(var v="",
N=m,C;m<a.length;){C=a.charAt(m);if(C=="."||f(C)||e(C))v+=C;else break;m++}C=lb[v];t.push({index:N,text:v,json:C,fn:C||D(Fb(v),{assign:function(X,ca){return Ra(X,v,ca)}})})}function k(v){var N=m;m++;for(var C="",X=v,ca=false;m<a.length;){var W=a.charAt(m);X+=W;if(ca){if(W=="u"){W=a.substring(m+1,m+5);W.match(/[\da-f]{4}/i)||h("Invalid unicode escape [\\u"+W+"]");m+=4;C+=String.fromCharCode(parseInt(W,16))}else{ca=vc[W];C+=ca?ca:W}ca=false}else if(W=="\\")ca=true;else if(W==v){m++;t.push({index:N,
text:X,string:C,json:true,fn:function(){return C.length==p?B.String.toDate(C):C}});return}else C+=W;m++}h("Unterminated quote",N)}for(var p=b?Cb:-1,t=[],o,m=0,r=[],n,s=":";m<a.length;){n=a.charAt(m);if(c("\"'"))k(n);else if(e(n)||c(".")&&e(d()))i();else if(f(n)){j();if("{,".indexOf(s)!=-1&&r[0]=="{"&&(o=t[t.length-1]))o.json=o.text.indexOf(".")==-1}else if(c("(){}[].,;:")){t.push({index:m,text:n,json:":[,".indexOf(s)!=-1&&c("{[")||c("}]:,")});c("{[")&&r.unshift(n);c("}]")&&r.shift();m++}else if(n==
" "||n=="\r"||n=="\t"||n=="\n"||n=="\u000b"||n=="\u00a0"){m++;continue}else{var z=n+d(),O=lb[n],L=lb[z];if(L){t.push({index:m,text:z,fn:L});m+=2}else if(O){t.push({index:m,text:n,fn:O,json:"[,:".indexOf(s)!=-1&&c("+-")});m+=1}else h("Unexpected next character ",m,m+1)}s=n}return t}function Pa(a,b){function c(l,q){throw na("Parse Error: Token '"+q.text+"' "+l+" at column "+(q.index+1)+" of expression ["+a+"] starting at ["+a.substring(q.index)+"].");}function d(){if(ja.length===0)throw na("Unexpected end of expression: "+
a);return ja[0]}function e(l,q,w,x){if(ja.length>0){var G=ja[0],da=G.text;if(da==l||da==q||da==w||da==x||!l&&!q&&!w&&!x)return G}return false}function f(l,q,w,x){if(l=e(l,q,w,x)){if(b&&!l.json){index=l.index;c("is not valid json",l)}ja.shift();return this.currentToken=l}return false}function g(l){f(l)||c("is unexpected, expecting ["+l+"]",e())}function h(l,q){return function(w){return l(w,q(w))}}function i(l,q,w){return function(x){return q(x,l(x),w(x))}}function j(){ja.length!==0&&c("is extra token not part of expression",
ja[0])}function k(){for(var l=[];;){ja.length>0&&!e("}",")",";","]")&&l.push(p());if(!f(";"))return function(q){for(var w,x=0;x<l.length;x++){var G=l[x];if(G)w=G(q)}return w}}}function p(){for(var l=m(),q;;)if(q=f("|"))l=i(l,q.fn,t());else return l}function t(){return o(ea)}function o(l){for(var q=v(l),w=[];;)if(f(":"))w.push(m());else{var x=function(G,da){for(var Da=[da],Ea=0;Ea<w.length;Ea++)Da.push(w[Ea](G));return q.apply(G,Da)};return function(){return x}}}function m(){var l=r(),q,w;if(w=f("=")){l.assign||
c("implies assignment but ["+a.substring(0,w.index)+"] can not be assigned to",w);q=r();return function(x){return l.assign(x,q(x))}}else return l}function r(){for(var l=n(),q;;)if(q=f("||"))l=i(l,q.fn,n());else return l}function n(){var l=s(),q;if(q=f("&&"))l=i(l,q.fn,n());return l}function s(){var l=z(),q;if(q=f("==","!="))l=i(l,q.fn,s());return l}function z(){var l;l=O();for(var q;q=f("+","-");)l=i(l,q.fn,O());l=l;if(q=f("<",">","<=",">="))l=i(l,q.fn,z());return l}function O(){for(var l=L(),q;q=
f("*","/","%");)l=i(l,q.fn,L());return l}function L(){var l;return f("+")?N():(l=f("-"))?i(wc,l.fn,L()):(l=f("!"))?h(l.fn,L()):N()}function v(l){var q=f(),w=q.text.split(".");l=l;for(var x,G=0;G<w.length;G++){x=w[G];if(l)l=l[x]}typeof l!=ia&&c("should be a function",q);return l}function N(){var l;if(f("(")){l=p();g(")");l=l}else if(f("["))l=W();else if(f("{"))l=xc();else{var q=f();(l=q.fn)||c("not a primary expression",q)}for(;q=f("(","[",".");)if(q.text==="(")l=ca(l);else if(q.text==="[")l=X(l);
else if(q.text===".")l=C(l);else c("IMPOSSIBLE");return l}function C(l){var q=f().text,w=Fb(q);return D(function(x){return w(l(x))},{assign:function(x,G){return Ra(l(x),q,G)}})}function X(l){var q=m();g("]");return D(function(w){var x=l(w);w=q(w);return x?x[w]:V},{assign:function(w,x){return l(w)[q(w)]=x}})}function ca(l){var q=[];if(d().text!=")"){do q.push(m());while(f(","))}g(")");return function(w){for(var x=[],G=0;G<q.length;G++)x.push(q[G](w));G=l(w)||F;return G.apply?G.apply(w,x):G(x[0],x[1],
x[2],x[3],x[4])}}function W(){var l=[];if(d().text!="]"){do l.push(m());while(f(","))}g("]");return function(q){for(var w=[],x=0;x<l.length;x++)w.push(l[x](q));return w}}function xc(){var l=[];if(d().text!="}"){do{var q=f();q=q.string||q.text;g(":");var w=m();l.push({key:q,value:w})}while(f(","))}g("}");return function(x){for(var G={},da=0;da<l.length;da++){var Da=l[da],Ea=Da.value(x);G[Da.key]=Ea}return G}}function yc(){var l=f().text;g(":");var q;if(d().text=="{"){g("{");q=k();g("}")}else q=m();
return function(){return{name:l,fn:q}}}var wc=bb(0),ja=uc(a,b);return{assertAllConsumed:j,primary:N,statements:k,validator:function(){return o(mb)},filter:t,watch:function(){for(var l=[];ja.length>0;){l.push(yc());f(";")||j()}j();return function(q){for(var w=0;w<l.length;w++){var x=l[w](q);q.addListener(x.name,x.fn)}}}}}function Lb(a,b){this.template=a+="#";this.defaults=b||{};var c=this.urlParams={};u(a.split(/\W/),function(d){if(d&&a.match(RegExp(":"+d+"\\W")))c[d]=true})}function Ta(a){this.xhr=
a}function zc(a,b,c,d,e,f){function g(n){try{n.apply(null,Na.call(arguments,1))}finally{j--;if(j===0)for(;k.length;)try{k.pop()()}catch(s){e.error(s)}}}var h=this;h.isMock=false;var i=0,j=0,k=[];h.xhr=function(n,s,z,O){if(J(z)){O=z;z=y}if(Q(n)=="json"){var L="angular_"+Math.random()+"_"+i++;L=L.replace(/\d\./,"");n=b[0].createElement("script");n.type="text/javascript";n.src=s.replace("JSON_CALLBACK",L);H[L]=function(N){H[L]=V;O(200,N)};c.append(n)}else{var v=new d;v.open(n,s,true);v.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");v.setRequestHeader("Accept","application/json, text/plain, */*");v.setRequestHeader("X-Requested-With","XMLHttpRequest");j++;v.onreadystatechange=function(){if(v.readyState==4)g(O,v.status||200,v.responseText)};v.send(z||"")}};h.notifyWhenNoOutstandingRequests=function(n){j===0?n():k.push(n)};var p=[];h.poll=function(){u(p,function(n){n()})};h.addPollFn=function(n){p.push(n);return n};h.startPoller=function(n,s){(function z(){h.poll();s(z,n)})()};h.setUrl=function(n){a.href.match(/#/);
n.match(/#/)||(n+="#");a.href=n};h.getUrl=function(){return a.href};var t=b[0],o={},m="";h.cookies=function(n,s){var z,O,L;if(n)if(s===V)t.cookie=escape(n)+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT";else{if(I(s)){t.cookie=escape(n)+"="+escape(s);z=n.length+s.length+1;z>4096&&e.warn("Cookie '"+n+"' possibly not set or overflowed because it was too large ("+z+" > 4096 bytes)!");o.length>20&&e.warn("Cookie '"+n+"' possibly not set or overflowed because too many cookies were already set ("+o.length+" > 20 )")}}else{if(t.cookie!==
m){m=t.cookie;z=m.split("; ");o={};for(O=0;O<z.length;O++){L=z[O].split("=");if(L.length===2)o[unescape(L[0])]=unescape(L[1])}}return o}};h.defer=function(n){j++;f(function(){g(n)},0)};var r=F;h.hover=function(n){r=n};h.bind=function(){b.bind("mouseover",function(n){r(A(ka?n.srcElement:n.target),true);return true});b.bind("mouseleave mouseout click dblclick keypress keyup",function(n){r(A(n.target),false);return true})};h.addCss=function(n){var s=A(t.createElement("link"));s.attr("rel","stylesheet");
s.attr("type","text/css");s.attr("href",n);c.append(s)};h.addJs=function(n,s){var z=A(t.createElement("script"));z.attr("type","text/javascript");z.attr("src",n);s&&z.attr("id",s);c.append(z)}}function lc(a,b){function c(i,j,k,p){j=Q(j);if(Mb[j])for(;g.last()&&Nb[g.last()];)d("",g.last());Ob[j]&&g.last()==j&&d("",j);(p=Pb[j]||!!p)||g.push(j);var t={};k.replace(Ac,function(o,m,r,n,s){t[m]=nb(r?r:n?n:s?s:Qb[m]?m:"")});b.start(j,t,p)}function d(i,j){var k=0,p;if(j=Q(j))for(k=g.length-1;k>=0;k--)if(g[k]==
j)break;if(k>=0){for(p=g.length-1;p>=k;p--)b.end(g[p]);g.length=k}}var e,f,g=[],h=a;for(g.last=function(){return g[g.length-1]};a;){f=true;if(!g.last()||!Rb[g.last()]){if(a.indexOf("<!--")===0){e=a.indexOf("--\>");if(e>=0){b.comment&&b.comment(a.substring(4,e));a=a.substring(e+3);f=false}}else if(Bc.test(a)){if(e=a.match(Sb)){a=a.substring(e[0].length);e[0].replace(Sb,d);f=false}}else if(Cc.test(a))if(e=a.match(Tb)){a=a.substring(e[0].length);e[0].replace(Tb,c);f=false}if(f){e=a.indexOf("<");f=e<
0?a:a.substring(0,e);a=e<0?"":a.substring(e);b.chars(nb(f))}}else{a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+g.last()+"[^>]*>","i"),function(i,j){j=j.replace(Dc,"$1").replace(Ec,"$1");b.chars(nb(j));return""});d("",g.last())}if(a==h)throw"Parse Error: "+a;h=a}d()}function la(a){var b={};a=a.split(",");var c;for(c=0;c<a.length;c++)b[a[c]]=true;return b}function nb(a){ob.innerHTML=a.replace(/</g,"&lt;");return ob.innerText||ob.textContent}function Ub(a){return a.replace(/&/g,"&amp;").replace(Fc,function(b){return"&#"+
b.charCodeAt(0)+";"}).replace(/</g,"&lt;").replace(/>/g,"&gt;")}function wb(a){var b=false,c=M(a,a.push);return{start:function(d,e,f){d=Q(d);if(!b&&Rb[d])b=d;if(!b&&Vb[d]==true){c("<");c(d);u(e,function(g,h){var i=Q(h);if(Gc[i]==true&&(Wb[i]!==true||g.match(Hc))){c(" ");c(h);c('="');c(Ub(g));c('"')}});c(f?"/>":">")}},end:function(d){d=Q(d);if(!b&&Vb[d]==true){c("</");c(d);c(">")}if(d==b)b=false},chars:function(d){b||c(Ub(d))}}}function Xb(a){var b=a[Fa],c=Ua[b];if(c){u(c.bind||{},function(d,e){Ic(a,
e,d)});delete Ua[b];if(ka)a[Fa]="";else delete a[Fa]}}function Jc(a){var b={};a=a[0].style;var c,d;if(typeof a.length=="number")for(c=0;c<a.length;c++){d=a[c];b[d]=a[d]}else for(d in a){c=a[d];if(1*d!=d&&d!="cssText"&&c&&typeof c=="string"&&c!="false")b[d]=c}return b}function pa(a){if(Ja(a)){this[0]=a;this.length=1}else if(E(a.length)&&a.item){for(var b=0;b<a.length;b++)this[b]=a[b];this.length=a.length}}function va(a,b){B[a]=B[a]||{};u(b,function(c){D(B[a],c)})}function fa(a,b,c){var d="";if(a<0){d=
"-";a=-a}for(a=""+a;a.length<b;)a="0"+a;if(c)a=a.substr(a.length-b);return d+a}function R(a,b,c,d){return function(e){e=e["get"+a]();if(c>0||e>-c)e+=c;if(e===0&&c==-12)e=12;return fa(e,b,d)}}function za(a,b){return{format:a,parse:b||a}}function Yb(a){return E(a)&&a!==y?""+a:a}function P(a,b,c,d){kb(a,b,{$inject:c,$creation:d})}function Zb(a,b,c){var d="^"+b.replace(/[\.\\\(\)\^\$]/g,"$1")+"$",e=[],f={};u(b.split(/\W/),function(h){if(h){var i=RegExp(":"+h+"([\\W])");if(d.match(i)){d=d.replace(i,"([^/]*)$1");
e.push(h)}}});var g=a.match(RegExp(d));if(g){u(e,function(h,i){f[h]=g[i+1]});c&&this.$set(c,f)}return g?f:y}function $b(a){var b=ac[a];if(!b){var c=[];u(Va(a),function(d){var e=Wa(d);c.push(e?function(f){var g,h=this.$tryEval(e,function(i){g=$(i)});ra(f,Sa,g);return g?g:h}:function(){return d})});ac[a]=b=function(d){var e=[],f=this.hasOwnProperty(bc)?this.$element:V;this.$element=d;for(var g=0;g<c.length;g++){var h=c[g].call(this,d);if(Ja(h))h="";else if(T(h))h=$(h,true);e.push(h)}this.$element=f;
return e.join("")}}return b}function pb(a){return function(b,c){var d=c[0].className+" ";return function(e){this.$onEval(function(){if(a(this.$index)){var f=this.$eval(b);if(ha(f))f=f.join(" ");e[0].className=xa(d+f)}},e)}}}function Va(a){for(var b=[],c=0,d;(d=a.indexOf("{{",c))>-1;){c<d&&b.push(a.substr(c,d-c));c=d;d=a.indexOf("}}",d);d=d<0?a.length:d+2;b.push(a.substr(c,d-c));c=d}c!=a.length&&b.push(a.substr(c,a.length-c));return b.length===0?[a]:b}function Wa(a){return(a=a.replace(/\n/gm," ").match(/^\{\{(.*)\}\}$/))?
a[1]:y}function cc(a,b){var c=b.attr("name");if(c)return{get:function(){return a.$eval(c)},set:function(d){if(d!==V)return a.$tryEval(c+"="+$(d),b)}}}function Ga(a,b){var c=cc(a,b),d=b.attr("ng:format")||qb,e=ma(d);if(!e)throw"Formatter named '"+d+"' not found.";if(c)return{get:function(){return e.format(c.get())},set:function(f){return c.set(e.parse(f))}}}function rb(a,b){function c(){var o=xa(b.val());if(b[0].disabled||b[0].readOnly){ra(b,Ha,y);t.markValid(b)}else{var m=hc(a,{$element:b});o=p&&
!o?"Required":o?e(m,o):y;ra(b,Ha,o);(k=o)?t.markInvalid(b):t.markValid(b)}}var d=b.attr("ng:validate")||qb,e=Pa(d).validator()(),f=b.attr("ng:required"),g=b.attr("ng:format")||qb,h=ma(g),i,j,k,p,t=a.$invalidWidgets||{markValid:F,markInvalid:F};if(!e)throw"Validator named '"+d+"' not found.";if(!h)throw"Formatter named '"+g+"' not found.";i=h.format;j=h.parse;if(f)a.$watch(f,function(o){p=o;c()});else p=f==="";b.data(sb,c);return{get:function(){k&&ra(b,Ha,y);try{var o=j(b.val());c();return o}catch(m){k=
m;ra(b,Ha,m)}},set:function(o){var m=b.val();o=i(o);if(m!=o)b.val(o||"");c()}}}function tb(){return{get:F,set:F}}function Xa(a){return function(b,c){var d=c.get();if(!d&&E(a))d=U(a);ba(b.get())&&E(d)&&b.set(d)}}function Aa(a,b,c,d,e){return function(f){var g=this,h=b(g,f),i=c(g,f),j=f.attr("ng:change")||"",k;if(h){d.call(g,h,i,f);this.$eval(f.attr("ng:init")||"");if(j||b!==tb)f.bind(a,function(){var p=i.get();if(!e||p!=k){h.set(p);k=h.get();g.$tryEval(j,f);g.$root.$eval()}});g.$watch(h.get,function(p){if(k!==
p)i.set(k=p)})}}}function Ya(a){this.directives(true);return Kc[Q(a[0].type)]||F}if(typeof Y.getAttribute==qa)Y.getAttribute=function(){};var Q=function(a){return I(a)?a.toLowerCase():a},Za=function(a){return I(a)?a.toUpperCase():a},S=function(a){return I(a)?a.replace(/[A-Z]/g,function(b){b=b.charCodeAt(0)|32;return String.fromCharCode(b)}):a},aa=function(a){return I(a)?a.replace(/[a-z]/g,function(b){b=b.charCodeAt(0)&-33;return String.fromCharCode(b)}):a};if("i"!=="I".toLowerCase()){Q=S;Za=aa}var V=
undefined,y=null,bc="$element",jb="$scope",sb="$validate",rc="boolean",ia="function",fc="length",gc="name",Qa="null",kc="number",vb="object",jc="string",qa="undefined",Sa="ng-exception",Ha="ng-validation-error",qb="noop",Jb=-1E3,Lc={FIRST:-99999,LAST:99999,WATCH:Jb},na=H.Error,cb=H.jQuery||H.$,ka=parseInt((/msie (\d+)/.exec(Q(navigator.userAgent))||[])[1],10),A=cb||ic,Na=Array.prototype.slice,Db=H.console?M(H.console,H.console.error||F):F,B=H.angular||(H.angular={}),eb=ga(B,"markup"),Ab=ga(B,"attrMarkup"),
K=ga(B,"directive"),Z=ga(B,"widget",Q),mb=ga(B,"validator"),ea=ga(B,"filter"),ma=ga(B,"formatter"),kb=ga(B,"service");ga(B,"callbacks");var Ba,qc=/^(|.*\/)angular(-.*?)?(\.min)?.js(\?[^#]*)?(#(.*))?$/,Cb=24;Ba=ka?function(a){a=a.nodeName?a:a[0];return a.scopeName&&a.scopeName!="HTML"?Za(a.scopeName+":"+a.nodeName):a.nodeName}:function(a){return a.nodeName?a.nodeName:a[0].nodeName};B.toJson=$;B.fromJson=sa;ib.prototype={init:function(a,b){var c={};this.collectInits(a,c,b);$a(c,function(d){u(d,function(e){e()})})},
collectInits:function(a,b,c){var d=b[this.priority],e=c;d||(b[this.priority]=d=[]);a=A(a);if(this.newScope){e=ua(c);c.$onEval(e.$eval);a.data(jb,e)}u(this.inits,function(j){d.push(function(){e.$tryEval(function(){return e.$inject(j,e,a)},a)})});var f=a[0].childNodes,g=this.children,h=this.paths,i=h.length;for(c=0;c<i;c++)g[c].collectInits(f[h[c]],b,e)},addInit:function(a){a&&this.inits.push(a)},addChild:function(a,b){if(b){this.paths.push(a);this.children.push(b)}},empty:function(){return this.inits.length===
0&&this.paths.length===0}};zb.prototype={compile:function(a){a=A(a);var b=0,c,d=a.parent();if(d&&d[0]){d=d[0];for(var e=0;e<d.childNodes.length;e++)if(d.childNodes[e]==a[0])b=e}c=this.templatize(a,b,0)||new ib;return function(f,g){f=A(f);var h=g&&g.$eval?g:ua(g);f.data(jb,h);return D(h,{$element:f,$init:function(){c.init(f,h);h.$eval();delete h.$init;return h}})}},templatize:function(a,b,c){var d=this,e,f,g=d.directives,h=true,i=true,j=Ba(a),k,p={compile:M(d,d.compile),comment:function(r){return A(Y.createComment(r))},
element:function(r){return A(Y.createElement(r))},text:function(r){return A(Y.createTextNode(r))},descend:function(r){if(E(r))h=r;return h},directives:function(r){if(E(r))i=r;return i},scope:function(r){if(E(r))k.newScope=k.newScope||r;return k.newScope}};try{c=a.attr("ng:eval-order")||c||0}catch(t){c=c||0}if(I(c))c=Lc[Za(c)]||parseInt(c,10);k=new ib(c);Oa(a,function(r,n){if(!e)if(e=d.widgets("@"+n)){a.addClass("ng-attr-widget");e=M(p,e,r,a)}});if(!e)if(e=d.widgets(j)){j.indexOf(":")>0&&a.addClass("ng-widget");
e=M(p,e,a)}if(e){i=h=false;j=a.parent();k.addInit(e.call(p,a));if(j&&j[0])a=A(j[0].childNodes[b])}if(h)for(var o=0,m=a[0].childNodes;o<m.length;o++)Ba(m[o])=="#text"&&u(d.markup,function(r){if(o<m.length){var n=A(m[o]);r.call(p,n.text(),n,a)}});if(i){Oa(a,function(r,n){u(d.attrMarkup,function(s){s.call(p,r,n,a)})});Oa(a,function(r,n){if(f=g[n]){a.addClass("ng-directive");k.addInit(g[n].call(p,r,a))}})}h&&Eb(a,function(r,n){k.addChild(n,d.templatize(r,n,c))});return k.empty()?y:k}};var tc=0,Gb={},
Ib={},Hb={};u("abstract,boolean,break,byte,case,catch,char,class,const,continue,debugger,default,delete,do,double,else,enum,export,extends,false,final,finally,float,for,function,goto,if,implements,import,ininstanceof,intinterface,long,native,new,null,package,private,protected,public,return,short,static,super,switch,synchronized,this,throw,throws,transient,true,try,typeof,var,volatile,void,undefined,while,with".split(/,/),function(a){Hb[a]=true});var lb={"null":function(){return y},"true":function(){return true},
"false":function(){return false},$undefined:F,"+":function(a,b,c){return(E(b)?b:0)+(E(c)?c:0)},"-":function(a,b,c){return(E(b)?b:0)-(E(c)?c:0)},"*":function(a,b,c){return b*c},"/":function(a,b,c){return b/c},"%":function(a,b,c){return b%c},"^":function(a,b,c){return b^c},"=":F,"==":function(a,b,c){return b==c},"!=":function(a,b,c){return b!=c},"<":function(a,b,c){return b<c},">":function(a,b,c){return b>c},"<=":function(a,b,c){return b<=c},">=":function(a,b,c){return b>=c},"&&":function(a,b,c){return b&&
c},"||":function(a,b,c){return b||c},"&":function(a,b,c){return b&c},"|":function(a,b,c){return c(a,b)},"!":function(a,b){return!b}},vc={n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'};Lb.prototype={url:function(a){var b=this,c=this.template;a=a||{};u(this.urlParams,function(e,f){c=c.replace(RegExp(":"+f+"(\\W)"),(a[f]||b.defaults[f]||"")+"$1")});c=c.replace(/\/?#$/,"");var d=[];$a(a,function(e,f){b.urlParams[f]||d.push(encodeURI(f)+"="+encodeURI(e))});c=c.replace(/\/*$/,"");return c+
(d.length?"?"+d.join("&"):"")}};Ta.DEFAULT_ACTIONS={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:true},remove:{method:"DELETE"},"delete":{method:"DELETE"}};Ta.prototype={route:function(a,b,c){function d(h){var i={};u(b||{},function(j,k){i[k]=j.charAt&&j.charAt(0)=="@"?Ca(h,j.substr(1)):j});return i}function e(h){U(h||{},this)}var f=this,g=new Lb(a);c=D({},Ta.DEFAULT_ACTIONS,c);u(c,function(h,i){var j=h.method=="POST"||h.method=="PUT";e[i]=function(k,p,t){var o={},m,r=F;switch(arguments.length){case 3:r=
t;case 2:if(J(p))r=p;else{o=k;m=p;break}case 1:if(J(k))r=k;else if(j)m=k;else o=k;break;case 0:break;default:throw"Expected between 0-3 arguments [params, data, callback], got "+arguments.length+" arguments.";}var n=this instanceof e?this:h.isArray?[]:new e(m);f.xhr(h.method,g.url(D({},h.params||{},d(m),o)),m,function(s,z){if(s==200){if(h.isArray){n.length=0;u(z,function(O){n.push(new e(O))})}else U(z,n);(r||F)(n)}else throw{status:s,response:z,message:s+": "+z};},h.verifyCache);return n};e.bind=
function(k){return f.route(a,D({},b,k),c)};e.prototype["$"+i]=function(k,p){var t=d(this),o=F;switch(arguments.length){case 2:t=k;o=p;case 1:if(typeof k==ia)o=k;else t=k;case 0:break;default:throw"Expected between 1-2 arguments [params, callback], got "+arguments.length+" arguments.";}e[i].call(this,t,j?this:V,o)}});return e}};var Mc=H.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(b){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(c){}throw new na("This browser does not support XMLHttpRequest.");
},Tb=/^<\s*([\w:]+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,Sb=/^<\s*\/\s*([\w:]+)[^>]*>/,Ac=/(\w+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,Cc=/^</,Bc=/^<\s*\//,Dc=/<!--(.*?)--\>/g,Ec=/<!\[CDATA\[(.*?)]]\>/g,Hc=/^((ftp|https?):\/\/|mailto:|#)/,Fc=/([^\#-~| |!])/g,Pb=la("area,br,col,hr,img"),Mb=la("address,blockquote,center,dd,del,dir,div,dl,dt,hr,ins,li,map,menu,ol,p,pre,script,table,tbody,td,tfoot,th,thead,tr,ul"),Nb=la("a,abbr,acronym,b,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,q,s,samp,small,span,strike,strong,sub,sup,tt,u,var"),
Ob=la("colgroup,dd,dt,li,p,td,tfoot,th,thead,tr"),Rb=la("script,style"),Vb=D({},Pb,Mb,Nb,Ob),Qb=la("compact,ismap,nohref,nowrap"),Wb=la("background,href,longdesc,src,usemap"),Gc=D({},Qb,Wb,la("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,coords,dir,face,headers,height,hreflang,hspace,lang,language,rel,rev,rows,rowspan,rules,scope,scrolling,shape,span,start,summary,target,title,type,valign,value,vspace,width")),ob=Y.createElement("pre"),Ua={},Fa="ng-"+(new Date).getTime(),
Nc=1,Oc=H.document.attachEvent?function(a,b,c){a.attachEvent("on"+b,c)}:function(a,b,c){a.addEventListener(b,c,false)},Ic=H.document.detachEvent?function(a,b,c){a.detachEvent("on"+b,c)}:function(a,b,c){a.removeEventListener(b,c,false)};pa.prototype={data:function(a,b){var c=this[0],d=c[Fa];d=Ua[d||-1];if(E(b)){if(!d){c[Fa]=d=Nc++;d=Ua[d]={}}d[a]=b}else return d?d[a]:y},removeData:function(){Xb(this[0])},dealoc:function(){(function a(b){Xb(b);var c=0;for(b=b.childNodes;c<b.length;c++)a(b[c])})(this[0])},
bind:function(a,b){var c=this,d=c[0],e=c.data("bind"),f;e||this.data("bind",e={});u(a.split(" "),function(g){f=e[g];if(!f){e[g]=f=function(h){if(!h.preventDefault)h.preventDefault=function(){h.returnValue=false};if(!h.stopPropagation)h.stopPropagation=function(){h.cancelBubble=true};u(f.fns,function(i){i.call(c,h)})};f.fns=[];Oc(d,g,f)}f.fns.push(b)})},replaceWith:function(a){this[0].parentNode.replaceChild(A(a)[0],this[0])},children:function(){return new pa(this[0].childNodes)},append:function(a){var b=
this[0];a=A(a);u(a,function(c){b.appendChild(c)})},remove:function(){this.dealoc();var a=this[0].parentNode;a&&a.removeChild(this[0])},removeAttr:function(a){this[0].removeAttribute(a)},after:function(a){this[0].parentNode.insertBefore(A(a)[0],this[0].nextSibling)},hasClass:function(a){a=" "+a+" ";if((" "+this[0].className+" ").replace(/[\n\t]/g," ").indexOf(a)>-1)return true;return false},removeClass:function(a){this[0].className=xa((" "+this[0].className+" ").replace(/[\n\t]/g," ").replace(" "+
a+" ",""))},toggleClass:function(a,b){(b?this.addClass:this.removeClass).call(this,a)},addClass:function(a){if(!this.hasClass(a))this[0].className=xa(this[0].className+" "+a)},css:function(a,b){var c=this[0].style;if(I(a))if(E(b))c[a]=b;else return c[a];else D(c,a)},attr:function(a,b){var c=this[0];if(T(a))u(a,function(d,e){c.setAttribute(e,d)});else if(E(b))c.setAttribute(a,b);else return c.getAttribute(a,2)},text:function(a){if(E(a))this[0].textContent=a;return this[0].textContent},val:function(a){if(E(a))this[0].value=
a;return this[0].value},html:function(a){if(E(a)){for(var b=0,c=this[0].childNodes;b<c.length;b++)A(c[b]).dealoc();this[0].innerHTML=a}return this[0].innerHTML},parent:function(){return A(this[0].parentNode)},clone:function(){return A(this[0].cloneNode(true))}};ka&&D(pa.prototype,{text:function(a){var b=this[0];if(b.nodeType==3){if(E(a))b.nodeValue=a;return b.nodeValue}else{if(E(a))b.innerText=a;return b.innerText}}});S={typeOf:function(a){if(a===y)return Qa;var b=typeof a;if(b==vb){if(a instanceof
Array)return"array";if(a instanceof Date)return"date";if(a.nodeType==1)return"element"}return b}};aa={copy:U,size:function(a){var b=0;if(a)if(wa(a.length))return a.length;else if(T(a))for(key in a)b++;return b},equals:La};var Pc={extend:D},Qc={indexOf:Ka,sum:function(a,b){for(var c=B.Function.compile(b),d=0,e=0;e<a.length;e++){var f=1*c(a[e]);isNaN(f)||(d+=f)}return d},remove:function(a,b){var c=Ka(a,b);c>=0&&a.splice(c,1);return b},filter:function(a,b){var c=[];c.check=function(i){for(var j=0;j<
c.length;j++)if(!c[j](i))return false;return true};var d=function(i,j){if(j.charAt(0)==="!")return!d(i,j.substr(1));switch(typeof i){case "boolean":case "number":case "string":return(""+i).toLowerCase().indexOf(j)>-1;case "object":for(var k in i)if(k.charAt(0)!=="$"&&d(i[k],j))return true;return false;case "array":for(k=0;k<i.length;k++)if(d(i[k],j))return true;return false;default:return false}};switch(typeof b){case "boolean":case "number":case "string":b={$:b};case "object":for(var e in b)e=="$"?
function(){var i=(""+b[e]).toLowerCase();i&&c.push(function(j){return d(j,i)})}():function(){var i=e,j=(""+b[e]).toLowerCase();j&&c.push(function(k){return d(Ca(k,i),j)})}();break;case ia:c.push(b);break;default:return a}for(var f=[],g=0;g<a.length;g++){var h=a[g];c.check(h)&&f.push(h)}return f},add:function(a,b){a.push(ba(b)?{}:b);return a},count:function(a,b){if(!b)return a.length;var c=B.Function.compile(b),d=0;u(a,function(e){c(e)&&d++});return d},orderBy:function(a,b,c){function d(h,i){return ya(i)?
function(j,k){return h(k,j)}:h}function e(h,i){var j=typeof h,k=typeof i;if(j==k){if(j=="string")h=h.toLowerCase();if(j=="string")i=i.toLowerCase();if(h===i)return 0;return h<i?-1:1}else return j<k?-1:1}b=ha(b)?b:[b];b=mc(b,function(h){var i=false,j=h||oa;if(I(h)){if(h.charAt(0)=="+"||h.charAt(0)=="-"){i=h.charAt(0)=="-";h=h.substring(1)}j=ta(h).fnSelf}return d(function(k,p){return e(j(k),j(p))},i)});for(var f=[],g=0;g<a.length;g++)f.push(a[g]);return f.sort(d(function(h,i){for(var j=0;j<b.length;j++){var k=
b[j](h,i);if(k!==0)return k}return 0},c))},limitTo:function(a,b){b=parseInt(b,10);var c=[],d,e;if(b>0){d=0;e=b}else{d=a.length+b;e=a.length}for(;d<e;d++)c.push(a[d]);return c}},Rc=/^(\d{4})-(\d\d)-(\d\d)(?:T(\d\d)(?:\:(\d\d)(?:\:(\d\d)(?:\.(\d{3}))?)?)?Z)?$/,hb={quote:function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\v/g,"\\v")+'"'},quoteUnicode:function(a){a=B.String.quote(a);for(var b=[],
c=0;c<a.length;c++){var d=a.charCodeAt(c);if(d<128)b.push(a.charAt(c));else{d="000"+d.toString(16);b.push("\\u"+d.substring(d.length-4))}}return b.join("")},toDate:function(a){var b;if(I(a)&&(b=a.match(Rc))){a=new Date(0);a.setUTCFullYear(b[1],b[2]-1,b[3]);a.setUTCHours(b[4]||0,b[5]||0,b[6]||0,b[7]||0);return a}return a}},dc={toString:function(a){return!a?a:a.toISOString?a.toISOString():fa(a.getUTCFullYear(),4)+"-"+fa(a.getUTCMonth()+1,2)+"-"+fa(a.getUTCDate(),2)+"T"+fa(a.getUTCHours(),2)+":"+fa(a.getUTCMinutes(),
2)+":"+fa(a.getUTCSeconds(),2)+"."+fa(a.getUTCMilliseconds(),3)+"Z"}};va("Global",[S]);va("Collection",[S,aa]);va("Array",[S,aa,Qc]);va("Object",[S,aa,Pc]);va("String",[S,hb]);va("Date",[S,dc]);B.Date.toString=dc.toString;va("Function",[S,aa,{compile:function(a){return J(a)?a:a?ta(a).fnSelf:oa}}]);ea.currency=function(a){this.$element.toggleClass("ng-format-negative",a<0);return"$"+ea.number.apply(this,[a,2])};ea.number=function(a,b){if(isNaN(a)||!isFinite(a))return"";b=typeof b==qa?2:b;var c=a<0;
a=Math.abs(a);var d=""+Math.round(a*Math.pow(10,b)),e=d.substring(0,d.length-b);e=e||"0";var f=d.substring(d.length-b);d=c?"-":"";for(c=0;c<e.length;c++){if((e.length-c)%3===0&&c!==0)d+=",";d+=e.charAt(c)}if(b>0){for(e=f.length;e<b;e++)f+="0";d+="."+f.substring(0,b)}return d};var Sc={yyyy:R("FullYear",4),yy:R("FullYear",2,0,true),MM:R("Month",2,1),M:R("Month",1,1),dd:R("Date",2),d:R("Date",1),HH:R("Hours",2),H:R("Hours",1),hh:R("Hours",2,-12),h:R("Hours",1,-12),mm:R("Minutes",2),m:R("Minutes",1),
ss:R("Seconds",2),s:R("Seconds",1),a:function(a){return a.getHours()<12?"am":"pm"},Z:function(a){a=a.getTimezoneOffset();return fa(a/60,2)+fa(Math.abs(a%60),2)}},Tc=/([^yMdHhmsaZ]*)(y+|M+|d+|H+|h+|m+|s+|a|Z)(.*)/,Uc=/^\d+$/;ea.date=function(a,b){if(I(a))a=Uc.test(a)?parseInt(a,10):hb.toDate(a);if(wa(a))a=new Date(a);if(!(a instanceof Date))return a;var c=a.toLocaleDateString(),d;if(b&&I(b)){c="";for(var e=[];b;){e=Ma(e,Tc.exec(b),1);b=e.pop()}u(e,function(f){d=Sc[f];c+=d?d(a):f})}return c};ea.json=
function(a){this.$element.addClass("ng-monospace");return $(a,true)};ea.lowercase=Q;ea.uppercase=Za;ea.html=function(a,b){return new db(a,b)};ea.linky=function(a){if(!a)return a;for(var b=/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,c=a,d=[],e=wb(d),f,g;a=c.match(b);){f=a[0];if(a[2]==a[3])f="mailto:"+f;g=a.index;e.chars(c.substr(0,g));e.start("a",{href:f});e.chars(a[0].replace(/^mailto:/,""));e.end("a");c=c.substring(g+a[0].length)}e.chars(c);return new db(d.join(""))};
var Vc=/^\s*[-+]?\d*(\.\d*)?\s*$/;ma.noop=za(oa,oa);ma.json=za($,sa);ma["boolean"]=za(Yb,ya);ma.number=za(Yb,function(a){if(a==y||Vc.exec(a))return a===y||a===""?y:1*a;else throw"Not a number";});ma.list=za(function(a){return a?a.join(", "):a},function(a){var b=[];u((a||"").split(","),function(c){(c=xa(c))&&b.push(c)});return b});ma.trim=za(function(a){return a?xa(""+a):""});D(mb,{noop:function(){return y},regexp:function(a,b,c){return a.match(b)?y:c||"Value does not match expected format "+b+"."},
number:function(a,b,c){var d=1*a;if(d==a){if(typeof b!=qa&&d<b)return"Value can not be less than "+b+".";if(typeof b!=qa&&d>c)return"Value can not be greater than "+c+".";return y}else return"Not a number"},integer:function(a,b,c){if(b=mb.number(a,b,c))return b;if(!(""+a).match(/^\s*[\d+]*\s*$/)||a!=Math.round(a))return"Not a whole number";return y},date:function(a){var b=(a=/^(\d\d?)\/(\d\d?)\/(\d\d\d\d)$/.exec(a))?new Date(a[3],a[1]-1,a[2]):0;return b&&b.getFullYear()==a[3]&&b.getMonth()==a[1]-
1&&b.getDate()==a[2]?y:"Value is not a date. (Expecting format: 12/31/2009)."},email:function(a){if(a.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/))return y;return"Email needs to be in username@host.com format."},phone:function(a){if(a.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/))return y;if(a.match(/^\+\d{2,3} (\(\d{1,5}\))?[\d ]+\d$/))return y;return"Phone number needs to be in 1(987)654-3210 format in North America or +999 (123) 45678 906 internationaly."},url:function(a){if(a.match(/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/))return y;
return"URL needs to be in http://server[:port]/path format."},json:function(a){try{sa(a);return y}catch(b){return b.toString()}},asynchronous:function(a,b,c){if(a){var d=this,e=d.$element,f=e.data("$asyncValidator");f||e.data("$asyncValidator",f={inputs:{}});f.current=a;var g=f.inputs[a];if(g)g.inFlight?d.$invalidWidgets.markInvalid(d.$element):(c||F)(g.response);else{f.inputs[a]=g={inFlight:true};d.$invalidWidgets.markInvalid(d.$element);e.addClass("ng-input-indicator-wait");b(a,function(h,i){g.response=
i;g.error=h;g.inFlight=false;if(f.current==a){e.removeClass("ng-input-indicator-wait");d.$invalidWidgets.markValid(e)}e.data(sb)();d.$root.$eval()})}return g.error}}});var Wc=/^(file|ftp|http|https):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,Xc=/^([^\?]*)?(\?([^\?]*))?$/,ec={http:80,https:443,ftp:21};P("$window",M(H,oa,H),[],"eager-published");P("$document",function(a){return A(a.document)},["$window"],"eager-published");P("$location",function(a){function b(o){if(I(o)){var m=
D,r=j,n={},s=Wc.exec(o);if(s){n.href=o.replace(/#$/,"");n.protocol=s[1];n.host=s[3]||"";n.port=s[5]||ec[n.protocol]||y;n.path=s[6]||"";n.search=fb(s[8]);n.hash=s[10]||"";D(n,h(n.hash))}m(r,n)}else{E(o.hash)&&D(o,h(o.hash));D(j,o);if(E(o.hashPath||o.hashSearch))j.hash=g(j);j.href=f(j)}}function c(){if(j.href==p){if(j.hash==t)j.hash=g(j);j.href=f(j)}b(j.href)}function d(){p=j.href;t=j.hash}function e(){c();if(j.href!=p){a.setUrl(k=j.href);d()}}function f(o){var m=Bb(o.search),r=o.port==ec[o.protocol]?
y:o.port;return o.protocol+"://"+o.host+(r?":"+r:"")+o.path+(m?"?"+m:"")+(o.hash?"#"+o.hash:"")}function g(o){var m=Bb(o.hashSearch);return escape(o.hashPath).replace(/%21/gi,"!").replace(/%3A/gi,":").replace(/%24/gi,"$")+(m?"?"+m:"")}function h(o){var m={},r=Xc.exec(o);if(r){m.hash=o;m.hashPath=unescape(r[1]||"");m.hashSearch=fb(r[3])}return m}var i=this,j={toString:function(){c();return j.href},update:b,updateHash:function(o,m){var r={};if(I(o)){r.hashPath=o;if(E(m))r.hashSearch=m}else r.hashSearch=
o;b(r)}},k=a.getUrl(),p,t;a.addPollFn(function(){if(k!=a.getUrl()){b(k=a.getUrl());d();i.$eval()}});this.$onEval(-99999,e);this.$onEval(99999,e);b(k);d();return j},["$browser"],"eager-published");P("$log",function(a){function b(c){var d=a.console||{},e=d[c]||d.log||F;return e.apply?function(){var f=[];u(arguments,function(g){f.push(ab(g))});return e.apply(d,f)}:e}return{log:b("log"),warn:b("warn"),info:b("info"),error:b("error")}},["$window"],"eager-published");P("$exceptionHandler",function(a){return function(b){a.error(b)}},
["$log"],"eager-published");P("$hover",function(a,b){var c,d,e=A(b[0].body);a.hover(function(f,g){if(g&&(d=f.attr(Sa)||f.attr(Ha))){if(!c){c={callout:A('<div id="ng-callout"></div>'),arrow:A("<div></div>"),title:A('<div class="ng-title"></div>'),content:A('<div class="ng-content"></div>')};c.callout.append(c.arrow);c.callout.append(c.title);c.callout.append(c.content);e.append(c.callout)}var h=e[0].getBoundingClientRect(),i=f[0].getBoundingClientRect();h=h.right-i.right-10;c.title.text(f.hasClass("ng-exception")?
"EXCEPTION:":"Validation error...");c.content.text(d);if(h<300){c.arrow.addClass("ng-arrow-right");c.arrow.css({left:"301px"});c.callout.css({position:"fixed",left:i.left-10-300-4+"px",top:i.top-3+"px",width:"300px"})}else{c.arrow.addClass("ng-arrow-left");c.callout.css({position:"fixed",left:i.right+10+"px",top:i.top-3+"px",width:"300px"})}}else if(c){c.callout.remove();c=y}})},["$browser","$document"],"eager");P("$invalidWidgets",function(){function a(c){if(c==H.document)return false;c=c.parentNode;
return!c||a(c)}var b=[];b.markValid=function(c){c=Ka(b,c);c!=-1&&b.splice(c,1)};b.markInvalid=function(c){Ka(b,c)===-1&&b.push(c)};b.visible=function(){var c=0;u(b,function(d){var e=c;d=d[0].getBoundingClientRect();var f=d.height||d.bottom||0-d.top||0;c=e+((d.width||d.right||0-d.left||0)>0&&f>0?1:0)});return c};this.$onEval(99999,function(){for(var c=0;c<b.length;){var d=b[c];if(a(d[0])){b.splice(c,1);d.dealoc&&d.dealoc()}else c++}});return b},[],"eager-published");P("$route",function(a){var b={},
c=[],d=this,e=0,f={routes:b,onChange:M(c,c.push),when:function(g,h){if(B.isUndefined(g))return b;var i=b[g];i||(i=b[g]={});h&&B.extend(i,h);e++;return i}};this.$watch(function(){return e+a.hash},function(){var g;f.current=y;B.foreach(b,function(h,i){if(!g){var j=Zb(a.hashPath,i);if(j){g=B.scope(d);f.current=B.extend({},h,{scope:g,params:B.extend({},a.hashSearch,j)})}}});B.foreach(c,d.$tryEval);g&&g.$become(f.current.controller)});return f},["$location"],"eager-published");P("$xhr",function(a,b,c){var d=
this;return function(e,f,g,h){if(J(g)){h=g;g=y}if(g&&T(g))g=$(g);a.xhr(e,f,g,function(i,j){try{if(I(j)&&/^\s*[\[\{]/.exec(j)&&/[\}\]]\s*$/.exec(j))j=sa(j,true);i==200?h(i,j):b({method:e,url:f,data:g,callback:h},{status:i,body:j})}catch(k){c.error(k)}finally{d.$eval()}})}},["$browser","$xhr.error","$log"]);P("$xhr.error",function(a){return function(b,c){a.error("ERROR: XHR: "+b.url,b,c)}},["$log"]);P("$xhr.bulk",function(a,b,c){function d(f,g,h,i){if(J(h)){i=h;h=y}var j;u(d.urls,function(k){if(J(k.match)?
k.match(g):k.match.exec(g))j=k});if(j){if(!j.requests)j.requests=[];j.requests.push({method:f,url:g,data:h,callback:i})}else a(f,g,h,i)}var e=this;d.urls={};d.flush=function(f){u(d.urls,function(g,h){var i=g.requests;if(i&&i.length){g.requests=[];g.callbacks=[];a("POST",h,{requests:i},function(j,k){u(k,function(p,t){try{p.status==200?(i[t].callback||F)(p.status,p.response):b(i[t],p)}catch(o){c.error(o)}});(f||F)()});e.$eval()}})};this.$onEval(99999,d.flush);return d},["$xhr","$xhr.error","$log"]);
P("$defer",function(a,b){var c=this;return function(d){a.defer(function(){try{d()}catch(e){b(e)}finally{c.$eval()}})}},["$browser","$exceptionHandler"]);P("$xhr.cache",function(a,b){function c(f,g,h,i,j){if(J(h)){i=h;h=y}if(f=="GET"){var k;if(k=c.data[g]){b(function(){i(200,U(k.value))});if(!j)return}if(j=d[g])j.callbacks.push(i);else{d[g]={callbacks:[i]};c.delegate(f,g,h,function(p,t){if(p==200)c.data[g]={value:t};var o=d[g].callbacks;delete d[g];u(o,function(m){try{(m||F)(p,U(t))}catch(r){e.$log.error(r)}})})}}else{c.data=
{};c.delegate(f,g,h,i)}}var d={},e=this;c.data={};c.delegate=a;return c},["$xhr.bulk","$defer"]);P("$resource",function(a){a=new Ta(a);return M(a,a.route)},["$xhr.cache"]);P("$cookies",function(a){var b=this,c={},d={},e;a.addPollFn(function(){var f=a.cookies();if(e!=f){e=f;U(f,d);U(f,c);b.$eval()}})();this.$onEval(99999,function(){var f,g,h;for(f in d)ba(c[f])&&a.cookies(f,V);for(f in c)if(c[f]!==d[f]){a.cookies(f,c[f]);h=true}if(h){h=!h;g=a.cookies();for(f in c)if(c[f]!==g[f]){if(ba(g[f]))delete c[f];
else c[f]=g[f];h=true}h&&b.$eval()}});return c},["$browser"],"eager-published");P("$cookieStore",function(a){return{get:function(b){return sa(a[b])},put:function(b,c){a[b]=$(c)},remove:function(b){delete a[b]}}},["$cookies"]);K("ng:init",function(a){return function(b){this.$tryEval(a,b)}});K("ng:controller",function(a){this.scope(true);return function(){var b=Ca(H,a,true)||Ca(this,a,true);if(!b)throw"Can not find '"+a+"' controller.";if(!J(b))throw"Reference '"+a+"' is not a class.";this.$become(b)}});
K("ng:eval",function(a){return function(b){this.$onEval(a,b)}});K("ng:bind",function(a,b){b.addClass("ng-binding");return function(c){var d=F,e=F;this.$onEval(function(){var f,g,h,i,j;i=this.hasOwnProperty(bc)?this.$element:V;this.$element=c;g=this.$tryEval(a,function(k){f=ab(k)});this.$element=i;if(i=g instanceof db)g=(h=g).html;if(!(d===g&&e==f)){j=Ja(g);if(!i&&!j&&T(g))g=$(g);if(g!=d||f!=e){d=g;e=f;ra(c,Sa,f);if(f)g=f;if(i)c.html(h.get());else if(j){c.html("");c.append(g)}else c.text(g===V?"":
g)}}},c)}});var ac={};K("ng:bind-template",function(a,b){b.addClass("ng-binding");var c=$b(a);return function(d){var e;this.$onEval(function(){var f=c.call(this,d);if(f!=e){d.text(f);e=f}},d)}});var Yc={disabled:"disabled",readonly:"readOnly",checked:"checked",selected:"selected"};K("ng:bind-attr",function(a){return function(b){var c={},d=b.data("$update")||F;this.$onEval(function(){var e=this.$eval(a),f=F,g;for(g in e){var h=$b(e[g]).call(this,b),i=Yc[Q(g)];if(c[g]!==h){c[g]=h;if(i){if(ya(h)){b.attr(i,
i);b.attr("ng-"+i,h)}else{b.removeAttr(i);b.removeAttr("ng-"+i)}(b.data(sb)||F)()}else b.attr(g,h);f=d}}f()},b)}});K("ng:click",function(a){return function(b){var c=this;b.bind("click",function(d){c.$tryEval(a,b);c.$root.$eval();d.stopPropagation()})}});K("ng:submit",function(a){return function(b){var c=this;b.bind("submit",function(d){c.$tryEval(a,b);c.$root.$eval();d.preventDefault()})}});K("ng:watch",function(a){return function(b){var c=this;Pa(a).watch()({addListener:function(d,e){c.$watch(d,
function(){return e(c)},b)}})}});K("ng:class",pb(function(){return true}));K("ng:class-odd",pb(function(a){return a%2===0}));K("ng:class-even",pb(function(a){return a%2===1}));K("ng:show",function(a){return function(b){this.$onEval(function(){b.css("display",ya(this.$eval(a))?"":"none")},b)}});K("ng:hide",function(a){return function(b){this.$onEval(function(){b.css("display",ya(this.$eval(a))?"none":"")},b)}});K("ng:style",function(a){return function(b){var c=Jc(b);this.$onEval(function(){var d=this.$eval(a)||
{},e,f={};for(e in d){if(c[e]===V)c[e]="";f[e]=d[e]}for(e in c)f[e]=f[e]||c[e];b.css(f)},b)}});eb("{{}}",function(a,b,c){var d=Va(a),e=this;if(d.length>1||Wa(d[0])!==y)if(nc(c[0]))c.attr("ng:bind-template",a);else{var f=b,g;u(Va(a),function(h){var i=Wa(h);if(i){g=e.element("span");g.attr("ng:bind",i)}else g=e.text(h);if(ka&&h.charAt(0)==" "){g=A("<span>&nbsp;</span>");i=g.html();g.text(h.substr(1));g.html(i+g.html())}f.after(g);f=g});b.remove()}});eb("OPTION",function(a,b,c){if(Ba(c)=="OPTION"){b=
Y.createElement("select");b.insertBefore(c[0].cloneNode(true),y);b.innerHTML.match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi)||c.attr("value",a)}});var Zc={"ng:src":"src","ng:href":"href"};Ab("{{}}",function(a,b,c){if(!(K(b)||K("@"+b))){if(ka&&b=="src")a=decodeURI(a);var d=Va(a);if(d.length>1||Wa(d[0])!==y){c.removeAttr(b);d=sa(c.attr("ng:bind-attr")||"{}");d[Zc[b]||b]=a;c.attr("ng:bind-attr",$(d))}}});S=Aa("keyup change",cc,rb,Xa(),true);aa=Aa("click",tb,tb,F);var Kc={text:S,textarea:S,
hidden:S,password:S,button:aa,submit:aa,reset:aa,image:aa,checkbox:Aa("click",Ga,function(a,b){var c=b[0];return{get:function(){return!!c.checked},set:function(d){c.checked=ya(d)}}},Xa(false)),radio:Aa("click",Ga,function(a,b){var c=b[0];return{get:function(){return c.checked?c.value:y},set:function(d){c.checked=d==c.value}}},function(a,b,c){var d=a.get(),e=b.get();c=c[0];c.checked=false;c.name=this.$id+"@"+c.name;if(ba(d))a.set(d=y);d==y&&e!==y&&a.set(e);b.set(d)}),"select-one":Aa("change",Ga,rb,
Xa(y)),"select-multiple":Aa("change",Ga,function(a,b){var c=b[0].options;return{get:function(){var d=[];u(c,function(e){e.selected&&d.push(e.value)});return d},set:function(d){var e={};u(d,function(f){e[f]=true});u(c,function(f){f.selected=e[f.value]})}}},Xa([]))};Z("input",Ya);Z("textarea",Ya);Z("button",Ya);Z("select",function(a){this.descend(true);return Ya.call(this,a)});Z("option",function(){this.descend(true);this.directives(true);return function(a){var b=a.parent(),c=sc(b),d=Ga(c,b),e=rb(c,
b),f=a.attr("value"),g=a.attr("ng-selected");a.data("$update",function(){var h=a.attr("value"),i=a.attr("ng-selected"),j=d.get();if(g!=i||f!=h){g=i;f=h;if(i||j==y||j==V)d.set(h);h==j&&e.set(f)}})}});Z("ng:include",function(a){var b=this,c=a.attr("src"),d=a.attr("scope")||"",e=a[0].getAttribute("onload")||"";if(a[0]["ng:compiled"]){this.descend(true);this.directives(true)}else{a[0]["ng:compiled"]=true;return D(function(f,g){function h(){k++}var i=this,j,k=0,p=false;this.$watch(c,h);this.$watch(d,h);
i.$onEval(function(){if(j&&!p){p=true;try{j.$eval()}finally{p=false}}});this.$watch(function(){return k},function(){var t=this.$eval(c),o=this.$eval(d);if(t)f("GET",t,function(m,r){g.html(r);j=o||ua(i);b.compile(g)(g,j);j.$init();i.$eval(e)});else{j=null;g.html("")}})},{$inject:["$xhr.cache"]})}});var $c=Z("ng:switch",function(a){var b=this,c=a.attr("on"),d=a.attr("using")||"equals",e=d.split(":"),f=$c[e.shift()],g=a.attr("change")||"",h=[];if(!f)throw"Using expression '"+d+"' unknown.";if(!c)throw"Missing 'on' attribute.";
Eb(a,function(i){var j=i.attr("ng:switch-when"),k={change:g,element:i,template:b.compile(i)};if(I(j)){k.when=function(p,t){var o=[t,j];u(e,function(m){o.push(m)});return f.apply(p,o)};h.unshift(k)}else if(I(i.attr("ng:switch-default"))){k.when=bb(true);h.push(k)}});u(h,function(i){i.element.remove()});a.html("");return function(i){var j=this,k;this.$watch(c,function(p){var t=false;i.html("");k=ua(j);u(h,function(o){if(!t&&o.when(k,p)){t=true;var m=A(o.element[0].cloneNode(true));i.append(m);k.$tryEval(o.change,
i);o.template(m,k);k.$init()}})});j.$onEval(function(){k&&k.$eval()})}},{equals:function(a,b){return""+a==b},route:Zb});Z("a",function(){this.descend(true);this.directives(true);return function(a){a.attr("href")===""&&a.bind("click",function(b){b.preventDefault()})}});Z("@ng:repeat",function(a,b){b.removeAttr("ng:repeat");b.replaceWith(this.comment("ng:repeat: "+a));var c=this.compile(b);return function(d){var e=a.match(/^\s*(.+)\s+in\s+(.*)\s*$/),f,g,h,i;if(!e)throw na("Expected ng:repeat in form of 'item in collection' but got '"+
a+"'.");f=e[1];g=e[2];e=f.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/);if(!e)throw na("'item' in 'item in collection' should be identifier or (key, value) but got '"+keyValue+"'.");h=e[3]||e[1];i=e[2];var j=[],k=this;this.$onEval(function(){var p=0,t=j.length,o=d,m=this.$tryEval(g,d),r=ha(m),n=0,s,z;if(r)n=m.length;else for(z in m)m.hasOwnProperty(z)&&n++;for(z in m)if(!r||m.hasOwnProperty(z)){if(p<t){s=j[p];s[h]=m[z];if(i)s[i]=z}else{s=c(A(b[0].cloneNode(true)),ua(k));s[h]=m[z];if(i)s[i]=z;
o.after(s.$element);s.$index=p;s.$position=p==0?"first":p==n-1?"last":"middle";s.$element.attr("ng:repeat-index",p);s.$init();j.push(s)}s.$eval();o=s.$element;p++}for(;j.length>p;)j.pop().$element.remove()},d)}});Z("@ng:non-bindable",F);var Ia;kb("$browser",function(a){if(!Ia){Ia=new zc(H.location,A(H.document),A(H.document.getElementsByTagName("head")[0]),Mc,a,H.setTimeout);Ia.startPoller(50,function(b,c){setTimeout(b,c)});Ia.bind()}return Ia},{inject:["$log"]});D(B,{element:A,compile:yb,scope:ua,
copy:U,extend:D,equals:La,foreach:u,injector:Kb,noop:F,bind:M,toJson:$,fromJson:sa,identity:oa,isUndefined:ba,isDefined:E,isString:I,isFunction:J,isObject:T,isNumber:wa,isArray:ha});H.onload=function(){try{ub&&ub()}catch(a){}var b=pc(Y);if(b.autobind){var c=yb(H.document,y,{$config:b}),d=c.$inject("$browser");if(b.css)d.addCss(b.base_url+b.css);else ka<8&&d.addJs(b.base_url+b.ie_compat,b.ie_compat_id);c.$init()}}})(window,document,window.onload);document.write('<style type="text/css">@charset "UTF-8";.ng-format-negative{color:red;}.ng-exception{border:2px solid #FF0000;font-family:"Courier New",Courier,monospace;font-size:smaller;white-space:pre;}.ng-validation-error{border:2px solid #FF0000;}#ng-callout{margin:0;padding:0;border:0;outline:0;font-size:13px;font-weight:normal;font-family:Verdana,Arial,Helvetica,sans-serif;vertical-align:baseline;background:transparent;text-decoration:none;}#ng-callout .ng-arrow-left{background-image:url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrSLoc/AG8FeUUIN+sGebWAnbKSJodqqlsOxJtqYooU9vvk+vcJIcTkg+QAAA7");background-repeat:no-repeat;background-position:left top;position:absolute;z-index:101;left:-12px;height:23px;width:10px;top:-3px;}#ng-callout .ng-arrow-right{background-image:url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrCLTcoM29yN6k9socs91e5X3EyJloipYrO4ohTMqA0Fn2XVNswJe+H+SXAAA7");background-repeat:no-repeat;background-position:left top;position:absolute;z-index:101;height:23px;width:11px;top:-2px;}#ng-callout{position:absolute;z-index:100;border:2px solid #CCCCCC;background-color:#fff;}#ng-callout .ng-content{padding:10px 10px 10px 10px;color:#333333;}#ng-callout .ng-title{background-color:#CCCCCC;text-align:left;padding-left:8px;padding-bottom:5px;padding-top:2px;font-weight:bold;}.ng-input-indicator-wait{background-image:url("data:image/png;base64,R0lGODlhEAAQAPQAAP///wAAAPDw8IqKiuDg4EZGRnp6egAAAFhYWCQkJKysrL6+vhQUFJycnAQEBDY2NmhoaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFdyAgAgIJIeWoAkRCCMdBkKtIHIngyMKsErPBYbADpkSCwhDmQCBethRB6Vj4kFCkQPG4IlWDgrNRIwnO4UKBXDufzQvDMaoSDBgFb886MiQadgNABAokfCwzBA8LCg0Egl8jAggGAA1kBIA1BAYzlyILczULC2UhACH5BAkKAAAALAAAAAAQABAAAAV2ICACAmlAZTmOREEIyUEQjLKKxPHADhEvqxlgcGgkGI1DYSVAIAWMx+lwSKkICJ0QsHi9RgKBwnVTiRQQgwF4I4UFDQQEwi6/3YSGWRRmjhEETAJfIgMFCnAKM0KDV4EEEAQLiF18TAYNXDaSe3x6mjidN1s3IQAh+QQJCgAAACwAAAAAEAAQAAAFeCAgAgLZDGU5jgRECEUiCI+yioSDwDJyLKsXoHFQxBSHAoAAFBhqtMJg8DgQBgfrEsJAEAg4YhZIEiwgKtHiMBgtpg3wbUZXGO7kOb1MUKRFMysCChAoggJCIg0GC2aNe4gqQldfL4l/Ag1AXySJgn5LcoE3QXI3IQAh+QQJCgAAACwAAAAAEAAQAAAFdiAgAgLZNGU5joQhCEjxIssqEo8bC9BRjy9Ag7GILQ4QEoE0gBAEBcOpcBA0DoxSK/e8LRIHn+i1cK0IyKdg0VAoljYIg+GgnRrwVS/8IAkICyosBIQpBAMoKy9dImxPhS+GKkFrkX+TigtLlIyKXUF+NjagNiEAIfkECQoAAAAsAAAAABAAEAAABWwgIAICaRhlOY4EIgjH8R7LKhKHGwsMvb4AAy3WODBIBBKCsYA9TjuhDNDKEVSERezQEL0WrhXucRUQGuik7bFlngzqVW9LMl9XWvLdjFaJtDFqZ1cEZUB0dUgvL3dgP4WJZn4jkomWNpSTIyEAIfkECQoAAAAsAAAAABAAEAAABX4gIAICuSxlOY6CIgiD8RrEKgqGOwxwUrMlAoSwIzAGpJpgoSDAGifDY5kopBYDlEpAQBwevxfBtRIUGi8xwWkDNBCIwmC9Vq0aiQQDQuK+VgQPDXV9hCJjBwcFYU5pLwwHXQcMKSmNLQcIAExlbH8JBwttaX0ABAcNbWVbKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICSRBlOY7CIghN8zbEKsKoIjdFzZaEgUBHKChMJtRwcWpAWoWnifm6ESAMhO8lQK0EEAV3rFopIBCEcGwDKAqPh4HUrY4ICHH1dSoTFgcHUiZjBhAJB2AHDykpKAwHAwdzf19KkASIPl9cDgcnDkdtNwiMJCshACH5BAkKAAAALAAAAAAQABAAAAV3ICACAkkQZTmOAiosiyAoxCq+KPxCNVsSMRgBsiClWrLTSWFoIQZHl6pleBh6suxKMIhlvzbAwkBWfFWrBQTxNLq2RG2yhSUkDs2b63AYDAoJXAcFRwADeAkJDX0AQCsEfAQMDAIPBz0rCgcxky0JRWE1AmwpKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICKZzkqJ4nQZxLqZKv4NqNLKK2/Q4Ek4lFXChsg5ypJjs1II3gEDUSRInEGYAw6B6zM4JhrDAtEosVkLUtHA7RHaHAGJQEjsODcEg0FBAFVgkQJQ1pAwcDDw8KcFtSInwJAowCCA6RIwqZAgkPNgVpWndjdyohACH5BAkKAAAALAAAAAAQABAAAAV5ICACAimc5KieLEuUKvm2xAKLqDCfC2GaO9eL0LABWTiBYmA06W6kHgvCqEJiAIJiu3gcvgUsscHUERm+kaCxyxa+zRPk0SgJEgfIvbAdIAQLCAYlCj4DBw0IBQsMCjIqBAcPAooCBg9pKgsJLwUFOhCZKyQDA3YqIQAh+QQJCgAAACwAAAAAEAAQAAAFdSAgAgIpnOSonmxbqiThCrJKEHFbo8JxDDOZYFFb+A41E4H4OhkOipXwBElYITDAckFEOBgMQ3arkMkUBdxIUGZpEb7kaQBRlASPg0FQQHAbEEMGDSVEAA1QBhAED1E0NgwFAooCDWljaQIQCE5qMHcNhCkjIQAh+QQJCgAAACwAAAAAEAAQAAAFeSAgAgIpnOSoLgxxvqgKLEcCC65KEAByKK8cSpA4DAiHQ/DkKhGKh4ZCtCyZGo6F6iYYPAqFgYy02xkSaLEMV34tELyRYNEsCQyHlvWkGCzsPgMCEAY7Cg04Uk48LAsDhRA8MVQPEF0GAgqYYwSRlycNcWskCkApIyEAOwAAAAAAAAAAAA==");background-position:right;background-repeat:no-repeat;}</style>');

@ -0,0 +1 @@
<p>This is the partial for view 1.</p>

@ -0,0 +1 @@
<p>This is the partial for view 2.</p>

@ -0,0 +1,12 @@
server: http://localhost:9876
load:
- test/lib/jasmine/jasmine.js
- test/lib/jasmine-jstd-adapter/JasmineAdapter.js
- app/lib/angular/angular.js
- test/lib/angular/angular-mocks.js
- app/js/*.js
- test/unit/*.js
exclude:

2
logs/.gitignore vendored

@ -0,0 +1,2 @@
*
!.gitignore

@ -0,0 +1,12 @@
#!/bin/bash
base_dir=`dirname $0`
port=9876
echo "Starting JSTD server at http://localhost:$port"
echo ""
echo "Please open the url above and capture one or more browsers."
echo ""
echo "For more info please see: http://code.google.com/p/js-test-driver/"
java -jar "$base_dir/../test/lib/jstestdriver/JsTestDriver.jar" --port $port --browserTimeout 20000

@ -0,0 +1,10 @@
#!/bin/sh
base_dir=`dirname $0`
tests=$1
if [[ $tests = "" ]]; then
tests="all"
fi
java -jar "$base_dir/../test/lib/jstestdriver/JsTestDriver.jar" --config "$base_dir/../jsTestDriver.conf" --tests "$tests"

@ -0,0 +1,19 @@
#!/usr/bin/env watchr
# config file for watchr http://github.com/mynyml/watchr
# install: gem install watchr
# run: watch watchr.rb
# note: make sure that you have jstd server running (server.sh) and a browser captured
log_file = File.expand_path(File.dirname(__FILE__) + '/../logs/jstd.log')
`cd ..`
`touch #{log_file}`
puts "String watchr... log file: #{log_file}"
watch( '(app/js|test/unit)' ) do
`echo "\n\ntest run started @ \`date\`" > #{log_file}`
`scripts/test.sh &> #{log_file}`
end

@ -0,0 +1,243 @@
#!/usr/bin/env node
var sys = require('sys'),
http = require('http'),
fs = require('fs'),
url = require('url'),
events = require('events');
var DEFAULT_PORT = 8000;
function main(argv) {
new HttpServer({
'GET': createServlet(StaticServlet),
'HEAD': createServlet(StaticServlet)
}).start(Number(argv[2]) || DEFAULT_PORT);
}
function escapeHtml(value) {
return value.toString().
replace('<', '&lt;').
replace('>', '&gt').
replace('"', '&quot;');
}
function createServlet(Class) {
var servlet = new Class();
return servlet.handleRequest.bind(servlet);
}
/**
* An Http server implementation that uses a map of methods to decide
* action routing.
*
* @param {Object} Map of method => Handler function
*/
function HttpServer(handlers) {
this.handlers = handlers;
this.server = http.createServer(this.handleRequest_.bind(this));
}
HttpServer.prototype.start = function(port) {
this.port = port;
this.server.listen(port);
sys.puts('Http Server running at http://localhost:' + port + '/');
};
HttpServer.prototype.parseUrl_ = function(urlString) {
var parsed = url.parse(urlString);
parsed.pathname = url.resolve('/', parsed.pathname);
return url.parse(url.format(parsed), true);
};
HttpServer.prototype.handleRequest_ = function(req, res) {
var logEntry = req.method + ' ' + req.url;
if (req.headers['user-agent']) {
logEntry += ' ' + req.headers['user-agent'];
}
sys.puts(logEntry);
req.url = this.parseUrl_(req.url);
var handler = this.handlers[req.method];
if (!handler) {
res.writeHead(501);
res.end();
} else {
handler.call(this, req, res);
}
};
/**
* Handles static content.
*/
function StaticServlet() {}
StaticServlet.MimeMap = {
'txt': 'text/plain',
'html': 'text/html',
'css': 'text/css',
'xml': 'application/xml',
'json': 'application/json',
'js': 'application/javascript',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'gif': 'image/gif',
'png': 'image/png'
};
StaticServlet.prototype.handleRequest = function(req, res) {
var self = this;
var path = ('./' + req.url.pathname).replace('//','/').replace(/%(..)/, function(match, hex){
return String.fromCharCode(parseInt(hex, 16));
});
var parts = path.split('/');
if (parts[parts.length-1].charAt(0) === '.')
return self.sendForbidden_(req, res, path);
fs.stat(path, function(err, stat) {
if (err)
return self.sendMissing_(req, res, path);
if (stat.isDirectory())
return self.sendDirectory_(req, res, path);
return self.sendFile_(req, res, path);
});
}
StaticServlet.prototype.sendError_ = function(req, res, error) {
res.writeHead(500, {
'Content-Type': 'text/html'
});
res.write('<!doctype html>\n');
res.write('<title>Internal Server Error</title>\n');
res.write('<h1>Internal Server Error</h1>');
res.write('<pre>' + escapeHtml(sys.inspect(error)) + '</pre>');
sys.puts('500 Internal Server Error');
sys.puts(sys.inspect(error));
};
StaticServlet.prototype.sendMissing_ = function(req, res, path) {
path = path.substring(1);
res.writeHead(404, {
'Content-Type': 'text/html'
});
res.write('<!doctype html>\n');
res.write('<title>404 Not Found</title>\n');
res.write('<h1>Not Found</h1>');
res.write(
'<p>The requested URL ' +
escapeHtml(path) +
' was not found on this server.</p>'
);
res.end();
sys.puts('404 Not Found: ' + path);
};
StaticServlet.prototype.sendForbidden_ = function(req, res, path) {
path = path.substring(1);
res.writeHead(403, {
'Content-Type': 'text/html'
});
res.write('<!doctype html>\n');
res.write('<title>403 Forbidden</title>\n');
res.write('<h1>Forbidden</h1>');
res.write(
'<p>You do not have permission to access ' +
escapeHtml(path) + ' on this server.</p>'
);
res.end();
sys.puts('403 Forbidden: ' + path);
};
StaticServlet.prototype.sendRedirect_ = function(req, res, redirectUrl) {
res.writeHead(301, {
'Content-Type': 'text/html',
'Location': redirectUrl
});
res.write('<!doctype html>\n');
res.write('<title>301 Moved Permanently</title>\n');
res.write('<h1>Moved Permanently</h1>');
res.write(
'<p>The document has moved <a href="' +
redirectUrl +
'">here</a>.</p>'
);
res.end();
sys.puts('401 Moved Permanently: ' + redirectUrl);
};
StaticServlet.prototype.sendFile_ = function(req, res, path) {
var self = this;
var file = fs.createReadStream(path);
res.writeHead(200, {
'Content-Type': StaticServlet.
MimeMap[path.split('.').pop()] || 'text/plain'
});
if (req.method === 'HEAD') {
res.end();
} else {
file.on('data', res.write.bind(res));
file.on('close', function() {
res.end();
});
file.on('error', function(error) {
self.sendError_(req, res, error);
});
}
};
StaticServlet.prototype.sendDirectory_ = function(req, res, path) {
var self = this;
if (path.match(/[^\/]$/)) {
req.url.pathname += '/';
var redirectUrl = url.format(url.parse(url.format(req.url)));
return self.sendRedirect_(req, res, redirectUrl);
}
fs.readdir(path, function(err, files) {
if (err)
return self.sendError_(req, res, error);
if (!files.length)
return self.writeDirectoryIndex_(req, res, path, []);
var remaining = files.length;
files.forEach(function(fileName, index) {
fs.stat(path + '/' + fileName, function(err, stat) {
if (err)
return self.sendError_(req, res, err);
if (stat.isDirectory()) {
files[index] = fileName + '/';
}
if (!(--remaining))
return self.writeDirectoryIndex_(req, res, path, files);
});
});
});
};
StaticServlet.prototype.writeDirectoryIndex_ = function(req, res, path, files) {
path = path.substring(1);
res.writeHead(200, {
'Content-Type': 'text/html'
});
if (req.method === 'HEAD') {
res.end();
return;
}
res.write('<!doctype html>\n');
res.write('<title>' + escapeHtml(path) + '</title>\n');
res.write('<style>\n');
res.write(' ol { list-style-type: none; font-size: 1.2em; }\n');
res.write('</style>\n');
res.write('<h1>Directory: ' + escapeHtml(path) + '</h1>');
res.write('<ol>');
files.forEach(function(fileName) {
if (fileName.charAt(0) !== '.') {
res.write('<li><a href="' +
escapeHtml(fileName) + '">' +
escapeHtml(fileName) + '</a></li>');
}
});
res.write('</ol>');
res.end();
};
// Must be last,
main(process.argv);

@ -0,0 +1,10 @@
<!doctype html">
<html lang="en">
<head>
<title>End2end Test Runner</title>
<script src="../lib/angular/angular-scenario.js"></script>
<script src="scenarios.js"></script>
</head>
<body>
</body>
</html>

@ -0,0 +1,41 @@
describe('my app', function() {
beforeEach(function() {
browser().navigateTo('../../app/index.html');
});
it('should automatically redirect to /view1 when location hash/fragment is empty', function() {
expect(browser().location().hash()).toBe("/view1");
});
describe('view1', function() {
beforeEach(function() {
browser().navigateTo('#/view1');
});
it('should render view1 when user navigates to /view1', function() {
expect(element('ng\\:include p:first').text()).
toMatch(/partial for view 1/)
});
});
describe('view2', function() {
beforeEach(function() {
browser().navigateTo('#/view2');
});
it('should render view1 when user navigates to /view2', function() {
expect(element('ng\\:include p:first').text()).
toMatch(/partial for view 2/)
});
});
});

@ -0,0 +1,303 @@
/**
* The MIT License
*
* Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
NUGGGGGH MUST TONGUE WANGS
\
.....
C C /
/< /
___ __________/_#__=o
/(- /(\_\________ \
\ ) \ )_ \o \
/|\ /|\ |' |
| _|
/o __\
/ ' |
/ / |
/_/\______|
( _( <
\ \ \
\ \ |
\____\____\
____\_\__\_\
/` /` o\
|___ |_______|.. . b'ger
IN THE FINAL BUILD THIS FILE DOESN'T HAVE DIRECT ACCESS TO GLOBAL FUNCTIONS
DEFINED IN Angular.js YOU *MUST* REFER TO THEM VIA angular OBJECT
(e.g. angular.forEach(...)) AND MAKE SURE THAT THE GIVEN FUNCTION IS EXPORTED
TO THE angular NAMESPACE in AngularPublic.js
*/
function MockBrowser() {
var self = this,
expectations = {},
requests = [];
this.isMock = true;
self.url = "http://server";
self.pollFns = [];
self.xhr = function(method, url, data, callback) {
if (angular.isFunction(data)) {
callback = data;
data = null;
}
if (data && angular.isObject(data)) data = angular.toJson(data);
if (data && angular.isString(data)) url += "|" + data;
var expect = expectations[method] || {};
var response = expect[url];
if (!response) {
throw {
message: "Unexpected request for method '" + method + "' and url '" + url + "'.",
name: "Unexpected Request"
};
}
requests.push(function(){
callback(response.code, response.response);
});
};
self.xhr.expectations = expectations;
self.xhr.requests = requests;
self.xhr.expect = function(method, url, data) {
if (data && angular.isObject(data)) data = angular.toJson(data);
if (data && angular.isString(data)) url += "|" + data;
var expect = expectations[method] || (expectations[method] = {});
return {
respond: function(code, response) {
if (!angular.isNumber(code)) {
response = code;
code = 200;
}
expect[url] = {code:code, response:response};
}
};
};
self.xhr.expectGET = angular.bind(self, self.xhr.expect, 'GET');
self.xhr.expectPOST = angular.bind(self, self.xhr.expect, 'POST');
self.xhr.expectDELETE = angular.bind(self, self.xhr.expect, 'DELETE');
self.xhr.expectPUT = angular.bind(self, self.xhr.expect, 'PUT');
self.xhr.expectJSON = angular.bind(self, self.xhr.expect, 'JSON');
self.xhr.flush = function() {
while(requests.length) {
requests.pop()();
}
};
self.cookieHash = {};
self.lastCookieHash = {};
self.deferredFns = [];
self.defer = function(fn) {
self.deferredFns.push(fn);
};
self.defer.flush = function() {
while (self.deferredFns.length) self.deferredFns.shift()();
};
}
MockBrowser.prototype = {
poll: function poll(){
angular.foreach(this.pollFns, function(pollFn){
pollFn();
});
},
addPollFn: function(pollFn) {
this.pollFns.push(pollFn);
return pollFn;
},
hover: function(onHover) {
},
getUrl: function(){
return this.url;
},
setUrl: function(url){
this.url = url;
},
cookies: function(name, value) {
if (name) {
if (value == undefined) {
delete this.cookieHash[name];
} else {
if (angular.isString(value) && //strings only
value.length <= 4096) { //strict cookie storage limits
this.cookieHash[name] = value;
}
}
} else {
if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
this.lastCookieHash = angular.copy(this.cookieHash);
this.cookieHash = angular.copy(this.cookieHash);
}
return this.cookieHash;
}
}
};
angular.service('$browser', function(){
return new MockBrowser();
});
/**
* Mock of the Date type which has its timezone specified via constroctor arg.
*
* The main purpose is to create Date-like instances with timezone fixed to the specified timezone
* offset, so that we can test code that depends on local timezone settings without dependency on
* the time zone settings of the machine where the code is running.
*
* @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
* @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
*
* @example
* var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
* newYearInBratislava.getTimezoneOffset() => -60;
* newYearInBratislava.getFullYear() => 2010;
* newYearInBratislava.getMonth() => 0;
* newYearInBratislava.getDate() => 1;
* newYearInBratislava.getHours() => 0;
* newYearInBratislava.getMinutes() => 0;
*
*
* !!!! WARNING !!!!!
* This is not a complete Date object so only methods that were implemented can be called safely.
* To make matters worse, TzDate instances inherit stuff from Date via a prototype.
*
* We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
* incomplete we might be missing some non-standard methods. This can result in errors like:
* "Date.prototype.foo called on incompatible Object".
*/
function TzDate(offset, timestamp) {
if (angular.isString(timestamp)) {
var tsStr = timestamp;
this.origDate = angular.String.toDate(timestamp);
timestamp = this.origDate.getTime();
if (isNaN(timestamp))
throw {
name: "Illegal Argument",
message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
};
} else {
this.origDate = new Date(timestamp);
}
var localOffset = new Date(timestamp).getTimezoneOffset();
this.offsetDiff = localOffset*60*1000 - offset*1000*60*60;
this.date = new Date(timestamp + this.offsetDiff);
this.getTime = function() {
return this.date.getTime() - this.offsetDiff;
};
this.toLocaleDateString = function() {
return this.date.toLocaleDateString();
};
this.getFullYear = function() {
return this.date.getFullYear();
};
this.getMonth = function() {
return this.date.getMonth();
};
this.getDate = function() {
return this.date.getDate();
};
this.getHours = function() {
return this.date.getHours();
};
this.getMinutes = function() {
return this.date.getMinutes();
};
this.getSeconds = function() {
return this.date.getSeconds();
};
this.getTimezoneOffset = function() {
return offset * 60;
};
this.getUTCFullYear = function() {
return this.origDate.getUTCFullYear();
};
this.getUTCMonth = function() {
return this.origDate.getUTCMonth();
};
this.getUTCDate = function() {
return this.origDate.getUTCDate();
};
this.getUTCHours = function() {
return this.origDate.getUTCHours();
};
this.getUTCMinutes = function() {
return this.origDate.getUTCMinutes();
};
this.getUTCSeconds = function() {
return this.origDate.getUTCSeconds();
};
//hide all methods not implemented in this mock that the Date prototype exposes
var unimplementedMethods = ['getDay', 'getMilliseconds', 'getTime', 'getUTCDay',
'getUTCMilliseconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
'setYear', 'toDateString', 'toJSON', 'toGMTString', 'toLocaleFormat', 'toLocaleString',
'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
angular.foreach(unimplementedMethods, function(methodName) {
this[methodName] = function() {
throw {
name: "MethodNotImplemented",
message: "Method '" + methodName + "' is not implemented in the TzDate mock"
};
};
});
}
//make "tzDateInstance instanceof Date" return true
TzDate.prototype = Date.prototype;

File diff suppressed because it is too large Load Diff

@ -0,0 +1,111 @@
/**
* @fileoverview Jasmine JsTestDriver Adapter.
* @author ibolmo@gmail.com (Olmo Maldonado)
* @author misko@hevery.com (Misko Hevery)
*/
(function() {
function bind(_this, _function){
return function(){
return _function.call(_this);
};
}
var currentFrame = frame(null, null);
function frame(parent, name){
var caseName = (parent && parent.caseName ? parent.caseName + " " : '') + (name ? name : '');
var frame = {
name: name,
caseName: caseName,
parent: parent,
testCase: TestCase(caseName),
before: [],
after: [],
runBefore: function(){
if (parent) parent.runBefore.apply(this);
for ( var i = 0; i < frame.before.length; i++) {
frame.before[i].apply(this);
}
},
runAfter: function(){
for ( var i = 0; i < frame.after.length; i++) {
frame.after[i].apply(this);
}
if (parent) parent.runAfter.apply(this);
}
};
return frame;
};
jasmine.Env.prototype.describe = (function(describe){
return function(description){
currentFrame = frame(currentFrame, description);
var val = describe.apply(this, arguments);
currentFrame = currentFrame.parent;
return val;
};
})(jasmine.Env.prototype.describe);
var id = 0;
jasmine.Env.prototype.it = (function(it){
return function(desc, itFn){
var self = this;
var spec = it.apply(this, arguments);
var currentSpec = this.currentSpec;
if (!currentSpec.$id) {
currentSpec.$id = id++;
}
var frame = this.jstdFrame = currentFrame;
var name = 'test that it ' + desc;
if (this.jstdFrame.testCase.prototype[name])
throw "Spec with name '" + desc + "' already exists.";
this.jstdFrame.testCase.prototype[name] = function(){
jasmine.getEnv().currentSpec = currentSpec;
frame.runBefore.apply(currentSpec);
try {
itFn.apply(currentSpec);
} finally {
frame.runAfter.apply(currentSpec);
}
};
return spec;
};
})(jasmine.Env.prototype.it);
jasmine.Env.prototype.beforeEach = (function(beforeEach){
return function(beforeEachFunction) {
beforeEach.apply(this, arguments);
currentFrame.before.push(beforeEachFunction);
};
})(jasmine.Env.prototype.beforeEach);
jasmine.Env.prototype.afterEach = (function(afterEach){
return function(afterEachFunction) {
afterEach.apply(this, arguments);
currentFrame.after.push(afterEachFunction);
};
})(jasmine.Env.prototype.afterEach);
jasmine.NestedResults.prototype.addResult = (function(addResult){
return function(result) {
addResult.call(this, result);
if (result.type != 'MessageResult' && !result.passed()) fail(result.message);
};
})(jasmine.NestedResults.prototype.addResult);
// Reset environment with overriden methods.
jasmine.currentEnv_ = null;
jasmine.getEnv();
})();

@ -0,0 +1,20 @@
Copyright (c) 2008-2010 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,180 @@
var fs = require('fs');
var sys = require('sys');
var path = require('path');
var filename = __dirname + '/jasmine.js';
global.window = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setInterval: setInterval,
clearInterval: clearInterval
};
var src = fs.readFileSync(filename);
var jasmine = process.compile(src + '\njasmine;', filename);
delete global.window;
function noop(){}
jasmine.executeSpecsInFolder = function(folder, done, isVerbose, showColors, matcher){
var log = [];
var columnCounter = 0;
var start = 0;
var elapsed = 0;
var verbose = isVerbose || false;
var fileMatcher = new RegExp(matcher || "\.js$");
var colors = showColors || false;
var specs = jasmine.getAllSpecFiles(folder, fileMatcher);
var ansi = {
green: '\033[32m',
red: '\033[31m',
yellow: '\033[33m',
none: '\033[0m'
};
for (var i = 0, len = specs.length; i < len; ++i){
var filename = specs[i];
require(filename.replace(/\.*$/, ""));
}
var jasmineEnv = jasmine.getEnv();
jasmineEnv.reporter = {
log: function(str){
},
reportSpecStarting: function(runner) {
},
reportRunnerStarting: function(runner) {
sys.puts('Started');
start = Number(new Date);
},
reportSuiteResults: function(suite) {
var specResults = suite.results();
var path = [];
while(suite) {
path.unshift(suite.description);
suite = suite.parentSuite;
}
var description = path.join(' ');
if (verbose)
log.push('Spec ' + description);
specResults.items_.forEach(function(spec){
if (spec.failedCount > 0 && spec.description) {
if (!verbose)
log.push(description);
log.push(' it ' + spec.description);
spec.items_.forEach(function(result){
log.push(' ' + result.trace.stack + '\n');
});
}
});
},
reportSpecResults: function(spec) {
var result = spec.results();
var msg = '';
if (result.passed())
{
msg = (colors) ? (ansi.green + '.' + ansi.none) : '.';
// } else if (result.skipped) { TODO: Research why "result.skipped" returns false when "xit" is called on a spec?
// msg = (colors) ? (ansi.yellow + '*' + ansi.none) : '*';
} else {
msg = (colors) ? (ansi.red + 'F' + ansi.none) : 'F';
}
sys.print(msg);
if (columnCounter++ < 50) return;
columnCounter = 0;
sys.print('\n');
},
reportRunnerResults: function(runner) {
elapsed = (Number(new Date) - start) / 1000;
sys.puts('\n');
log.forEach(function(log){
sys.puts(log);
});
sys.puts('Finished in ' + elapsed + ' seconds');
var summary = jasmine.printRunnerResults(runner);
if(colors)
{
if(runner.results().failedCount === 0 )
sys.puts(ansi.green + summary + ansi.none);
else
sys.puts(ansi.red + summary + ansi.none);
} else {
sys.puts(summary);
}
(done||noop)(runner, log);
}
};
jasmineEnv.execute();
};
jasmine.getAllSpecFiles = function(dir, matcher){
var specs = [];
if (fs.statSync(dir).isFile() && dir.match(matcher)) {
specs.push(dir);
} else {
var files = fs.readdirSync(dir);
for (var i = 0, len = files.length; i < len; ++i){
var filename = dir + '/' + files[i];
if (fs.statSync(filename).isFile() && filename.match(matcher)){
specs.push(filename);
}else if (fs.statSync(filename).isDirectory()){
var subfiles = this.getAllSpecFiles(filename, matcher);
subfiles.forEach(function(result){
specs.push(result);
});
}
}
}
return specs;
};
jasmine.printRunnerResults = function(runner){
var results = runner.results();
var suites = runner.suites();
var msg = '';
msg += suites.length + ' test' + ((suites.length === 1) ? '' : 's') + ', ';
msg += results.totalCount + ' assertion' + ((results.totalCount === 1) ? '' : 's') + ', ';
msg += results.failedCount + ' failure' + ((results.failedCount === 1) ? '' : 's') + '\n';
return msg;
};
function now(){
return new Date().getTime();
}
jasmine.asyncSpecWait = function(){
var wait = jasmine.asyncSpecWait;
wait.start = now();
wait.done = false;
(function innerWait(){
waits(10);
runs(function() {
if (wait.start + wait.timeout < now()) {
expect('timeout waiting for spec').toBeNull();
} else if (wait.done) {
wait.done = false;
} else {
innerWait();
}
});
})();
};
jasmine.asyncSpecWait.timeout = 4 * 1000;
jasmine.asyncSpecDone = function(){
jasmine.asyncSpecWait.done = true;
};
for ( var key in jasmine) {
exports[key] = jasmine[key];
}

@ -0,0 +1,188 @@
jasmine.TrivialReporter = function(doc) {
this.document = doc || document;
this.suiteDivs = {};
this.logRunningSpecs = false;
};
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
var el = document.createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(document.createTextNode(child));
} else {
if (child) { el.appendChild(child); }
}
}
for (var attr in attrs) {
if (attr == "className") {
el[attr] = attrs[attr];
} else {
el.setAttribute(attr, attrs[attr]);
}
}
return el;
};
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
var showPassed, showSkipped;
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
this.createDom('div', { className: 'banner' },
this.createDom('div', { className: 'logo' },
this.createDom('a', { href: 'http://pivotal.github.com/jasmine/', target: "_blank" }, "Jasmine"),
this.createDom('span', { className: 'version' }, runner.env.versionString())),
this.createDom('div', { className: 'options' },
"Show ",
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
)
),
this.runnerDiv = this.createDom('div', { className: 'runner running' },
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
);
this.document.body.appendChild(this.outerDiv);
var suites = runner.suites();
for (var i = 0; i < suites.length; i++) {
var suite = suites[i];
var suiteDiv = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
this.suiteDivs[suite.id] = suiteDiv;
var parentDiv = this.outerDiv;
if (suite.parentSuite) {
parentDiv = this.suiteDivs[suite.parentSuite.id];
}
parentDiv.appendChild(suiteDiv);
}
this.startedAt = new Date();
var self = this;
showPassed.onclick = function(evt) {
if (showPassed.checked) {
self.outerDiv.className += ' show-passed';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
}
};
showSkipped.onclick = function(evt) {
if (showSkipped.checked) {
self.outerDiv.className += ' show-skipped';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
}
};
};
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
var results = runner.results();
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
this.runnerDiv.setAttribute("class", className);
//do it twice for IE
this.runnerDiv.setAttribute("className", className);
var specs = runner.specs();
var specCount = 0;
for (var i = 0; i < specs.length; i++) {
if (this.specFilter(specs[i])) {
specCount++;
}
}
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
};
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
var results = suite.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.totalCount == 0) { // todo: change this to check results.skipped
status = 'skipped';
}
this.suiteDivs[suite.id].className += " " + status;
};
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
if (this.logRunningSpecs) {
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
var results = spec.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
var specDiv = this.createDom('div', { className: 'spec ' + status },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(spec.getFullName()),
title: spec.getFullName()
}, spec.description));
var resultItems = results.getItems();
var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) {
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
}
if (messagesDiv.childNodes.length > 0) {
specDiv.appendChild(messagesDiv);
}
this.suiteDivs[spec.suite.id].appendChild(specDiv);
};
jasmine.TrivialReporter.prototype.log = function() {
var console = jasmine.getGlobal().console;
if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
};
jasmine.TrivialReporter.prototype.getLocation = function() {
return this.document.location;
};
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
var paramMap = {};
var params = this.getLocation().search.substring(1).split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
if (!paramMap["spec"]) return true;
return spec.getFullName().indexOf(paramMap["spec"]) == 0;
};

@ -0,0 +1,166 @@
body {
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
}
.jasmine_reporter a:visited, .jasmine_reporter a {
color: #303;
}
.jasmine_reporter a:hover, .jasmine_reporter a:active {
color: blue;
}
.run_spec {
float:right;
padding-right: 5px;
font-size: .8em;
text-decoration: none;
}
.jasmine_reporter {
margin: 0 5px;
}
.banner {
color: #303;
background-color: #fef;
padding: 5px;
}
.logo {
float: left;
font-size: 1.1em;
padding-left: 5px;
}
.logo .version {
font-size: .6em;
padding-left: 1em;
}
.runner.running {
background-color: yellow;
}
.options {
text-align: right;
font-size: .8em;
}
.suite {
border: 1px outset gray;
margin: 5px 0;
padding-left: 1em;
}
.suite .suite {
margin: 5px;
}
.suite.passed {
background-color: #dfd;
}
.suite.failed {
background-color: #fdd;
}
.spec {
margin: 5px;
padding-left: 1em;
clear: both;
}
.spec.failed, .spec.passed, .spec.skipped {
padding-bottom: 5px;
border: 1px solid gray;
}
.spec.failed {
background-color: #fbb;
border-color: red;
}
.spec.passed {
background-color: #bfb;
border-color: green;
}
.spec.skipped {
background-color: #bbb;
}
.messages {
border-left: 1px dashed gray;
padding-left: 1em;
padding-right: 1em;
}
.passed {
background-color: #cfc;
display: none;
}
.failed {
background-color: #fbb;
}
.skipped {
color: #777;
background-color: #eee;
display: none;
}
/*.resultMessage {*/
/*white-space: pre;*/
/*}*/
.resultMessage span.result {
display: block;
line-height: 2em;
color: black;
}
.resultMessage .mismatch {
color: black;
}
.stackTrace {
white-space: pre;
font-size: .8em;
margin-left: 10px;
max-height: 5em;
overflow: auto;
border: 1px inset red;
padding: 1em;
background: #eef;
}
.finished-at {
padding-left: 1em;
font-size: .6em;
}
.show-passed .passed,
.show-skipped .skipped {
display: block;
}
#jasmine_content {
position:fixed;
right: 100%;
}
.runner {
border: 1px solid gray;
display: block;
margin: 5px 0;
padding: 2px 0 2px 10px;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,2 @@
trunk @ 2010-11-11

@ -0,0 +1,29 @@
/* jasmine specs for controllers go here */
describe('MyCtrl1', function(){
var myCtrl1;
beforeEach(function(){
myCtrl1 = new MyCtrl1();
});
it('should ....', function() {
//spec body
});
});
describe('MyCtrl2', function(){
var myCtrl2;
beforeEach(function(){
myCtrl2 = new MyCtrl2();
});
it('should ....', function() {
//spec body
});
});

@ -0,0 +1 @@
/* jasmine specs for filters go here */

@ -0,0 +1 @@
/* jasmine specs for services go here */

@ -0,0 +1 @@
/* jasmine specs for widgets go here */