├── .cordova
└── config.json
├── .gitignore
├── LICENSE
├── README.md
├── platforms
└── .gitignore
├── plugins
└── .gitignore
└── www
├── config.xml
├── css
├── app.css
├── ionic.css
├── ionic.min.css
└── themes
│ ├── ionic-ios7.css
│ └── ionic-ios7.min.css
├── fonts
├── ionicons.eot
├── ionicons.svg
├── ionicons.ttf
└── ionicons.woff
├── img
└── ionic.png
├── index.html
├── js
├── angular
│ ├── angular-animate.js
│ ├── angular-animate.min.js
│ ├── angular-animate.min.js.map
│ ├── angular-cookies.js
│ ├── angular-cookies.min.js
│ ├── angular-cookies.min.js.map
│ ├── angular-csp.css
│ ├── angular-loader.js
│ ├── angular-loader.min.js
│ ├── angular-loader.min.js.map
│ ├── angular-mocks.js
│ ├── angular-resource.js
│ ├── angular-resource.min.js
│ ├── angular-resource.min.js.map
│ ├── angular-route.js
│ ├── angular-route.min.js
│ ├── angular-route.min.js.map
│ ├── angular-sanitize.js
│ ├── angular-sanitize.min.js
│ ├── angular-sanitize.min.js.map
│ ├── angular-scenario.js
│ ├── angular-touch.js
│ ├── angular-touch.min.js
│ ├── angular-touch.min.js.map
│ ├── angular.js
│ ├── angular.min.js
│ ├── angular.min.js.map
│ ├── errors.json
│ ├── version.json
│ └── version.txt
├── app.js
├── controllers.js
├── ionic-angular.js
├── ionic-angular.min.js
├── ionic.js
├── ionic.min.js
└── services.js
├── res
├── icon
│ ├── android
│ │ ├── icon-36-ldpi.png
│ │ ├── icon-48-mdpi.png
│ │ ├── icon-72-hdpi.png
│ │ └── icon-96-xhdpi.png
│ ├── bada-wac
│ │ ├── icon-48-type5.png
│ │ ├── icon-50-type3.png
│ │ └── icon-80-type4.png
│ ├── bada
│ │ └── icon-128.png
│ ├── blackberry
│ │ └── icon-80.png
│ ├── ios
│ │ ├── icon-57-2x.png
│ │ ├── icon-57.png
│ │ ├── icon-72-2x.png
│ │ └── icon-72.png
│ ├── tizen
│ │ └── icon-128.png
│ ├── webos
│ │ └── icon-64.png
│ └── windows-phone
│ │ ├── icon-173-tile.png
│ │ ├── icon-48.png
│ │ └── icon-62-tile.png
└── screen
│ ├── android
│ ├── screen-hdpi-landscape.png
│ ├── screen-hdpi-portrait.png
│ ├── screen-ldpi-landscape.png
│ ├── screen-ldpi-portrait.png
│ ├── screen-mdpi-landscape.png
│ ├── screen-mdpi-portrait.png
│ ├── screen-xhdpi-landscape.png
│ └── screen-xhdpi-portrait.png
│ ├── bada-wac
│ ├── screen-type3.png
│ ├── screen-type4.png
│ └── screen-type5.png
│ ├── bada
│ └── screen-portrait.png
│ ├── blackberry
│ └── screen-225.png
│ ├── ios
│ ├── screen-ipad-landscape-2x.png
│ ├── screen-ipad-landscape.png
│ ├── screen-ipad-portrait-2x.png
│ ├── screen-ipad-portrait.png
│ ├── screen-iphone-landscape-2x.png
│ ├── screen-iphone-landscape.png
│ ├── screen-iphone-portrait-2x.png
│ ├── screen-iphone-portrait-568h-2x.png
│ └── screen-iphone-portrait.png
│ ├── tizen
│ └── README.md
│ ├── webos
│ └── screen-64.png
│ └── windows-phone
│ └── screen-portrait.jpg
└── templates
├── app.html
└── pet.html
/.cordova/config.json:
--------------------------------------------------------------------------------
1 | {"id":"com.ionicframework.starter","name":"StarterApp"}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.keystore
2 | *.sw*
3 | platforms/^.*
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Drifty
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ionic-intro
2 | ===========
3 |
4 | A demo app for showing an intro tutorial for your apps
5 |
--------------------------------------------------------------------------------
/platforms/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
5 |
--------------------------------------------------------------------------------
/plugins/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
5 |
--------------------------------------------------------------------------------
/www/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | StarterApp
4 |
5 | A sample Ionic Framework app using Cordova and AngularJS
6 |
7 |
8 | Apache Cordova Team
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/www/css/app.css:
--------------------------------------------------------------------------------
1 | #splash-page {
2 | background-color: white;
3 | }
4 | #logo {
5 | background: url('../img/ionic.png') no-repeat transparent;
6 | width: 128px;
7 | height: 128px;
8 | position: absolute;
9 | top: 50%;
10 | left: 50%;
11 | margin: -64px 0px 0px -64px;
12 | }
13 |
--------------------------------------------------------------------------------
/www/css/themes/ionic-ios7.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | /*!
3 | * Copyright 2013 Drifty Co.
4 | * http://drifty.com/
5 |
6 | * Ionic - a powerful HTML5 mobile app framework.
7 | * http://ionicframework.com/
8 | *
9 | *
10 | * By @maxlynch, @helloimben, @adamdbradley <3
11 | *
12 | * Licensed under the MIT license. Please see LICENSE for more information.
13 | *
14 | */
15 | /**
16 | * Nav controllers and header bar animations
17 | */
18 | /*
19 | .content-slide-in {
20 | &.ng-enter, > .ng-enter {
21 | -webkit-transition: 0.5s ease-in-out all;
22 | -webkit-transform:translate3d(100%,0,0) ;
23 | box-shadow: -1px 0px 10px rgba(0,0,0,0.6);
24 | }
25 | &.ng-enter-active, > .ng-enter-active {
26 | -webkit-transform:translate3d(0,0,0) ;
27 | }
28 | &.ng-leave, > .ng-leave {
29 | -webkit-transition: 0.5s ease-in-out all;
30 | -webkit-transform:translate3d(0%,0,0);
31 | }
32 | &.ng-leave-active, > .ng-leave-active {
33 | -webkit-transform:translate3d(-10%,0,0);
34 | opacity: 0.8;
35 | }
36 | }
37 | */
38 | .content-slide-out.ng-enter, .content-slide-out > .ng-enter {
39 | z-index: 1;
40 | -webkit-transition: 0.5s ease-in-out all;
41 | -webkit-transform: translate3d(-100%, 0, 0);
42 | box-shadow: -1px 0px 10px rgba(0, 0, 0, 0.6); }
43 | .content-slide-out.ng-enter-active, .content-slide-out > .ng-enter-active {
44 | -webkit-transform: translate3d(0, 0, 0); }
45 | .content-slide-out.ng-leave, .content-slide-out > .ng-leave {
46 | z-index: 0;
47 | -webkit-transition: 0.5s ease-in-out all;
48 | -webkit-transform: translate3d(0%, 0, 0); }
49 | .content-slide-out.ng-leave-active, .content-slide-out > .ng-leave-active {
50 | -webkit-transform: translate3d(10%, 0, 0);
51 | opacity: 0.8; }
52 |
53 | .bar-title-in-add {
54 | -webkit-transition: -webkit-transform 0.5s ease-in-out, opacity 0.5s ease-in-out;
55 | -webkit-transform: translate3d(100%, 0, 0);
56 | opacity: 0; }
57 |
58 | .bar-title-in-add-active {
59 | -webkit-transform: translate3d(0px, 0, 0);
60 | opacity: 1; }
61 |
62 | .bar-title-out-add {
63 | -webkit-transition: -webkit-transform 0.5s ease-in-out, opacity 0.5s ease-in-out; }
64 |
65 | .bar-title-out-add-active {
66 | -webkit-transform: translate3d(-100%, 0, 0);
67 | opacity: 0; }
68 |
69 | .bar-button-in {
70 | opacity: 0; }
71 |
72 | .bar-button-in-add {
73 | -webkit-transition: -webkit-transform 0.5s ease-in-out, opacity 0.5s ease-in-out;
74 | -webkit-transform: translate3d(50%, 0, 0);
75 | opacity: 0; }
76 |
77 | .bar-button-in-active {
78 | -webkit-transform: translate3d(0px, 0, 0);
79 | opacity: 1; }
80 |
81 | /**
82 | * Tab controller animations
83 | */
84 | .fade-in-out.ng-enter, .fade-in-out > .ng-enter {
85 | opacity: 0;
86 | -webkit-transition: opacity 0.3s ease-in-out; }
87 | .fade-in-out.ng-enter-active, .fade-in-out > .ng-enter-active {
88 | opacity: 1; }
89 | .fade-in-out.ng-leave, .fade-in-out > .ng-leave {
90 | opacity: 1;
91 | -webkit-transition: opacity 0.3s ease-in-out; }
92 | .fade-in-out.ng-leave-active, .fade-in-out > .ng-leave-active {
93 | opacity: 0; }
94 |
95 | /* the overall container of the toggle */
96 | .toggle {
97 | display: inline-block; }
98 |
99 | /* hide the actual checkbox */
100 | .toggle input {
101 | display: none; }
102 |
103 | .toggle .track {
104 | /* the background of the toggle's track area */
105 | /* also the track appearance when the toggle is "off" */
106 | position: relative;
107 | display: inline-block;
108 | box-sizing: border-box;
109 | width: 54px;
110 | height: 32px;
111 | border: solid 2px #dddddd;
112 | border-radius: 20px;
113 | background-color: white;
114 | cursor: pointer;
115 | transition: 0.4s ease; }
116 |
117 | .toggle .handle {
118 | /* the handle (circle) thats inside the toggle's track area */
119 | /* also the appearance when the handle is "off" */
120 | position: absolute;
121 | display: block;
122 | width: auto;
123 | /* override defaults */
124 | height: auto;
125 | /* override defaults */
126 | box-shadow: 0 0 2px rgba(0, 0, 0, 0.5), 0 4px 5px rgba(0, 0, 0, 0.25);
127 | border-radius: 20px;
128 | background-color: white;
129 | left: 0;
130 | top: 0;
131 | bottom: 0;
132 | right: 20px;
133 | transition: 0.2s ease;
134 | transition-property: left, right;
135 | transition-delay: 0s, .05s; }
136 |
137 | .toggle :checked + .track {
138 | /* When the toggle is "on" */
139 | /* the track when the toggle is "on" */
140 | border-color: #4bd863;
141 | background-color: #ccc;
142 | box-shadow: inset 0 0 0 20px #4bd863;
143 | transition: 0.2s ease;
144 | /* the handle when the toggle is "on" */ }
145 | .toggle :checked + .track .handle {
146 | background-color: white;
147 | right: 0;
148 | left: 20px;
149 | -webkit-transform: none;
150 | transition-delay: .05s, 0s; }
151 |
--------------------------------------------------------------------------------
/www/css/themes/ionic-ios7.min.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";/*!
2 | * Copyright 2013 Drifty Co.
3 | * http://drifty.com/
4 |
5 | * Ionic - a powerful HTML5 mobile app framework.
6 | * http://ionicframework.com/
7 | *
8 | *
9 | * By @maxlynch, @helloimben, @adamdbradley <3
10 | *
11 | * Licensed under the MIT license. Please see LICENSE for more information.
12 | *
13 | */.content-slide-out.ng-enter,.content-slide-out>.ng-enter{z-index:1;-webkit-transition:.5s ease-in-out all;-webkit-transform:translate3d(-100%,0,0);box-shadow:-1px 0 10px rgba(0,0,0,.6)}.content-slide-out.ng-enter-active,.content-slide-out>.ng-enter-active{-webkit-transform:translate3d(0,0,0)}.content-slide-out.ng-leave,.content-slide-out>.ng-leave{z-index:0;-webkit-transition:.5s ease-in-out all;-webkit-transform:translate3d(0%,0,0)}.content-slide-out.ng-leave-active,.content-slide-out>.ng-leave-active{-webkit-transform:translate3d(10%,0,0);opacity:.8}.bar-title-in-add{-webkit-transition:-webkit-transform .5s ease-in-out,opacity .5s ease-in-out;-webkit-transform:translate3d(100%,0,0);opacity:0}.bar-title-in-add-active{-webkit-transform:translate3d(0px,0,0);opacity:1}.bar-title-out-add{-webkit-transition:-webkit-transform .5s ease-in-out,opacity .5s ease-in-out}.bar-title-out-add-active{-webkit-transform:translate3d(-100%,0,0);opacity:0}.bar-button-in{opacity:0}.bar-button-in-add{-webkit-transition:-webkit-transform .5s ease-in-out,opacity .5s ease-in-out;-webkit-transform:translate3d(50%,0,0);opacity:0}.bar-button-in-active{-webkit-transform:translate3d(0px,0,0);opacity:1}.fade-in-out.ng-enter,.fade-in-out>.ng-enter{opacity:0;-webkit-transition:opacity .3s ease-in-out}.fade-in-out.ng-enter-active,.fade-in-out>.ng-enter-active{opacity:1}.fade-in-out.ng-leave,.fade-in-out>.ng-leave{opacity:1;-webkit-transition:opacity .3s ease-in-out}.fade-in-out.ng-leave-active,.fade-in-out>.ng-leave-active{opacity:0}.toggle{display:inline-block}.toggle input{display:none}.toggle .track{position:relative;display:inline-block;box-sizing:border-box;width:54px;height:32px;border:solid 2px #ddd;border-radius:20px;background-color:#fff;cursor:pointer;transition:.4s ease}.toggle .handle{position:absolute;display:block;width:auto;height:auto;box-shadow:0 0 2px rgba(0,0,0,.5),0 4px 5px rgba(0,0,0,.25);border-radius:20px;background-color:#fff;left:0;top:0;bottom:0;right:20px;transition:.2s ease;transition-property:left,right;transition-delay:0s,.05s}.toggle :checked+.track{border-color:#4bd863;background-color:#ccc;box-shadow:inset 0 0 0 20px #4bd863;transition:.2s ease}.toggle :checked+.track .handle{background-color:#fff;right:0;left:20px;-webkit-transform:none;transition-delay:.05s,0s}
--------------------------------------------------------------------------------
/www/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/fonts/ionicons.eot
--------------------------------------------------------------------------------
/www/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/www/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/fonts/ionicons.woff
--------------------------------------------------------------------------------
/www/img/ionic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/img/ionic.png
--------------------------------------------------------------------------------
/www/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ionic Seed
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/www/js/angular/angular-animate.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.4
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(C,k,F){'use strict';k.module("ngAnimate",["ng"]).config(["$provide","$animateProvider",function(M,G){function l(l){for(var h=0;h=v&&d>=p&&f()}var r=a.data(z),m=l(a);if(-1!=m.className.indexOf(c)&&r){var k=r.timings,n=r.stagger,p=r.maxDuration,q=r.activeClassName,v=1E3*Math.max(k.transitionDelay,k.animationDelay),x=Date.now(),w=Q+" "+P,u=r.ii,y,r="",s=[];if(0
20 | *
21 | * See {@link ngCookies.$cookies `$cookies`} and
22 | * {@link ngCookies.$cookieStore `$cookieStore`} for usage.
23 | */
24 |
25 |
26 | angular.module('ngCookies', ['ng']).
27 | /**
28 | * @ngdoc object
29 | * @name ngCookies.$cookies
30 | * @requires $browser
31 | *
32 | * @description
33 | * Provides read/write access to browser's cookies.
34 | *
35 | * Only a simple Object is exposed and by adding or removing properties to/from
36 | * this object, new cookies are created/deleted at the end of current $eval.
37 | *
38 | * Requires the {@link ngCookies `ngCookies`} module to be installed.
39 | *
40 | * @example
41 |
42 |
43 |
51 |
52 |
53 | */
54 | factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) {
55 | var cookies = {},
56 | lastCookies = {},
57 | lastBrowserCookies,
58 | runEval = false,
59 | copy = angular.copy,
60 | isUndefined = angular.isUndefined;
61 |
62 | //creates a poller fn that copies all cookies from the $browser to service & inits the service
63 | $browser.addPollFn(function() {
64 | var currentCookies = $browser.cookies();
65 | if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
66 | lastBrowserCookies = currentCookies;
67 | copy(currentCookies, lastCookies);
68 | copy(currentCookies, cookies);
69 | if (runEval) $rootScope.$apply();
70 | }
71 | })();
72 |
73 | runEval = true;
74 |
75 | //at the end of each eval, push cookies
76 | //TODO: this should happen before the "delayed" watches fire, because if some cookies are not
77 | // strings or browser refuses to store some cookies, we update the model in the push fn.
78 | $rootScope.$watch(push);
79 |
80 | return cookies;
81 |
82 |
83 | /**
84 | * Pushes all the cookies from the service to the browser and verifies if all cookies were
85 | * stored.
86 | */
87 | function push() {
88 | var name,
89 | value,
90 | browserCookies,
91 | updated;
92 |
93 | //delete any cookies deleted in $cookies
94 | for (name in lastCookies) {
95 | if (isUndefined(cookies[name])) {
96 | $browser.cookies(name, undefined);
97 | }
98 | }
99 |
100 | //update all cookies updated in $cookies
101 | for(name in cookies) {
102 | value = cookies[name];
103 | if (!angular.isString(value)) {
104 | if (angular.isDefined(lastCookies[name])) {
105 | cookies[name] = lastCookies[name];
106 | } else {
107 | delete cookies[name];
108 | }
109 | } else if (value !== lastCookies[name]) {
110 | $browser.cookies(name, value);
111 | updated = true;
112 | }
113 | }
114 |
115 | //verify what was actually stored
116 | if (updated){
117 | updated = false;
118 | browserCookies = $browser.cookies();
119 |
120 | for (name in cookies) {
121 | if (cookies[name] !== browserCookies[name]) {
122 | //delete or reset all cookies that the browser dropped from $cookies
123 | if (isUndefined(browserCookies[name])) {
124 | delete cookies[name];
125 | } else {
126 | cookies[name] = browserCookies[name];
127 | }
128 | updated = true;
129 | }
130 | }
131 | }
132 | }
133 | }]).
134 |
135 |
136 | /**
137 | * @ngdoc object
138 | * @name ngCookies.$cookieStore
139 | * @requires $cookies
140 | *
141 | * @description
142 | * Provides a key-value (string-object) storage, that is backed by session cookies.
143 | * Objects put or retrieved from this storage are automatically serialized or
144 | * deserialized by angular's toJson/fromJson.
145 | *
146 | * Requires the {@link ngCookies `ngCookies`} module to be installed.
147 | *
148 | * @example
149 | */
150 | factory('$cookieStore', ['$cookies', function($cookies) {
151 |
152 | return {
153 | /**
154 | * @ngdoc method
155 | * @name ngCookies.$cookieStore#get
156 | * @methodOf ngCookies.$cookieStore
157 | *
158 | * @description
159 | * Returns the value of given cookie key
160 | *
161 | * @param {string} key Id to use for lookup.
162 | * @returns {Object} Deserialized cookie value.
163 | */
164 | get: function(key) {
165 | var value = $cookies[key];
166 | return value ? angular.fromJson(value) : value;
167 | },
168 |
169 | /**
170 | * @ngdoc method
171 | * @name ngCookies.$cookieStore#put
172 | * @methodOf ngCookies.$cookieStore
173 | *
174 | * @description
175 | * Sets a value for given cookie key
176 | *
177 | * @param {string} key Id for the `value`.
178 | * @param {Object} value Value to be stored.
179 | */
180 | put: function(key, value) {
181 | $cookies[key] = angular.toJson(value);
182 | },
183 |
184 | /**
185 | * @ngdoc method
186 | * @name ngCookies.$cookieStore#remove
187 | * @methodOf ngCookies.$cookieStore
188 | *
189 | * @description
190 | * Remove given cookie
191 | *
192 | * @param {string} key Id of the key-value pair to delete.
193 | */
194 | remove: function(key) {
195 | delete $cookies[key];
196 | }
197 | };
198 |
199 | }]);
200 |
201 |
202 | })(window, window.angular);
203 |
--------------------------------------------------------------------------------
/www/js/angular/angular-cookies.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.4
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(d,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&d.$apply())})();k=!0;d.$watch(function(){var a,e,d;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)(e=c[a],f.isString(e))?e!==g[a]&&(b.cookies(a,e),d=!0):f.isDefined(g[a])?c[a]=g[a]:delete c[a];if(d)for(a in e=b.cookies(),c)c[a]!==e[a]&&(m(e[a])?delete c[a]:c[a]=e[a])});
7 | return c}]).factory("$cookieStore",["$cookies",function(d){return{get:function(b){return(b=d[b])?f.fromJson(b):b},put:function(b,c){d[b]=f.toJson(c)},remove:function(b){delete d[b]}}}])})(window,window.angular);
8 | //# sourceMappingURL=angular-cookies.min.js.map
9 |
--------------------------------------------------------------------------------
/www/js/angular/angular-cookies.min.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version":3,
3 | "file":"angular-cookies.min.js",
4 | "lineCount":7,
5 | "mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAoBtCD,CAAAE,OAAA,CAAe,WAAf,CAA4B,CAAC,IAAD,CAA5B,CAAAC,QAAA,CA4BW,UA5BX,CA4BuB,CAAC,YAAD,CAAe,UAAf,CAA2B,QAAS,CAACC,CAAD,CAAaC,CAAb,CAAuB,CAAA,IACxEC,EAAU,EAD8D,CAExEC,EAAc,EAF0D,CAGxEC,CAHwE,CAIxEC,EAAU,CAAA,CAJ8D,CAKxEC,EAAOV,CAAAU,KALiE,CAMxEC,EAAcX,CAAAW,YAGlBN,EAAAO,UAAA,CAAmB,QAAQ,EAAG,CAC5B,IAAIC,EAAiBR,CAAAC,QAAA,EACjBE,EAAJ,EAA0BK,CAA1B,GACEL,CAGA,CAHqBK,CAGrB,CAFAH,CAAA,CAAKG,CAAL,CAAqBN,CAArB,CAEA,CADAG,CAAA,CAAKG,CAAL,CAAqBP,CAArB,CACA,CAAIG,CAAJ,EAAaL,CAAAU,OAAA,EAJf,CAF4B,CAA9B,CAAA,EAUAL,EAAA,CAAU,CAAA,CAKVL,EAAAW,OAAA,CASAC,QAAa,EAAG,CAAA,IACVC,CADU,CAEVC,CAFU,CAIVC,CAGJ,KAAKF,CAAL,GAAaV,EAAb,CACMI,CAAA,CAAYL,CAAA,CAAQW,CAAR,CAAZ,CAAJ,EACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBhB,CAAvB,CAKJ,KAAIgB,CAAJ,GAAYX,EAAZ,CAEE,CADAY,CACK,CADGZ,CAAA,CAAQW,CAAR,CACH,CAAAjB,CAAAoB,SAAA,CAAiBF,CAAjB,CAAL,EAMWA,CANX,GAMqBX,CAAA,CAAYU,CAAZ,CANrB,GAOEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBC,CAAvB,CACA,CAAAC,CAAA,CAAU,CAAA,CARZ,EACMnB,CAAAqB,UAAA,CAAkBd,CAAA,CAAYU,CAAZ,CAAlB,CAAJ,CACEX,CAAA,CAAQW,CAAR,CADF,CACkBV,CAAA,CAAYU,CAAZ,CADlB,CAGE,OAAOX,CAAA,CAAQW,CAAR,CASb,IAAIE,CAAJ,CAIE,IAAKF,CAAL,GAFAK,EAEahB,CAFID,CAAAC,QAAA,EAEJA,CAAAA,CAAb,CACMA,CAAA,CAAQW,CAAR,CAAJ,GAAsBK,CAAA,CAAeL,CAAf,CAAtB,GAEMN,CAAA,CAAYW,CAAA,CAAeL,CAAf,CAAZ,CAAJ,CACE,OAAOX,CAAA,CAAQW,CAAR,CADT,CAGEX,CAAA,CAAQW,CAAR,CAHF,CAGkBK,CAAA,CAAeL,CAAf,CALpB,CAlCU,CAThB,CAEA;MAAOX,EA1BqE,CAA3D,CA5BvB,CAAAH,QAAA,CA4HW,cA5HX,CA4H2B,CAAC,UAAD,CAAa,QAAQ,CAACoB,CAAD,CAAW,CAErD,MAAO,KAYAC,QAAQ,CAACC,CAAD,CAAM,CAEjB,MAAO,CADHP,CACG,CADKK,CAAA,CAASE,CAAT,CACL,EAAQzB,CAAA0B,SAAA,CAAiBR,CAAjB,CAAR,CAAkCA,CAFxB,CAZd,KA4BAS,QAAQ,CAACF,CAAD,CAAMP,CAAN,CAAa,CACxBK,CAAA,CAASE,CAAT,CAAA,CAAgBzB,CAAA4B,OAAA,CAAeV,CAAf,CADQ,CA5BrB,QA0CGW,QAAQ,CAACJ,CAAD,CAAM,CACpB,OAAOF,CAAA,CAASE,CAAT,CADa,CA1CjB,CAF8C,CAAhC,CA5H3B,CApBsC,CAArC,CAAA,CAoME1B,MApMF,CAoMUA,MAAAC,QApMV;",
6 | "sources":["angular-cookies.js"],
7 | "names":["window","angular","undefined","module","factory","$rootScope","$browser","cookies","lastCookies","lastBrowserCookies","runEval","copy","isUndefined","addPollFn","currentCookies","$apply","$watch","push","name","value","updated","isString","isDefined","browserCookies","$cookies","get","key","fromJson","put","toJson","remove"]
8 | }
9 |
--------------------------------------------------------------------------------
/www/js/angular/angular-csp.css:
--------------------------------------------------------------------------------
1 | /* Include this file in your html if you are using the CSP mode. */
2 |
3 | @charset "UTF-8";
4 |
5 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
6 | .ng-cloak, .x-ng-cloak,
7 | .ng-hide {
8 | display: none !important;
9 | }
10 |
11 | ng\:form {
12 | display: block;
13 | }
14 |
15 | /* The styles below ensure that the CSS transition will ALWAYS
16 | * animate and close. A nasty bug occurs with CSS transitions where
17 | * when the active class isn't set, or if the active class doesn't
18 | * contain any styles to transition to, then, if ngAnimate is used,
19 | * it will appear as if the webpage is broken due to the forever hanging
20 | * animations. The border-spacing (!ie) and zoom (ie) CSS properties are
21 | * used below since they trigger a transition without making the browser
22 | * animate anything and they're both highly underused CSS properties */
23 | .ng-animate-start { border-spacing:1px 1px; -ms-zoom:1.0001; }
24 | .ng-animate-active { border-spacing:0px 0px; -ms-zoom:1; }
25 |
--------------------------------------------------------------------------------
/www/js/angular/angular-loader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.2.4
3 | * (c) 2010-2014 Google, Inc. http://angularjs.org
4 | * License: MIT
5 | */
6 |
7 | (function() {'use strict';
8 |
9 | /**
10 | * @description
11 | *
12 | * This object provides a utility for producing rich Error messages within
13 | * Angular. It can be called as follows:
14 | *
15 | * var exampleMinErr = minErr('example');
16 | * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
17 | *
18 | * The above creates an instance of minErr in the example namespace. The
19 | * resulting error will have a namespaced error code of example.one. The
20 | * resulting error will replace {0} with the value of foo, and {1} with the
21 | * value of bar. The object is not restricted in the number of arguments it can
22 | * take.
23 | *
24 | * If fewer arguments are specified than necessary for interpolation, the extra
25 | * interpolation markers will be preserved in the final string.
26 | *
27 | * Since data will be parsed statically during a build step, some restrictions
28 | * are applied with respect to how minErr instances are created and called.
29 | * Instances should have names of the form namespaceMinErr for a minErr created
30 | * using minErr('namespace') . Error codes, namespaces and template strings
31 | * should all be static strings, not variables or general expressions.
32 | *
33 | * @param {string} module The namespace to use for the new minErr instance.
34 | * @returns {function(string, string, ...): Error} instance
35 | */
36 |
37 | function minErr(module) {
38 | return function () {
39 | var code = arguments[0],
40 | prefix = '[' + (module ? module + ':' : '') + code + '] ',
41 | template = arguments[1],
42 | templateArgs = arguments,
43 | stringify = function (obj) {
44 | if (typeof obj === 'function') {
45 | return obj.toString().replace(/ \{[\s\S]*$/, '');
46 | } else if (typeof obj === 'undefined') {
47 | return 'undefined';
48 | } else if (typeof obj !== 'string') {
49 | return JSON.stringify(obj);
50 | }
51 | return obj;
52 | },
53 | message, i;
54 |
55 | message = prefix + template.replace(/\{\d+\}/g, function (match) {
56 | var index = +match.slice(1, -1), arg;
57 |
58 | if (index + 2 < templateArgs.length) {
59 | arg = templateArgs[index + 2];
60 | if (typeof arg === 'function') {
61 | return arg.toString().replace(/ ?\{[\s\S]*$/, '');
62 | } else if (typeof arg === 'undefined') {
63 | return 'undefined';
64 | } else if (typeof arg !== 'string') {
65 | return toJson(arg);
66 | }
67 | return arg;
68 | }
69 | return match;
70 | });
71 |
72 | message = message + '\nhttp://errors.angularjs.org/1.2.4/' +
73 | (module ? module + '/' : '') + code;
74 | for (i = 2; i < arguments.length; i++) {
75 | message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
76 | encodeURIComponent(stringify(arguments[i]));
77 | }
78 |
79 | return new Error(message);
80 | };
81 | }
82 |
83 | /**
84 | * @ngdoc interface
85 | * @name angular.Module
86 | * @description
87 | *
88 | * Interface for configuring angular {@link angular.module modules}.
89 | */
90 |
91 | function setupModuleLoader(window) {
92 |
93 | var $injectorMinErr = minErr('$injector');
94 | var ngMinErr = minErr('ng');
95 |
96 | function ensure(obj, name, factory) {
97 | return obj[name] || (obj[name] = factory());
98 | }
99 |
100 | var angular = ensure(window, 'angular', Object);
101 |
102 | // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
103 | angular.$$minErr = angular.$$minErr || minErr;
104 |
105 | return ensure(angular, 'module', function() {
106 | /** @type {Object.} */
107 | var modules = {};
108 |
109 | /**
110 | * @ngdoc function
111 | * @name angular.module
112 | * @description
113 | *
114 | * The `angular.module` is a global place for creating, registering and retrieving Angular
115 | * modules.
116 | * All modules (angular core or 3rd party) that should be available to an application must be
117 | * registered using this mechanism.
118 | *
119 | * When passed two or more arguments, a new module is created. If passed only one argument, an
120 | * existing module (the name passed as the first argument to `module`) is retrieved.
121 | *
122 | *
123 | * # Module
124 | *
125 | * A module is a collection of services, directives, filters, and configuration information.
126 | * `angular.module` is used to configure the {@link AUTO.$injector $injector}.
127 | *
128 | *
129 | * // Create a new module
130 | * var myModule = angular.module('myModule', []);
131 | *
132 | * // register a new service
133 | * myModule.value('appName', 'MyCoolApp');
134 | *
135 | * // configure existing services inside initialization blocks.
136 | * myModule.config(function($locationProvider) {
137 | * // Configure existing providers
138 | * $locationProvider.hashPrefix('!');
139 | * });
140 | *
141 | *
142 | * Then you can create an injector and load your modules like this:
143 | *
144 | *
145 | * var injector = angular.injector(['ng', 'MyModule'])
146 | *
147 | *
148 | * However it's more likely that you'll just use
149 | * {@link ng.directive:ngApp ngApp} or
150 | * {@link angular.bootstrap} to simplify this process for you.
151 | *
152 | * @param {!string} name The name of the module to create or retrieve.
153 | * @param {Array.=} requires If specified then new module is being created. If
154 | * unspecified then the the module is being retrieved for further configuration.
155 | * @param {Function} configFn Optional configuration function for the module. Same as
156 | * {@link angular.Module#methods_config Module#config()}.
157 | * @returns {module} new module with the {@link angular.Module} api.
158 | */
159 | return function module(name, requires, configFn) {
160 | var assertNotHasOwnProperty = function(name, context) {
161 | if (name === 'hasOwnProperty') {
162 | throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
163 | }
164 | };
165 |
166 | assertNotHasOwnProperty(name, 'module');
167 | if (requires && modules.hasOwnProperty(name)) {
168 | modules[name] = null;
169 | }
170 | return ensure(modules, name, function() {
171 | if (!requires) {
172 | throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
173 | "the module name or forgot to load it. If registering a module ensure that you " +
174 | "specify the dependencies as the second argument.", name);
175 | }
176 |
177 | /** @type {!Array.>} */
178 | var invokeQueue = [];
179 |
180 | /** @type {!Array.} */
181 | var runBlocks = [];
182 |
183 | var config = invokeLater('$injector', 'invoke');
184 |
185 | /** @type {angular.Module} */
186 | var moduleInstance = {
187 | // Private state
188 | _invokeQueue: invokeQueue,
189 | _runBlocks: runBlocks,
190 |
191 | /**
192 | * @ngdoc property
193 | * @name angular.Module#requires
194 | * @propertyOf angular.Module
195 | * @returns {Array.} List of module names which must be loaded before this module.
196 | * @description
197 | * Holds the list of modules which the injector will load before the current module is
198 | * loaded.
199 | */
200 | requires: requires,
201 |
202 | /**
203 | * @ngdoc property
204 | * @name angular.Module#name
205 | * @propertyOf angular.Module
206 | * @returns {string} Name of the module.
207 | * @description
208 | */
209 | name: name,
210 |
211 |
212 | /**
213 | * @ngdoc method
214 | * @name angular.Module#provider
215 | * @methodOf angular.Module
216 | * @param {string} name service name
217 | * @param {Function} providerType Construction function for creating new instance of the
218 | * service.
219 | * @description
220 | * See {@link AUTO.$provide#provider $provide.provider()}.
221 | */
222 | provider: invokeLater('$provide', 'provider'),
223 |
224 | /**
225 | * @ngdoc method
226 | * @name angular.Module#factory
227 | * @methodOf angular.Module
228 | * @param {string} name service name
229 | * @param {Function} providerFunction Function for creating new instance of the service.
230 | * @description
231 | * See {@link AUTO.$provide#factory $provide.factory()}.
232 | */
233 | factory: invokeLater('$provide', 'factory'),
234 |
235 | /**
236 | * @ngdoc method
237 | * @name angular.Module#service
238 | * @methodOf angular.Module
239 | * @param {string} name service name
240 | * @param {Function} constructor A constructor function that will be instantiated.
241 | * @description
242 | * See {@link AUTO.$provide#service $provide.service()}.
243 | */
244 | service: invokeLater('$provide', 'service'),
245 |
246 | /**
247 | * @ngdoc method
248 | * @name angular.Module#value
249 | * @methodOf angular.Module
250 | * @param {string} name service name
251 | * @param {*} object Service instance object.
252 | * @description
253 | * See {@link AUTO.$provide#value $provide.value()}.
254 | */
255 | value: invokeLater('$provide', 'value'),
256 |
257 | /**
258 | * @ngdoc method
259 | * @name angular.Module#constant
260 | * @methodOf angular.Module
261 | * @param {string} name constant name
262 | * @param {*} object Constant value.
263 | * @description
264 | * Because the constant are fixed, they get applied before other provide methods.
265 | * See {@link AUTO.$provide#constant $provide.constant()}.
266 | */
267 | constant: invokeLater('$provide', 'constant', 'unshift'),
268 |
269 | /**
270 | * @ngdoc method
271 | * @name angular.Module#animation
272 | * @methodOf angular.Module
273 | * @param {string} name animation name
274 | * @param {Function} animationFactory Factory function for creating new instance of an
275 | * animation.
276 | * @description
277 | *
278 | * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
279 | *
280 | *
281 | * Defines an animation hook that can be later used with
282 | * {@link ngAnimate.$animate $animate} service and directives that use this service.
283 | *
284 | *
285 | * module.animation('.animation-name', function($inject1, $inject2) {
286 | * return {
287 | * eventName : function(element, done) {
288 | * //code to run the animation
289 | * //once complete, then run done()
290 | * return function cancellationFunction(element) {
291 | * //code to cancel the animation
292 | * }
293 | * }
294 | * }
295 | * })
296 | *
297 | *
298 | * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and
299 | * {@link ngAnimate ngAnimate module} for more information.
300 | */
301 | animation: invokeLater('$animateProvider', 'register'),
302 |
303 | /**
304 | * @ngdoc method
305 | * @name angular.Module#filter
306 | * @methodOf angular.Module
307 | * @param {string} name Filter name.
308 | * @param {Function} filterFactory Factory function for creating new instance of filter.
309 | * @description
310 | * See {@link ng.$filterProvider#register $filterProvider.register()}.
311 | */
312 | filter: invokeLater('$filterProvider', 'register'),
313 |
314 | /**
315 | * @ngdoc method
316 | * @name angular.Module#controller
317 | * @methodOf angular.Module
318 | * @param {string|Object} name Controller name, or an object map of controllers where the
319 | * keys are the names and the values are the constructors.
320 | * @param {Function} constructor Controller constructor function.
321 | * @description
322 | * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
323 | */
324 | controller: invokeLater('$controllerProvider', 'register'),
325 |
326 | /**
327 | * @ngdoc method
328 | * @name angular.Module#directive
329 | * @methodOf angular.Module
330 | * @param {string|Object} name Directive name, or an object map of directives where the
331 | * keys are the names and the values are the factories.
332 | * @param {Function} directiveFactory Factory function for creating new instance of
333 | * directives.
334 | * @description
335 | * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}.
336 | */
337 | directive: invokeLater('$compileProvider', 'directive'),
338 |
339 | /**
340 | * @ngdoc method
341 | * @name angular.Module#config
342 | * @methodOf angular.Module
343 | * @param {Function} configFn Execute this function on module load. Useful for service
344 | * configuration.
345 | * @description
346 | * Use this method to register work which needs to be performed on module loading.
347 | */
348 | config: config,
349 |
350 | /**
351 | * @ngdoc method
352 | * @name angular.Module#run
353 | * @methodOf angular.Module
354 | * @param {Function} initializationFn Execute this function after injector creation.
355 | * Useful for application initialization.
356 | * @description
357 | * Use this method to register work which should be performed when the injector is done
358 | * loading all modules.
359 | */
360 | run: function(block) {
361 | runBlocks.push(block);
362 | return this;
363 | }
364 | };
365 |
366 | if (configFn) {
367 | config(configFn);
368 | }
369 |
370 | return moduleInstance;
371 |
372 | /**
373 | * @param {string} provider
374 | * @param {string} method
375 | * @param {String=} insertMethod
376 | * @returns {angular.Module}
377 | */
378 | function invokeLater(provider, method, insertMethod) {
379 | return function() {
380 | invokeQueue[insertMethod || 'push']([provider, method, arguments]);
381 | return moduleInstance;
382 | };
383 | }
384 | });
385 | };
386 | });
387 |
388 | }
389 |
390 | setupModuleLoader(window);
391 | })(window);
392 |
393 | /**
394 | * Closure compiler type information
395 | *
396 | * @typedef { {
397 | * requires: !Array.,
398 | * invokeQueue: !Array.>,
399 | *
400 | * service: function(string, Function):angular.Module,
401 | * factory: function(string, Function):angular.Module,
402 | * value: function(string, *):angular.Module,
403 | *
404 | * filter: function(string, Function):angular.Module,
405 | *
406 | * init: function(Function):angular.Module
407 | * } }
408 | */
409 | angular.Module;
410 |
411 |
--------------------------------------------------------------------------------
/www/js/angular/angular-loader.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.4
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(){'use strict';function d(a){return function(){var c=arguments[0],b,c="["+(a?a+":":"")+c+"] http://errors.angularjs.org/1.2.4/"+(a?a+"/":"")+c;for(b=1;b
45 | *
46 | * See {@link ngResource.$resource `$resource`} for usage.
47 | */
48 |
49 | /**
50 | * @ngdoc object
51 | * @name ngResource.$resource
52 | * @requires $http
53 | *
54 | * @description
55 | * A factory which creates a resource object that lets you interact with
56 | * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
57 | *
58 | * The returned resource object has action methods which provide high-level behaviors without
59 | * the need to interact with the low level {@link ng.$http $http} service.
60 | *
61 | * Requires the {@link ngResource `ngResource`} module to be installed.
62 | *
63 | * @param {string} url A parametrized URL template with parameters prefixed by `:` as in
64 | * `/user/:username`. If you are using a URL with a port number (e.g.
65 | * `http://example.com:8080/api`), it will be respected.
66 | *
67 | * If you are using a url with a suffix, just add the suffix, like this:
68 | * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
69 | * or even `$resource('http://example.com/resource/:resource_id.:format')`
70 | * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
71 | * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
72 | * can escape it with `/\.`.
73 | *
74 | * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
75 | * `actions` methods. If any of the parameter value is a function, it will be executed every time
76 | * when a param value needs to be obtained for a request (unless the param was overridden).
77 | *
78 | * Each key value in the parameter object is first bound to url template if present and then any
79 | * excess keys are appended to the url search query after the `?`.
80 | *
81 | * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
82 | * URL `/path/greet?salutation=Hello`.
83 | *
84 | * If the parameter value is prefixed with `@` then the value of that parameter is extracted from
85 | * the data object (useful for non-GET operations).
86 | *
87 | * @param {Object.=} actions Hash with declaration of custom action that should extend the
88 | * default set of resource actions. The declaration should be created in the format of {@link
89 | * ng.$http#usage_parameters $http.config}:
90 | *
91 | * {action1: {method:?, params:?, isArray:?, headers:?, ...},
92 | * action2: {method:?, params:?, isArray:?, headers:?, ...},
93 | * ...}
94 | *
95 | * Where:
96 | *
97 | * - **`action`** – {string} – The name of action. This name becomes the name of the method on
98 | * your resource object.
99 | * - **`method`** – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`,
100 | * `DELETE`, and `JSONP`.
101 | * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of
102 | * the parameter value is a function, it will be executed every time when a param value needs to
103 | * be obtained for a request (unless the param was overridden).
104 | * - **`url`** – {string} – action specific `url` override. The url templating is supported just
105 | * like for the resource-level urls.
106 | * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
107 | * see `returns` section.
108 | * - **`transformRequest`** –
109 | * `{function(data, headersGetter)|Array.}` –
110 | * transform function or an array of such functions. The transform function takes the http
111 | * request body and headers and returns its transformed (typically serialized) version.
112 | * - **`transformResponse`** –
113 | * `{function(data, headersGetter)|Array.}` –
114 | * transform function or an array of such functions. The transform function takes the http
115 | * response body and headers and returns its transformed (typically deserialized) version.
116 | * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
117 | * GET request, otherwise if a cache instance built with
118 | * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
119 | * caching.
120 | * - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that
121 | * should abort the request when resolved.
122 | * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the
123 | * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
124 | * requests with credentials} for more information.
125 | * - **`responseType`** - `{string}` - see {@link
126 | * https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
127 | * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
128 | * `response` and `responseError`. Both `response` and `responseError` interceptors get called
129 | * with `http response` object. See {@link ng.$http $http interceptors}.
130 | *
131 | * @returns {Object} A resource "class" object with methods for the default set of resource actions
132 | * optionally extended with custom `actions`. The default set contains these actions:
133 | *
134 | * { 'get': {method:'GET'},
135 | * 'save': {method:'POST'},
136 | * 'query': {method:'GET', isArray:true},
137 | * 'remove': {method:'DELETE'},
138 | * 'delete': {method:'DELETE'} };
139 | *
140 | * Calling these methods invoke an {@link ng.$http} with the specified http method,
141 | * destination and parameters. When the data is returned from the server then the object is an
142 | * instance of the resource class. The actions `save`, `remove` and `delete` are available on it
143 | * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
144 | * read, update, delete) on server-side data like this:
145 | *
146 | var User = $resource('/user/:userId', {userId:'@id'});
147 | var user = User.get({userId:123}, function() {
148 | user.abc = true;
149 | user.$save();
150 | });
151 |
152 | *
153 | * It is important to realize that invoking a $resource object method immediately returns an
154 | * empty reference (object or array depending on `isArray`). Once the data is returned from the
155 | * server the existing reference is populated with the actual data. This is a useful trick since
156 | * usually the resource is assigned to a model which is then rendered by the view. Having an empty
157 | * object results in no rendering, once the data arrives from the server then the object is
158 | * populated with the data and the view automatically re-renders itself showing the new data. This
159 | * means that in most cases one never has to write a callback function for the action methods.
160 | *
161 | * The action methods on the class object or instance object can be invoked with the following
162 | * parameters:
163 | *
164 | * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
165 | * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
166 | * - non-GET instance actions: `instance.$action([parameters], [success], [error])`
167 | *
168 | * Success callback is called with (value, responseHeaders) arguments. Error callback is called
169 | * with (httpResponse) argument.
170 | *
171 | * Class actions return empty instance (with additional properties below).
172 | * Instance actions return promise of the action.
173 | *
174 | * The Resource instances and collection have these additional properties:
175 | *
176 | * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
177 | * instance or collection.
178 | *
179 | * On success, the promise is resolved with the same resource instance or collection object,
180 | * updated with data from server. This makes it easy to use in
181 | * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view
182 | * rendering until the resource(s) are loaded.
183 | *
184 | * On failure, the promise is resolved with the {@link ng.$http http response} object, without
185 | * the `resource` property.
186 | *
187 | * - `$resolved`: `true` after first server interaction is completed (either with success or
188 | * rejection), `false` before that. Knowing if the Resource has been resolved is useful in
189 | * data-binding.
190 | *
191 | * @example
192 | *
193 | * # Credit card resource
194 | *
195 | *
196 | // Define CreditCard class
197 | var CreditCard = $resource('/user/:userId/card/:cardId',
198 | {userId:123, cardId:'@id'}, {
199 | charge: {method:'POST', params:{charge:true}}
200 | });
201 |
202 | // We can retrieve a collection from the server
203 | var cards = CreditCard.query(function() {
204 | // GET: /user/123/card
205 | // server returns: [ {id:456, number:'1234', name:'Smith'} ];
206 |
207 | var card = cards[0];
208 | // each item is an instance of CreditCard
209 | expect(card instanceof CreditCard).toEqual(true);
210 | card.name = "J. Smith";
211 | // non GET methods are mapped onto the instances
212 | card.$save();
213 | // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
214 | // server returns: {id:456, number:'1234', name: 'J. Smith'};
215 |
216 | // our custom method is mapped as well.
217 | card.$charge({amount:9.99});
218 | // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
219 | });
220 |
221 | // we can create an instance as well
222 | var newCard = new CreditCard({number:'0123'});
223 | newCard.name = "Mike Smith";
224 | newCard.$save();
225 | // POST: /user/123/card {number:'0123', name:'Mike Smith'}
226 | // server returns: {id:789, number:'01234', name: 'Mike Smith'};
227 | expect(newCard.id).toEqual(789);
228 | *
229 | *
230 | * The object returned from this function execution is a resource "class" which has "static" method
231 | * for each action in the definition.
232 | *
233 | * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and
234 | * `headers`.
235 | * When the data is returned from the server then the object is an instance of the resource type and
236 | * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
237 | * operations (create, read, update, delete) on server-side data.
238 |
239 |
240 | var User = $resource('/user/:userId', {userId:'@id'});
241 | var user = User.get({userId:123}, function() {
242 | user.abc = true;
243 | user.$save();
244 | });
245 |
246 | *
247 | * It's worth noting that the success callback for `get`, `query` and other methods gets passed
248 | * in the response that came from the server as well as $http header getter function, so one
249 | * could rewrite the above example and get access to http headers as:
250 | *
251 |
252 | var User = $resource('/user/:userId', {userId:'@id'});
253 | User.get({userId:123}, function(u, getResponseHeaders){
254 | u.abc = true;
255 | u.$save(function(u, putResponseHeaders) {
256 | //u => saved user object
257 | //putResponseHeaders => $http header getter
258 | });
259 | });
260 |
261 | */
262 | angular.module('ngResource', ['ng']).
263 | factory('$resource', ['$http', '$q', function($http, $q) {
264 |
265 | var DEFAULT_ACTIONS = {
266 | 'get': {method:'GET'},
267 | 'save': {method:'POST'},
268 | 'query': {method:'GET', isArray:true},
269 | 'remove': {method:'DELETE'},
270 | 'delete': {method:'DELETE'}
271 | };
272 | var noop = angular.noop,
273 | forEach = angular.forEach,
274 | extend = angular.extend,
275 | copy = angular.copy,
276 | isFunction = angular.isFunction;
277 |
278 | /**
279 | * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
280 | * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
281 | * segments:
282 | * segment = *pchar
283 | * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
284 | * pct-encoded = "%" HEXDIG HEXDIG
285 | * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
286 | * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
287 | * / "*" / "+" / "," / ";" / "="
288 | */
289 | function encodeUriSegment(val) {
290 | return encodeUriQuery(val, true).
291 | replace(/%26/gi, '&').
292 | replace(/%3D/gi, '=').
293 | replace(/%2B/gi, '+');
294 | }
295 |
296 |
297 | /**
298 | * This method is intended for encoding *key* or *value* parts of query component. We need a
299 | * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
300 | * have to be encoded per http://tools.ietf.org/html/rfc3986:
301 | * query = *( pchar / "/" / "?" )
302 | * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
303 | * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
304 | * pct-encoded = "%" HEXDIG HEXDIG
305 | * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
306 | * / "*" / "+" / "," / ";" / "="
307 | */
308 | function encodeUriQuery(val, pctEncodeSpaces) {
309 | return encodeURIComponent(val).
310 | replace(/%40/gi, '@').
311 | replace(/%3A/gi, ':').
312 | replace(/%24/g, '$').
313 | replace(/%2C/gi, ',').
314 | replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
315 | }
316 |
317 | function Route(template, defaults) {
318 | this.template = template;
319 | this.defaults = defaults || {};
320 | this.urlParams = {};
321 | }
322 |
323 | Route.prototype = {
324 | setUrlParams: function(config, params, actionUrl) {
325 | var self = this,
326 | url = actionUrl || self.template,
327 | val,
328 | encodedVal;
329 |
330 | var urlParams = self.urlParams = {};
331 | forEach(url.split(/\W/), function(param){
332 | if (param === 'hasOwnProperty') {
333 | throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name.");
334 | }
335 | if (!(new RegExp("^\\d+$").test(param)) && param &&
336 | (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
337 | urlParams[param] = true;
338 | }
339 | });
340 | url = url.replace(/\\:/g, ':');
341 |
342 | params = params || {};
343 | forEach(self.urlParams, function(_, urlParam){
344 | val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
345 | if (angular.isDefined(val) && val !== null) {
346 | encodedVal = encodeUriSegment(val);
347 | url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), encodedVal + "$1");
348 | } else {
349 | url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
350 | leadingSlashes, tail) {
351 | if (tail.charAt(0) == '/') {
352 | return tail;
353 | } else {
354 | return leadingSlashes + tail;
355 | }
356 | });
357 | }
358 | });
359 |
360 | // strip trailing slashes and set the url
361 | url = url.replace(/\/+$/, '');
362 | // then replace collapse `/.` if found in the last URL path segment before the query
363 | // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
364 | url = url.replace(/\/\.(?=\w+($|\?))/, '.');
365 | // replace escaped `/\.` with `/.`
366 | config.url = url.replace(/\/\\\./, '/.');
367 |
368 |
369 | // set params - delegate param encoding to $http
370 | forEach(params, function(value, key){
371 | if (!self.urlParams[key]) {
372 | config.params = config.params || {};
373 | config.params[key] = value;
374 | }
375 | });
376 | }
377 | };
378 |
379 |
380 | function resourceFactory(url, paramDefaults, actions) {
381 | var route = new Route(url);
382 |
383 | actions = extend({}, DEFAULT_ACTIONS, actions);
384 |
385 | function extractParams(data, actionParams){
386 | var ids = {};
387 | actionParams = extend({}, paramDefaults, actionParams);
388 | forEach(actionParams, function(value, key){
389 | if (isFunction(value)) { value = value(); }
390 | ids[key] = value && value.charAt && value.charAt(0) == '@' ?
391 | lookupDottedPath(data, value.substr(1)) : value;
392 | });
393 | return ids;
394 | }
395 |
396 | function defaultResponseInterceptor(response) {
397 | return response.resource;
398 | }
399 |
400 | function Resource(value){
401 | copy(value || {}, this);
402 | }
403 |
404 | forEach(actions, function(action, name) {
405 | var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
406 |
407 | Resource[name] = function(a1, a2, a3, a4) {
408 | var params = {}, data, success, error;
409 |
410 | /* jshint -W086 */ /* (purposefully fall through case statements) */
411 | switch(arguments.length) {
412 | case 4:
413 | error = a4;
414 | success = a3;
415 | //fallthrough
416 | case 3:
417 | case 2:
418 | if (isFunction(a2)) {
419 | if (isFunction(a1)) {
420 | success = a1;
421 | error = a2;
422 | break;
423 | }
424 |
425 | success = a2;
426 | error = a3;
427 | //fallthrough
428 | } else {
429 | params = a1;
430 | data = a2;
431 | success = a3;
432 | break;
433 | }
434 | case 1:
435 | if (isFunction(a1)) success = a1;
436 | else if (hasBody) data = a1;
437 | else params = a1;
438 | break;
439 | case 0: break;
440 | default:
441 | throw $resourceMinErr('badargs',
442 | "Expected up to 4 arguments [params, data, success, error], got {0} arguments",
443 | arguments.length);
444 | }
445 | /* jshint +W086 */ /* (purposefully fall through case statements) */
446 |
447 | var isInstanceCall = this instanceof Resource;
448 | var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
449 | var httpConfig = {};
450 | var responseInterceptor = action.interceptor && action.interceptor.response ||
451 | defaultResponseInterceptor;
452 | var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
453 | undefined;
454 |
455 | forEach(action, function(value, key) {
456 | if (key != 'params' && key != 'isArray' && key != 'interceptor') {
457 | httpConfig[key] = copy(value);
458 | }
459 | });
460 |
461 | if (hasBody) httpConfig.data = data;
462 | route.setUrlParams(httpConfig,
463 | extend({}, extractParams(data, action.params || {}), params),
464 | action.url);
465 |
466 | var promise = $http(httpConfig).then(function(response) {
467 | var data = response.data,
468 | promise = value.$promise;
469 |
470 | if (data) {
471 | // Need to convert action.isArray to boolean in case it is undefined
472 | // jshint -W018
473 | if ( angular.isArray(data) !== (!!action.isArray) ) {
474 | throw $resourceMinErr('badcfg', 'Error in resource configuration. Expected ' +
475 | 'response to contain an {0} but got an {1}',
476 | action.isArray?'array':'object', angular.isArray(data)?'array':'object');
477 | }
478 | // jshint +W018
479 | if (action.isArray) {
480 | value.length = 0;
481 | forEach(data, function(item) {
482 | value.push(new Resource(item));
483 | });
484 | } else {
485 | copy(data, value);
486 | value.$promise = promise;
487 | }
488 | }
489 |
490 | value.$resolved = true;
491 |
492 | response.resource = value;
493 |
494 | return response;
495 | }, function(response) {
496 | value.$resolved = true;
497 |
498 | (error||noop)(response);
499 |
500 | return $q.reject(response);
501 | });
502 |
503 | promise = promise.then(
504 | function(response) {
505 | var value = responseInterceptor(response);
506 | (success||noop)(value, response.headers);
507 | return value;
508 | },
509 | responseErrorInterceptor);
510 |
511 | if (!isInstanceCall) {
512 | // we are creating instance / collection
513 | // - set the initial promise
514 | // - return the instance / collection
515 | value.$promise = promise;
516 | value.$resolved = false;
517 |
518 | return value;
519 | }
520 |
521 | // instance call
522 | return promise;
523 | };
524 |
525 |
526 | Resource.prototype['$' + name] = function(params, success, error) {
527 | if (isFunction(params)) {
528 | error = success; success = params; params = {};
529 | }
530 | var result = Resource[name].call(this, params, this, success, error);
531 | return result.$promise || result;
532 | };
533 | });
534 |
535 | Resource.bind = function(additionalParamDefaults){
536 | return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
537 | };
538 |
539 | return Resource;
540 | }
541 |
542 | return resourceFactory;
543 | }]);
544 |
545 |
546 | })(window, window.angular);
547 |
--------------------------------------------------------------------------------
/www/js/angular/angular-resource.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.4
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(H,f,z){'use strict';var u=f.$$minErr("$resource"),A=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;f.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(D,E){function n(f,h){this.template=f;this.defaults=h||{};this.urlParams={}}function v(m,h,k){function r(d,c){var e={};c=w({},h,c);s(c,function(a,c){t(a)&&(a=a());var g;if(a&&a.charAt&&"@"==a.charAt(0)){g=d;var b=a.substr(1);if(null==b||""===b||"hasOwnProperty"===b||!A.test("."+b))throw u("badmember",b);for(var b=b.split("."),f=0,h=
7 | b.length;f
22 | *
23 | * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
24 | */
25 |
26 | /*
27 | * HTML Parser By Misko Hevery (misko@hevery.com)
28 | * based on: HTML Parser By John Resig (ejohn.org)
29 | * Original code by Erik Arvidsson, Mozilla Public License
30 | * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
31 | *
32 | * // Use like so:
33 | * htmlParser(htmlString, {
34 | * start: function(tag, attrs, unary) {},
35 | * end: function(tag) {},
36 | * chars: function(text) {},
37 | * comment: function(text) {}
38 | * });
39 | *
40 | */
41 |
42 |
43 | /**
44 | * @ngdoc service
45 | * @name ngSanitize.$sanitize
46 | * @function
47 | *
48 | * @description
49 | * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
50 | * then serialized back to properly escaped html string. This means that no unsafe input can make
51 | * it into the returned string, however, since our parser is more strict than a typical browser
52 | * parser, it's possible that some obscure input, which would be recognized as valid HTML by a
53 | * browser, won't make it through the sanitizer.
54 | * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
55 | * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
56 | *
57 | * @param {string} html Html input.
58 | * @returns {string} Sanitized html.
59 | *
60 | * @example
61 |
62 |
63 |
74 |
75 | Snippet:
76 |
77 |
78 | Directive
79 | How
80 | Source
81 | Rendered
82 |
83 |
84 | ng-bind-html
85 | Automatically uses $sanitize
86 | <div ng-bind-html="snippet"> </div>
87 |
88 |
89 |
90 | ng-bind-html
91 | Bypass $sanitize by explicitly trusting the dangerous value
92 |
93 | <div ng-bind-html="deliberatelyTrustDangerousSnippet()">
94 | </div>
95 |
96 |
97 |
98 |
99 | ng-bind
100 | Automatically escapes
101 | <div ng-bind="snippet"> </div>
102 |
103 |
104 |
105 |
106 |
107 |
108 | it('should sanitize the html snippet by default', function() {
109 | expect(using('#bind-html-with-sanitize').element('div').html()).
110 | toBe('an html\nclick here \nsnippet
');
111 | });
112 |
113 | it('should inline raw snippet if bound to a trusted value', function() {
114 | expect(using('#bind-html-with-trust').element("div").html()).
115 | toBe("an html\n" +
116 | "click here \n" +
117 | "snippet
");
118 | });
119 |
120 | it('should escape snippet without any filter', function() {
121 | expect(using('#bind-default').element('div').html()).
122 | toBe("<p style=\"color:blue\">an html\n" +
123 | "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
124 | "snippet</p>");
125 | });
126 |
127 | it('should update', function() {
128 | input('snippet').enter('new text ');
129 | expect(using('#bind-html-with-sanitize').element('div').html()).toBe('new text ');
130 | expect(using('#bind-html-with-trust').element('div').html()).toBe(
131 | 'new text ');
132 | expect(using('#bind-default').element('div').html()).toBe(
133 | "new <b onclick=\"alert(1)\">text</b>");
134 | });
135 |
136 |
137 | */
138 | function $SanitizeProvider() {
139 | this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
140 | return function(html) {
141 | var buf = [];
142 | htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
143 | return !/^unsafe/.test($$sanitizeUri(uri, isImage));
144 | }));
145 | return buf.join('');
146 | };
147 | }];
148 | }
149 |
150 | function sanitizeText(chars) {
151 | var buf = [];
152 | var writer = htmlSanitizeWriter(buf, angular.noop);
153 | writer.chars(chars);
154 | return buf.join('');
155 | }
156 |
157 |
158 | // Regular Expressions for parsing tags and attributes
159 | var START_TAG_REGEXP =
160 | /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
161 | END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
162 | ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
163 | BEGIN_TAG_REGEXP = /^,
164 | BEGING_END_TAGE_REGEXP = /^<\s*\//,
165 | COMMENT_REGEXP = //g,
166 | DOCTYPE_REGEXP = /]*?)>/i,
167 | CDATA_REGEXP = //g,
168 | // Match everything outside of normal chars and " (quote character)
169 | NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
170 |
171 |
172 | // Good source of info about elements and attributes
173 | // http://dev.w3.org/html5/spec/Overview.html#semantics
174 | // http://simon.html5.org/html-elements
175 |
176 | // Safe Void Elements - HTML5
177 | // http://dev.w3.org/html5/spec/Overview.html#void-elements
178 | var voidElements = makeMap("area,br,col,hr,img,wbr");
179 |
180 | // Elements that you can, intentionally, leave open (and which close themselves)
181 | // http://dev.w3.org/html5/spec/Overview.html#optional-tags
182 | var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
183 | optionalEndTagInlineElements = makeMap("rp,rt"),
184 | optionalEndTagElements = angular.extend({},
185 | optionalEndTagInlineElements,
186 | optionalEndTagBlockElements);
187 |
188 | // Safe Block Elements - HTML5
189 | var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
190 | "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
191 | "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
192 |
193 | // Inline Elements - HTML5
194 | var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
195 | "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
196 | "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
197 |
198 |
199 | // Special Elements (can contain anything)
200 | var specialElements = makeMap("script,style");
201 |
202 | var validElements = angular.extend({},
203 | voidElements,
204 | blockElements,
205 | inlineElements,
206 | optionalEndTagElements);
207 |
208 | //Attributes that have href and hence need to be sanitized
209 | var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
210 | var validAttrs = angular.extend({}, uriAttrs, makeMap(
211 | 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
212 | 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
213 | 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
214 | 'scope,scrolling,shape,span,start,summary,target,title,type,'+
215 | 'valign,value,vspace,width'));
216 |
217 | function makeMap(str) {
218 | var obj = {}, items = str.split(','), i;
219 | for (i = 0; i < items.length; i++) obj[items[i]] = true;
220 | return obj;
221 | }
222 |
223 |
224 | /**
225 | * @example
226 | * htmlParser(htmlString, {
227 | * start: function(tag, attrs, unary) {},
228 | * end: function(tag) {},
229 | * chars: function(text) {},
230 | * comment: function(text) {}
231 | * });
232 | *
233 | * @param {string} html string
234 | * @param {object} handler
235 | */
236 | function htmlParser( html, handler ) {
237 | var index, chars, match, stack = [], last = html;
238 | stack.last = function() { return stack[ stack.length - 1 ]; };
239 |
240 | while ( html ) {
241 | chars = true;
242 |
243 | // Make sure we're not in a script or style element
244 | if ( !stack.last() || !specialElements[ stack.last() ] ) {
245 |
246 | // Comment
247 | if ( html.indexOf("", index) === index) {
252 | if (handler.comment) handler.comment( html.substring( 4, index ) );
253 | html = html.substring( index + 3 );
254 | chars = false;
255 | }
256 | // DOCTYPE
257 | } else if ( DOCTYPE_REGEXP.test(html) ) {
258 | match = html.match( DOCTYPE_REGEXP );
259 |
260 | if ( match ) {
261 | html = html.replace( match[0] , '');
262 | chars = false;
263 | }
264 | // end tag
265 | } else if ( BEGING_END_TAGE_REGEXP.test(html) ) {
266 | match = html.match( END_TAG_REGEXP );
267 |
268 | if ( match ) {
269 | html = html.substring( match[0].length );
270 | match[0].replace( END_TAG_REGEXP, parseEndTag );
271 | chars = false;
272 | }
273 |
274 | // start tag
275 | } else if ( BEGIN_TAG_REGEXP.test(html) ) {
276 | match = html.match( START_TAG_REGEXP );
277 |
278 | if ( match ) {
279 | html = html.substring( match[0].length );
280 | match[0].replace( START_TAG_REGEXP, parseStartTag );
281 | chars = false;
282 | }
283 | }
284 |
285 | if ( chars ) {
286 | index = html.indexOf("<");
287 |
288 | var text = index < 0 ? html : html.substring( 0, index );
289 | html = index < 0 ? "" : html.substring( index );
290 |
291 | if (handler.chars) handler.chars( decodeEntities(text) );
292 | }
293 |
294 | } else {
295 | html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
296 | function(all, text){
297 | text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
298 |
299 | if (handler.chars) handler.chars( decodeEntities(text) );
300 |
301 | return "";
302 | });
303 |
304 | parseEndTag( "", stack.last() );
305 | }
306 |
307 | if ( html == last ) {
308 | throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
309 | "of html: {0}", html);
310 | }
311 | last = html;
312 | }
313 |
314 | // Clean up any remaining tags
315 | parseEndTag();
316 |
317 | function parseStartTag( tag, tagName, rest, unary ) {
318 | tagName = angular.lowercase(tagName);
319 | if ( blockElements[ tagName ] ) {
320 | while ( stack.last() && inlineElements[ stack.last() ] ) {
321 | parseEndTag( "", stack.last() );
322 | }
323 | }
324 |
325 | if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) {
326 | parseEndTag( "", tagName );
327 | }
328 |
329 | unary = voidElements[ tagName ] || !!unary;
330 |
331 | if ( !unary )
332 | stack.push( tagName );
333 |
334 | var attrs = {};
335 |
336 | rest.replace(ATTR_REGEXP,
337 | function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
338 | var value = doubleQuotedValue
339 | || singleQuotedValue
340 | || unquotedValue
341 | || '';
342 |
343 | attrs[name] = decodeEntities(value);
344 | });
345 | if (handler.start) handler.start( tagName, attrs, unary );
346 | }
347 |
348 | function parseEndTag( tag, tagName ) {
349 | var pos = 0, i;
350 | tagName = angular.lowercase(tagName);
351 | if ( tagName )
352 | // Find the closest opened tag of the same type
353 | for ( pos = stack.length - 1; pos >= 0; pos-- )
354 | if ( stack[ pos ] == tagName )
355 | break;
356 |
357 | if ( pos >= 0 ) {
358 | // Close all the open elements, up the stack
359 | for ( i = stack.length - 1; i >= pos; i-- )
360 | if (handler.end) handler.end( stack[ i ] );
361 |
362 | // Remove the open elements from the stack
363 | stack.length = pos;
364 | }
365 | }
366 | }
367 |
368 | var hiddenPre=document.createElement("pre");
369 | var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/;
370 | /**
371 | * decodes all entities into regular string
372 | * @param value
373 | * @returns {string} A string with decoded entities.
374 | */
375 | function decodeEntities(value) {
376 | if (!value) { return ''; }
377 |
378 | // Note: IE8 does not preserve spaces at the start/end of innerHTML
379 | // so we must capture them and reattach them afterward
380 | var parts = spaceRe.exec(value);
381 | var spaceBefore = parts[1];
382 | var spaceAfter = parts[3];
383 | var content = parts[2];
384 | if (content) {
385 | hiddenPre.innerHTML=content.replace(//g, '>');
411 | }
412 |
413 | /**
414 | * create an HTML/XML writer which writes to buffer
415 | * @param {Array} buf use buf.jain('') to get out sanitized html string
416 | * @returns {object} in the form of {
417 | * start: function(tag, attrs, unary) {},
418 | * end: function(tag) {},
419 | * chars: function(text) {},
420 | * comment: function(text) {}
421 | * }
422 | */
423 | function htmlSanitizeWriter(buf, uriValidator){
424 | var ignore = false;
425 | var out = angular.bind(buf, buf.push);
426 | return {
427 | start: function(tag, attrs, unary){
428 | tag = angular.lowercase(tag);
429 | if (!ignore && specialElements[tag]) {
430 | ignore = tag;
431 | }
432 | if (!ignore && validElements[tag] === true) {
433 | out('<');
434 | out(tag);
435 | angular.forEach(attrs, function(value, key){
436 | var lkey=angular.lowercase(key);
437 | var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
438 | if (validAttrs[lkey] === true &&
439 | (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
440 | out(' ');
441 | out(key);
442 | out('="');
443 | out(encodeEntities(value));
444 | out('"');
445 | }
446 | });
447 | out(unary ? '/>' : '>');
448 | }
449 | },
450 | end: function(tag){
451 | tag = angular.lowercase(tag);
452 | if (!ignore && validElements[tag] === true) {
453 | out('');
454 | out(tag);
455 | out('>');
456 | }
457 | if (tag == ignore) {
458 | ignore = false;
459 | }
460 | },
461 | chars: function(chars){
462 | if (!ignore) {
463 | out(encodeEntities(chars));
464 | }
465 | }
466 | };
467 | }
468 |
469 |
470 | // define ngSanitize module and register $sanitize service
471 | angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
472 |
473 | /* global sanitizeText: false */
474 |
475 | /**
476 | * @ngdoc filter
477 | * @name ngSanitize.filter:linky
478 | * @function
479 | *
480 | * @description
481 | * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
482 | * plain email address links.
483 | *
484 | * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
485 | *
486 | * @param {string} text Input text.
487 | * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
488 | * @returns {string} Html-linkified text.
489 | *
490 | * @usage
491 |
492 | *
493 | * @example
494 |
495 |
496 |
507 |
508 | Snippet:
509 |
510 |
511 | Filter
512 | Source
513 | Rendered
514 |
515 |
516 | linky filter
517 |
518 | <div ng-bind-html="snippet | linky"> </div>
519 |
520 |
521 |
522 |
523 |
524 |
525 | linky target
526 |
527 | <div ng-bind-html="snippetWithTarget | linky:'_blank'"> </div>
528 |
529 |
530 |
531 |
532 |
533 |
534 | no filter
535 | <div ng-bind="snippet"> </div>
536 |
537 |
538 |
539 |
540 |
541 | it('should linkify the snippet with urls', function() {
542 | expect(using('#linky-filter').binding('snippet | linky')).
543 | toBe('Pretty text with some links:
' +
544 | 'http://angularjs.org/ ,
' +
545 | 'us@somewhere.org ,
' +
546 | 'another@somewhere.org ,
' +
547 | 'and one more: ftp://127.0.0.1/ .');
548 | });
549 |
550 | it ('should not linkify snippet without the linky filter', function() {
551 | expect(using('#escaped-html').binding('snippet')).
552 | toBe("Pretty text with some links:\n" +
553 | "http://angularjs.org/,\n" +
554 | "mailto:us@somewhere.org,\n" +
555 | "another@somewhere.org,\n" +
556 | "and one more: ftp://127.0.0.1/.");
557 | });
558 |
559 | it('should update', function() {
560 | input('snippet').enter('new http://link.');
561 | expect(using('#linky-filter').binding('snippet | linky')).
562 | toBe('new http://link .');
563 | expect(using('#escaped-html').binding('snippet')).toBe('new http://link.');
564 | });
565 |
566 | it('should work with the target property', function() {
567 | expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")).
568 | toBe('http://angularjs.org/ ');
569 | });
570 |
571 |
572 | */
573 | angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
574 | var LINKY_URL_REGEXP =
575 | /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,
576 | MAILTO_REGEXP = /^mailto:/;
577 |
578 | return function(text, target) {
579 | if (!text) return text;
580 | var match;
581 | var raw = text;
582 | var html = [];
583 | var url;
584 | var i;
585 | while ((match = raw.match(LINKY_URL_REGEXP))) {
586 | // We can not end in these as they are sometimes found at the end of the sentence
587 | url = match[0];
588 | // if we did not match ftp/http/mailto then assume mailto
589 | if (match[2] == match[3]) url = 'mailto:' + url;
590 | i = match.index;
591 | addText(raw.substr(0, i));
592 | addLink(url, match[0].replace(MAILTO_REGEXP, ''));
593 | raw = raw.substring(i + match[0].length);
594 | }
595 | addText(raw);
596 | return $sanitize(html.join(''));
597 |
598 | function addText(text) {
599 | if (!text) {
600 | return;
601 | }
602 | html.push(sanitizeText(text));
603 | }
604 |
605 | function addLink(url, text) {
606 | html.push('
');
615 | addText(text);
616 | html.push(' ');
617 | }
618 | };
619 | }]);
620 |
621 |
622 | })(window, window.angular);
623 |
--------------------------------------------------------------------------------
/www/js/angular/angular-sanitize.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.4
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(p,h,q){'use strict';function E(a){var e=[];s(e,h.noop).chars(a);return e.join("")}function k(a){var e={};a=a.split(",");var d;for(d=0;d
=c;d--)e.end&&e.end(f[d]);f.length=c}}var b,g,f=[],l=a;for(f.last=function(){return f[f.length-1]};a;){g=!0;if(f.last()&&x[f.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(b,a){a=a.replace(H,"$1").replace(I,"$1");e.chars&&e.chars(r(a));return""}),c("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(e.comment&&e.comment(a.substring(4,b)),a=a.substring(b+3),g=!1);else if(y.test(a)){if(b=a.match(y))a=
8 | a.replace(b[0],""),g=!1}else if(J.test(a)){if(b=a.match(z))a=a.substring(b[0].length),b[0].replace(z,c),g=!1}else K.test(a)&&(b=a.match(A))&&(a=a.substring(b[0].length),b[0].replace(A,d),g=!1);g&&(b=a.indexOf("<"),g=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),e.chars&&e.chars(r(g)))}if(a==l)throw L("badparse",a);l=a}c()}function r(a){if(!a)return"";var e=M.exec(a);a=e[1];var d=e[3];if(e=e[2])n.innerHTML=e.replace(//g,">")}function s(a,e){var d=!1,c=h.bind(a,a.push);return{start:function(a,g,f){a=h.lowercase(a);!d&&x[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(g,function(d,f){var g=h.lowercase(f),k="img"===a&&"src"===g||"background"===g;!0!==O[g]||!0===D[g]&&!e(d,k)||(c(" "),c(f),c('="'),c(B(d)),c('"'))}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c(""),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||
10 | c(B(a))}}}var L=h.$$minErr("$sanitize"),A=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,z=/^<\s*\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^,J=/^<\s*\//,H=/\x3c!--(.*?)--\x3e/g,y=/]*?)>/i,I=/]/,d=/^mailto:/;return function(c,b){function g(a){a&&m.push(E(a))}function f(a,c){m.push("');g(c);m.push(" ")}if(!c)return c;for(var l,k=c,m=[],n,p;l=k.match(e);)n=l[0],l[2]==l[3]&&(n="mailto:"+n),p=l.index,g(k.substr(0,p)),f(n,l[0].replace(d,"")),k=k.substring(p+l[0].length);g(k);return a(m.join(""))}}])})(window,window.angular);
14 | //# sourceMappingURL=angular-sanitize.min.js.map
15 |
--------------------------------------------------------------------------------
/www/js/angular/angular-sanitize.min.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version":3,
3 | "file":"angular-sanitize.min.js",
4 | "lineCount":13,
5 | "mappings":"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",
6 | "sources":["angular-sanitize.js"],
7 | "names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","makeMap","str","obj","items","split","i","length","htmlParser","html","handler","parseStartTag","tag","tagName","rest","unary","lowercase","blockElements","stack","last","inlineElements","parseEndTag","optionalEndTagElements","voidElements","push","attrs","replace","ATTR_REGEXP","match","name","doubleQuotedValue","singleQuotedValue","unquotedValue","decodeEntities","start","pos","end","index","stack.last","specialElements","RegExp","all","text","COMMENT_REGEXP","CDATA_REGEXP","indexOf","lastIndexOf","comment","substring","DOCTYPE_REGEXP","test","BEGING_END_TAGE_REGEXP","END_TAG_REGEXP","BEGIN_TAG_REGEXP","START_TAG_REGEXP","$sanitizeMinErr","value","parts","spaceRe","exec","spaceBefore","spaceAfter","content","hiddenPre","innerHTML","textContent","innerText","encodeEntities","NON_ALPHANUMERIC_REGEXP","charCodeAt","uriValidator","ignore","out","bind","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","extend","document","createElement","module","provider","$SanitizeProvider","$get","$$sanitizeUri","uri","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","target","addText","addLink","url","isDefined","raw","substr"]
8 | }
9 |
--------------------------------------------------------------------------------
/www/js/angular/angular-touch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.2.4
3 | * (c) 2010-2014 Google, Inc. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular, undefined) {'use strict';
7 |
8 | /**
9 | * @ngdoc overview
10 | * @name ngTouch
11 | * @description
12 | *
13 | * # ngTouch
14 | *
15 | * The `ngTouch` module provides touch events and other helpers for touch-enabled devices.
16 | * The implementation is based on jQuery Mobile touch event handling
17 | * ([jquerymobile.com](http://jquerymobile.com/)).
18 | *
19 | * {@installModule touch}
20 | *
21 | * See {@link ngTouch.$swipe `$swipe`} for usage.
22 | *
23 | *
24 | *
25 | */
26 |
27 | // define ngTouch module
28 | /* global -ngTouch */
29 | var ngTouch = angular.module('ngTouch', []);
30 |
31 | /* global ngTouch: false */
32 |
33 | /**
34 | * @ngdoc object
35 | * @name ngTouch.$swipe
36 | *
37 | * @description
38 | * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe
39 | * behavior, to make implementing swipe-related directives more convenient.
40 | *
41 | * Requires the {@link ngTouch `ngTouch`} module to be installed.
42 | *
43 | * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by
44 | * `ngCarousel` in a separate component.
45 | *
46 | * # Usage
47 | * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element
48 | * which is to be watched for swipes, and an object with four handler functions. See the
49 | * documentation for `bind` below.
50 | */
51 |
52 | ngTouch.factory('$swipe', [function() {
53 | // The total distance in any direction before we make the call on swipe vs. scroll.
54 | var MOVE_BUFFER_RADIUS = 10;
55 |
56 | function getCoordinates(event) {
57 | var touches = event.touches && event.touches.length ? event.touches : [event];
58 | var e = (event.changedTouches && event.changedTouches[0]) ||
59 | (event.originalEvent && event.originalEvent.changedTouches &&
60 | event.originalEvent.changedTouches[0]) ||
61 | touches[0].originalEvent || touches[0];
62 |
63 | return {
64 | x: e.clientX,
65 | y: e.clientY
66 | };
67 | }
68 |
69 | return {
70 | /**
71 | * @ngdoc method
72 | * @name ngTouch.$swipe#bind
73 | * @methodOf ngTouch.$swipe
74 | *
75 | * @description
76 | * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an
77 | * object containing event handlers.
78 | *
79 | * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end`
80 | * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`.
81 | *
82 | * `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is
83 | * watching for `touchmove` or `mousemove` events. These events are ignored until the total
84 | * distance moved in either dimension exceeds a small threshold.
85 | *
86 | * Once this threshold is exceeded, either the horizontal or vertical delta is greater.
87 | * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow.
88 | * - If the vertical distance is greater, this is a scroll, and we let the browser take over.
89 | * A `cancel` event is sent.
90 | *
91 | * `move` is called on `mousemove` and `touchmove` after the above logic has determined that
92 | * a swipe is in progress.
93 | *
94 | * `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`.
95 | *
96 | * `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling
97 | * as described above.
98 | *
99 | */
100 | bind: function(element, eventHandlers) {
101 | // Absolute total movement, used to control swipe vs. scroll.
102 | var totalX, totalY;
103 | // Coordinates of the start position.
104 | var startCoords;
105 | // Last event's position.
106 | var lastPos;
107 | // Whether a swipe is active.
108 | var active = false;
109 |
110 | element.on('touchstart mousedown', function(event) {
111 | startCoords = getCoordinates(event);
112 | active = true;
113 | totalX = 0;
114 | totalY = 0;
115 | lastPos = startCoords;
116 | eventHandlers['start'] && eventHandlers['start'](startCoords, event);
117 | });
118 |
119 | element.on('touchcancel', function(event) {
120 | active = false;
121 | eventHandlers['cancel'] && eventHandlers['cancel'](event);
122 | });
123 |
124 | element.on('touchmove mousemove', function(event) {
125 | if (!active) return;
126 |
127 | // Android will send a touchcancel if it thinks we're starting to scroll.
128 | // So when the total distance (+ or - or both) exceeds 10px in either direction,
129 | // we either:
130 | // - On totalX > totalY, we send preventDefault() and treat this as a swipe.
131 | // - On totalY > totalX, we let the browser handle it as a scroll.
132 |
133 | if (!startCoords) return;
134 | var coords = getCoordinates(event);
135 |
136 | totalX += Math.abs(coords.x - lastPos.x);
137 | totalY += Math.abs(coords.y - lastPos.y);
138 |
139 | lastPos = coords;
140 |
141 | if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
142 | return;
143 | }
144 |
145 | // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll.
146 | if (totalY > totalX) {
147 | // Allow native scrolling to take over.
148 | active = false;
149 | eventHandlers['cancel'] && eventHandlers['cancel'](event);
150 | return;
151 | } else {
152 | // Prevent the browser from scrolling.
153 | event.preventDefault();
154 | eventHandlers['move'] && eventHandlers['move'](coords, event);
155 | }
156 | });
157 |
158 | element.on('touchend mouseup', function(event) {
159 | if (!active) return;
160 | active = false;
161 | eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);
162 | });
163 | }
164 | };
165 | }]);
166 |
167 | /* global ngTouch: false */
168 |
169 | /**
170 | * @ngdoc directive
171 | * @name ngTouch.directive:ngClick
172 | *
173 | * @description
174 | * A more powerful replacement for the default ngClick designed to be used on touchscreen
175 | * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending
176 | * the click event. This version handles them immediately, and then prevents the
177 | * following click event from propagating.
178 | *
179 | * Requires the {@link ngTouch `ngTouch`} module to be installed.
180 | *
181 | * This directive can fall back to using an ordinary click event, and so works on desktop
182 | * browsers as well as mobile.
183 | *
184 | * This directive also sets the CSS class `ng-click-active` while the element is being held
185 | * down (by a mouse click or touch) so you can restyle the depressed element if you wish.
186 | *
187 | * @element ANY
188 | * @param {expression} ngClick {@link guide/expression Expression} to evaluate
189 | * upon tap. (Event object is available as `$event`)
190 | *
191 | * @example
192 |
193 |
194 |
195 | Increment
196 |
197 | count: {{ count }}
198 |
199 |
200 | */
201 |
202 | ngTouch.config(['$provide', function($provide) {
203 | $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
204 | // drop the default ngClick directive
205 | $delegate.shift();
206 | return $delegate;
207 | }]);
208 | }]);
209 |
210 | ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
211 | function($parse, $timeout, $rootElement) {
212 | var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag.
213 | var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers.
214 | var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click
215 | var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks.
216 |
217 | var ACTIVE_CLASS_NAME = 'ng-click-active';
218 | var lastPreventedTime;
219 | var touchCoordinates;
220 |
221 |
222 | // TAP EVENTS AND GHOST CLICKS
223 | //
224 | // Why tap events?
225 | // Mobile browsers detect a tap, then wait a moment (usually ~300ms) to see if you're
226 | // double-tapping, and then fire a click event.
227 | //
228 | // This delay sucks and makes mobile apps feel unresponsive.
229 | // So we detect touchstart, touchmove, touchcancel and touchend ourselves and determine when
230 | // the user has tapped on something.
231 | //
232 | // What happens when the browser then generates a click event?
233 | // The browser, of course, also detects the tap and fires a click after a delay. This results in
234 | // tapping/clicking twice. So we do "clickbusting" to prevent it.
235 | //
236 | // How does it work?
237 | // We attach global touchstart and click handlers, that run during the capture (early) phase.
238 | // So the sequence for a tap is:
239 | // - global touchstart: Sets an "allowable region" at the point touched.
240 | // - element's touchstart: Starts a touch
241 | // (- touchmove or touchcancel ends the touch, no click follows)
242 | // - element's touchend: Determines if the tap is valid (didn't move too far away, didn't hold
243 | // too long) and fires the user's tap handler. The touchend also calls preventGhostClick().
244 | // - preventGhostClick() removes the allowable region the global touchstart created.
245 | // - The browser generates a click event.
246 | // - The global click handler catches the click, and checks whether it was in an allowable region.
247 | // - If preventGhostClick was called, the region will have been removed, the click is busted.
248 | // - If the region is still there, the click proceeds normally. Therefore clicks on links and
249 | // other elements without ngTap on them work normally.
250 | //
251 | // This is an ugly, terrible hack!
252 | // Yeah, tell me about it. The alternatives are using the slow click events, or making our users
253 | // deal with the ghost clicks, so I consider this the least of evils. Fortunately Angular
254 | // encapsulates this ugly logic away from the user.
255 | //
256 | // Why not just put click handlers on the element?
257 | // We do that too, just to be sure. The problem is that the tap event might have caused the DOM
258 | // to change, so that the click fires in the same position but something else is there now. So
259 | // the handlers are global and care only about coordinates and not elements.
260 |
261 | // Checks if the coordinates are close enough to be within the region.
262 | function hit(x1, y1, x2, y2) {
263 | return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD;
264 | }
265 |
266 | // Checks a list of allowable regions against a click location.
267 | // Returns true if the click should be allowed.
268 | // Splices out the allowable region from the list after it has been used.
269 | function checkAllowableRegions(touchCoordinates, x, y) {
270 | for (var i = 0; i < touchCoordinates.length; i += 2) {
271 | if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) {
272 | touchCoordinates.splice(i, i + 2);
273 | return true; // allowable region
274 | }
275 | }
276 | return false; // No allowable region; bust it.
277 | }
278 |
279 | // Global click handler that prevents the click if it's in a bustable zone and preventGhostClick
280 | // was called recently.
281 | function onClick(event) {
282 | if (Date.now() - lastPreventedTime > PREVENT_DURATION) {
283 | return; // Too old.
284 | }
285 |
286 | var touches = event.touches && event.touches.length ? event.touches : [event];
287 | var x = touches[0].clientX;
288 | var y = touches[0].clientY;
289 | // Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label
290 | // and on the input element). Depending on the exact browser, this second click we don't want
291 | // to bust has either (0,0) or negative coordinates.
292 | if (x < 1 && y < 1) {
293 | return; // offscreen
294 | }
295 |
296 | // Look for an allowable region containing this click.
297 | // If we find one, that means it was created by touchstart and not removed by
298 | // preventGhostClick, so we don't bust it.
299 | if (checkAllowableRegions(touchCoordinates, x, y)) {
300 | return;
301 | }
302 |
303 | // If we didn't find an allowable region, bust the click.
304 | event.stopPropagation();
305 | event.preventDefault();
306 |
307 | // Blur focused form elements
308 | event.target && event.target.blur();
309 | }
310 |
311 |
312 | // Global touchstart handler that creates an allowable region for a click event.
313 | // This allowable region can be removed by preventGhostClick if we want to bust it.
314 | function onTouchStart(event) {
315 | var touches = event.touches && event.touches.length ? event.touches : [event];
316 | var x = touches[0].clientX;
317 | var y = touches[0].clientY;
318 | touchCoordinates.push(x, y);
319 |
320 | $timeout(function() {
321 | // Remove the allowable region.
322 | for (var i = 0; i < touchCoordinates.length; i += 2) {
323 | if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) {
324 | touchCoordinates.splice(i, i + 2);
325 | return;
326 | }
327 | }
328 | }, PREVENT_DURATION, false);
329 | }
330 |
331 | // On the first call, attaches some event handlers. Then whenever it gets called, it creates a
332 | // zone around the touchstart where clicks will get busted.
333 | function preventGhostClick(x, y) {
334 | if (!touchCoordinates) {
335 | $rootElement[0].addEventListener('click', onClick, true);
336 | $rootElement[0].addEventListener('touchstart', onTouchStart, true);
337 | touchCoordinates = [];
338 | }
339 |
340 | lastPreventedTime = Date.now();
341 |
342 | checkAllowableRegions(touchCoordinates, x, y);
343 | }
344 |
345 | // Actual linking function.
346 | return function(scope, element, attr) {
347 | var clickHandler = $parse(attr.ngClick),
348 | tapping = false,
349 | tapElement, // Used to blur the element after a tap.
350 | startTime, // Used to check if the tap was held too long.
351 | touchStartX,
352 | touchStartY;
353 |
354 | function resetState() {
355 | tapping = false;
356 | element.removeClass(ACTIVE_CLASS_NAME);
357 | }
358 |
359 | element.on('touchstart', function(event) {
360 | tapping = true;
361 | tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement.
362 | // Hack for Safari, which can target text nodes instead of containers.
363 | if(tapElement.nodeType == 3) {
364 | tapElement = tapElement.parentNode;
365 | }
366 |
367 | element.addClass(ACTIVE_CLASS_NAME);
368 |
369 | startTime = Date.now();
370 |
371 | var touches = event.touches && event.touches.length ? event.touches : [event];
372 | var e = touches[0].originalEvent || touches[0];
373 | touchStartX = e.clientX;
374 | touchStartY = e.clientY;
375 | });
376 |
377 | element.on('touchmove', function(event) {
378 | resetState();
379 | });
380 |
381 | element.on('touchcancel', function(event) {
382 | resetState();
383 | });
384 |
385 | element.on('touchend', function(event) {
386 | var diff = Date.now() - startTime;
387 |
388 | var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches :
389 | ((event.touches && event.touches.length) ? event.touches : [event]);
390 | var e = touches[0].originalEvent || touches[0];
391 | var x = e.clientX;
392 | var y = e.clientY;
393 | var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) );
394 |
395 | if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) {
396 | // Call preventGhostClick so the clickbuster will catch the corresponding click.
397 | preventGhostClick(x, y);
398 |
399 | // Blur the focused element (the button, probably) before firing the callback.
400 | // This doesn't work perfectly on Android Chrome, but seems to work elsewhere.
401 | // I couldn't get anything to work reliably on Android Chrome.
402 | if (tapElement) {
403 | tapElement.blur();
404 | }
405 |
406 | if (!angular.isDefined(attr.disabled) || attr.disabled === false) {
407 | element.triggerHandler('click', [event]);
408 | }
409 | }
410 |
411 | resetState();
412 | });
413 |
414 | // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
415 | // something else nearby.
416 | element.onclick = function(event) { };
417 |
418 | // Actual click handler.
419 | // There are three different kinds of clicks, only two of which reach this point.
420 | // - On desktop browsers without touch events, their clicks will always come here.
421 | // - On mobile browsers, the simulated "fast" click will call this.
422 | // - But the browser's follow-up slow click will be "busted" before it reaches this handler.
423 | // Therefore it's safe to use this directive on both mobile and desktop.
424 | element.on('click', function(event, touchend) {
425 | scope.$apply(function() {
426 | clickHandler(scope, {$event: (touchend || event)});
427 | });
428 | });
429 |
430 | element.on('mousedown', function(event) {
431 | element.addClass(ACTIVE_CLASS_NAME);
432 | });
433 |
434 | element.on('mousemove mouseup', function(event) {
435 | element.removeClass(ACTIVE_CLASS_NAME);
436 | });
437 |
438 | };
439 | }]);
440 |
441 | /* global ngTouch: false */
442 |
443 | /**
444 | * @ngdoc directive
445 | * @name ngTouch.directive:ngSwipeLeft
446 | *
447 | * @description
448 | * Specify custom behavior when an element is swiped to the left on a touchscreen device.
449 | * A leftward swipe is a quick, right-to-left slide of the finger.
450 | * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag
451 | * too.
452 | *
453 | * Requires the {@link ngTouch `ngTouch`} module to be installed.
454 | *
455 | * @element ANY
456 | * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
457 | * upon left swipe. (Event object is available as `$event`)
458 | *
459 | * @example
460 |
461 |
462 |
463 | Some list content, like an email in the inbox
464 |
465 |
466 | Reply
467 | Delete
468 |
469 |
470 |
471 | */
472 |
473 | /**
474 | * @ngdoc directive
475 | * @name ngTouch.directive:ngSwipeRight
476 | *
477 | * @description
478 | * Specify custom behavior when an element is swiped to the right on a touchscreen device.
479 | * A rightward swipe is a quick, left-to-right slide of the finger.
480 | * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag
481 | * too.
482 | *
483 | * Requires the {@link ngTouch `ngTouch`} module to be installed.
484 | *
485 | * @element ANY
486 | * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate
487 | * upon right swipe. (Event object is available as `$event`)
488 | *
489 | * @example
490 |
491 |
492 |
493 | Some list content, like an email in the inbox
494 |
495 |
496 | Reply
497 | Delete
498 |
499 |
500 |
501 | */
502 |
503 | function makeSwipeDirective(directiveName, direction, eventName) {
504 | ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) {
505 | // The maximum vertical delta for a swipe should be less than 75px.
506 | var MAX_VERTICAL_DISTANCE = 75;
507 | // Vertical distance should not be more than a fraction of the horizontal distance.
508 | var MAX_VERTICAL_RATIO = 0.3;
509 | // At least a 30px lateral motion is necessary for a swipe.
510 | var MIN_HORIZONTAL_DISTANCE = 30;
511 |
512 | return function(scope, element, attr) {
513 | var swipeHandler = $parse(attr[directiveName]);
514 |
515 | var startCoords, valid;
516 |
517 | function validSwipe(coords) {
518 | // Check that it's within the coordinates.
519 | // Absolute vertical distance must be within tolerances.
520 | // Horizontal distance, we take the current X - the starting X.
521 | // This is negative for leftward swipes and positive for rightward swipes.
522 | // After multiplying by the direction (-1 for left, +1 for right), legal swipes
523 | // (ie. same direction as the directive wants) will have a positive delta and
524 | // illegal ones a negative delta.
525 | // Therefore this delta must be positive, and larger than the minimum.
526 | if (!startCoords) return false;
527 | var deltaY = Math.abs(coords.y - startCoords.y);
528 | var deltaX = (coords.x - startCoords.x) * direction;
529 | return valid && // Short circuit for already-invalidated swipes.
530 | deltaY < MAX_VERTICAL_DISTANCE &&
531 | deltaX > 0 &&
532 | deltaX > MIN_HORIZONTAL_DISTANCE &&
533 | deltaY / deltaX < MAX_VERTICAL_RATIO;
534 | }
535 |
536 | $swipe.bind(element, {
537 | 'start': function(coords, event) {
538 | startCoords = coords;
539 | valid = true;
540 | },
541 | 'cancel': function(event) {
542 | valid = false;
543 | },
544 | 'end': function(coords, event) {
545 | if (validSwipe(coords)) {
546 | scope.$apply(function() {
547 | element.triggerHandler(eventName);
548 | swipeHandler(scope, {$event: event});
549 | });
550 | }
551 | }
552 | });
553 | };
554 | }]);
555 | }
556 |
557 | // Left is negative X-coordinate, right is positive.
558 | makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft');
559 | makeSwipeDirective('ngSwipeRight', 1, 'swiperight');
560 |
561 |
562 |
563 | })(window, window.angular);
564 |
--------------------------------------------------------------------------------
/www/js/angular/angular-touch.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.4
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(y,v,z){'use strict';function t(g,a,b){q.directive(g,["$parse","$swipe",function(l,n){var r=75,h=0.3,d=30;return function(p,m,k){function e(e){if(!u)return!1;var c=Math.abs(e.y-u.y);e=(e.x-u.x)*a;return f&&cd&&c/el&&10>n||
8 | (n>l?(d=!1,b.cancel&&b.cancel(a)):(a.preventDefault(),b.move&&b.move(m,a)))}});a.on("touchend mouseup",function(a){d&&(d=!1,b.end&&b.end(g(a),a))})}}}]);q.config(["$provide",function(g){g.decorator("ngClickDirective",["$delegate",function(a){a.shift();return a}])}]);q.directive("ngClick",["$parse","$timeout","$rootElement",function(g,a,b){function l(a,c,b){for(var f=0;fh)){var c=
9 | a.touches&&a.touches.length?a.touches:[a],b=c[0].clientX,c=c[0].clientY;1>b&&1>c||l(k,b,c)||(a.stopPropagation(),a.preventDefault(),a.target&&a.target.blur())}}function r(b){b=b.touches&&b.touches.length?b.touches:[b];var c=b[0].clientX,d=b[0].clientY;k.push(c,d);a(function(){for(var a=0;ah&&12>p)&&(k||(b[0].addEventListener("click",n,!0),b[0].addEventListener("touchstart",r,!0),k=[]),m=Date.now(),l(k,e,g),s&&s.blur(),v.isDefined(d.disabled)&&!1!==d.disabled||c.triggerHandler("click",[a]));f()});c.onclick=function(a){};c.on("click",function(b,c){a.$apply(function(){h(a,{$event:c||b})})});c.on("mousedown",function(a){c.addClass(p)});c.on("mousemove mouseup",function(a){c.removeClass(p)})}}]);t("ngSwipeLeft",-1,"swipeleft");t("ngSwipeRight",1,"swiperight")})(window,
12 | window.angular);
13 | //# sourceMappingURL=angular-touch.min.js.map
14 |
--------------------------------------------------------------------------------
/www/js/angular/angular-touch.min.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version":3,
3 | "file":"angular-touch.min.js",
4 | "lineCount":12,
5 | "mappings":"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",
6 | "sources":["angular-touch.js"],
7 | "names":["window","angular","undefined","makeSwipeDirective","directiveName","direction","eventName","ngTouch","directive","$parse","$swipe","MAX_VERTICAL_DISTANCE","MAX_VERTICAL_RATIO","MIN_HORIZONTAL_DISTANCE","scope","element","attr","validSwipe","coords","startCoords","deltaY","Math","abs","y","deltaX","x","valid","swipeHandler","bind","start","event","cancel","end","$apply","triggerHandler","module","factory","getCoordinates","touches","length","e","changedTouches","originalEvent","clientX","clientY","eventHandlers","totalX","totalY","lastPos","active","on","MOVE_BUFFER_RADIUS","preventDefault","config","$provide","decorator","$delegate","shift","$timeout","$rootElement","checkAllowableRegions","touchCoordinates","i","x1","CLICKBUSTER_THRESHOLD","y1","splice","onClick","Date","now","lastPreventedTime","PREVENT_DURATION","stopPropagation","target","blur","onTouchStart","push","ACTIVE_CLASS_NAME","resetState","tapping","removeClass","clickHandler","ngClick","tapElement","startTime","touchStartX","touchStartY","srcElement","nodeType","parentNode","addClass","diff","dist","sqrt","pow","TAP_DURATION","MOVE_TOLERANCE","addEventListener","isDefined","disabled","onclick","element.onclick","touchend"]
8 | }
9 |
--------------------------------------------------------------------------------
/www/js/angular/errors.json:
--------------------------------------------------------------------------------
1 | {"id":"ng","generated":"Fri Dec 06 2013 13:49:28 GMT-0500 (EST)","errors":{"$cacheFactory":{"iid":"CacheId '{0}' is already taken!"},"ngModel":{"nonassign":"Expression '{0}' is non-assignable. Element: {1}"},"$sce":{"iequirks":"Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks mode. You can fix this by adding the text to the top of your HTML document. See http://docs.angularjs.org/api/ng.$sce for more information.","insecurl":"Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}","icontext":"Attempted to trust a value in invalid context. Context: {0}; Value: {1}","imatcher":"Matchers may only be \"self\", string patterns or RegExp objects","iwcard":"Illegal sequence *** in string matcher. String: {0}","itype":"Attempted to trust a non-string value in a content requiring a string: Context: {0}","unsafe":"Attempting to use an unsafe value in a safe context."},"$controller":{"noscp":"Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`."},"$compile":{"nodomevents":"Interpolations for HTML DOM event attributes are disallowed. Please use the ng- versions (such as ng-click instead of onclick) instead.","multidir":"Multiple directives [{0}, {1}] asking for {2} on: {3}","nonassign":"Expression '{0}' used with directive '{1}' is non-assignable!","tplrt":"Template for directive '{0}' must have exactly one root element. {1}","selmulti":"Binding to the 'multiple' attribute is not supported. Element: {0}","tpload":"Failed to load template: {0}","iscp":"Invalid isolate scope definition for directive '{0}'. Definition: {... {1}: '{2}' ...}","ctreq":"Controller '{0}', required by directive '{1}', can't be found!","uterdir":"Unterminated attribute, found '{0}' but no matching '{1}' found."},"$injector":{"modulerr":"Failed to instantiate module {0} due to:\n{1}","unpr":"Unknown provider: {0}","itkn":"Incorrect injection token! Expected service name as string, got {0}","cdep":"Circular dependency found: {0}","nomod":"Module '{0}' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.","pget":"Provider '{0}' must define $get factory method."},"$rootScope":{"inprog":"{0} already in progress","infdig":"{0} $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: {1}"},"ngPattern":{"noregexp":"Expected {0} to be a RegExp but was {1}. Element: {2}"},"$interpolate":{"noconcat":"Error while interpolating: {0}\nStrict Contextual Escaping disallows interpolations that concatenate multiple expressions when a trusted value is required. See http://docs.angularjs.org/api/ng.$sce","interr":"Can't interpolate: {0}\n{1}"},"jqLite":{"offargs":"jqLite#off() does not support the `selector` argument","onargs":"jqLite#on() does not support the `selector` or `eventData` parameters","nosel":"Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element"},"ngOptions":{"iexp":"Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}"},"ngRepeat":{"iidexp":"'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.","dupes":"Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}","iexp":"Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'."},"ng":{"areq":"Argument '{0}' is {1}","cpws":"Can't copy! Making copies of Window or Scope instances is not supported.","badname":"hasOwnProperty is not a valid {0} name","btstrpd":"App Already Bootstrapped with this Element '{0}'","cpi":"Can't copy! Source and destination are identical."},"$animate":{"notcsel":"Expecting class selector starting with '.' got '{0}'."},"ngTransclude":{"orphan":"Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element: {0}"},"$parse":{"isecfld":"Referencing \"constructor\" field in Angular expressions is disallowed! Expression: {0}","syntax":"Syntax Error: Token '{0}' {1} at column {2} of the expression [{3}] starting at [{4}].","isecdom":"Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}","lexerr":"Lexer Error: {0} at column{1} in expression [{2}].","ueoe":"Unexpected end of expression: {0}","isecwindow":"Referencing the Window in Angular expressions is disallowed! Expression: {0}","isecfn":"Referencing Function in Angular expressions is disallowed! Expression: {0}"},"$httpBackend":{"noxhr":"This browser does not support XMLHttpRequest."},"$location":{"ipthprfx":"Invalid url \"{0}\", missing path prefix \"{1}\".","isrcharg":"The first argument of the `$location#search()` call must be a string or an object.","ihshprfx":"Invalid url \"{0}\", missing hash prefix \"{1}\"."},"$resource":{"badargs":"Expected up to 4 arguments [params, data, success, error], got {0} arguments","badmember":"Dotted member path \"@{0}\" is invalid.","badcfg":"Error in resource configuration. Expected response to contain an {0} but got an {1}","badname":"hasOwnProperty is not a valid parameter name."},"$sanitize":{"badparse":"The sanitizer was unable to parse the following block of html: {0}"}}}
--------------------------------------------------------------------------------
/www/js/angular/version.json:
--------------------------------------------------------------------------------
1 | {"full":"1.2.4","major":"1","minor":"2","dot":"4","codename":"wormhole-baster","cdn":"1.2.3"}
--------------------------------------------------------------------------------
/www/js/angular/version.txt:
--------------------------------------------------------------------------------
1 | 1.2.4
--------------------------------------------------------------------------------
/www/js/app.js:
--------------------------------------------------------------------------------
1 | // angular.module is a global place for creating, registering and retrieving Angular modules
2 | // 'starter' is the name of this angular module example (also set in a attribute in index.html)
3 | // the 2nd parameter is an array or 'requires'
4 | // 'starter.services' is found in services.js
5 | // 'starter.controllers' is found in controllers.js
6 | angular.module('starter', ['ionic', 'ngRoute', 'ngAnimate', 'starter.services', 'starter.controllers'])
7 |
8 | .config(function ($compileProvider){
9 | // Needed for routing to work
10 | $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
11 | })
12 |
13 | .config(function($routeProvider, $locationProvider) {
14 |
15 | // Set up the initial routes that our app will respond to.
16 | // These are then tied up to our nav router which animates and
17 | // updates a navigation bar
18 | $routeProvider.when('/home', {
19 | templateUrl: 'templates/app.html',
20 | controller: 'AppCtrl'
21 | });
22 |
23 | // if the url matches something like /pet/2 then this route
24 | // will fire off the PetCtrl controller (controllers.js)
25 | $routeProvider.when('/pet/:petId', {
26 | templateUrl: 'templates/pet.html',
27 | controller: 'PetCtrl'
28 | });
29 |
30 | // if none of the above routes are met, use this fallback
31 | // which executes the 'AppCtrl' controller (controllers.js)
32 | $routeProvider.otherwise({
33 | redirectTo: '/home'
34 | });
35 |
36 | });
37 |
38 |
--------------------------------------------------------------------------------
/www/js/controllers.js:
--------------------------------------------------------------------------------
1 | angular.module('starter.controllers', [])
2 |
3 | .controller('AppCtrl', function($scope) {
4 | // Main app controller, empty for the example
5 | })
6 |
7 | // A simple controller that fetches a list of data
8 | .controller('PetsTabCtrl', function($scope, Pets) {
9 | // "Pets" is a service returning mock data (services.js)
10 | $scope.pets = Pets.all();
11 |
12 | $scope.$on('tab.shown', function() {
13 | // Might do a load here
14 | });
15 | $scope.$on('tab.hidden', function() {
16 | // Might recycle content here
17 | });
18 | })
19 |
20 | // A simple controller that shows a tapped item's data
21 | .controller('PetCtrl', function($scope, $routeParams, Pets) {
22 | // "Pets" is a service returning mock data (services.js)
23 | $scope.pet = Pets.get($routeParams.petId);
24 | });
25 |
--------------------------------------------------------------------------------
/www/js/services.js:
--------------------------------------------------------------------------------
1 | angular.module('starter.services', [])
2 |
3 | /**
4 | * A simple example service that returns some data.
5 | */
6 | .factory('Pets', function() {
7 | // Might use a resource here that returns a JSON array
8 |
9 | // Some fake testing data
10 | var pets = [
11 | { id: 0, title: 'Cats', description: 'Furry little creatures. Obsessed with plotting assassination, but never following through on it.' },
12 | { id: 1, title: 'Dogs', description: 'Lovable. Loyal almost to a fault. Smarter than they let on.' },
13 | { id: 2, title: 'Turtles', description: 'Everyone likes turtles.' },
14 | { id: 3, title: 'Sharks', description: 'An advanced pet. Needs millions of gallons of salt water. Will happily eat you.' }
15 | ];
16 |
17 | return {
18 | all: function() {
19 | return pets;
20 | },
21 | get: function(petId) {
22 | // Simple index lookup
23 | return pets[petId];
24 | }
25 | }
26 | });
27 |
--------------------------------------------------------------------------------
/www/res/icon/android/icon-36-ldpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/android/icon-36-ldpi.png
--------------------------------------------------------------------------------
/www/res/icon/android/icon-48-mdpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/android/icon-48-mdpi.png
--------------------------------------------------------------------------------
/www/res/icon/android/icon-72-hdpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/android/icon-72-hdpi.png
--------------------------------------------------------------------------------
/www/res/icon/android/icon-96-xhdpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/android/icon-96-xhdpi.png
--------------------------------------------------------------------------------
/www/res/icon/bada-wac/icon-48-type5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/bada-wac/icon-48-type5.png
--------------------------------------------------------------------------------
/www/res/icon/bada-wac/icon-50-type3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/bada-wac/icon-50-type3.png
--------------------------------------------------------------------------------
/www/res/icon/bada-wac/icon-80-type4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/bada-wac/icon-80-type4.png
--------------------------------------------------------------------------------
/www/res/icon/bada/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/bada/icon-128.png
--------------------------------------------------------------------------------
/www/res/icon/blackberry/icon-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/blackberry/icon-80.png
--------------------------------------------------------------------------------
/www/res/icon/ios/icon-57-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/ios/icon-57-2x.png
--------------------------------------------------------------------------------
/www/res/icon/ios/icon-57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/ios/icon-57.png
--------------------------------------------------------------------------------
/www/res/icon/ios/icon-72-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/ios/icon-72-2x.png
--------------------------------------------------------------------------------
/www/res/icon/ios/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/ios/icon-72.png
--------------------------------------------------------------------------------
/www/res/icon/tizen/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/tizen/icon-128.png
--------------------------------------------------------------------------------
/www/res/icon/webos/icon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/webos/icon-64.png
--------------------------------------------------------------------------------
/www/res/icon/windows-phone/icon-173-tile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/windows-phone/icon-173-tile.png
--------------------------------------------------------------------------------
/www/res/icon/windows-phone/icon-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/windows-phone/icon-48.png
--------------------------------------------------------------------------------
/www/res/icon/windows-phone/icon-62-tile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/icon/windows-phone/icon-62-tile.png
--------------------------------------------------------------------------------
/www/res/screen/android/screen-hdpi-landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/android/screen-hdpi-landscape.png
--------------------------------------------------------------------------------
/www/res/screen/android/screen-hdpi-portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/android/screen-hdpi-portrait.png
--------------------------------------------------------------------------------
/www/res/screen/android/screen-ldpi-landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/android/screen-ldpi-landscape.png
--------------------------------------------------------------------------------
/www/res/screen/android/screen-ldpi-portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/android/screen-ldpi-portrait.png
--------------------------------------------------------------------------------
/www/res/screen/android/screen-mdpi-landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/android/screen-mdpi-landscape.png
--------------------------------------------------------------------------------
/www/res/screen/android/screen-mdpi-portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/android/screen-mdpi-portrait.png
--------------------------------------------------------------------------------
/www/res/screen/android/screen-xhdpi-landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/android/screen-xhdpi-landscape.png
--------------------------------------------------------------------------------
/www/res/screen/android/screen-xhdpi-portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/android/screen-xhdpi-portrait.png
--------------------------------------------------------------------------------
/www/res/screen/bada-wac/screen-type3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/bada-wac/screen-type3.png
--------------------------------------------------------------------------------
/www/res/screen/bada-wac/screen-type4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/bada-wac/screen-type4.png
--------------------------------------------------------------------------------
/www/res/screen/bada-wac/screen-type5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/bada-wac/screen-type5.png
--------------------------------------------------------------------------------
/www/res/screen/bada/screen-portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/bada/screen-portrait.png
--------------------------------------------------------------------------------
/www/res/screen/blackberry/screen-225.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/blackberry/screen-225.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-ipad-landscape-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-ipad-landscape-2x.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-ipad-landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-ipad-landscape.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-ipad-portrait-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-ipad-portrait-2x.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-ipad-portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-ipad-portrait.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-iphone-landscape-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-iphone-landscape-2x.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-iphone-landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-iphone-landscape.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-iphone-portrait-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-iphone-portrait-2x.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-iphone-portrait-568h-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-iphone-portrait-568h-2x.png
--------------------------------------------------------------------------------
/www/res/screen/ios/screen-iphone-portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/ios/screen-iphone-portrait.png
--------------------------------------------------------------------------------
/www/res/screen/tizen/README.md:
--------------------------------------------------------------------------------
1 | # Tizen Splash Screen
2 |
3 | Splash screens are unsupported on the Tizen platform.
4 |
--------------------------------------------------------------------------------
/www/res/screen/webos/screen-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/webos/screen-64.png
--------------------------------------------------------------------------------
/www/res/screen/windows-phone/screen-portrait.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic-intro/484f0ec4da051940fb30383ded9aa7f3e6fac736/www/res/screen/windows-phone/screen-portrait.jpg
--------------------------------------------------------------------------------
/www/templates/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{pet.title}}
16 | {{pet.description}}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
Adopt a pet today.
28 |
29 |
30 |
31 | Your name
32 |
33 |
34 |
35 | Your email
36 |
37 |
38 |
39 |
40 |
41 | Adopt
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | About this app
50 |
51 | This is a sample seed project for the Ionic Framework. Please change it to match your needs.
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/www/templates/pet.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | {{ pet.description }}
10 |
11 |
--------------------------------------------------------------------------------