├── .gitignore
├── LICENSE
├── README.rst
├── aurelia-f7-todo
├── .babelrc
├── README.rst
├── app
│ ├── app.html
│ ├── app.js
│ ├── main.js
│ ├── pages
│ │ ├── list-todos
│ │ │ ├── list-todos.html
│ │ │ └── list-todos.js
│ │ └── todo
│ │ │ ├── todo.html
│ │ │ └── todo.js
│ └── services
│ │ ├── f7.js
│ │ └── storage.js
├── config.xml
├── hooks
│ └── README.md
├── index.html
├── index.prod.html
├── package.json
├── styles
│ └── style.css
├── webpack.config.js
├── webpack.prod.config.js
└── www
│ └── index.html
├── aurelia-ux-todo
├── .editorconfig
├── .gitignore
├── assets
│ ├── aurelia-icon-128x128.png
│ ├── css
│ │ └── font-awesome.min.css
│ └── fonts
│ │ ├── FontAwesome.otf
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.svg
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ └── fontawesome-webfont.woff2
├── aurelia_project
│ ├── aurelia.json
│ ├── environments
│ │ ├── dev.ts
│ │ ├── prod.ts
│ │ └── stage.ts
│ ├── generators
│ │ ├── attribute.json
│ │ ├── attribute.ts
│ │ ├── binding-behavior.json
│ │ ├── binding-behavior.ts
│ │ ├── element.json
│ │ ├── element.ts
│ │ ├── generator.json
│ │ ├── generator.ts
│ │ ├── task.json
│ │ ├── task.ts
│ │ ├── value-converter.json
│ │ └── value-converter.ts
│ └── tasks
│ │ ├── build.json
│ │ ├── build.ts
│ │ ├── process-css.ts
│ │ ├── process-markup.ts
│ │ ├── run.json
│ │ ├── run.ts
│ │ ├── test.json
│ │ ├── test.ts
│ │ ├── transpile.ts
│ │ └── update-ux.ts
├── custom_typings
│ └── aurelia-protractor.d.ts
├── favicon.ico
├── index.html
├── karma.conf.js
├── package-lock.json
├── package.json
├── scripts
│ ├── require.js
│ └── text.js
├── src
│ ├── app.css
│ ├── app.html
│ ├── app.ts
│ ├── common.css
│ ├── environment.ts
│ ├── main.ts
│ ├── models
│ │ └── todo.ts
│ ├── pages
│ │ ├── edit.html
│ │ ├── edit.ts
│ │ ├── list.html
│ │ └── list.ts
│ ├── reset.css
│ ├── routes.ts
│ └── services
│ │ └── storage.ts
├── test
│ ├── aurelia-karma.js
│ └── unit
│ │ ├── app.spec.ts
│ │ └── setup.ts
├── tsconfig.json
├── tslint.json
└── typings.json
└── ionic2-todo
├── README.rst
├── app
├── app.ts
├── models.ts
├── pages
│ ├── list-todos
│ │ ├── list-todos.html
│ │ ├── list-todos.scss
│ │ └── list-todos.ts
│ └── todo
│ │ ├── todo.html
│ │ └── todo.ts
└── theme
│ ├── app.core.scss
│ ├── app.ios.scss
│ ├── app.md.scss
│ ├── app.variables.scss
│ └── app.wp.scss
├── config.xml
├── gulpfile.js
├── hooks
├── README.md
└── after_prepare
│ └── 010_add_platform_class.js
├── ionic.config.js
├── package.json
├── resources
├── android
│ ├── icon
│ │ ├── drawable-hdpi-icon.png
│ │ ├── drawable-ldpi-icon.png
│ │ ├── drawable-mdpi-icon.png
│ │ ├── drawable-xhdpi-icon.png
│ │ ├── drawable-xxhdpi-icon.png
│ │ └── drawable-xxxhdpi-icon.png
│ └── splash
│ │ ├── drawable-land-hdpi-screen.png
│ │ ├── drawable-land-ldpi-screen.png
│ │ ├── drawable-land-mdpi-screen.png
│ │ ├── drawable-land-xhdpi-screen.png
│ │ ├── drawable-land-xxhdpi-screen.png
│ │ ├── drawable-land-xxxhdpi-screen.png
│ │ ├── drawable-port-hdpi-screen.png
│ │ ├── drawable-port-ldpi-screen.png
│ │ ├── drawable-port-mdpi-screen.png
│ │ ├── drawable-port-xhdpi-screen.png
│ │ ├── drawable-port-xxhdpi-screen.png
│ │ └── drawable-port-xxxhdpi-screen.png
├── icon.png
├── ios
│ ├── icon
│ │ ├── icon-40.png
│ │ ├── icon-40@2x.png
│ │ ├── icon-50.png
│ │ ├── icon-50@2x.png
│ │ ├── icon-60.png
│ │ ├── icon-60@2x.png
│ │ ├── icon-60@3x.png
│ │ ├── icon-72.png
│ │ ├── icon-72@2x.png
│ │ ├── icon-76.png
│ │ ├── icon-76@2x.png
│ │ ├── icon-small.png
│ │ ├── icon-small@2x.png
│ │ ├── icon-small@3x.png
│ │ ├── icon.png
│ │ └── icon@2x.png
│ └── splash
│ │ ├── Default-568h@2x~iphone.png
│ │ ├── Default-667h.png
│ │ ├── Default-736h.png
│ │ ├── Default-Landscape-736h.png
│ │ ├── Default-Landscape@2x~ipad.png
│ │ ├── Default-Landscape~ipad.png
│ │ ├── Default-Portrait@2x~ipad.png
│ │ ├── Default-Portrait~ipad.png
│ │ ├── Default@2x~iphone.png
│ │ └── Default~iphone.png
└── splash.png
├── tsconfig.json
├── typings.json
├── webpack.config.js
└── www
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | # Specifies files to intentionally ignore when using Git
2 | # http://git-scm.com/docs/gitignore
3 |
4 | node_modules/
5 | ionic2-todo/www/build/
6 | aurelia-f7-todo/www/
7 | platforms/
8 | plugins/
9 | typings
10 | ionic.project
11 | *.swp
12 | .DS_Store
13 | Thumbs.db
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Julien Enselme
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, 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,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | This repository contains my comparison of Ionic2/Angular2 and Aurelia/Framework7
2 | to build mobile hybrid applications. The ionic2 app is in the *ionic2-todo*
3 | folder and the Aurelia app is in *aurelia-f7-todo*. Both applications are basic
4 | todo list applications that can:
5 |
6 | - List all the saved todos (home page)
7 | - Edit an existing todo
8 | - Add a todo
9 | - Mark a todo as done on the home page. Done todos must have their title
10 | strike-through on the home page.
11 |
12 | All todos must be stored in the permanent SqlStorage of the phone.
13 |
14 | In additions to these features, both applications must work on a browser (for
15 | debug and development purposes), on an android emulator and on an android
16 | phone.
17 |
18 | See the README file in each subfolder to know how to launch and install the
19 | applications and what features they have.
20 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-1"],
3 | "plugins": ["transform-decorators-legacy"]
4 | }
5 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/README.rst:
--------------------------------------------------------------------------------
1 | Requiremts
2 | ==========
3 |
4 | - cordova
5 | - webpack
6 | - webpack-dev-server
7 |
8 |
9 | Setup
10 | =====
11 |
12 | - Install node dependencies: ``npm install``
13 |
14 |
15 | Run in browser
16 | ==============
17 |
18 | - Launch ``npm run dev`` to launch the webpack debug server (with live reload).
19 |
20 |
21 | Build for android
22 | =================
23 |
24 | - Add platform: ``cordova platform add browser``
25 | - Add platform: ``cordova platform add android``
26 | - Run on browser (with cordova for debug): ``cardova run browser``
27 | - Build for phone: ``cordova build android``
28 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Left panel content goes here
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
Aurelia + F7 TODO Application
22 |
23 |
24 |
25 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/app.js:
--------------------------------------------------------------------------------
1 | export class App {
2 | configureRouter(config, router) {
3 | config.title = 'Aurelia';
4 | config.map([
5 | {
6 | route: ['', 'todos'],
7 | name: 'todos',
8 | moduleId: 'pages/list-todos/list-todos',
9 | nav: true,
10 | title: 'todos'
11 | }, {
12 | route: ['todo', 'todo/:id'],
13 | name: 'todo',
14 | moduleId: 'pages/todo/todo',
15 | nav: true,
16 | title: 'View Todo',
17 | }
18 | ]);
19 |
20 | this.router = router;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/main.js:
--------------------------------------------------------------------------------
1 | import {bootstrap} from 'aurelia-bootstrapper-webpack';
2 |
3 | import 'framework7/dist/css/framework7.material.css'
4 | import 'framework7/dist/css/framework7.material.colors.css'
5 | import 'framework7/dist/js/framework7.js'
6 | import '../styles/style.css';
7 |
8 |
9 | bootstrap(function (aurelia) {
10 | aurelia.use
11 | .standardConfiguration()
12 | .plugin('aurelia-validation')
13 | .developmentLogging();
14 |
15 | aurelia.start().then(() => aurelia.setRoot('app', document.body));
16 | });
17 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/pages/list-todos/list-todos.html:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
16 |
17 |
20 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/pages/list-todos/list-todos.js:
--------------------------------------------------------------------------------
1 | import { Storage } from '../../services/storage';
2 | import { F7 } from '../../services/f7';
3 | import {inject} from 'aurelia-framework';
4 | import { Router } from 'aurelia-router';
5 |
6 |
7 | @inject(F7, Router, Storage)
8 | export class ListTodosPage {
9 | heading = 'Welcome to the Aurelia Framework 7 TODO App';
10 |
11 | constructor(f7, router, storage) {
12 | this.f7 = f7;
13 | this.router = router;
14 | this.storage = storage;
15 | this.todos = [];
16 |
17 | this.storage.getTodos().then(todos => this.todos = todos);
18 | }
19 |
20 | viewTodo(todo) {
21 | this.router.navigateToRoute('todo', {id: todo.id});
22 | }
23 |
24 | addTodo() {
25 | this.router.navigate('/todo');
26 | }
27 |
28 | toggleDone(todo, event) {
29 | event.stopPropagation();
30 |
31 | if (todo.done === true || todo.done === 'true') {
32 | todo.done = 'false';
33 | } else {
34 | todo.done = 'true';
35 | }
36 |
37 | this.storage.saveTodo(todo);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/pages/todo/todo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 | Title
9 | ${errorInfo.error.message}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | -
18 |
19 |
20 |
Description
21 |
22 |
23 |
24 |
25 |
26 |
27 | -
28 |
39 |
40 |
41 |
42 |
43 |
53 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/pages/todo/todo.js:
--------------------------------------------------------------------------------
1 | import { inject, ObserverLocator } from 'aurelia-framework';
2 | import { Router } from 'aurelia-router';
3 | import { ValidationControllerFactory, ValidationRules, Validator, validateTrigger } from 'aurelia-validation';
4 |
5 | import { Storage } from '../../services/storage';
6 |
7 |
8 | /**
9 | * Custom validator that complies with the Validator interface:
10 | * https://github.com/aurelia/validation/blob/master/src/validator.ts
11 | */
12 | class TodoValidator {
13 | constructor(validator, cb) {
14 | this.validator = validator;
15 | this.cb = cb;
16 | }
17 |
18 | /**
19 | * This method will be called by the controller when validating a specific field. For instance,
20 | * when the user is interacting with the title input. So, we need to validate the whole form
21 | * and call our callback in order for TodoPage.canSave to be correctly updated.
22 | */
23 | validateProperty(object, propertyName, rules) {
24 | let validationDefered = this.validator.validateProperty(object, propertyName, rules);
25 | validationDefered.then(() => this.validateObject(object, rules));
26 |
27 | return validationDefered;
28 | }
29 |
30 | /**
31 | * Each time the whole form is validated, we call the registered callback to do whatever
32 | * the user wants to do with the results of the validation. In our case: update
33 | * TodoPage.canSave.
34 | */
35 | validateObject(object, rules) {
36 | return this.validator.validateObject(object, rules).then(results => {
37 | this.cb(results);
38 | return results;
39 | });
40 | }
41 |
42 | /**
43 | * Implemented so the interface is complete.
44 | */
45 | ruleExists(rules, rule) {
46 | return this.validator(rules, rule);
47 | }
48 | }
49 |
50 |
51 | @inject(Router, Storage, ValidationControllerFactory, Validator, ObserverLocator)
52 | export class TodoPage {
53 | constructor(router, storage, controllerFactory, validator, ol) {
54 | this.router = router;
55 | this.storage = storage;
56 |
57 | this.validator = new TodoValidator(validator, results => this.updateCanSave(results));
58 | this.controller = controllerFactory.createForCurrentScope(this.validator);
59 | this.controller.validateTrigger = validateTrigger.changeOrBlur;
60 |
61 | // We don't know if we can save. This will be updated when the view is activated (the form
62 | // should be valid if we are editing an existing todo but invalid if we are creating a
63 | // new one).
64 | this.canSave = false;
65 | }
66 |
67 | activate(params) {
68 | if (params.id) {
69 | // In this case, we are editing a TODO. We fetch it from the storage and assign it to
70 | // the todo property. We can then setup validation on this property. If we had set it
71 | // up in the constructor, validation would become uneffective: we replaced the object
72 | // in this.todo by another one. ValidationRules.on is not tracking the right object.
73 | // Once this is done, we setup validation and validate the form so this.canSave is
74 | // true if the edited TODO is valid. If the user modifies the TODO, then the
75 | // controller will handle the validation and this.canSave will be updated accordingly.
76 | this.storage.getTodo(params.id)
77 | .then(todo => this.todo = todo)
78 | .then(() => {
79 | this.setupValidation();
80 | this.validate();
81 | });
82 | } else {
83 | // We are creating a new todo. We just need to initialize this.todo and validation.
84 | this.todo = {};
85 | this.setupValidation();
86 | }
87 | }
88 |
89 | setupValidation() {
90 | ValidationRules
91 | .ensure('title').required().minLength(3).withMessage('Title must at least be 3 chars long.')
92 | .on(this.todo);
93 | }
94 |
95 | validate() {
96 | this.validator.validateObject(this.todo);
97 | }
98 |
99 | updateCanSave(validationResults) {
100 | let valid = true;
101 |
102 | for (let result of validationResults) {
103 | valid = valid && result.valid;
104 | }
105 |
106 | this.canSave = valid;
107 | }
108 |
109 | saveTodo() {
110 | this.storage.saveTodo(this.todo)
111 | .then(() => this.router.navigateToRoute('todos'));
112 | }
113 |
114 | cancel() {
115 | this.router.navigateToRoute('todos');
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/services/f7.js:
--------------------------------------------------------------------------------
1 | import 'framework7';
2 |
3 |
4 | export const F7 = new Framework7({
5 | material: true,
6 | });
7 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/app/services/storage.js:
--------------------------------------------------------------------------------
1 | import * as localforage from '../../node_modules/localforage/dist/localforage.js';
2 |
3 |
4 | export class Storage {
5 | constructor() {
6 | this.storage = localforage;
7 | }
8 |
9 | getTodos() {
10 | return this.storage.getItem('todos')
11 | .then(todos => JSON.parse(todos))
12 | .then(todos => todos ? todos : []);
13 | }
14 |
15 | saveTodo(todo) {
16 | let prepareTodos;
17 | if (!todo.id) {
18 | prepareTodos = this.getTodos()
19 | .then(todos => {
20 | todo.id = todos.length;
21 | todos.push(todo);
22 | return todos;
23 | });
24 | } else {
25 | prepareTodos = this.getTodos()
26 | .then(todos => {
27 | let index = todo.id;
28 | todos[index] = todo;
29 |
30 | return todos;
31 | });
32 | }
33 |
34 | return prepareTodos.then(todos => this.storage.setItem('todos', JSON.stringify(todos)));
35 | }
36 |
37 | getTodo(id) {
38 | return this.getTodos()
39 | .then(todos => todos[id]);
40 | }
41 | }
--------------------------------------------------------------------------------
/aurelia-f7-todo/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Aurelia F7 TODO
4 |
5 | A sample Apache Cordova application made with Aurelia and Framework 7.
6 |
7 |
8 | Julien Enselme
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/hooks/README.md:
--------------------------------------------------------------------------------
1 |
21 | # Cordova Hooks
22 |
23 | Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. See Hooks Guide for more details: http://cordova.apache.org/docs/en/edge/guide_appdev_hooks_index.md.html#Hooks%20Guide.
24 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | TODO Application
11 |
12 |
13 |
14 |
15 |
Aurelia Navigation Skeleton
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/index.prod.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Aurelia
5 |
6 |
7 |
8 |
9 |
Aurelia Navigation Skeleton
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aurelia-f7-todo",
3 | "version": "0.1.0",
4 | "description": "A starter kit for building a standard navigation-style app with Aurelia and webpack.",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "webpack-dev-server --config webpack.config.js --inline --progress --devtool eval",
8 | "build": "webpack --config webpack.config.js --progress --profile",
9 | "build-android": "webpack -p --config webpack.prod.config.js --progress && cordova build android",
10 | "test": "karma start"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+ssh://git@github.com/aurelia/skeleton-navigation.git"
15 | },
16 | "keywords": [
17 | "aurelia",
18 | "skeleton",
19 | "navigation",
20 | "webpack"
21 | ],
22 | "author": "Julien Enselme",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/aurelia/skeleton-navigation/issues"
26 | },
27 | "homepage": "https://github.com/aurelia/skeleton-navigation#readme",
28 | "aurelia": {
29 | "build": {
30 | "moduleRootOverride": {
31 | "aurelia-templating-resources": "dist/commonjs"
32 | }
33 | }
34 | },
35 | "dependencies": {
36 | "aurelia-bootstrapper-webpack": "1.1.0",
37 | "aurelia-event-aggregator": "1.0.1",
38 | "aurelia-fetch-client": "1.1.0",
39 | "aurelia-framework": "1.0.8",
40 | "aurelia-history-browser": "1.0.0",
41 | "aurelia-logging-console": "1.0.0",
42 | "aurelia-pal-browser": "1.1.0",
43 | "aurelia-polyfills": "1.1.1",
44 | "aurelia-router": "1.1.1",
45 | "aurelia-templating-binding": "1.2.0",
46 | "aurelia-templating-resources": "1.2.0",
47 | "aurelia-templating-router": "1.0.1",
48 | "aurelia-validation": "1.0.0-beta.1.0.1",
49 | "bootstrap": "3.3.7",
50 | "font-awesome": "4.7.0",
51 | "framework7": "1.5.2",
52 | "isomorphic-fetch": "^2.2.1",
53 | "localforage": "1.4.3"
54 | },
55 | "devDependencies": {
56 | "aurelia-tools": "1.0.0",
57 | "aurelia-webpack-plugin": "1.2.0",
58 | "babel-core": "6.22.1",
59 | "babel-eslint": "7.1.1",
60 | "babel-plugin-syntax-flow": "6.18.0",
61 | "babel-plugin-transform-decorators-legacy": "1.3.4",
62 | "babel-plugin-transform-es2015-modules-amd": "6.8.0",
63 | "babel-plugin-transform-es2015-modules-commonjs": "6.18.0",
64 | "babel-plugin-transform-flow-strip-types": "6.18.0",
65 | "babel-polyfill": "6.16.0",
66 | "babel-preset-es2015": "6.18.0",
67 | "babel-preset-es2015-loose": "8.0.0",
68 | "babel-preset-stage-1": "6.16.0",
69 | "babel-register": "6.18.0",
70 | "babel-runtime": "6.18.0",
71 | "babel-loader": "6.2.10",
72 | "css-loader": "0.26.1",
73 | "eslint": "3.14.0",
74 | "file-loader": "0.9.0",
75 | "html-webpack-plugin": "2.26.0",
76 | "jasmine-core": "2.5.2",
77 | "karma": "1.4.0",
78 | "karma-babel-preprocessor": "6.0.1",
79 | "karma-chrome-launcher": "2.0.0",
80 | "karma-jasmine": "^1.1.0",
81 | "karma-webpack": "2.0.1",
82 | "protractor": "5.0.0",
83 | "html-loader": "^0.4.4",
84 | "raw-loader": "0.5.1",
85 | "style-loader": "0.13.1",
86 | "url-loader": "0.5.7",
87 | "webpack": "3.0.0",
88 | "webpack-dev-server": "2.5.0"
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/styles/style.css:
--------------------------------------------------------------------------------
1 | .navbar .center {
2 | margin: auto;
3 | }
4 |
5 | .done {
6 | text-decoration: line-through;
7 | }
8 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/webpack.config.js:
--------------------------------------------------------------------------------
1 | /*eslint-disable no-var*/
2 |
3 | var path = require('path');
4 | var AureliaWebpackPlugin = require('aurelia-webpack-plugin');
5 |
6 | module.exports = {
7 | devServer: {
8 | host: 'localhost',
9 | port: 3000
10 | },
11 | entry: {
12 | main: [
13 | './app/main'
14 | ]
15 | },
16 | output: {
17 | path: path.join(__dirname, 'build'),
18 | filename: 'bundle.js'
19 | },
20 | plugins: [
21 | new AureliaWebpackPlugin({
22 | src: path.resolve('./app/'),
23 | })
24 | ],
25 | module: {
26 | loaders: [
27 | { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
28 | { test: /\.css?$/, use: [{loader: 'style-loader'}, {loader: 'css-loader'}] },
29 | { test: /\.html$/, loader: 'html-loader' },
30 | { test: /\.(png|gif|jpg)$/, loader: 'url-loader?limit=8192' },
31 | { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff2' },
32 | { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff' },
33 | { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader' }
34 | ]
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/webpack.prod.config.js:
--------------------------------------------------------------------------------
1 | /*eslint-disable no-var*/
2 |
3 | var path = require('path');
4 | var HtmlWebpackPlugin = require('html-webpack-plugin');
5 | var AureliaWebpackPlugin = require('aurelia-webpack-plugin');
6 | var pkg = require('./package.json');
7 |
8 | var outputFileTemplateSuffix = '-' + pkg.version;
9 |
10 | module.exports = {
11 | entry: {
12 | main: [
13 | './app/main'
14 | ]
15 | },
16 | output: {
17 | path: path.join(__dirname, 'www/'),
18 | filename: 'bundle.js',
19 | },
20 | plugins: [
21 | new AureliaWebpackPlugin({
22 | src: path.resolve('./app/'),
23 | }),
24 | ],
25 | resolve: {
26 | root: [
27 | path.resolve('./')
28 | ]
29 | },
30 | module: {
31 | loaders: [
32 | { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
33 | { test: /\.css?$/, use: [{loader: 'style-loader'}, {loader: 'css-loader'}] },
34 | { test: /\.html$/, loader: 'html-loader' },
35 | { test: /\.(png|gif|jpg)$/, loader: 'url-loader?limit=8192' },
36 | { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff2' },
37 | { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff' },
38 | { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader' }
39 | ]
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/aurelia-f7-todo/www/index.html:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | TODO Application
41 |
42 |
43 |
44 |
45 |
Aurelia Navigation Skeleton
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
11 | # 2 space indentation
12 | [**.*]
13 | indent_style = space
14 | indent_size = 2
--------------------------------------------------------------------------------
/aurelia-ux-todo/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
3 | .DS_STORE
4 | scripts/*
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/assets/aurelia-icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jenselme/tests-ionic2-and-aurelia-framework7/fea62c4f7cda6d99045a90af81971d448d4c68ad/aurelia-ux-todo/assets/aurelia-icon-128x128.png
--------------------------------------------------------------------------------
/aurelia-ux-todo/assets/css/font-awesome.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/assets/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jenselme/tests-ionic2-and-aurelia-framework7/fea62c4f7cda6d99045a90af81971d448d4c68ad/aurelia-ux-todo/assets/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/aurelia-ux-todo/assets/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jenselme/tests-ionic2-and-aurelia-framework7/fea62c4f7cda6d99045a90af81971d448d4c68ad/aurelia-ux-todo/assets/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/aurelia-ux-todo/assets/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jenselme/tests-ionic2-and-aurelia-framework7/fea62c4f7cda6d99045a90af81971d448d4c68ad/aurelia-ux-todo/assets/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/aurelia-ux-todo/assets/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jenselme/tests-ionic2-and-aurelia-framework7/fea62c4f7cda6d99045a90af81971d448d4c68ad/aurelia-ux-todo/assets/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/aurelia-ux-todo/assets/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jenselme/tests-ionic2-and-aurelia-framework7/fea62c4f7cda6d99045a90af81971d448d4c68ad/aurelia-ux-todo/assets/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/aurelia.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app-ux-showcase",
3 | "type": "project:application",
4 | "platform": {
5 | "id": "web",
6 | "displayName": "Web",
7 | "output": "scripts",
8 | "index": "index.html"
9 | },
10 | "transpiler": {
11 | "id": "typescript",
12 | "displayName": "TypeScript",
13 | "fileExtension": ".ts",
14 | "dtsSource": [
15 | "./typings/**/*.d.ts",
16 | "./custom_typings/**/*.d.ts"
17 | ],
18 | "source": "src/**/*.ts"
19 | },
20 | "markupProcessor": {
21 | "id": "none",
22 | "displayName": "None",
23 | "fileExtension": ".html",
24 | "source": "src/**/*.html"
25 | },
26 | "cssProcessor": {
27 | "id": "none",
28 | "displayName": "None",
29 | "fileExtension": ".css",
30 | "source": "src/**/*.css"
31 | },
32 | "editor": {
33 | "id": "vscode",
34 | "displayName": "Visual Studio Code"
35 | },
36 | "unitTestRunner": {
37 | "id": "karma",
38 | "displayName": "Karma",
39 | "source": "test/unit/**/*.ts"
40 | },
41 | "paths": {
42 | "root": "src",
43 | "resources": "src/resources",
44 | "elements": "src/resources/elements",
45 | "attributes": "src/resources/attributes",
46 | "valueConverters": "src/resources/value-converters",
47 | "bindingBehaviors": "src/resources/binding-behaviors"
48 | },
49 | "testFramework": {
50 | "id": "jasmine",
51 | "displayName": "Jasmine"
52 | },
53 | "build": {
54 | "targets": [
55 | {
56 | "id": "web",
57 | "displayName": "Web",
58 | "output": "scripts",
59 | "index": "index.html"
60 | }
61 | ],
62 | "loader": {
63 | "type": "require",
64 | "configTarget": "vendor-bundle.js",
65 | "includeBundleMetadataInConfig": "auto",
66 | "plugins": [
67 | {
68 | "name": "text",
69 | "extensions": [
70 | ".html",
71 | ".css"
72 | ],
73 | "stub": true
74 | }
75 | ]
76 | },
77 | "options": {
78 | "minify": "stage & prod",
79 | "sourcemaps": "dev & stage"
80 | },
81 | "bundles": [
82 | {
83 | "name": "app-bundle.js",
84 | "source": [
85 | "[**/*.js]",
86 | "**/*.{css,html}"
87 | ]
88 | },
89 | {
90 | "name": "vendor-bundle.js",
91 | "prepend": [
92 | "node_modules/bluebird/js/browser/bluebird.core.js",
93 | "scripts/require.js"
94 | ],
95 | "dependencies": [
96 | "aurelia-binding",
97 | "aurelia-bootstrapper",
98 | "aurelia-dependency-injection",
99 | "aurelia-event-aggregator",
100 | "aurelia-framework",
101 | "aurelia-history",
102 | "aurelia-history-browser",
103 | "aurelia-loader",
104 | "aurelia-loader-default",
105 | "aurelia-logging",
106 | "aurelia-logging-console",
107 | "aurelia-metadata",
108 | "aurelia-pal",
109 | "aurelia-pal-browser",
110 | "aurelia-path",
111 | "aurelia-polyfills",
112 | "aurelia-route-recognizer",
113 | "aurelia-router",
114 | "aurelia-task-queue",
115 | "aurelia-templating",
116 | "aurelia-templating-binding",
117 | {
118 | "name": "text",
119 | "path": "../scripts/text"
120 | },
121 | {
122 | "name": "aurelia-templating-resources",
123 | "path": "../node_modules/aurelia-templating-resources/dist/amd",
124 | "main": "aurelia-templating-resources"
125 | },
126 | {
127 | "name": "aurelia-templating-router",
128 | "path": "../node_modules/aurelia-templating-router/dist/amd",
129 | "main": "aurelia-templating-router"
130 | },
131 | {
132 | "name": "aurelia-testing",
133 | "path": "../node_modules/aurelia-testing/dist/amd",
134 | "main": "aurelia-testing",
135 | "env": "dev"
136 | },
137 | {
138 | "name": "aurelia-validation",
139 | "path": "../node_modules/aurelia-validation/dist/amd",
140 | "main": "aurelia-validation"
141 | },
142 | {
143 | "name": "aurelia-ux",
144 | "path": "../node_modules/aurelia-ux/dist/amd",
145 | "main": "index",
146 | "resources": ["**/*.{css,html}"]
147 | }
148 | ]
149 | }
150 | ]
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/environments/dev.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | debug: true,
3 | testing: true
4 | };
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/environments/prod.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | debug: false,
3 | testing: false
4 | };
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/environments/stage.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | debug: true,
3 | testing: false
4 | };
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/attribute.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "attribute",
3 | "description": "Creates a custom attribute class and places it in the project resources."
4 | }
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/attribute.ts:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli';
3 |
4 | @inject(Project, CLIOptions, UI)
5 | export default class AttributeGenerator {
6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { }
7 |
8 | execute() {
9 | return this.ui
10 | .ensureAnswer(this.options.args[0], 'What would you like to call the custom attribute?')
11 | .then(name => {
12 | let fileName = this.project.makeFileName(name);
13 | let className = this.project.makeClassName(name);
14 |
15 | this.project.attributes.add(
16 | ProjectItem.text(`${fileName}.ts`, this.generateSource(className))
17 | );
18 |
19 | return this.project.commitChanges()
20 | .then(() => this.ui.log(`Created ${fileName}.`));
21 | });
22 | }
23 |
24 | generateSource(className) {
25 | return `import {autoinject} from 'aurelia-framework';
26 |
27 | @autoinject()
28 | export class ${className}CustomAttribute {
29 | constructor(private element: Element) { }
30 |
31 | valueChanged(newValue, oldValue) {
32 |
33 | }
34 | }
35 |
36 | `
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/binding-behavior.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "binding-behavior",
3 | "description": "Creates a binding behavior class and places it in the project resources."
4 | }
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/binding-behavior.ts:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli';
3 |
4 | @inject(Project, CLIOptions, UI)
5 | export default class BindingBehaviorGenerator {
6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { }
7 |
8 | execute() {
9 | return this.ui
10 | .ensureAnswer(this.options.args[0], 'What would you like to call the binding behavior?')
11 | .then(name => {
12 | let fileName = this.project.makeFileName(name);
13 | let className = this.project.makeClassName(name);
14 |
15 | this.project.bindingBehaviors.add(
16 | ProjectItem.text(`${fileName}.ts`, this.generateSource(className))
17 | );
18 |
19 | return this.project.commitChanges()
20 | .then(() => this.ui.log(`Created ${fileName}.`));
21 | });
22 | }
23 |
24 | generateSource(className) {
25 | return `export class ${className}BindingBehavior {
26 | bind(binding, source) {
27 |
28 | }
29 |
30 | unbind(binding, source) {
31 |
32 | }
33 | }
34 |
35 | `
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/element.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "element",
3 | "description": "Creates a custom element class and template, placing them in the project resources."
4 | }
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/element.ts:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli';
3 |
4 | @inject(Project, CLIOptions, UI)
5 | export default class ElementGenerator {
6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { }
7 |
8 | execute() {
9 | return this.ui
10 | .ensureAnswer(this.options.args[0], 'What would you like to call the custom element?')
11 | .then(name => {
12 | let fileName = this.project.makeFileName(name);
13 | let className = this.project.makeClassName(name);
14 |
15 | this.project.elements.add(
16 | ProjectItem.text(`${fileName}.ts`, this.generateJSSource(className)),
17 | ProjectItem.text(`${fileName}.html`, this.generateHTMLSource(className))
18 | );
19 |
20 | return this.project.commitChanges()
21 | .then(() => this.ui.log(`Created ${fileName}.`));
22 | });
23 | }
24 |
25 | generateJSSource(className) {
26 | return `import {bindable} from 'aurelia-framework';
27 |
28 | export class ${className} {
29 | @bindable value;
30 |
31 | valueChanged(newValue, oldValue) {
32 |
33 | }
34 | }
35 |
36 | `
37 | }
38 |
39 | generateHTMLSource(className) {
40 | return `
41 | \${value}
42 | `
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "generator",
3 | "description": "Creates a generator class and places it in the project generators folder."
4 | }
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/generator.ts:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli';
3 |
4 | @inject(Project, CLIOptions, UI)
5 | export default class GeneratorGenerator {
6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { }
7 |
8 | execute() {
9 | return this.ui
10 | .ensureAnswer(this.options.args[0], 'What would you like to call the generator?')
11 | .then(name => {
12 | let fileName = this.project.makeFileName(name);
13 | let className = this.project.makeClassName(name);
14 |
15 | this.project.generators.add(
16 | ProjectItem.text(`${fileName}.ts`, this.generateSource(className))
17 | );
18 |
19 | return this.project.commitChanges()
20 | .then(() => this.ui.log(`Created ${fileName}.`));
21 | });
22 | }
23 |
24 | generateSource(className) {
25 | return `import {autoinject} from 'aurelia-dependency-injection';
26 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli';
27 |
28 | @autoinject()
29 | export default class ${className}Generator {
30 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { }
31 |
32 | execute() {
33 | return this.ui
34 | .ensureAnswer(this.options.args[0], 'What would you like to call the new item?')
35 | .then(name => {
36 | let fileName = this.project.makeFileName(name);
37 | let className = this.project.makeClassName(name);
38 |
39 | this.project.elements.add(
40 | ProjectItem.text(\`\${fileName}.js\`, this.generateSource(className))
41 | );
42 |
43 | return this.project.commitChanges()
44 | .then(() => this.ui.log(\`Created \${fileName}.\`));
45 | });
46 | }
47 |
48 | generateSource(className) {
49 | return \`import {bindable} from 'aurelia-framework';
50 |
51 | export class \${className} {
52 | @bindable value;
53 |
54 | valueChanged(newValue, oldValue) {
55 |
56 | }
57 | }
58 |
59 | \`
60 | }
61 | }
62 |
63 | `
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/task.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task",
3 | "description": "Creates a task and places it in the project tasks folder."
4 | }
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/task.ts:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli';
3 |
4 | @inject(Project, CLIOptions, UI)
5 | export default class TaskGenerator {
6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { }
7 |
8 | execute() {
9 | return this.ui
10 | .ensureAnswer(this.options.args[0], 'What would you like to call the task?')
11 | .then(name => {
12 | let fileName = this.project.makeFileName(name);
13 | let functionName = this.project.makeFunctionName(name);
14 |
15 | this.project.tasks.add(
16 | ProjectItem.text(`${fileName}.ts`, this.generateSource(functionName))
17 | );
18 |
19 | return this.project.commitChanges()
20 | .then(() => this.ui.log(`Created ${fileName}.`));
21 | });
22 | }
23 |
24 | generateSource(functionName) {
25 | return `import * as gulp from 'gulp';
26 | import * as changed from 'gulp-changed';
27 | import * as project from '../aurelia.json';
28 |
29 | export default function ${functionName}() {
30 | return gulp.src(project.paths.???)
31 | .pipe(changed(project.paths.output, {extension: '.???'}))
32 | .pipe(gulp.dest(project.paths.output));
33 | }
34 |
35 | `
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/value-converter.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "value-converter",
3 | "description": "Creates a value converter class and places it in the project resources."
4 | }
5 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/generators/value-converter.ts:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-dependency-injection';
2 | import {Project, ProjectItem, CLIOptions, UI} from 'aurelia-cli';
3 |
4 | @inject(Project, CLIOptions, UI)
5 | export default class ValueConverterGenerator {
6 | constructor(private project: Project, private options: CLIOptions, private ui: UI) { }
7 |
8 | execute() {
9 | return this.ui
10 | .ensureAnswer(this.options.args[0], 'What would you like to call the value converter?')
11 | .then(name => {
12 | let fileName = this.project.makeFileName(name);
13 | let className = this.project.makeClassName(name);
14 |
15 | this.project.valueConverters.add(
16 | ProjectItem.text(`${fileName}.ts`, this.generateSource(className))
17 | );
18 |
19 | return this.project.commitChanges()
20 | .then(() => this.ui.log(`Created ${fileName}.`));
21 | });
22 | }
23 |
24 | generateSource(className) {
25 | return `export class ${className}ValueConverter {
26 | toView(value) {
27 |
28 | }
29 |
30 | fromView(value) {
31 |
32 | }
33 | }
34 |
35 | `
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build",
3 | "description": "Builds and processes all application assets.",
4 | "flags": [
5 | {
6 | "name": "env",
7 | "description": "Sets the build environment.",
8 | "type": "string"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/build.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import transpile from './transpile';
3 | import processMarkup from './process-markup';
4 | import processCSS from './process-css';
5 | import {build} from 'aurelia-cli';
6 | import * as project from '../aurelia.json';
7 |
8 | export default gulp.series(
9 | readProjectConfiguration,
10 | gulp.parallel(
11 | transpile,
12 | processMarkup,
13 | processCSS
14 | ),
15 | writeBundles
16 | );
17 |
18 | function readProjectConfiguration() {
19 | return build.src(project);
20 | }
21 |
22 | function writeBundles() {
23 | return build.dest();
24 | }
25 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/process-css.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as changedInPlace from 'gulp-changed-in-place';
3 | import * as project from '../aurelia.json';
4 | import {build} from 'aurelia-cli';
5 |
6 | export default function processCSS() {
7 | return gulp.src(project.cssProcessor.source)
8 | .pipe(changedInPlace({firstPass:true}))
9 | .pipe(build.bundle());
10 | };
11 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/process-markup.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as changedInPlace from 'gulp-changed-in-place';
3 | import * as project from '../aurelia.json';
4 | import {build} from 'aurelia-cli';
5 |
6 | export default function processMarkup() {
7 | return gulp.src(project.markupProcessor.source)
8 | .pipe(changedInPlace({firstPass:true}))
9 | .pipe(build.bundle());
10 | }
11 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/run.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "run",
3 | "description": "Builds the application and serves up the assets via a local web server, watching files for changes as you work.",
4 | "flags": [
5 | {
6 | "name": "env",
7 | "description": "Sets the build environment.",
8 | "type": "string"
9 | },
10 | {
11 | "name": "watch",
12 | "description": "Watches source files for changes and refreshes the app automatically.",
13 | "type": "boolean"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/run.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as browserSync from 'browser-sync';
3 | import * as historyApiFallback from 'connect-history-api-fallback/lib';
4 | import * as project from '../aurelia.json';
5 | import build from './build';
6 | import {CLIOptions} from 'aurelia-cli';
7 |
8 | function onChange(path) {
9 | console.log(`File Changed: ${path}`);
10 | }
11 |
12 | function reload(done) {
13 | browserSync.reload();
14 | done();
15 | }
16 |
17 | let serve = gulp.series(
18 | build,
19 | done => {
20 | browserSync({
21 | online: false,
22 | open: false,
23 | port: 9000,
24 | logLevel: 'silent',
25 | server: {
26 | baseDir: ['.'],
27 | middleware: [historyApiFallback(), function(req, res, next) {
28 | res.setHeader('Access-Control-Allow-Origin', '*');
29 | next();
30 | }]
31 | }
32 | }, function (err, bs) {
33 | let urls = bs.options.get('urls').toJS();
34 | console.log(`Application Available At: ${urls.local}`);
35 | console.log(`BrowserSync Available At: ${urls.ui}`);
36 | done();
37 | });
38 | }
39 | );
40 |
41 | let refresh = gulp.series(
42 | build,
43 | reload
44 | );
45 |
46 | let watch = function() {
47 | gulp.watch(project.transpiler.source, refresh).on('change', onChange);
48 | gulp.watch(project.markupProcessor.source, refresh).on('change', onChange);
49 | gulp.watch(project.cssProcessor.source, refresh).on('change', onChange);
50 | }
51 |
52 | let run;
53 |
54 | if (CLIOptions.hasFlag('watch')) {
55 | run = gulp.series(
56 | serve,
57 | watch
58 | );
59 | } else {
60 | run = serve;
61 | }
62 |
63 | export default run;
64 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test",
3 | "description": "Runs all unit tests and reports the results.",
4 | "flags": [
5 | {
6 | "name": "env",
7 | "description": "Sets the build environment.",
8 | "type": "string"
9 | },
10 | {
11 | "name": "watch",
12 | "description": "Watches test files for changes and re-runs the tests automatically.",
13 | "type": "boolean"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/test.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import {Server as Karma} from 'karma';
3 | import {CLIOptions} from 'aurelia-cli';
4 |
5 | export function unit(done) {
6 | new Karma({
7 | configFile: __dirname + '/../../karma.conf.js',
8 | singleRun: !CLIOptions.hasFlag('watch')
9 | }, done).start();
10 | }
11 |
12 | export default unit;
13 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/transpile.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as changedInPlace from 'gulp-changed-in-place';
3 | import * as plumber from 'gulp-plumber';
4 | import * as sourcemaps from 'gulp-sourcemaps';
5 | import * as notify from 'gulp-notify';
6 | import * as rename from 'gulp-rename';
7 | import * as ts from 'gulp-typescript';
8 | import * as project from '../aurelia.json';
9 | import {CLIOptions, build} from 'aurelia-cli';
10 | import * as eventStream from 'event-stream';
11 |
12 | function configureEnvironment() {
13 | let env = CLIOptions.getEnvironment();
14 |
15 | return gulp.src(`aurelia_project/environments/${env}.ts`)
16 | .pipe(changedInPlace({firstPass:true}))
17 | .pipe(rename('environment.ts'))
18 | .pipe(gulp.dest(project.paths.root));
19 | }
20 |
21 | var typescriptCompiler = typescriptCompiler || null;
22 |
23 | function buildTypeScript() {
24 | if(!typescriptCompiler) {
25 | typescriptCompiler = ts.createProject('tsconfig.json', {
26 | "typescript": require('typescript')
27 | });
28 | }
29 |
30 | let dts = gulp.src(project.transpiler.dtsSource);
31 |
32 | let src = gulp.src(project.transpiler.source)
33 | .pipe(changedInPlace({firstPass: true}));
34 |
35 | return eventStream.merge(dts, src)
36 | .pipe(plumber({ errorHandler: notify.onError('Error: <%= error.message %>') }))
37 | .pipe(sourcemaps.init())
38 | .pipe(ts(typescriptCompiler))
39 | .pipe(build.bundle());
40 | }
41 |
42 | export default gulp.series(
43 | configureEnvironment,
44 | buildTypeScript
45 | );
46 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/aurelia_project/tasks/update-ux.ts:
--------------------------------------------------------------------------------
1 | import * as fs from 'fs';
2 | import * as path from 'path';
3 |
4 | function mkdir(dir) {
5 | // making directory without exception if exists
6 | try {
7 | fs.mkdirSync(dir);
8 | } catch(e) {
9 | if(e.code != "EEXIST") {
10 | throw e;
11 | }
12 | }
13 | };
14 |
15 | function copyDir(src, dest) {
16 | try{
17 | mkdir(dest);
18 | let files = fs.readdirSync(src);
19 | for(let i = 0; i < files.length; i++) {
20 | let current = fs.lstatSync(path.join(src, files[i]));
21 | if(current.isDirectory()) {
22 | copyDir(path.join(src, files[i]), path.join(dest, files[i]));
23 | } else if(current.isSymbolicLink()) {
24 | let symlink = fs.readlinkSync(path.join(src, files[i]));
25 | fs.symlinkSync(symlink, path.join(dest, files[i]));
26 | } else {
27 | copy(path.join(src, files[i]), path.join(dest, files[i]));
28 | }
29 | }
30 | } catch(error){
31 | console.log(error);
32 | }
33 | };
34 |
35 | function copy(src, dest) {
36 | var oldFile = fs.createReadStream(src);
37 | var newFile = fs.createWriteStream(dest);
38 | console.log(`Copying from ${src} to ${dest}.`);
39 | oldFile.pipe(newFile);
40 | };
41 |
42 | export default function updateUX() {
43 | copyDir('../ux/dist/amd', './node_modules/aurelia-ux/dist/amd/')
44 | }
45 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/custom_typings/aurelia-protractor.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for Aurelia Protractor extensions
2 | // Project: https://github.com/aurelia/skeleton-navigation
3 | // Definitions by: Enrapt , Kirill Grishin
4 |
5 | // Extend existing interfaces with additional functionality from Aurelia Protractor Extender (aurelia.protractor.js)
6 |
7 | declare module protractor {
8 | interface IBrowser extends protractor.Protractor {
9 | loadAndWaitForAureliaPage(url: string): protractor.Protractor;
10 | waitForRouterComplete();
11 | }
12 |
13 | interface IProtractorLocatorStrategy {
14 | valueBind(bindTarget: string): webdriver.Locator;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/aurelia-ux-todo/favicon.ico:
--------------------------------------------------------------------------------
1 | �PNG
2 |
3 |
IHDR szz� bKGD �C� pHYs �� vpAg ���� TIDATXå�y�W��?���[�u�Pk��K�4�օ��AVqXZ6Q���Z�*��-BEaA�"��*��mSMm�Xm�E��� ��03�w��?���Y=�ͽ����~��{ν�]T����f������*�p�1k��xd���}��n��x��M\��MT�x�g�����{��H�]gj:8b���v�uޠ+�,��v�;fm��fm�#��G�;�x�ƈ�i!,i��t�ڳ\��>�1!�+��ܐ�M`{��US7WB P�yM��w�Zu����x��������qk�8���5�\0��IS���žZJ7������&j��������Vwv��;b��2f[���;Pۢ�ϝQY�9j��X9�bǔO�R`v�
4 | p�=�7�^�y���O=�BsZ�M� c���Eg���|��P��k+�}�~�;V�e(@D
���̮Zq �cvՊ^ ��"�\F���Ӏor�vS�5 I.�i����rͤ��O��r���;ܿ2��-���[��4\���Y�������� ]k��AZrh�P�h�h�>��C��;�=�~������e���W �VN�.�O�aA��i��1�]s��Y�N`:pЧ�Y�džo��j��>�]֧��1�1�p.���n���*��|p�"�B�r(eu� V�e~D
N�U��'=�o*��C�[�ՎX���%�����oN�}�4@b7�rvh�5|TY��})�X��@$BN�ȭ y� ��ƚ�m�ޱ�{M��e��.x_,&��d{����)}>��&��/z��- U