diff --git a/.gitignore b/.gitignore
index ca784df6e..1c10b129c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,11 +22,12 @@ tags
npm-debug.log
nativescript-angular*.tgz
-tests/app/**/*.js
-tests/test-output.txt
-tests/platforms
-tests/lib
-tests/node_modules
+
+tests/*/app/**/*.js
+tests/*/test-output.txt
+tests/*/platforms
+tests/*/lib
+tests/*/node_modules
ng-sample/app/**/*.js
ng-sample/app/global.d.ts
diff --git a/.travis.yml b/.travis.yml
index 903364dbc..30cca370e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,18 +29,18 @@ install:
- cd nativescript-angular
- npm install
- npm run tslint
-- cd ../tests
+- cd ../tests/tns
- npm install
- tns platform add android
before_script:
- echo no | android create avd --force -n test -t android-19 -b armeabi-v7a
- emulator -memory 1024 -avd test -no-audio -no-window &
script:
--
--
+- cd tests/tns
- tns build android
- android-wait-for-emulator
- npm run run-appium-android
+- npm run test
before_deploy:
- cd ../nativescript-angular
- npm install -g nativescript --ignore-scripts
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 424e4dcd2..ba9d374f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,73 @@
+
+## [1.5.1](https://github.com/NativeScript/nativescript-angular/compare/v1.5.0...v1.5.1) (2017-03-30)
+
+
+### Bug Fixes
+
+* **action bar:** attach #comment nodes with _addView ([#729](https://github.com/NativeScript/nativescript-angular/issues/729)) ([be93db6](https://github.com/NativeScript/nativescript-angular/commit/be93db6)), closes [#725](https://github.com/NativeScript/nativescript-angular/issues/725)
+* **ns-router-link:** navigate with urlTree ([#728](https://github.com/NativeScript/nativescript-angular/issues/728)) ([71058f8](https://github.com/NativeScript/nativescript-angular/commit/71058f8)), closes [#724](https://github.com/NativeScript/nativescript-angular/issues/724)
+
+
+
+
+# [1.5.0](https://github.com/NativeScript/nativescript-angular/compare/v1.4.1...v1.5.0) (2017-03-22)
+
+### Bug Fixes
+
+* **action-bar:** Don't remove action items twice. ([677d7e0](https://github.com/NativeScript/nativescript-angular/commit/677d7e0))
+* **animations:** add onDestroy method to NativeScriptAnimationPlayer ([2e24010](https://github.com/NativeScript/nativescript-angular/commit/2e24010))
+* **dom_adapter:** add missing `contains` method signature ([bae45f6](https://github.com/NativeScript/nativescript-angular/commit/bae45f6))
+* **dom_adapter:** update setTitle and getGlobalEventTarget to be compliant with Angular API ([25c134d](https://github.com/NativeScript/nativescript-angular/commit/25c134d))
+* **gitignore:** Add editor files into gitignore ([819a960](https://github.com/NativeScript/nativescript-angular/commit/819a960))
+* **init:** Bootstrap Angular on page "navigatingTo" event. ([ab04aba](https://github.com/NativeScript/nativescript-angular/commit/ab04aba))
+* **list-view-comp:** IterableDiffer is now parameterized on \ ([780967d](https://github.com/NativeScript/nativescript-angular/commit/780967d))
+* **ns-http:** make defaultOptions of type RequestOptions ([db730e2](https://github.com/NativeScript/nativescript-angular/commit/db730e2))
+* **page-router-outlet:** activateWith instead of activate method ([8d832bc](https://github.com/NativeScript/nativescript-angular/commit/8d832bc))
+* **page-router-outlet:** manually run detect changes when navigating to new page ([07caa74](https://github.com/NativeScript/nativescript-angular/commit/07caa74))
+* **platform:** import InjectionToken and ViewEncapsulation instead of OpaqueToken ([c4dc8d4](https://github.com/NativeScript/nativescript-angular/commit/c4dc8d4))
+* **platform:** import MissingTranslationStrategy ([d2328a5](https://github.com/NativeScript/nativescript-angular/commit/d2328a5))
+* **renderer:** implement createComment and createText methods using Placeholders ([c0ec870](https://github.com/NativeScript/nativescript-angular/commit/c0ec870))
+* **renderer:** use _eachChildView for nextSibling ([150c1ce](https://github.com/NativeScript/nativescript-angular/commit/150c1ce))
+* **renderer:** use flags in `setStyle` and `removeStyle` instead of booleans ([a6d9247](https://github.com/NativeScript/nativescript-angular/commit/a6d9247))
+* **ts:** ship package with reference to iterable interface ([7edfa6b](https://github.com/NativeScript/nativescript-angular/commit/7edfa6b))
+
+
+### Code Refactoring
+
+* stop exporting NativeScriptModule from platform ([#701](https://github.com/NativeScript/nativescript-angular/issues/701)) ([409e717](https://github.com/NativeScript/nativescript-angular/commit/409e717))
+
+
+### Features
+
+* **animations:** introduce NativeScriptAnimationsModule ([b5874ba](https://github.com/NativeScript/nativescript-angular/commit/b5874ba))
+* **renderer:** implement simple nextSibling method using parent's _eachChildView ([98d9d20](https://github.com/NativeScript/nativescript-angular/commit/98d9d20))
+* **renderer:** upgrade to be compliant with Angular 4's Renderer2 and RendererFactory2 ([a3adcca](https://github.com/NativeScript/nativescript-angular/commit/a3adcca))
+* **renderer:** use EmulatedRenderer to scope component styles ([25f5111](https://github.com/NativeScript/nativescript-angular/commit/25f5111))
+
+
+### BREAKING CHANGES
+
+* **NativeScriptModule:** User applications cannot import NativeScriptModule from
+"nativescript-angular/platform" anymore.
+Migration:
+Before:
+```
+import { NativeScriptModule } from "nativescript-angular/platform";
+```
+After
+```
+import { NativeScriptModule } from
+"nativescript-angular/nativescript.module";
+```
+* **animations:** To use animations, you need to import the
+NativeScriptAnimationsModule from "nativescript-angular/animations" in
+your root NgModule. Also you need a dependency to "@angular/animations".
+
+* **typescript:** The required version of TypeScript is ~2.1. Support for ~2.2 requires changes in `tns-core-modules` and will be provided with NativeScript 3.0.
+
+
# 1.1.2 (2016-10-28)
+
- Angular 2.1.2 compatibility release
# 1.1.1 (2016-10-21)
diff --git a/README.md b/README.md
index 78b6a2e16..44d7e2a50 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
[](https://travis-ci.org/NativeScript/nativescript-angular)
-Integrating NativeScript with Angular 2.
+Integrating NativeScript with Angular.
# Running locally
@@ -68,7 +68,7 @@ npm link nativescript-angular
1. Make changes to the `test`, `ng-sample` projects or in `nativescript-angular` folder.
2. Run the `tests` or `ng-sample` using as shown above.
-# Watch the video explaining Angular 2 and NativeScript
+# Watch the video explaining Angular and NativeScript
[NativeScript session on AngularConnect conference](https://www.youtube.com/watch?v=4SbiiyRSIwo)
# Explore the examples
diff --git a/build-doc-snippets.sh b/build-doc-snippets.sh
new file mode 100755
index 000000000..0550b3203
--- /dev/null
+++ b/build-doc-snippets.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+set -e
+
+ENV="${ENV:-dev}"
+DIST_DIR="bin/dist"
+TARGET_DIR="$DIST_DIR/snippets"
+PACKAGE_VERSION="${PACKAGE_VERSION:-0.0.0}"
+
+extractSnippets() {
+ BIN="./node_modules/markdown-snippet-injector/extract.js"
+ node "$BIN" --root="." --target="$TARGET_DIR" \
+ --sourceext=".js|.ts|.xml|.html|.css"
+}
+
+npm install markdown-snippet-injector
+rm -rf "$TARGET_DIR"
+mkdir -p "$TARGET_DIR"
+
+extractSnippets
+
+(cd "$DIST_DIR" && tar zcvf "nativescript-angular-snippets-$ENV-$PACKAGE_VERSION.tar.gz" snippets)
diff --git a/nativescript-angular/README.md b/nativescript-angular/README.md
index 1a5348eaf..8f87f938c 100644
--- a/nativescript-angular/README.md
+++ b/nativescript-angular/README.md
@@ -1 +1 @@
-[Get started with Angular 2 and NativeScript.](http://docs.nativescript.org/angular/start/introduction.html)
+[Get started with Angular and NativeScript.](http://docs.nativescript.org/angular/start/introduction.html)
diff --git a/nativescript-angular/directives/action-bar.ts b/nativescript-angular/directives/action-bar.ts
index b659310eb..bb9076a4b 100644
--- a/nativescript-angular/directives/action-bar.ts
+++ b/nativescript-angular/directives/action-bar.ts
@@ -5,9 +5,9 @@ import { Page } from "tns-core-modules/ui/page";
import { View } from "tns-core-modules/ui/core/view";
import { registerElement, ViewClassMeta, NgView } from "../element-registry";
-let actionBarMeta: ViewClassMeta = {
+const actionBarMeta: ViewClassMeta = {
skipAddToDom: true,
- insertChild: (parent: NgView, child: NgView, _atIndex: number) => {
+ insertChild: (parent: NgView, child: NgView, atIndex: number) => {
const bar = (parent);
const childView = child;
@@ -17,13 +17,16 @@ let actionBarMeta: ViewClassMeta = {
} else if (child instanceof ActionItem) {
bar.actionItems.addItem(childView);
childView.parent = bar;
- } else if (child.nodeName !== "#text" && child instanceof View) {
+ } else if (child.nodeName === "#comment") {
+ bar._addView(childView, atIndex);
+ } else if (child instanceof View) {
bar.titleView = childView;
}
},
removeChild: (parent: NgView, child: NgView) => {
const bar = (parent);
const childView = child;
+
if (child instanceof NavigationButton) {
if (bar.navigationButton === childView) {
bar.navigationButton = null;
diff --git a/nativescript-angular/directives/list-view-comp.ts b/nativescript-angular/directives/list-view-comp.ts
index 4449712e6..93115b52f 100644
--- a/nativescript-angular/directives/list-view-comp.ts
+++ b/nativescript-angular/directives/list-view-comp.ts
@@ -19,13 +19,12 @@ import {
Host,
ChangeDetectionStrategy
} from "@angular/core";
-import { isBlank } from "../lang-facade";
import { isListLikeIterable } from "../collection-facade";
-import { ListView } from "tns-core-modules/ui/list-view";
+import { ListView, ItemEventData } from "tns-core-modules/ui/list-view";
import { View, KeyedTemplate } from "tns-core-modules/ui/core/view";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { LayoutBase } from "tns-core-modules/ui/layouts/layout-base";
-import { listViewLog } from "../trace";
+import { listViewLog, listViewError } from "../trace";
const NG_VIEW = "_ngViewRef";
@@ -147,27 +146,31 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
this._templateMap.set(key, keyedTemplate);
}
- public onItemLoading(args) {
+ public onItemLoading(args: ItemEventData) {
if (!args.view && !this.itemTemplate) {
return;
}
- let index = args.index;
- let items = args.object.items;
- let currentItem = typeof (items.getItem) === "function" ?
- items.getItem(index) : items[index];
+ const index = args.index;
+ const items = (args.object).items;
+ const currentItem = typeof items.getItem === "function" ? items.getItem(index) : items[index];
let viewRef: EmbeddedViewRef;
- if (args.view && args.view[NG_VIEW]) {
+ if (args.view) {
listViewLog("onItemLoading: " + index + " - Reusing existing view");
viewRef = args.view[NG_VIEW];
- // getting angular view from original element (in cases when ProxyViewContainer
+ // Getting angular view from original element (in cases when ProxyViewContainer
// is used NativeScript internally wraps it in a StackLayout)
+ if (!viewRef && args.view instanceof LayoutBase && args.view.getChildrenCount() > 0) {
+ viewRef = args.view.getChildAt(0)[NG_VIEW];
+ }
+
if (!viewRef) {
- viewRef = (args.view._subViews && args.view._subViews.length > 0) ?
- args.view._subViews[0][NG_VIEW] : undefined;
+ listViewError("ViewReference not found for item " + index + ". View recycling is not working");
}
- } else {
+ };
+
+ if (!viewRef) {
listViewLog("onItemLoading: " + index + " - Creating view from template");
viewRef = this.loader.createEmbeddedView(this.itemTemplate, new ListItemContext(), 0);
args.view = getItemViewRoot(viewRef);
@@ -180,9 +183,6 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
}
public setupViewRef(viewRef: EmbeddedViewRef, data: any, index: number): void {
- if (isBlank(viewRef)) {
- return;
- }
const context = viewRef.context;
context.$implicit = data;
context.item = data;
@@ -194,13 +194,9 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
}
private detectChangesOnChild(viewRef: EmbeddedViewRef, index: number) {
- // Manually detect changes in child view ref
- // TODO: Is there a better way of getting viewRef"s change detector
- const childChangeDetector = (viewRef);
-
listViewLog("Manually detect changes in child: " + index);
- childChangeDetector.markForCheck();
- childChangeDetector.detectChanges();
+ viewRef.markForCheck();
+ viewRef.detectChanges();
}
ngDoCheck() {
@@ -243,10 +239,6 @@ export type RootLocator = (nodes: Array, nestLevel: number) => View;
export function getItemViewRoot(viewRef: ComponentView, rootLocator: RootLocator = getSingleViewRecursive): View {
const rootView = rootLocator(viewRef.rootNodes, 0);
- rootView.on("unloaded", () => {
- viewRef.destroy();
- delete rootView[NG_VIEW];
- });
return rootView;
}
diff --git a/nativescript-angular/package.json b/nativescript-angular/package.json
index e9d84752b..c3993ae35 100644
--- a/nativescript-angular/package.json
+++ b/nativescript-angular/package.json
@@ -1,12 +1,27 @@
{
"private": true,
"name": "nativescript-angular",
- "version": "2.0.0",
- "description": "An Angular 2 renderer that lets you build mobile apps with NativeScript.",
- "homepage": "http://www.telerik.com",
- "bugs": "http://www.telerik.com",
+ "version": "3.0.0",
+ "description": "An Angular renderer that lets you build mobile apps with NativeScript.",
+ "homepage": "https://www.nativescript.org/",
+ "bugs": "https://github.com/NativeScript/nativescript-angular/issues",
+ "author": {
+ "name": "NativeScript Team"
+ },
"contributors": [
- "Hristo Deshev "
+ "Hristo Deshev ",
+ "Alexander Vakrilov ",
+ "Stanimira Vlaeva "
+ ],
+ "nativescript": {
+ "platforms": {
+ "android": "3.0.0",
+ "ios": "3.0.0"
+ }
+ },
+ "keywords": [
+ "NativeScript",
+ "Angular"
],
"license": "Apache-2.0",
"repository": {
@@ -24,29 +39,37 @@
"update-app-ng-deps": "./bin/update-app-ng-deps"
},
"dependencies": {
- "nativescript-intl": "~0.0.8",
+ "nativescript-intl": "^0.0.8",
+ "reflect-metadata": "^0.1.8"
+ },
+ "peerDependencies": {
"@angular/core": "~4.0.0",
"@angular/common": "~4.0.0",
"@angular/compiler": "~4.0.0",
- "@angular/http": "~4.0.0",
"@angular/platform-browser": "~4.0.0",
- "@angular/platform-browser-dynamic": "~4.0.0",
- "@angular/forms": "~4.0.0",
+ "@angular/animations": "~4.0.0",
"@angular/router": "~4.0.0",
+ "@angular/forms": "~4.0.0",
+ "@angular/http": "~4.0.0",
+ "tns-core-modules": "^3.0.0 || ^3.0.0-rc.1",
"rxjs": "^5.0.1",
- "reflect-metadata": "~0.1.8",
- "punycode": "1.3.2",
- "querystring": "0.2.0",
- "url": "0.10.3"
+ "zone.js": "^0.8.4"
},
"devDependencies": {
- "@angular/animations": "~4.0.0",
+ "@angular/core": "~4.0.0",
+ "@angular/common": "~4.0.0",
+ "@angular/compiler": "~4.0.0",
"@angular/compiler-cli": "~4.0.0",
+ "@angular/platform-browser": "~4.0.0",
+ "@angular/animations": "~4.0.0",
+ "@angular/router": "~4.0.0",
+ "@angular/forms": "~4.0.0",
+ "@angular/http": "~4.0.0",
"codelyzer": "~3.0.0-beta.4",
"tns-core-modules": "internal-preview",
"tslint": "~4.5.0",
"typescript": "~2.2.1",
- "zone.js": "^0.8.2"
- },
- "nativescript": {}
+ "rxjs": "^5.0.1",
+ "zone.js": "^0.8.4"
+ }
}
diff --git a/nativescript-angular/router/ns-router-link.ts b/nativescript-angular/router/ns-router-link.ts
index e73c53b16..451fa2878 100644
--- a/nativescript-angular/router/ns-router-link.ts
+++ b/nativescript-angular/router/ns-router-link.ts
@@ -76,21 +76,19 @@ export class NSRouterLink implements OnChanges { // tslint:disable-line:directiv
JSON.stringify(this.pageTransition));
const extras = this.getExtras();
- this.navigator.navigate(this.commands, extras);
+ this.navigator.navigateByUrl(this.urlTree, extras);
}
- private getExtras() {
+ private getExtras(): NavigationExtras & NavigationOptions {
const transition = this.getTransition();
- const extras: NavigationExtras & NavigationOptions = {
+ return {
queryParams: this.queryParams,
fragment: this.fragment,
clearHistory: this.clearHistory,
animated: transition.animated,
transition: transition.transition,
+ relativeTo: this.currentRoute,
};
-
- return (Object).assign(extras,
- this.currentRoute.toString() !== "Route(url:'', path:'')" && this.currentRoute);
}
private getTransition(): { animated: boolean, transition?: NavigationTransition } {
diff --git a/nativescript-angular/router/page-router-outlet.ts b/nativescript-angular/router/page-router-outlet.ts
index 690643325..bc28fdd5b 100644
--- a/nativescript-angular/router/page-router-outlet.ts
+++ b/nativescript-angular/router/page-router-outlet.ts
@@ -1,6 +1,6 @@
import {
Attribute, ComponentFactory, ComponentRef, Directive,
- ViewContainerRef,
+ ViewContainerRef, Type, InjectionToken,
Inject, ComponentFactoryResolver, Injector
} from "@angular/core";
import { RouterOutletMap, ActivatedRoute, PRIMARY_OUTLET } from "@angular/router";
@@ -167,19 +167,22 @@ export class PageRouterOutlet { // tslint:disable-line:directive-class-suffix
activatedRoute: ActivatedRoute,
outletMap: RouterOutletMap,
loadedResolver: ComponentFactoryResolver): void {
- const factory = this.getComponentFactory(activatedRoute, loadedResolver);
-
const pageRoute = new PageRoute(activatedRoute);
+ let providers = new Map();
+ providers.set(PageRoute, pageRoute);
+ providers.set(ActivatedRoute, activatedRoute);
+ providers.set(RouterOutletMap, outletMap);
+ const childInjector = new ChildInjector(providers, this.location.injector);
+
+ const factory = this.getComponentFactory(activatedRoute, loadedResolver);
if (this.isInitialPage) {
log("PageRouterOutlet.activate() initial page - just load component");
this.isInitialPage = false;
- const injector = new OutletInjector(activatedRoute, outletMap, this.location.injector);
this.currentActivatedComp = this.location.createComponent(
- factory, this.location.length, injector, []);
-
+ factory, this.location.length, childInjector, []);
this.currentActivatedComp.changeDetectorRef.detectChanges();
this.refCache.push(this.currentActivatedComp, pageRoute, outletMap, null);
@@ -193,7 +196,7 @@ export class PageRouterOutlet { // tslint:disable-line:directive-class-suffix
componentType: factory.componentType
});
- const childInjector = new ChildInjector(activatedRoute, outletMap, page, this.location.injector);
+ providers.set(Page, page);
const loaderRef = this.location.createComponent(
this.detachedLoaderFactory, this.location.length, childInjector, []);
@@ -264,47 +267,23 @@ export class PageRouterOutlet { // tslint:disable-line:directive-class-suffix
): ComponentFactory {
const snapshot = activatedRoute._futureSnapshot;
const component = snapshot._routeConfig.component;
- let factory: ComponentFactory;
if (loadedResolver) {
- factory = loadedResolver.resolveComponentFactory(component);
+ return loadedResolver.resolveComponentFactory(component);
} else {
- factory = this.componentFactoryResolver.resolveComponentFactory(component);
- }
-
- return factory;
- }
-}
-
-class OutletInjector implements Injector {
- constructor(
- private route: ActivatedRoute, private map: RouterOutletMap, private parent: Injector) { }
-
- get(token: any, notFoundValue?: any): any {
- if (token === ActivatedRoute) {
- return this.route;
- }
-
- if (token === RouterOutletMap) {
- return this.map;
+ return this.componentFactoryResolver.resolveComponentFactory(component);
}
-
- return this.parent.get(token, notFoundValue);
}
}
-class ChildInjector extends OutletInjector {
+class ChildInjector implements Injector {
constructor(
- route: ActivatedRoute, map: RouterOutletMap, private page: Page, parent: Injector) {
- super(route, map, parent);
- }
-
- get(token: any, notFoundValue?: any): any {
- if (token === Page) {
- return this.page;
- }
+ private providers: Map|InjectionToken, any>,
+ private parent: Injector
+ ) {}
- return super.get(token, notFoundValue);
+ get(token: Type|InjectionToken, notFoundValue?: T): T {
+ return this.providers.get(token) || this.parent.get(token, notFoundValue);
}
}
diff --git a/nativescript-angular/testing/setup.js b/nativescript-angular/testing/setup.js
new file mode 100644
index 000000000..06ab18b14
--- /dev/null
+++ b/nativescript-angular/testing/setup.js
@@ -0,0 +1,19 @@
+require("reflect-metadata");
+require("nativescript-angular/zone-js/dist/zone-nativescript");
+require("zone.js/dist/long-stack-trace-zone");
+require("zone.js/dist/proxy"); // since zone.js 0.6.15
+require("zone.js/dist/sync-test");
+if (global.jasmine) {
+ require("zone.js/dist/jasmine-patch"); // put here since zone.js 0.6.14
+}
+require("zone.js/dist/async-test");
+require("zone.js/dist/fake-async-test");
+var testing_1 = require("@angular/platform-browser-dynamic/testing");
+var destroyPlatform = require("@angular/core").destroyPlatform;
+var TestBed = require("@angular/core/testing").TestBed;
+var platformCommon = require("nativescript-angular/platform-common");
+var platform = require("nativescript-angular/platform");
+// config TestBed with TNS provider
+//new platformCommon.NativeScriptPlatformRef(platform).destroy();
+destroyPlatform();
+TestBed.initTestEnvironment(testing_1.BrowserDynamicTestingModule, testing_1.platformBrowserDynamicTesting(platform.NS_COMPILER_PROVIDERS));
\ No newline at end of file
diff --git a/nativescript-angular/trace.ts b/nativescript-angular/trace.ts
index a98ad86b7..71324d6d5 100644
--- a/nativescript-angular/trace.ts
+++ b/nativescript-angular/trace.ts
@@ -23,3 +23,7 @@ export function styleError(message: string): void {
export function listViewLog(message: string): void {
write(message, listViewTraceCategory);
}
+
+export function listViewError(message: string): void {
+ write(message, listViewTraceCategory, messageType.error);
+}
diff --git a/nativescript-angular/tslint.json b/nativescript-angular/tslint.json
index 90e38b36c..4db4b9408 100644
--- a/nativescript-angular/tslint.json
+++ b/nativescript-angular/tslint.json
@@ -10,14 +10,10 @@
"use-host-property-decorator": true,
"no-input-rename": true,
"no-output-rename": true,
- "use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"pipe-naming": [true, "camelCase", "ns"],
"component-class-suffix": true,
"directive-class-suffix": true,
- "import-destructuring-spacing": true,
- "templates-use-public": true,
- "no-access-missing-member": true,
"invoke-injectable": true,
"member-access": false,
"no-any": false,
@@ -129,6 +125,7 @@
true,
"check-branch",
"check-decl",
+ "check-module",
"check-operator",
"check-separator",
"check-type"
diff --git a/tests/testbed/app/App_Resources/Android/AndroidManifest.xml b/tests/testbed/app/App_Resources/Android/AndroidManifest.xml
new file mode 100644
index 000000000..9db832151
--- /dev/null
+++ b/tests/testbed/app/App_Resources/Android/AndroidManifest.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/testbed/app/App_Resources/Android/app.gradle b/tests/testbed/app/App_Resources/Android/app.gradle
new file mode 100644
index 000000000..a63246ad3
--- /dev/null
+++ b/tests/testbed/app/App_Resources/Android/app.gradle
@@ -0,0 +1,16 @@
+// Add your native dependencies here:
+
+// Uncomment to add recyclerview-v7 dependency
+//dependencies {
+// compile 'com.android.support:recyclerview-v7:+'
+//}
+
+android {
+ defaultConfig {
+ generatedDensities = []
+ applicationId = "org.nativescript.sampleApp"
+ }
+ aaptOptions {
+ additionalParameters "--no-version-vectors"
+ }
+}
diff --git a/tests/testbed/app/App_Resources/Android/drawable-hdpi/background.png b/tests/testbed/app/App_Resources/Android/drawable-hdpi/background.png
new file mode 100644
index 000000000..eb381c258
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-hdpi/background.png differ
diff --git a/tests/app/App_Resources/Android/drawable-hdpi/icon.png b/tests/testbed/app/App_Resources/Android/drawable-hdpi/icon.png
similarity index 100%
rename from tests/app/App_Resources/Android/drawable-hdpi/icon.png
rename to tests/testbed/app/App_Resources/Android/drawable-hdpi/icon.png
diff --git a/tests/testbed/app/App_Resources/Android/drawable-hdpi/logo.png b/tests/testbed/app/App_Resources/Android/drawable-hdpi/logo.png
new file mode 100644
index 000000000..5218f4c90
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-hdpi/logo.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-ldpi/background.png b/tests/testbed/app/App_Resources/Android/drawable-ldpi/background.png
new file mode 100644
index 000000000..748b2adf5
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-ldpi/background.png differ
diff --git a/tests/app/App_Resources/Android/drawable-ldpi/icon.png b/tests/testbed/app/App_Resources/Android/drawable-ldpi/icon.png
similarity index 100%
rename from tests/app/App_Resources/Android/drawable-ldpi/icon.png
rename to tests/testbed/app/App_Resources/Android/drawable-ldpi/icon.png
diff --git a/tests/testbed/app/App_Resources/Android/drawable-ldpi/logo.png b/tests/testbed/app/App_Resources/Android/drawable-ldpi/logo.png
new file mode 100644
index 000000000..b9e102a76
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-ldpi/logo.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-mdpi/background.png b/tests/testbed/app/App_Resources/Android/drawable-mdpi/background.png
new file mode 100644
index 000000000..efeaf2907
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-mdpi/background.png differ
diff --git a/tests/app/App_Resources/Android/drawable-mdpi/icon.png b/tests/testbed/app/App_Resources/Android/drawable-mdpi/icon.png
similarity index 100%
rename from tests/app/App_Resources/Android/drawable-mdpi/icon.png
rename to tests/testbed/app/App_Resources/Android/drawable-mdpi/icon.png
diff --git a/tests/testbed/app/App_Resources/Android/drawable-mdpi/logo.png b/tests/testbed/app/App_Resources/Android/drawable-mdpi/logo.png
new file mode 100644
index 000000000..626338766
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-mdpi/logo.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-nodpi/splash_screen.xml b/tests/testbed/app/App_Resources/Android/drawable-nodpi/splash_screen.xml
new file mode 100644
index 000000000..ada77f92c
--- /dev/null
+++ b/tests/testbed/app/App_Resources/Android/drawable-nodpi/splash_screen.xml
@@ -0,0 +1,8 @@
+
+ -
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/tests/testbed/app/App_Resources/Android/drawable-xhdpi/background.png b/tests/testbed/app/App_Resources/Android/drawable-xhdpi/background.png
new file mode 100644
index 000000000..612bbd072
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-xhdpi/background.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-xhdpi/icon.png b/tests/testbed/app/App_Resources/Android/drawable-xhdpi/icon.png
new file mode 100644
index 000000000..f29188209
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-xhdpi/icon.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-xhdpi/logo.png b/tests/testbed/app/App_Resources/Android/drawable-xhdpi/logo.png
new file mode 100644
index 000000000..ad8ee2f4b
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-xhdpi/logo.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-xxhdpi/background.png b/tests/testbed/app/App_Resources/Android/drawable-xxhdpi/background.png
new file mode 100644
index 000000000..0fa88e235
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-xxhdpi/background.png differ
diff --git a/tests/app/App_Resources/iOS/icon-72@2x.png b/tests/testbed/app/App_Resources/Android/drawable-xxhdpi/icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from tests/app/App_Resources/iOS/icon-72@2x.png
rename to tests/testbed/app/App_Resources/Android/drawable-xxhdpi/icon.png
diff --git a/tests/testbed/app/App_Resources/Android/drawable-xxhdpi/logo.png b/tests/testbed/app/App_Resources/Android/drawable-xxhdpi/logo.png
new file mode 100644
index 000000000..668327832
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-xxhdpi/logo.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/background.png b/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/background.png
new file mode 100644
index 000000000..c650f6438
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/background.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/icon.png b/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/icon.png
new file mode 100644
index 000000000..50887a856
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/icon.png differ
diff --git a/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/logo.png b/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/logo.png
new file mode 100644
index 000000000..fa6331c8d
Binary files /dev/null and b/tests/testbed/app/App_Resources/Android/drawable-xxxhdpi/logo.png differ
diff --git a/tests/testbed/app/App_Resources/Android/values-v21/colors.xml b/tests/testbed/app/App_Resources/Android/values-v21/colors.xml
new file mode 100644
index 000000000..a64641a9d
--- /dev/null
+++ b/tests/testbed/app/App_Resources/Android/values-v21/colors.xml
@@ -0,0 +1,4 @@
+
+
+ #3d5afe
+
\ No newline at end of file
diff --git a/tests/testbed/app/App_Resources/Android/values-v21/styles.xml b/tests/testbed/app/App_Resources/Android/values-v21/styles.xml
new file mode 100644
index 000000000..dac8727c8
--- /dev/null
+++ b/tests/testbed/app/App_Resources/Android/values-v21/styles.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/testbed/app/App_Resources/Android/values/colors.xml b/tests/testbed/app/App_Resources/Android/values/colors.xml
new file mode 100644
index 000000000..74ad8829c
--- /dev/null
+++ b/tests/testbed/app/App_Resources/Android/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #F5F5F5
+ #757575
+ #33B5E5
+ #272734
+
\ No newline at end of file
diff --git a/tests/testbed/app/App_Resources/Android/values/styles.xml b/tests/testbed/app/App_Resources/Android/values/styles.xml
new file mode 100644
index 000000000..1e8c7f29b
--- /dev/null
+++ b/tests/testbed/app/App_Resources/Android/values/styles.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 000000000..5f5359340
--- /dev/null
+++ b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,128 @@
+{
+ "images" : [
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "icon-29.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "icon-29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "icon-29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "icon-40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "icon-40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "57x57",
+ "idiom" : "iphone",
+ "filename" : "icon-57.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "57x57",
+ "idiom" : "iphone",
+ "filename" : "icon-57@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon-60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon-60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "icon-29.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "icon-29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "icon-40.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "icon-40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "50x50",
+ "idiom" : "ipad",
+ "filename" : "icon-50.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "50x50",
+ "idiom" : "ipad",
+ "filename" : "icon-50@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "72x72",
+ "idiom" : "ipad",
+ "filename" : "icon-72.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "72x72",
+ "idiom" : "ipad",
+ "filename" : "icon-72@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon-76.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon-76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "icon-83.5@2x.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png
new file mode 100644
index 000000000..9e15af09d
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png
new file mode 100644
index 000000000..7b9e55537
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
new file mode 100644
index 000000000..76f61ec1f
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png
new file mode 100644
index 000000000..15b06db11
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png
new file mode 100644
index 000000000..585065f94
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
new file mode 100644
index 000000000..a450c421d
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png differ
diff --git a/tests/app/App_Resources/iOS/Icon-Small-50.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png
similarity index 100%
rename from tests/app/App_Resources/iOS/Icon-Small-50.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png
diff --git a/tests/app/App_Resources/iOS/Icon-Small-50@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png
similarity index 100%
rename from tests/app/App_Resources/iOS/Icon-Small-50@2x.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png
diff --git a/tests/app/App_Resources/iOS/icon.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png
diff --git a/tests/app/App_Resources/iOS/icon@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon@2x.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png
new file mode 100644
index 000000000..457b6d94c
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
new file mode 100644
index 000000000..fa5a6ac86
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png differ
diff --git a/tests/app/App_Resources/iOS/icon-72.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon-72.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png
new file mode 100755
index 000000000..4f69cb25b
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png
new file mode 100644
index 000000000..94abcf70d
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png
new file mode 100644
index 000000000..2e71dd3a0
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png
new file mode 100644
index 000000000..4abc9ec50
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/Contents.json b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/Contents.json
new file mode 100644
index 000000000..da4a164c9
--- /dev/null
+++ b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Contents.json b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Contents.json
new file mode 100644
index 000000000..4414bad08
--- /dev/null
+++ b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Contents.json
@@ -0,0 +1,158 @@
+{
+ "images" : [
+ {
+ "extent" : "full-screen",
+ "idiom" : "iphone",
+ "subtype" : "736h",
+ "filename" : "Default-736h@3x.png",
+ "minimum-system-version" : "8.0",
+ "orientation" : "portrait",
+ "scale" : "3x"
+ },
+ {
+ "extent" : "full-screen",
+ "idiom" : "iphone",
+ "subtype" : "736h",
+ "filename" : "Default-Landscape@3x.png",
+ "minimum-system-version" : "8.0",
+ "orientation" : "landscape",
+ "scale" : "3x"
+ },
+ {
+ "extent" : "full-screen",
+ "idiom" : "iphone",
+ "subtype" : "667h",
+ "filename" : "Default-667h@2x.png",
+ "minimum-system-version" : "8.0",
+ "orientation" : "portrait",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "filename" : "Default@2x.png",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "scale" : "2x"
+ },
+ {
+ "extent" : "full-screen",
+ "idiom" : "iphone",
+ "subtype" : "retina4",
+ "filename" : "Default-568h@2x.png",
+ "minimum-system-version" : "7.0",
+ "orientation" : "portrait",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "filename" : "Default-Portrait.png",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "filename" : "Default-Landscape.png",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "filename" : "Default-Portrait@2x.png",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "filename" : "Default-Landscape@2x.png",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "filename" : "Default.png",
+ "extent" : "full-screen",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "filename" : "Default@2x.png",
+ "extent" : "full-screen",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "filename" : "Default-568h@2x.png",
+ "extent" : "full-screen",
+ "subtype" : "retina4",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "extent" : "to-status-bar",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "filename" : "Default-Portrait.png",
+ "extent" : "full-screen",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "extent" : "to-status-bar",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "filename" : "Default-Landscape.png",
+ "extent" : "full-screen",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "extent" : "to-status-bar",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "filename" : "Default-Portrait@2x.png",
+ "extent" : "full-screen",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "extent" : "to-status-bar",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "filename" : "Default-Landscape@2x.png",
+ "extent" : "full-screen",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/tests/app/App_Resources/iOS/Default-568h@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png
old mode 100755
new mode 100644
similarity index 100%
rename from tests/app/App_Resources/iOS/Default-568h@2x.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png
new file mode 100644
index 000000000..b88415405
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png
new file mode 100644
index 000000000..faab4b631
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png differ
diff --git a/tests/app/App_Resources/iOS/Default-Landscape.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png
old mode 100755
new mode 100644
similarity index 100%
rename from tests/app/App_Resources/iOS/Default-Landscape.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png
diff --git a/tests/app/App_Resources/iOS/Default-Landscape@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png
old mode 100755
new mode 100644
similarity index 100%
rename from tests/app/App_Resources/iOS/Default-Landscape@2x.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png
new file mode 100644
index 000000000..e6dca6269
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png differ
diff --git a/tests/app/App_Resources/iOS/Default-Portrait.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png
old mode 100755
new mode 100644
similarity index 100%
rename from tests/app/App_Resources/iOS/Default-Portrait.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png
diff --git a/tests/app/App_Resources/iOS/Default-Portrait@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png
old mode 100755
new mode 100644
similarity index 100%
rename from tests/app/App_Resources/iOS/Default-Portrait@2x.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png
diff --git a/tests/app/App_Resources/iOS/Default.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png
old mode 100755
new mode 100644
similarity index 100%
rename from tests/app/App_Resources/iOS/Default.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png
diff --git a/tests/app/App_Resources/iOS/Default@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png
old mode 100755
new mode 100644
similarity index 100%
rename from tests/app/App_Resources/iOS/Default@2x.png
rename to tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json
new file mode 100644
index 000000000..4f4e9c506
--- /dev/null
+++ b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-AspectFill.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-AspectFill@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png
new file mode 100644
index 000000000..c293f9c7a
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png
new file mode 100644
index 000000000..233693a6e
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json
new file mode 100644
index 000000000..23c0ffd7a
--- /dev/null
+++ b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-Center.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-Center@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png
new file mode 100644
index 000000000..a5a775a2b
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png
new file mode 100644
index 000000000..154c19343
Binary files /dev/null and b/tests/testbed/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png differ
diff --git a/tests/testbed/app/App_Resources/iOS/Info.plist b/tests/testbed/app/App_Resources/iOS/Info.plist
new file mode 100644
index 000000000..ea3e3ea23
--- /dev/null
+++ b/tests/testbed/app/App_Resources/iOS/Info.plist
@@ -0,0 +1,47 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ ${PRODUCT_NAME}
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIRequiresFullScreen
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/tests/testbed/app/App_Resources/iOS/LaunchScreen.storyboard b/tests/testbed/app/App_Resources/iOS/LaunchScreen.storyboard
new file mode 100644
index 000000000..2ad9471e1
--- /dev/null
+++ b/tests/testbed/app/App_Resources/iOS/LaunchScreen.storyboard
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/testbed/app/App_Resources/iOS/build.xcconfig b/tests/testbed/app/App_Resources/iOS/build.xcconfig
new file mode 100644
index 000000000..9d738435d
--- /dev/null
+++ b/tests/testbed/app/App_Resources/iOS/build.xcconfig
@@ -0,0 +1,7 @@
+// You can add custom settings here
+// for example you can uncomment the following line to force distribution code signing
+// CODE_SIGN_IDENTITY = iPhone Distribution
+// To build for device with XCode 8 you need to specify your development team. More info: https://developer.apple.com/library/prerelease/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html
+// DEVELOPMENT_TEAM = YOUR_TEAM_ID;
+ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
diff --git a/tests/testbed/app/app.component.d.ts b/tests/testbed/app/app.component.d.ts
new file mode 100644
index 000000000..9ee2cf54a
--- /dev/null
+++ b/tests/testbed/app/app.component.d.ts
@@ -0,0 +1,2 @@
+export declare class AppComponent {
+}
diff --git a/tests/testbed/app/app.component.html b/tests/testbed/app/app.component.html
new file mode 100644
index 000000000..41b82ccc1
--- /dev/null
+++ b/tests/testbed/app/app.component.html
@@ -0,0 +1 @@
+
diff --git a/tests/testbed/app/app.component.ts b/tests/testbed/app/app.component.ts
new file mode 100644
index 000000000..1bc07aea1
--- /dev/null
+++ b/tests/testbed/app/app.component.ts
@@ -0,0 +1,10 @@
+import { Component } from "@angular/core";
+
+@Component({
+ selector: "ns-app",
+ templateUrl: "app.component.html",
+})
+export class AppComponent {
+
+
+}
diff --git a/tests/testbed/app/app.css b/tests/testbed/app/app.css
new file mode 100644
index 000000000..0b0e8df4b
--- /dev/null
+++ b/tests/testbed/app/app.css
@@ -0,0 +1,31 @@
+/*
+In NativeScript, the app.css file is where you place CSS rules that
+you would like to apply to your entire application. Check out
+http://docs.nativescript.org/ui/styling for a full list of the CSS
+selectors and properties you can use to style UI components.
+
+/*
+In many cases you may want to use the NativeScript core theme instead
+of writing your own CSS rules. For a full list of class names in the theme
+refer to http://docs.nativescript.org/ui/theme.
+*/
+@import 'nativescript-theme-core/css/core.light.css';
+
+Label {
+ padding:10;
+ horizontal-align: center;
+}
+
+.fa {
+ font-family: FontAwesome, fontawesome-webfont;
+ font-size:60;
+}
+
+.ion {
+ font-family: Ionicons, ionicons;
+ font-size:60;
+}
+
+GridLayout {
+ padding-bottom: 50;
+}
diff --git a/tests/testbed/app/app.module.d.ts b/tests/testbed/app/app.module.d.ts
new file mode 100644
index 000000000..09cdb35c8
--- /dev/null
+++ b/tests/testbed/app/app.module.d.ts
@@ -0,0 +1,2 @@
+export declare class AppModule {
+}
diff --git a/tests/testbed/app/app.module.ts b/tests/testbed/app/app.module.ts
new file mode 100644
index 000000000..a13cb1d99
--- /dev/null
+++ b/tests/testbed/app/app.module.ts
@@ -0,0 +1,30 @@
+import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
+import { NativeScriptModule } from "nativescript-angular/nativescript.module";
+
+import { AppRoutingModule } from "./app.routing";
+import { AppComponent } from "./app.component";
+import { ItemService } from "./item/item.service";
+import { ItemsComponent } from "./item/items.component";
+import { ItemDetailComponent } from "./item/item-detail.component";
+
+@NgModule({
+ bootstrap: [
+ AppComponent
+ ],
+ imports: [
+ NativeScriptModule,
+ AppRoutingModule
+ ],
+ declarations: [
+ AppComponent,
+ ItemsComponent,
+ ItemDetailComponent
+ ],
+ providers: [
+ ItemService
+ ],
+ schemas: [
+ NO_ERRORS_SCHEMA
+ ]
+})
+export class AppModule { }
diff --git a/tests/testbed/app/app.routing.d.ts b/tests/testbed/app/app.routing.d.ts
new file mode 100644
index 000000000..7044a280f
--- /dev/null
+++ b/tests/testbed/app/app.routing.d.ts
@@ -0,0 +1,2 @@
+export declare class AppRoutingModule {
+}
diff --git a/tests/testbed/app/app.routing.ts b/tests/testbed/app/app.routing.ts
new file mode 100644
index 000000000..26c691b5d
--- /dev/null
+++ b/tests/testbed/app/app.routing.ts
@@ -0,0 +1,18 @@
+import { NgModule } from "@angular/core";
+import { NativeScriptRouterModule } from "nativescript-angular/router";
+import { Routes } from "@angular/router";
+
+import { ItemsComponent } from "./item/items.component";
+import { ItemDetailComponent } from "./item/item-detail.component";
+
+const routes: Routes = [
+ { path: "", redirectTo: "/items", pathMatch: "full" },
+ { path: "items", component: ItemsComponent },
+ { path: "item/:id", component: ItemDetailComponent },
+];
+
+@NgModule({
+ imports: [NativeScriptRouterModule.forRoot(routes)],
+ exports: [NativeScriptRouterModule]
+})
+export class AppRoutingModule { }
\ No newline at end of file
diff --git a/tests/testbed/app/fonts/FontAwesome.ttf b/tests/testbed/app/fonts/FontAwesome.ttf
new file mode 100644
index 000000000..f221e50a2
Binary files /dev/null and b/tests/testbed/app/fonts/FontAwesome.ttf differ
diff --git a/tests/testbed/app/fonts/font-awesome.css b/tests/testbed/app/fonts/font-awesome.css
new file mode 100644
index 000000000..1a83e0be0
--- /dev/null
+++ b/tests/testbed/app/fonts/font-awesome.css
@@ -0,0 +1,1900 @@
+.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: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-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-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-end:before {
+ content: "\f253";
+}
+.fa-hourglass:before {
+ content: "\f254";
+}
+.fa-hand-rock-o:before {
+ content: "\f255";
+}
+.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-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";
+}
diff --git a/tests/testbed/app/fonts/fontawesome-webfont.ttf b/tests/testbed/app/fonts/fontawesome-webfont.ttf
new file mode 100644
index 000000000..f221e50a2
Binary files /dev/null and b/tests/testbed/app/fonts/fontawesome-webfont.ttf differ
diff --git a/tests/testbed/app/fonts/ionicons.css b/tests/testbed/app/fonts/ionicons.css
new file mode 100644
index 000000000..9264c3da4
--- /dev/null
+++ b/tests/testbed/app/fonts/ionicons.css
@@ -0,0 +1,1465 @@
+.ion-alert:before { content: "\f101"; }
+
+.ion-alert-circled:before { content: "\f100"; }
+
+.ion-android-add:before { content: "\f2c7"; }
+
+.ion-android-add-circle:before { content: "\f359"; }
+
+.ion-android-alarm-clock:before { content: "\f35a"; }
+
+.ion-android-alert:before { content: "\f35b"; }
+
+.ion-android-apps:before { content: "\f35c"; }
+
+.ion-android-archive:before { content: "\f2c9"; }
+
+.ion-android-arrow-back:before { content: "\f2ca"; }
+
+.ion-android-arrow-down:before { content: "\f35d"; }
+
+.ion-android-arrow-dropdown:before { content: "\f35f"; }
+
+.ion-android-arrow-dropdown-circle:before { content: "\f35e"; }
+
+.ion-android-arrow-dropleft:before { content: "\f361"; }
+
+.ion-android-arrow-dropleft-circle:before { content: "\f360"; }
+
+.ion-android-arrow-dropright:before { content: "\f363"; }
+
+.ion-android-arrow-dropright-circle:before { content: "\f362"; }
+
+.ion-android-arrow-dropup:before { content: "\f365"; }
+
+.ion-android-arrow-dropup-circle:before { content: "\f364"; }
+
+.ion-android-arrow-forward:before { content: "\f30f"; }
+
+.ion-android-arrow-up:before { content: "\f366"; }
+
+.ion-android-attach:before { content: "\f367"; }
+
+.ion-android-bar:before { content: "\f368"; }
+
+.ion-android-bicycle:before { content: "\f369"; }
+
+.ion-android-boat:before { content: "\f36a"; }
+
+.ion-android-bookmark:before { content: "\f36b"; }
+
+.ion-android-bulb:before { content: "\f36c"; }
+
+.ion-android-bus:before { content: "\f36d"; }
+
+.ion-android-calendar:before { content: "\f2d1"; }
+
+.ion-android-call:before { content: "\f2d2"; }
+
+.ion-android-camera:before { content: "\f2d3"; }
+
+.ion-android-cancel:before { content: "\f36e"; }
+
+.ion-android-car:before { content: "\f36f"; }
+
+.ion-android-cart:before { content: "\f370"; }
+
+.ion-android-chat:before { content: "\f2d4"; }
+
+.ion-android-checkbox:before { content: "\f374"; }
+
+.ion-android-checkbox-blank:before { content: "\f371"; }
+
+.ion-android-checkbox-outline:before { content: "\f373"; }
+
+.ion-android-checkbox-outline-blank:before { content: "\f372"; }
+
+.ion-android-checkmark-circle:before { content: "\f375"; }
+
+.ion-android-clipboard:before { content: "\f376"; }
+
+.ion-android-close:before { content: "\f2d7"; }
+
+.ion-android-cloud:before { content: "\f37a"; }
+
+.ion-android-cloud-circle:before { content: "\f377"; }
+
+.ion-android-cloud-done:before { content: "\f378"; }
+
+.ion-android-cloud-outline:before { content: "\f379"; }
+
+.ion-android-color-palette:before { content: "\f37b"; }
+
+.ion-android-compass:before { content: "\f37c"; }
+
+.ion-android-contact:before { content: "\f2d8"; }
+
+.ion-android-contacts:before { content: "\f2d9"; }
+
+.ion-android-contract:before { content: "\f37d"; }
+
+.ion-android-create:before { content: "\f37e"; }
+
+.ion-android-delete:before { content: "\f37f"; }
+
+.ion-android-desktop:before { content: "\f380"; }
+
+.ion-android-document:before { content: "\f381"; }
+
+.ion-android-done:before { content: "\f383"; }
+
+.ion-android-done-all:before { content: "\f382"; }
+
+.ion-android-download:before { content: "\f2dd"; }
+
+.ion-android-drafts:before { content: "\f384"; }
+
+.ion-android-exit:before { content: "\f385"; }
+
+.ion-android-expand:before { content: "\f386"; }
+
+.ion-android-favorite:before { content: "\f388"; }
+
+.ion-android-favorite-outline:before { content: "\f387"; }
+
+.ion-android-film:before { content: "\f389"; }
+
+.ion-android-folder:before { content: "\f2e0"; }
+
+.ion-android-folder-open:before { content: "\f38a"; }
+
+.ion-android-funnel:before { content: "\f38b"; }
+
+.ion-android-globe:before { content: "\f38c"; }
+
+.ion-android-hand:before { content: "\f2e3"; }
+
+.ion-android-hangout:before { content: "\f38d"; }
+
+.ion-android-happy:before { content: "\f38e"; }
+
+.ion-android-home:before { content: "\f38f"; }
+
+.ion-android-image:before { content: "\f2e4"; }
+
+.ion-android-laptop:before { content: "\f390"; }
+
+.ion-android-list:before { content: "\f391"; }
+
+.ion-android-locate:before { content: "\f2e9"; }
+
+.ion-android-lock:before { content: "\f392"; }
+
+.ion-android-mail:before { content: "\f2eb"; }
+
+.ion-android-map:before { content: "\f393"; }
+
+.ion-android-menu:before { content: "\f394"; }
+
+.ion-android-microphone:before { content: "\f2ec"; }
+
+.ion-android-microphone-off:before { content: "\f395"; }
+
+.ion-android-more-horizontal:before { content: "\f396"; }
+
+.ion-android-more-vertical:before { content: "\f397"; }
+
+.ion-android-navigate:before { content: "\f398"; }
+
+.ion-android-notifications:before { content: "\f39b"; }
+
+.ion-android-notifications-none:before { content: "\f399"; }
+
+.ion-android-notifications-off:before { content: "\f39a"; }
+
+.ion-android-open:before { content: "\f39c"; }
+
+.ion-android-options:before { content: "\f39d"; }
+
+.ion-android-people:before { content: "\f39e"; }
+
+.ion-android-person:before { content: "\f3a0"; }
+
+.ion-android-person-add:before { content: "\f39f"; }
+
+.ion-android-phone-landscape:before { content: "\f3a1"; }
+
+.ion-android-phone-portrait:before { content: "\f3a2"; }
+
+.ion-android-pin:before { content: "\f3a3"; }
+
+.ion-android-plane:before { content: "\f3a4"; }
+
+.ion-android-playstore:before { content: "\f2f0"; }
+
+.ion-android-print:before { content: "\f3a5"; }
+
+.ion-android-radio-button-off:before { content: "\f3a6"; }
+
+.ion-android-radio-button-on:before { content: "\f3a7"; }
+
+.ion-android-refresh:before { content: "\f3a8"; }
+
+.ion-android-remove:before { content: "\f2f4"; }
+
+.ion-android-remove-circle:before { content: "\f3a9"; }
+
+.ion-android-restaurant:before { content: "\f3aa"; }
+
+.ion-android-sad:before { content: "\f3ab"; }
+
+.ion-android-search:before { content: "\f2f5"; }
+
+.ion-android-send:before { content: "\f2f6"; }
+
+.ion-android-settings:before { content: "\f2f7"; }
+
+.ion-android-share:before { content: "\f2f8"; }
+
+.ion-android-share-alt:before { content: "\f3ac"; }
+
+.ion-android-star:before { content: "\f2fc"; }
+
+.ion-android-star-half:before { content: "\f3ad"; }
+
+.ion-android-star-outline:before { content: "\f3ae"; }
+
+.ion-android-stopwatch:before { content: "\f2fd"; }
+
+.ion-android-subway:before { content: "\f3af"; }
+
+.ion-android-sunny:before { content: "\f3b0"; }
+
+.ion-android-sync:before { content: "\f3b1"; }
+
+.ion-android-textsms:before { content: "\f3b2"; }
+
+.ion-android-time:before { content: "\f3b3"; }
+
+.ion-android-train:before { content: "\f3b4"; }
+
+.ion-android-unlock:before { content: "\f3b5"; }
+
+.ion-android-upload:before { content: "\f3b6"; }
+
+.ion-android-volume-down:before { content: "\f3b7"; }
+
+.ion-android-volume-mute:before { content: "\f3b8"; }
+
+.ion-android-volume-off:before { content: "\f3b9"; }
+
+.ion-android-volume-up:before { content: "\f3ba"; }
+
+.ion-android-walk:before { content: "\f3bb"; }
+
+.ion-android-warning:before { content: "\f3bc"; }
+
+.ion-android-watch:before { content: "\f3bd"; }
+
+.ion-android-wifi:before { content: "\f305"; }
+
+.ion-aperture:before { content: "\f313"; }
+
+.ion-archive:before { content: "\f102"; }
+
+.ion-arrow-down-a:before { content: "\f103"; }
+
+.ion-arrow-down-b:before { content: "\f104"; }
+
+.ion-arrow-down-c:before { content: "\f105"; }
+
+.ion-arrow-expand:before { content: "\f25e"; }
+
+.ion-arrow-graph-down-left:before { content: "\f25f"; }
+
+.ion-arrow-graph-down-right:before { content: "\f260"; }
+
+.ion-arrow-graph-up-left:before { content: "\f261"; }
+
+.ion-arrow-graph-up-right:before { content: "\f262"; }
+
+.ion-arrow-left-a:before { content: "\f106"; }
+
+.ion-arrow-left-b:before { content: "\f107"; }
+
+.ion-arrow-left-c:before { content: "\f108"; }
+
+.ion-arrow-move:before { content: "\f263"; }
+
+.ion-arrow-resize:before { content: "\f264"; }
+
+.ion-arrow-return-left:before { content: "\f265"; }
+
+.ion-arrow-return-right:before { content: "\f266"; }
+
+.ion-arrow-right-a:before { content: "\f109"; }
+
+.ion-arrow-right-b:before { content: "\f10a"; }
+
+.ion-arrow-right-c:before { content: "\f10b"; }
+
+.ion-arrow-shrink:before { content: "\f267"; }
+
+.ion-arrow-swap:before { content: "\f268"; }
+
+.ion-arrow-up-a:before { content: "\f10c"; }
+
+.ion-arrow-up-b:before { content: "\f10d"; }
+
+.ion-arrow-up-c:before { content: "\f10e"; }
+
+.ion-asterisk:before { content: "\f314"; }
+
+.ion-at:before { content: "\f10f"; }
+
+.ion-backspace:before { content: "\f3bf"; }
+
+.ion-backspace-outline:before { content: "\f3be"; }
+
+.ion-bag:before { content: "\f110"; }
+
+.ion-battery-charging:before { content: "\f111"; }
+
+.ion-battery-empty:before { content: "\f112"; }
+
+.ion-battery-full:before { content: "\f113"; }
+
+.ion-battery-half:before { content: "\f114"; }
+
+.ion-battery-low:before { content: "\f115"; }
+
+.ion-beaker:before { content: "\f269"; }
+
+.ion-beer:before { content: "\f26a"; }
+
+.ion-bluetooth:before { content: "\f116"; }
+
+.ion-bonfire:before { content: "\f315"; }
+
+.ion-bookmark:before { content: "\f26b"; }
+
+.ion-bowtie:before { content: "\f3c0"; }
+
+.ion-briefcase:before { content: "\f26c"; }
+
+.ion-bug:before { content: "\f2be"; }
+
+.ion-calculator:before { content: "\f26d"; }
+
+.ion-calendar:before { content: "\f117"; }
+
+.ion-camera:before { content: "\f118"; }
+
+.ion-card:before { content: "\f119"; }
+
+.ion-cash:before { content: "\f316"; }
+
+.ion-chatbox:before { content: "\f11b"; }
+
+.ion-chatbox-working:before { content: "\f11a"; }
+
+.ion-chatboxes:before { content: "\f11c"; }
+
+.ion-chatbubble:before { content: "\f11e"; }
+
+.ion-chatbubble-working:before { content: "\f11d"; }
+
+.ion-chatbubbles:before { content: "\f11f"; }
+
+.ion-checkmark:before { content: "\f122"; }
+
+.ion-checkmark-circled:before { content: "\f120"; }
+
+.ion-checkmark-round:before { content: "\f121"; }
+
+.ion-chevron-down:before { content: "\f123"; }
+
+.ion-chevron-left:before { content: "\f124"; }
+
+.ion-chevron-right:before { content: "\f125"; }
+
+.ion-chevron-up:before { content: "\f126"; }
+
+.ion-clipboard:before { content: "\f127"; }
+
+.ion-clock:before { content: "\f26e"; }
+
+.ion-close:before { content: "\f12a"; }
+
+.ion-close-circled:before { content: "\f128"; }
+
+.ion-close-round:before { content: "\f129"; }
+
+.ion-closed-captioning:before { content: "\f317"; }
+
+.ion-cloud:before { content: "\f12b"; }
+
+.ion-code:before { content: "\f271"; }
+
+.ion-code-download:before { content: "\f26f"; }
+
+.ion-code-working:before { content: "\f270"; }
+
+.ion-coffee:before { content: "\f272"; }
+
+.ion-compass:before { content: "\f273"; }
+
+.ion-compose:before { content: "\f12c"; }
+
+.ion-connection-bars:before { content: "\f274"; }
+
+.ion-contrast:before { content: "\f275"; }
+
+.ion-crop:before { content: "\f3c1"; }
+
+.ion-cube:before { content: "\f318"; }
+
+.ion-disc:before { content: "\f12d"; }
+
+.ion-document:before { content: "\f12f"; }
+
+.ion-document-text:before { content: "\f12e"; }
+
+.ion-drag:before { content: "\f130"; }
+
+.ion-earth:before { content: "\f276"; }
+
+.ion-easel:before { content: "\f3c2"; }
+
+.ion-edit:before { content: "\f2bf"; }
+
+.ion-egg:before { content: "\f277"; }
+
+.ion-eject:before { content: "\f131"; }
+
+.ion-email:before { content: "\f132"; }
+
+.ion-email-unread:before { content: "\f3c3"; }
+
+.ion-erlenmeyer-flask:before { content: "\f3c5"; }
+
+.ion-erlenmeyer-flask-bubbles:before { content: "\f3c4"; }
+
+.ion-eye:before { content: "\f133"; }
+
+.ion-eye-disabled:before { content: "\f306"; }
+
+.ion-female:before { content: "\f278"; }
+
+.ion-filing:before { content: "\f134"; }
+
+.ion-film-marker:before { content: "\f135"; }
+
+.ion-fireball:before { content: "\f319"; }
+
+.ion-flag:before { content: "\f279"; }
+
+.ion-flame:before { content: "\f31a"; }
+
+.ion-flash:before { content: "\f137"; }
+
+.ion-flash-off:before { content: "\f136"; }
+
+.ion-folder:before { content: "\f139"; }
+
+.ion-fork:before { content: "\f27a"; }
+
+.ion-fork-repo:before { content: "\f2c0"; }
+
+.ion-forward:before { content: "\f13a"; }
+
+.ion-funnel:before { content: "\f31b"; }
+
+.ion-gear-a:before { content: "\f13d"; }
+
+.ion-gear-b:before { content: "\f13e"; }
+
+.ion-grid:before { content: "\f13f"; }
+
+.ion-hammer:before { content: "\f27b"; }
+
+.ion-happy:before { content: "\f31c"; }
+
+.ion-happy-outline:before { content: "\f3c6"; }
+
+.ion-headphone:before { content: "\f140"; }
+
+.ion-heart:before { content: "\f141"; }
+
+.ion-heart-broken:before { content: "\f31d"; }
+
+.ion-help:before { content: "\f143"; }
+
+.ion-help-buoy:before { content: "\f27c"; }
+
+.ion-help-circled:before { content: "\f142"; }
+
+.ion-home:before { content: "\f144"; }
+
+.ion-icecream:before { content: "\f27d"; }
+
+.ion-image:before { content: "\f147"; }
+
+.ion-images:before { content: "\f148"; }
+
+.ion-information:before { content: "\f14a"; }
+
+.ion-information-circled:before { content: "\f149"; }
+
+.ion-ionic:before { content: "\f14b"; }
+
+.ion-ios-alarm:before { content: "\f3c8"; }
+
+.ion-ios-alarm-outline:before { content: "\f3c7"; }
+
+.ion-ios-albums:before { content: "\f3ca"; }
+
+.ion-ios-albums-outline:before { content: "\f3c9"; }
+
+.ion-ios-americanfootball:before { content: "\f3cc"; }
+
+.ion-ios-americanfootball-outline:before { content: "\f3cb"; }
+
+.ion-ios-analytics:before { content: "\f3ce"; }
+
+.ion-ios-analytics-outline:before { content: "\f3cd"; }
+
+.ion-ios-arrow-back:before { content: "\f3cf"; }
+
+.ion-ios-arrow-down:before { content: "\f3d0"; }
+
+.ion-ios-arrow-forward:before { content: "\f3d1"; }
+
+.ion-ios-arrow-left:before { content: "\f3d2"; }
+
+.ion-ios-arrow-right:before { content: "\f3d3"; }
+
+.ion-ios-arrow-thin-down:before { content: "\f3d4"; }
+
+.ion-ios-arrow-thin-left:before { content: "\f3d5"; }
+
+.ion-ios-arrow-thin-right:before { content: "\f3d6"; }
+
+.ion-ios-arrow-thin-up:before { content: "\f3d7"; }
+
+.ion-ios-arrow-up:before { content: "\f3d8"; }
+
+.ion-ios-at:before { content: "\f3da"; }
+
+.ion-ios-at-outline:before { content: "\f3d9"; }
+
+.ion-ios-barcode:before { content: "\f3dc"; }
+
+.ion-ios-barcode-outline:before { content: "\f3db"; }
+
+.ion-ios-baseball:before { content: "\f3de"; }
+
+.ion-ios-baseball-outline:before { content: "\f3dd"; }
+
+.ion-ios-basketball:before { content: "\f3e0"; }
+
+.ion-ios-basketball-outline:before { content: "\f3df"; }
+
+.ion-ios-bell:before { content: "\f3e2"; }
+
+.ion-ios-bell-outline:before { content: "\f3e1"; }
+
+.ion-ios-body:before { content: "\f3e4"; }
+
+.ion-ios-body-outline:before { content: "\f3e3"; }
+
+.ion-ios-bolt:before { content: "\f3e6"; }
+
+.ion-ios-bolt-outline:before { content: "\f3e5"; }
+
+.ion-ios-book:before { content: "\f3e8"; }
+
+.ion-ios-book-outline:before { content: "\f3e7"; }
+
+.ion-ios-bookmarks:before { content: "\f3ea"; }
+
+.ion-ios-bookmarks-outline:before { content: "\f3e9"; }
+
+.ion-ios-box:before { content: "\f3ec"; }
+
+.ion-ios-box-outline:before { content: "\f3eb"; }
+
+.ion-ios-briefcase:before { content: "\f3ee"; }
+
+.ion-ios-briefcase-outline:before { content: "\f3ed"; }
+
+.ion-ios-browsers:before { content: "\f3f0"; }
+
+.ion-ios-browsers-outline:before { content: "\f3ef"; }
+
+.ion-ios-calculator:before { content: "\f3f2"; }
+
+.ion-ios-calculator-outline:before { content: "\f3f1"; }
+
+.ion-ios-calendar:before { content: "\f3f4"; }
+
+.ion-ios-calendar-outline:before { content: "\f3f3"; }
+
+.ion-ios-camera:before { content: "\f3f6"; }
+
+.ion-ios-camera-outline:before { content: "\f3f5"; }
+
+.ion-ios-cart:before { content: "\f3f8"; }
+
+.ion-ios-cart-outline:before { content: "\f3f7"; }
+
+.ion-ios-chatboxes:before { content: "\f3fa"; }
+
+.ion-ios-chatboxes-outline:before { content: "\f3f9"; }
+
+.ion-ios-chatbubble:before { content: "\f3fc"; }
+
+.ion-ios-chatbubble-outline:before { content: "\f3fb"; }
+
+.ion-ios-checkmark:before { content: "\f3ff"; }
+
+.ion-ios-checkmark-empty:before { content: "\f3fd"; }
+
+.ion-ios-checkmark-outline:before { content: "\f3fe"; }
+
+.ion-ios-circle-filled:before { content: "\f400"; }
+
+.ion-ios-circle-outline:before { content: "\f401"; }
+
+.ion-ios-clock:before { content: "\f403"; }
+
+.ion-ios-clock-outline:before { content: "\f402"; }
+
+.ion-ios-close:before { content: "\f406"; }
+
+.ion-ios-close-empty:before { content: "\f404"; }
+
+.ion-ios-close-outline:before { content: "\f405"; }
+
+.ion-ios-cloud:before { content: "\f40c"; }
+
+.ion-ios-cloud-download:before { content: "\f408"; }
+
+.ion-ios-cloud-download-outline:before { content: "\f407"; }
+
+.ion-ios-cloud-outline:before { content: "\f409"; }
+
+.ion-ios-cloud-upload:before { content: "\f40b"; }
+
+.ion-ios-cloud-upload-outline:before { content: "\f40a"; }
+
+.ion-ios-cloudy:before { content: "\f410"; }
+
+.ion-ios-cloudy-night:before { content: "\f40e"; }
+
+.ion-ios-cloudy-night-outline:before { content: "\f40d"; }
+
+.ion-ios-cloudy-outline:before { content: "\f40f"; }
+
+.ion-ios-cog:before { content: "\f412"; }
+
+.ion-ios-cog-outline:before { content: "\f411"; }
+
+.ion-ios-color-filter:before { content: "\f414"; }
+
+.ion-ios-color-filter-outline:before { content: "\f413"; }
+
+.ion-ios-color-wand:before { content: "\f416"; }
+
+.ion-ios-color-wand-outline:before { content: "\f415"; }
+
+.ion-ios-compose:before { content: "\f418"; }
+
+.ion-ios-compose-outline:before { content: "\f417"; }
+
+.ion-ios-contact:before { content: "\f41a"; }
+
+.ion-ios-contact-outline:before { content: "\f419"; }
+
+.ion-ios-copy:before { content: "\f41c"; }
+
+.ion-ios-copy-outline:before { content: "\f41b"; }
+
+.ion-ios-crop:before { content: "\f41e"; }
+
+.ion-ios-crop-strong:before { content: "\f41d"; }
+
+.ion-ios-download:before { content: "\f420"; }
+
+.ion-ios-download-outline:before { content: "\f41f"; }
+
+.ion-ios-drag:before { content: "\f421"; }
+
+.ion-ios-email:before { content: "\f423"; }
+
+.ion-ios-email-outline:before { content: "\f422"; }
+
+.ion-ios-eye:before { content: "\f425"; }
+
+.ion-ios-eye-outline:before { content: "\f424"; }
+
+.ion-ios-fastforward:before { content: "\f427"; }
+
+.ion-ios-fastforward-outline:before { content: "\f426"; }
+
+.ion-ios-filing:before { content: "\f429"; }
+
+.ion-ios-filing-outline:before { content: "\f428"; }
+
+.ion-ios-film:before { content: "\f42b"; }
+
+.ion-ios-film-outline:before { content: "\f42a"; }
+
+.ion-ios-flag:before { content: "\f42d"; }
+
+.ion-ios-flag-outline:before { content: "\f42c"; }
+
+.ion-ios-flame:before { content: "\f42f"; }
+
+.ion-ios-flame-outline:before { content: "\f42e"; }
+
+.ion-ios-flask:before { content: "\f431"; }
+
+.ion-ios-flask-outline:before { content: "\f430"; }
+
+.ion-ios-flower:before { content: "\f433"; }
+
+.ion-ios-flower-outline:before { content: "\f432"; }
+
+.ion-ios-folder:before { content: "\f435"; }
+
+.ion-ios-folder-outline:before { content: "\f434"; }
+
+.ion-ios-football:before { content: "\f437"; }
+
+.ion-ios-football-outline:before { content: "\f436"; }
+
+.ion-ios-game-controller-a:before { content: "\f439"; }
+
+.ion-ios-game-controller-a-outline:before { content: "\f438"; }
+
+.ion-ios-game-controller-b:before { content: "\f43b"; }
+
+.ion-ios-game-controller-b-outline:before { content: "\f43a"; }
+
+.ion-ios-gear:before { content: "\f43d"; }
+
+.ion-ios-gear-outline:before { content: "\f43c"; }
+
+.ion-ios-glasses:before { content: "\f43f"; }
+
+.ion-ios-glasses-outline:before { content: "\f43e"; }
+
+.ion-ios-grid-view:before { content: "\f441"; }
+
+.ion-ios-grid-view-outline:before { content: "\f440"; }
+
+.ion-ios-heart:before { content: "\f443"; }
+
+.ion-ios-heart-outline:before { content: "\f442"; }
+
+.ion-ios-help:before { content: "\f446"; }
+
+.ion-ios-help-empty:before { content: "\f444"; }
+
+.ion-ios-help-outline:before { content: "\f445"; }
+
+.ion-ios-home:before { content: "\f448"; }
+
+.ion-ios-home-outline:before { content: "\f447"; }
+
+.ion-ios-infinite:before { content: "\f44a"; }
+
+.ion-ios-infinite-outline:before { content: "\f449"; }
+
+.ion-ios-information:before { content: "\f44d"; }
+
+.ion-ios-information-empty:before { content: "\f44b"; }
+
+.ion-ios-information-outline:before { content: "\f44c"; }
+
+.ion-ios-ionic-outline:before { content: "\f44e"; }
+
+.ion-ios-keypad:before { content: "\f450"; }
+
+.ion-ios-keypad-outline:before { content: "\f44f"; }
+
+.ion-ios-lightbulb:before { content: "\f452"; }
+
+.ion-ios-lightbulb-outline:before { content: "\f451"; }
+
+.ion-ios-list:before { content: "\f454"; }
+
+.ion-ios-list-outline:before { content: "\f453"; }
+
+.ion-ios-location:before { content: "\f456"; }
+
+.ion-ios-location-outline:before { content: "\f455"; }
+
+.ion-ios-locked:before { content: "\f458"; }
+
+.ion-ios-locked-outline:before { content: "\f457"; }
+
+.ion-ios-loop:before { content: "\f45a"; }
+
+.ion-ios-loop-strong:before { content: "\f459"; }
+
+.ion-ios-medical:before { content: "\f45c"; }
+
+.ion-ios-medical-outline:before { content: "\f45b"; }
+
+.ion-ios-medkit:before { content: "\f45e"; }
+
+.ion-ios-medkit-outline:before { content: "\f45d"; }
+
+.ion-ios-mic:before { content: "\f461"; }
+
+.ion-ios-mic-off:before { content: "\f45f"; }
+
+.ion-ios-mic-outline:before { content: "\f460"; }
+
+.ion-ios-minus:before { content: "\f464"; }
+
+.ion-ios-minus-empty:before { content: "\f462"; }
+
+.ion-ios-minus-outline:before { content: "\f463"; }
+
+.ion-ios-monitor:before { content: "\f466"; }
+
+.ion-ios-monitor-outline:before { content: "\f465"; }
+
+.ion-ios-moon:before { content: "\f468"; }
+
+.ion-ios-moon-outline:before { content: "\f467"; }
+
+.ion-ios-more:before { content: "\f46a"; }
+
+.ion-ios-more-outline:before { content: "\f469"; }
+
+.ion-ios-musical-note:before { content: "\f46b"; }
+
+.ion-ios-musical-notes:before { content: "\f46c"; }
+
+.ion-ios-navigate:before { content: "\f46e"; }
+
+.ion-ios-navigate-outline:before { content: "\f46d"; }
+
+.ion-ios-nutrition:before { content: "\f470"; }
+
+.ion-ios-nutrition-outline:before { content: "\f46f"; }
+
+.ion-ios-paper:before { content: "\f472"; }
+
+.ion-ios-paper-outline:before { content: "\f471"; }
+
+.ion-ios-paperplane:before { content: "\f474"; }
+
+.ion-ios-paperplane-outline:before { content: "\f473"; }
+
+.ion-ios-partlysunny:before { content: "\f476"; }
+
+.ion-ios-partlysunny-outline:before { content: "\f475"; }
+
+.ion-ios-pause:before { content: "\f478"; }
+
+.ion-ios-pause-outline:before { content: "\f477"; }
+
+.ion-ios-paw:before { content: "\f47a"; }
+
+.ion-ios-paw-outline:before { content: "\f479"; }
+
+.ion-ios-people:before { content: "\f47c"; }
+
+.ion-ios-people-outline:before { content: "\f47b"; }
+
+.ion-ios-person:before { content: "\f47e"; }
+
+.ion-ios-person-outline:before { content: "\f47d"; }
+
+.ion-ios-personadd:before { content: "\f480"; }
+
+.ion-ios-personadd-outline:before { content: "\f47f"; }
+
+.ion-ios-photos:before { content: "\f482"; }
+
+.ion-ios-photos-outline:before { content: "\f481"; }
+
+.ion-ios-pie:before { content: "\f484"; }
+
+.ion-ios-pie-outline:before { content: "\f483"; }
+
+.ion-ios-pint:before { content: "\f486"; }
+
+.ion-ios-pint-outline:before { content: "\f485"; }
+
+.ion-ios-play:before { content: "\f488"; }
+
+.ion-ios-play-outline:before { content: "\f487"; }
+
+.ion-ios-plus:before { content: "\f48b"; }
+
+.ion-ios-plus-empty:before { content: "\f489"; }
+
+.ion-ios-plus-outline:before { content: "\f48a"; }
+
+.ion-ios-pricetag:before { content: "\f48d"; }
+
+.ion-ios-pricetag-outline:before { content: "\f48c"; }
+
+.ion-ios-pricetags:before { content: "\f48f"; }
+
+.ion-ios-pricetags-outline:before { content: "\f48e"; }
+
+.ion-ios-printer:before { content: "\f491"; }
+
+.ion-ios-printer-outline:before { content: "\f490"; }
+
+.ion-ios-pulse:before { content: "\f493"; }
+
+.ion-ios-pulse-strong:before { content: "\f492"; }
+
+.ion-ios-rainy:before { content: "\f495"; }
+
+.ion-ios-rainy-outline:before { content: "\f494"; }
+
+.ion-ios-recording:before { content: "\f497"; }
+
+.ion-ios-recording-outline:before { content: "\f496"; }
+
+.ion-ios-redo:before { content: "\f499"; }
+
+.ion-ios-redo-outline:before { content: "\f498"; }
+
+.ion-ios-refresh:before { content: "\f49c"; }
+
+.ion-ios-refresh-empty:before { content: "\f49a"; }
+
+.ion-ios-refresh-outline:before { content: "\f49b"; }
+
+.ion-ios-reload:before { content: "\f49d"; }
+
+.ion-ios-reverse-camera:before { content: "\f49f"; }
+
+.ion-ios-reverse-camera-outline:before { content: "\f49e"; }
+
+.ion-ios-rewind:before { content: "\f4a1"; }
+
+.ion-ios-rewind-outline:before { content: "\f4a0"; }
+
+.ion-ios-rose:before { content: "\f4a3"; }
+
+.ion-ios-rose-outline:before { content: "\f4a2"; }
+
+.ion-ios-search:before { content: "\f4a5"; }
+
+.ion-ios-search-strong:before { content: "\f4a4"; }
+
+.ion-ios-settings:before { content: "\f4a7"; }
+
+.ion-ios-settings-strong:before { content: "\f4a6"; }
+
+.ion-ios-shuffle:before { content: "\f4a9"; }
+
+.ion-ios-shuffle-strong:before { content: "\f4a8"; }
+
+.ion-ios-skipbackward:before { content: "\f4ab"; }
+
+.ion-ios-skipbackward-outline:before { content: "\f4aa"; }
+
+.ion-ios-skipforward:before { content: "\f4ad"; }
+
+.ion-ios-skipforward-outline:before { content: "\f4ac"; }
+
+.ion-ios-snowy:before { content: "\f4ae"; }
+
+.ion-ios-speedometer:before { content: "\f4b0"; }
+
+.ion-ios-speedometer-outline:before { content: "\f4af"; }
+
+.ion-ios-star:before { content: "\f4b3"; }
+
+.ion-ios-star-half:before { content: "\f4b1"; }
+
+.ion-ios-star-outline:before { content: "\f4b2"; }
+
+.ion-ios-stopwatch:before { content: "\f4b5"; }
+
+.ion-ios-stopwatch-outline:before { content: "\f4b4"; }
+
+.ion-ios-sunny:before { content: "\f4b7"; }
+
+.ion-ios-sunny-outline:before { content: "\f4b6"; }
+
+.ion-ios-telephone:before { content: "\f4b9"; }
+
+.ion-ios-telephone-outline:before { content: "\f4b8"; }
+
+.ion-ios-tennisball:before { content: "\f4bb"; }
+
+.ion-ios-tennisball-outline:before { content: "\f4ba"; }
+
+.ion-ios-thunderstorm:before { content: "\f4bd"; }
+
+.ion-ios-thunderstorm-outline:before { content: "\f4bc"; }
+
+.ion-ios-time:before { content: "\f4bf"; }
+
+.ion-ios-time-outline:before { content: "\f4be"; }
+
+.ion-ios-timer:before { content: "\f4c1"; }
+
+.ion-ios-timer-outline:before { content: "\f4c0"; }
+
+.ion-ios-toggle:before { content: "\f4c3"; }
+
+.ion-ios-toggle-outline:before { content: "\f4c2"; }
+
+.ion-ios-trash:before { content: "\f4c5"; }
+
+.ion-ios-trash-outline:before { content: "\f4c4"; }
+
+.ion-ios-undo:before { content: "\f4c7"; }
+
+.ion-ios-undo-outline:before { content: "\f4c6"; }
+
+.ion-ios-unlocked:before { content: "\f4c9"; }
+
+.ion-ios-unlocked-outline:before { content: "\f4c8"; }
+
+.ion-ios-upload:before { content: "\f4cb"; }
+
+.ion-ios-upload-outline:before { content: "\f4ca"; }
+
+.ion-ios-videocam:before { content: "\f4cd"; }
+
+.ion-ios-videocam-outline:before { content: "\f4cc"; }
+
+.ion-ios-volume-high:before { content: "\f4ce"; }
+
+.ion-ios-volume-low:before { content: "\f4cf"; }
+
+.ion-ios-wineglass:before { content: "\f4d1"; }
+
+.ion-ios-wineglass-outline:before { content: "\f4d0"; }
+
+.ion-ios-world:before { content: "\f4d3"; }
+
+.ion-ios-world-outline:before { content: "\f4d2"; }
+
+.ion-ipad:before { content: "\f1f9"; }
+
+.ion-iphone:before { content: "\f1fa"; }
+
+.ion-ipod:before { content: "\f1fb"; }
+
+.ion-jet:before { content: "\f295"; }
+
+.ion-key:before { content: "\f296"; }
+
+.ion-knife:before { content: "\f297"; }
+
+.ion-laptop:before { content: "\f1fc"; }
+
+.ion-leaf:before { content: "\f1fd"; }
+
+.ion-levels:before { content: "\f298"; }
+
+.ion-lightbulb:before { content: "\f299"; }
+
+.ion-link:before { content: "\f1fe"; }
+
+.ion-load-a:before { content: "\f29a"; }
+
+.ion-load-b:before { content: "\f29b"; }
+
+.ion-load-c:before { content: "\f29c"; }
+
+.ion-load-d:before { content: "\f29d"; }
+
+.ion-location:before { content: "\f1ff"; }
+
+.ion-lock-combination:before { content: "\f4d4"; }
+
+.ion-locked:before { content: "\f200"; }
+
+.ion-log-in:before { content: "\f29e"; }
+
+.ion-log-out:before { content: "\f29f"; }
+
+.ion-loop:before { content: "\f201"; }
+
+.ion-magnet:before { content: "\f2a0"; }
+
+.ion-male:before { content: "\f2a1"; }
+
+.ion-man:before { content: "\f202"; }
+
+.ion-map:before { content: "\f203"; }
+
+.ion-medkit:before { content: "\f2a2"; }
+
+.ion-merge:before { content: "\f33f"; }
+
+.ion-mic-a:before { content: "\f204"; }
+
+.ion-mic-b:before { content: "\f205"; }
+
+.ion-mic-c:before { content: "\f206"; }
+
+.ion-minus:before { content: "\f209"; }
+
+.ion-minus-circled:before { content: "\f207"; }
+
+.ion-minus-round:before { content: "\f208"; }
+
+.ion-model-s:before { content: "\f2c1"; }
+
+.ion-monitor:before { content: "\f20a"; }
+
+.ion-more:before { content: "\f20b"; }
+
+.ion-mouse:before { content: "\f340"; }
+
+.ion-music-note:before { content: "\f20c"; }
+
+.ion-navicon:before { content: "\f20e"; }
+
+.ion-navicon-round:before { content: "\f20d"; }
+
+.ion-navigate:before { content: "\f2a3"; }
+
+.ion-network:before { content: "\f341"; }
+
+.ion-no-smoking:before { content: "\f2c2"; }
+
+.ion-nuclear:before { content: "\f2a4"; }
+
+.ion-outlet:before { content: "\f342"; }
+
+.ion-paintbrush:before { content: "\f4d5"; }
+
+.ion-paintbucket:before { content: "\f4d6"; }
+
+.ion-paper-airplane:before { content: "\f2c3"; }
+
+.ion-paperclip:before { content: "\f20f"; }
+
+.ion-pause:before { content: "\f210"; }
+
+.ion-person:before { content: "\f213"; }
+
+.ion-person-add:before { content: "\f211"; }
+
+.ion-person-stalker:before { content: "\f212"; }
+
+.ion-pie-graph:before { content: "\f2a5"; }
+
+.ion-pin:before { content: "\f2a6"; }
+
+.ion-pinpoint:before { content: "\f2a7"; }
+
+.ion-pizza:before { content: "\f2a8"; }
+
+.ion-plane:before { content: "\f214"; }
+
+.ion-planet:before { content: "\f343"; }
+
+.ion-play:before { content: "\f215"; }
+
+.ion-playstation:before { content: "\f30a"; }
+
+.ion-plus:before { content: "\f218"; }
+
+.ion-plus-circled:before { content: "\f216"; }
+
+.ion-plus-round:before { content: "\f217"; }
+
+.ion-podium:before { content: "\f344"; }
+
+.ion-pound:before { content: "\f219"; }
+
+.ion-power:before { content: "\f2a9"; }
+
+.ion-pricetag:before { content: "\f2aa"; }
+
+.ion-pricetags:before { content: "\f2ab"; }
+
+.ion-printer:before { content: "\f21a"; }
+
+.ion-pull-request:before { content: "\f345"; }
+
+.ion-qr-scanner:before { content: "\f346"; }
+
+.ion-quote:before { content: "\f347"; }
+
+.ion-radio-waves:before { content: "\f2ac"; }
+
+.ion-record:before { content: "\f21b"; }
+
+.ion-refresh:before { content: "\f21c"; }
+
+.ion-reply:before { content: "\f21e"; }
+
+.ion-reply-all:before { content: "\f21d"; }
+
+.ion-ribbon-a:before { content: "\f348"; }
+
+.ion-ribbon-b:before { content: "\f349"; }
+
+.ion-sad:before { content: "\f34a"; }
+
+.ion-sad-outline:before { content: "\f4d7"; }
+
+.ion-scissors:before { content: "\f34b"; }
+
+.ion-search:before { content: "\f21f"; }
+
+.ion-settings:before { content: "\f2ad"; }
+
+.ion-share:before { content: "\f220"; }
+
+.ion-shuffle:before { content: "\f221"; }
+
+.ion-skip-backward:before { content: "\f222"; }
+
+.ion-skip-forward:before { content: "\f223"; }
+
+.ion-social-android:before { content: "\f225"; }
+
+.ion-social-android-outline:before { content: "\f224"; }
+
+.ion-social-angular:before { content: "\f4d9"; }
+
+.ion-social-angular-outline:before { content: "\f4d8"; }
+
+.ion-social-apple:before { content: "\f227"; }
+
+.ion-social-apple-outline:before { content: "\f226"; }
+
+.ion-social-bitcoin:before { content: "\f2af"; }
+
+.ion-social-bitcoin-outline:before { content: "\f2ae"; }
+
+.ion-social-buffer:before { content: "\f229"; }
+
+.ion-social-buffer-outline:before { content: "\f228"; }
+
+.ion-social-chrome:before { content: "\f4db"; }
+
+.ion-social-chrome-outline:before { content: "\f4da"; }
+
+.ion-social-codepen:before { content: "\f4dd"; }
+
+.ion-social-codepen-outline:before { content: "\f4dc"; }
+
+.ion-social-css3:before { content: "\f4df"; }
+
+.ion-social-css3-outline:before { content: "\f4de"; }
+
+.ion-social-designernews:before { content: "\f22b"; }
+
+.ion-social-designernews-outline:before { content: "\f22a"; }
+
+.ion-social-dribbble:before { content: "\f22d"; }
+
+.ion-social-dribbble-outline:before { content: "\f22c"; }
+
+.ion-social-dropbox:before { content: "\f22f"; }
+
+.ion-social-dropbox-outline:before { content: "\f22e"; }
+
+.ion-social-euro:before { content: "\f4e1"; }
+
+.ion-social-euro-outline:before { content: "\f4e0"; }
+
+.ion-social-facebook:before { content: "\f231"; }
+
+.ion-social-facebook-outline:before { content: "\f230"; }
+
+.ion-social-foursquare:before { content: "\f34d"; }
+
+.ion-social-foursquare-outline:before { content: "\f34c"; }
+
+.ion-social-freebsd-devil:before { content: "\f2c4"; }
+
+.ion-social-github:before { content: "\f233"; }
+
+.ion-social-github-outline:before { content: "\f232"; }
+
+.ion-social-google:before { content: "\f34f"; }
+
+.ion-social-google-outline:before { content: "\f34e"; }
+
+.ion-social-googleplus:before { content: "\f235"; }
+
+.ion-social-googleplus-outline:before { content: "\f234"; }
+
+.ion-social-hackernews:before { content: "\f237"; }
+
+.ion-social-hackernews-outline:before { content: "\f236"; }
+
+.ion-social-html5:before { content: "\f4e3"; }
+
+.ion-social-html5-outline:before { content: "\f4e2"; }
+
+.ion-social-instagram:before { content: "\f351"; }
+
+.ion-social-instagram-outline:before { content: "\f350"; }
+
+.ion-social-javascript:before { content: "\f4e5"; }
+
+.ion-social-javascript-outline:before { content: "\f4e4"; }
+
+.ion-social-linkedin:before { content: "\f239"; }
+
+.ion-social-linkedin-outline:before { content: "\f238"; }
+
+.ion-social-markdown:before { content: "\f4e6"; }
+
+.ion-social-nodejs:before { content: "\f4e7"; }
+
+.ion-social-octocat:before { content: "\f4e8"; }
+
+.ion-social-pinterest:before { content: "\f2b1"; }
+
+.ion-social-pinterest-outline:before { content: "\f2b0"; }
+
+.ion-social-python:before { content: "\f4e9"; }
+
+.ion-social-reddit:before { content: "\f23b"; }
+
+.ion-social-reddit-outline:before { content: "\f23a"; }
+
+.ion-social-rss:before { content: "\f23d"; }
+
+.ion-social-rss-outline:before { content: "\f23c"; }
+
+.ion-social-sass:before { content: "\f4ea"; }
+
+.ion-social-skype:before { content: "\f23f"; }
+
+.ion-social-skype-outline:before { content: "\f23e"; }
+
+.ion-social-snapchat:before { content: "\f4ec"; }
+
+.ion-social-snapchat-outline:before { content: "\f4eb"; }
+
+.ion-social-tumblr:before { content: "\f241"; }
+
+.ion-social-tumblr-outline:before { content: "\f240"; }
+
+.ion-social-tux:before { content: "\f2c5"; }
+
+.ion-social-twitch:before { content: "\f4ee"; }
+
+.ion-social-twitch-outline:before { content: "\f4ed"; }
+
+.ion-social-twitter:before { content: "\f243"; }
+
+.ion-social-twitter-outline:before { content: "\f242"; }
+
+.ion-social-usd:before { content: "\f353"; }
+
+.ion-social-usd-outline:before { content: "\f352"; }
+
+.ion-social-vimeo:before { content: "\f245"; }
+
+.ion-social-vimeo-outline:before { content: "\f244"; }
+
+.ion-social-whatsapp:before { content: "\f4f0"; }
+
+.ion-social-whatsapp-outline:before { content: "\f4ef"; }
+
+.ion-social-windows:before { content: "\f247"; }
+
+.ion-social-windows-outline:before { content: "\f246"; }
+
+.ion-social-wordpress:before { content: "\f249"; }
+
+.ion-social-wordpress-outline:before { content: "\f248"; }
+
+.ion-social-yahoo:before { content: "\f24b"; }
+
+.ion-social-yahoo-outline:before { content: "\f24a"; }
+
+.ion-social-yen:before { content: "\f4f2"; }
+
+.ion-social-yen-outline:before { content: "\f4f1"; }
+
+.ion-social-youtube:before { content: "\f24d"; }
+
+.ion-social-youtube-outline:before { content: "\f24c"; }
+
+.ion-soup-can:before { content: "\f4f4"; }
+
+.ion-soup-can-outline:before { content: "\f4f3"; }
+
+.ion-speakerphone:before { content: "\f2b2"; }
+
+.ion-speedometer:before { content: "\f2b3"; }
+
+.ion-spoon:before { content: "\f2b4"; }
+
+.ion-star:before { content: "\f24e"; }
+
+.ion-stats-bars:before { content: "\f2b5"; }
+
+.ion-steam:before { content: "\f30b"; }
+
+.ion-stop:before { content: "\f24f"; }
+
+.ion-thermometer:before { content: "\f2b6"; }
+
+.ion-thumbsdown:before { content: "\f250"; }
+
+.ion-thumbsup:before { content: "\f251"; }
+
+.ion-toggle:before { content: "\f355"; }
+
+.ion-toggle-filled:before { content: "\f354"; }
+
+.ion-transgender:before { content: "\f4f5"; }
+
+.ion-trash-a:before { content: "\f252"; }
+
+.ion-trash-b:before { content: "\f253"; }
+
+.ion-trophy:before { content: "\f356"; }
+
+.ion-tshirt:before { content: "\f4f7"; }
+
+.ion-tshirt-outline:before { content: "\f4f6"; }
+
+.ion-umbrella:before { content: "\f2b7"; }
+
+.ion-university:before { content: "\f357"; }
+
+.ion-unlocked:before { content: "\f254"; }
+
+.ion-upload:before { content: "\f255"; }
+
+.ion-usb:before { content: "\f2b8"; }
+
+.ion-videocamera:before { content: "\f256"; }
+
+.ion-volume-high:before { content: "\f257"; }
+
+.ion-volume-low:before { content: "\f258"; }
+
+.ion-volume-medium:before { content: "\f259"; }
+
+.ion-volume-mute:before { content: "\f25a"; }
+
+.ion-wand:before { content: "\f358"; }
+
+.ion-waterdrop:before { content: "\f25b"; }
+
+.ion-wifi:before { content: "\f25c"; }
+
+.ion-wineglass:before { content: "\f2b9"; }
+
+.ion-woman:before { content: "\f25d"; }
+
+.ion-wrench:before { content: "\f2ba"; }
+
+.ion-xbox:before { content: "\f30c"; }
diff --git a/tests/testbed/app/fonts/ionicons.ttf b/tests/testbed/app/fonts/ionicons.ttf
new file mode 100644
index 000000000..c4e463248
Binary files /dev/null and b/tests/testbed/app/fonts/ionicons.ttf differ
diff --git a/tests/testbed/app/item/item-detail.component.d.ts b/tests/testbed/app/item/item-detail.component.d.ts
new file mode 100644
index 000000000..8dedb4801
--- /dev/null
+++ b/tests/testbed/app/item/item-detail.component.d.ts
@@ -0,0 +1,11 @@
+import { OnInit } from "@angular/core";
+import { ActivatedRoute } from "@angular/router";
+import { Item } from "./item";
+import { ItemService } from "./item.service";
+export declare class ItemDetailComponent implements OnInit {
+ private itemService;
+ private route;
+ item: Item;
+ constructor(itemService: ItemService, route: ActivatedRoute);
+ ngOnInit(): void;
+}
diff --git a/tests/testbed/app/item/item-detail.component.html b/tests/testbed/app/item/item-detail.component.html
new file mode 100644
index 000000000..3bbd174c0
--- /dev/null
+++ b/tests/testbed/app/item/item-detail.component.html
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/tests/testbed/app/item/item-detail.component.ts b/tests/testbed/app/item/item-detail.component.ts
new file mode 100644
index 000000000..9183f7876
--- /dev/null
+++ b/tests/testbed/app/item/item-detail.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit } from "@angular/core";
+import { ActivatedRoute } from "@angular/router";
+
+import { Item } from "./item";
+import { ItemService } from "./item.service";
+
+@Component({
+ selector: "ns-details",
+ moduleId: module.id,
+ templateUrl: "./item-detail.component.html",
+})
+export class ItemDetailComponent implements OnInit {
+ item: Item;
+
+ constructor(
+ private itemService: ItemService,
+ private route: ActivatedRoute
+ ) { }
+
+ ngOnInit(): void {
+ const id = +this.route.snapshot.params["id"];
+ this.item = this.itemService.getItem(id);
+ }
+}
diff --git a/tests/testbed/app/item/item.d.ts b/tests/testbed/app/item/item.d.ts
new file mode 100644
index 000000000..ab7c77a3b
--- /dev/null
+++ b/tests/testbed/app/item/item.d.ts
@@ -0,0 +1,5 @@
+export declare class Item {
+ id: number;
+ name: string;
+ role: string;
+}
diff --git a/tests/testbed/app/item/item.service.d.ts b/tests/testbed/app/item/item.service.d.ts
new file mode 100644
index 000000000..6cf55ec2e
--- /dev/null
+++ b/tests/testbed/app/item/item.service.d.ts
@@ -0,0 +1,6 @@
+import { Item } from "./item";
+export declare class ItemService {
+ private items;
+ getItems(): Item[];
+ getItem(id: number): Item;
+}
diff --git a/tests/testbed/app/item/item.service.ts b/tests/testbed/app/item/item.service.ts
new file mode 100644
index 000000000..0feb6c5ff
--- /dev/null
+++ b/tests/testbed/app/item/item.service.ts
@@ -0,0 +1,39 @@
+import { Injectable } from "@angular/core";
+
+import { Item } from "./item";
+
+@Injectable()
+export class ItemService {
+ private items = new Array- (
+ { id: 1, name: "Ter Stegen", role: "Goalkeeper" },
+ { id: 3, name: "Piqué", role: "Defender" },
+ { id: 4, name: "I. Rakitic", role: "Midfielder" },
+ { id: 5, name: "Sergio", role: "Midfielder" },
+ { id: 6, name: "Denis Suárez", role: "Midfielder" },
+ { id: 7, name: "Arda", role: "Midfielder" },
+ { id: 8, name: "A. Iniesta", role: "Midfielder" },
+ { id: 9, name: "Suárez", role: "Forward" },
+ { id: 10, name: "Messi", role: "Forward" },
+ { id: 11, name: "Neymar", role: "Forward" },
+ { id: 12, name: "Rafinha", role: "Midfielder" },
+ { id: 13, name: "Cillessen", role: "Goalkeeper" },
+ { id: 14, name: "Mascherano", role: "Defender" },
+ { id: 17, name: "Paco Alcácer", role: "Forward" },
+ { id: 18, name: "Jordi Alba", role: "Defender" },
+ { id: 19, name: "Digne", role: "Defender" },
+ { id: 20, name: "Sergi Roberto", role: "Midfielder" },
+ { id: 21, name: "André Gomes", role: "Midfielder" },
+ { id: 22, name: "Aleix Vidal", role: "Midfielder" },
+ { id: 23, name: "Umtiti", role: "Defender" },
+ { id: 24, name: "Mathieu", role: "Defender" },
+ { id: 25, name: "Masip", role: "Goalkeeper" },
+ );
+
+ getItems(): Item[] {
+ return this.items;
+ }
+
+ getItem(id: number): Item {
+ return this.items.filter(item => item.id === id)[0];
+ }
+}
diff --git a/tests/testbed/app/item/item.ts b/tests/testbed/app/item/item.ts
new file mode 100644
index 000000000..02e2b01bb
--- /dev/null
+++ b/tests/testbed/app/item/item.ts
@@ -0,0 +1,5 @@
+export class Item {
+ id: number;
+ name: string;
+ role: string;
+}
diff --git a/tests/testbed/app/item/items.component.d.ts b/tests/testbed/app/item/items.component.d.ts
new file mode 100644
index 000000000..ec4da37cb
--- /dev/null
+++ b/tests/testbed/app/item/items.component.d.ts
@@ -0,0 +1,9 @@
+import { OnInit } from "@angular/core";
+import { Item } from "./item";
+import { ItemService } from "./item.service";
+export declare class ItemsComponent implements OnInit {
+ private itemService;
+ items: Item[];
+ constructor(itemService: ItemService);
+ ngOnInit(): void;
+}
diff --git a/tests/testbed/app/item/items.component.html b/tests/testbed/app/item/items.component.html
new file mode 100644
index 000000000..b1a6e852e
--- /dev/null
+++ b/tests/testbed/app/item/items.component.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/tests/testbed/app/item/items.component.ts b/tests/testbed/app/item/items.component.ts
new file mode 100644
index 000000000..aa65fd226
--- /dev/null
+++ b/tests/testbed/app/item/items.component.ts
@@ -0,0 +1,19 @@
+import { Component, OnInit } from "@angular/core";
+
+import { Item } from "./item";
+import { ItemService } from "./item.service";
+
+@Component({
+ selector: "ns-items",
+ moduleId: module.id,
+ templateUrl: "./items.component.html",
+})
+export class ItemsComponent implements OnInit {
+ items: Item[];
+
+ constructor(private itemService: ItemService) { }
+
+ ngOnInit(): void {
+ this.items = this.itemService.getItems();
+ }
+}
diff --git a/tests/testbed/app/main.aot.d.ts b/tests/testbed/app/main.aot.d.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/testbed/app/main.aot.ts b/tests/testbed/app/main.aot.ts
new file mode 100644
index 000000000..8f033e9cd
--- /dev/null
+++ b/tests/testbed/app/main.aot.ts
@@ -0,0 +1,6 @@
+// this import should be first in order to load some required settings (like globals and reflect-metadata)
+import { platformNativeScript } from "nativescript-angular/platform-static";
+
+import { AppModuleNgFactory } from "./app.module.ngfactory";
+
+platformNativeScript().bootstrapModuleFactory(AppModuleNgFactory);
diff --git a/tests/testbed/app/main.d.ts b/tests/testbed/app/main.d.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/testbed/app/main.ts b/tests/testbed/app/main.ts
new file mode 100644
index 000000000..1057aef25
--- /dev/null
+++ b/tests/testbed/app/main.ts
@@ -0,0 +1,6 @@
+// this import should be first in order to load some required settings (like globals and reflect-metadata)
+import { platformNativeScriptDynamic } from "nativescript-angular/platform";
+
+import { AppModule } from "./app.module";
+
+platformNativeScriptDynamic().bootstrapModule(AppModule);
diff --git a/tests/testbed/app/package.json b/tests/testbed/app/package.json
new file mode 100644
index 000000000..8f5374a3b
--- /dev/null
+++ b/tests/testbed/app/package.json
@@ -0,0 +1,8 @@
+{
+ "android": {
+ "v8Flags": "--expose_gc"
+ },
+ "main": "main.js",
+ "name": "tns-template-hello-world-ng",
+ "version": "2.5.0"
+}
\ No newline at end of file
diff --git a/tests/testbed/app/tests/app-component-tests.ts b/tests/testbed/app/tests/app-component-tests.ts
new file mode 100644
index 000000000..3bf11e966
--- /dev/null
+++ b/tests/testbed/app/tests/app-component-tests.ts
@@ -0,0 +1,19 @@
+import { inject, TestBed } from '@angular/core/testing';
+import { AppComponent } from '../app.component';
+
+describe('AppComponent', () => {
+
+ // provide our implementations or mocks to the dependency injector
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [
+ AppComponent
+ ]
+ });
+ });
+
+ it('should init', inject([AppComponent], (appComponent: AppComponent) => {
+ expect(appComponent).toBeDefined;
+ }));
+
+});
diff --git a/tests/testbed/app/vendor-platform.android.ts b/tests/testbed/app/vendor-platform.android.ts
new file mode 100644
index 000000000..ba9742fd9
--- /dev/null
+++ b/tests/testbed/app/vendor-platform.android.ts
@@ -0,0 +1,25 @@
+// Resolve JavaScript classes that extend a Java class, and need to resolve
+// their JavaScript module from a bundled script. For example:
+// NativeScriptApplication, NativeScriptActivity, etc.
+//
+// This module gets bundled together with the rest of the app code and the
+// `require` calls get resolved to the correct bundling import call.
+//
+// At runtime the module gets loaded *before* the rest of the app code, so code
+// placed here needs to be careful about its dependencies.
+
+require("application");
+require("ui/frame");
+require("ui/frame/activity");
+
+if (global.TNS_WEBPACK) {
+ global.__requireOverride = function (name, dir) {
+ if (name === "./tns_modules/application/application.js") {
+ return require("application");
+ } else if (name === "./tns_modules/ui/frame/frame.js") {
+ return require("ui/frame");
+ } else if (name === "./tns_modules/ui/frame/activity.js") {
+ return require("ui/frame/activity");
+ }
+ };
+}
diff --git a/tests/testbed/app/vendor-platform.ios.ts b/tests/testbed/app/vendor-platform.ios.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/testbed/app/vendor.ts b/tests/testbed/app/vendor.ts
new file mode 100644
index 000000000..0d969654b
--- /dev/null
+++ b/tests/testbed/app/vendor.ts
@@ -0,0 +1,13 @@
+require("./vendor-platform");
+
+require("reflect-metadata");
+require("@angular/platform-browser");
+require("@angular/core");
+require("@angular/common");
+require("@angular/forms");
+require("@angular/http");
+require("@angular/router");
+
+require("nativescript-angular/platform-static");
+require("nativescript-angular/forms");
+require("nativescript-angular/router");
diff --git a/tests/testbed/hooks/after-prepare/nativescript-dev-android-snapshot.js b/tests/testbed/hooks/after-prepare/nativescript-dev-android-snapshot.js
new file mode 100644
index 000000000..f49441182
--- /dev/null
+++ b/tests/testbed/hooks/after-prepare/nativescript-dev-android-snapshot.js
@@ -0,0 +1 @@
+module.exports = require("nativescript-dev-android-snapshot/hooks/after-prepare-hook.js");
diff --git a/tests/hooks/before-livesync/nativescript-angular-sync.js b/tests/testbed/hooks/before-livesync/nativescript-angular-sync.js
similarity index 100%
rename from tests/hooks/before-livesync/nativescript-angular-sync.js
rename to tests/testbed/hooks/before-livesync/nativescript-angular-sync.js
diff --git a/tests/testbed/hooks/before-prepare/nativescript-dev-android-snapshot.js b/tests/testbed/hooks/before-prepare/nativescript-dev-android-snapshot.js
new file mode 100644
index 000000000..f693b74f2
--- /dev/null
+++ b/tests/testbed/hooks/before-prepare/nativescript-dev-android-snapshot.js
@@ -0,0 +1 @@
+module.exports = require("nativescript-dev-android-snapshot/hooks/before-prepare-hook.js");
diff --git a/tests/hooks/before-prepare/nativescript-dev-typescript.js b/tests/testbed/hooks/before-prepare/nativescript-dev-typescript.js
similarity index 100%
rename from tests/hooks/before-prepare/nativescript-dev-typescript.js
rename to tests/testbed/hooks/before-prepare/nativescript-dev-typescript.js
diff --git a/tests/hooks/before-watch/nativescript-dev-typescript.js b/tests/testbed/hooks/before-watch/nativescript-dev-typescript.js
similarity index 100%
rename from tests/hooks/before-watch/nativescript-dev-typescript.js
rename to tests/testbed/hooks/before-watch/nativescript-dev-typescript.js
diff --git a/tests/testbed/karma.conf.js b/tests/testbed/karma.conf.js
new file mode 100644
index 000000000..869d7b625
--- /dev/null
+++ b/tests/testbed/karma.conf.js
@@ -0,0 +1,79 @@
+module.exports = function(config) {
+ config.set({
+ browserNoActivityTimeout: 40000,
+
+ // base path that will be used to resolve all patterns (eg. files, exclude)
+ basePath: '',
+
+
+ // frameworks to use
+ // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+ frameworks: ['jasmine'],
+
+
+ // list of files / patterns to load in the browser
+ files: [
+ 'node_modules/nativescript-angular/testing/setup.js',
+ 'app/**/*.js',
+ ],
+
+
+ // list of files to exclude
+ exclude: [
+ ],
+
+
+ // preprocess matching files before serving them to the browser
+ // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+ preprocessors: {
+ },
+
+
+ // test results reporter to use
+ // possible values: 'dots', 'progress'
+ // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+ reporters: ['progress', 'junit'],
+
+
+ // web server port
+ port: 9876,
+
+
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+
+
+ // level of logging
+ // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+ logLevel: config.LOG_INFO,
+
+
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: true,
+
+
+ // start these browsers
+ // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+ browsers: [],
+
+ customLaunchers: {
+ android: {
+ base: 'NS',
+ platform: 'android'
+ },
+ ios: {
+ base: 'NS',
+ platform: 'ios'
+ },
+ ios_simulator: {
+ base: 'NS',
+ platform: 'ios',
+ arguments: ['--emulator']
+ }
+ },
+
+ // Continuous Integration mode
+ // if true, Karma captures browsers, runs the tests and exits
+ singleRun: false
+ })
+}
diff --git a/tests/testbed/package.json b/tests/testbed/package.json
new file mode 100644
index 000000000..2d2e47d2a
--- /dev/null
+++ b/tests/testbed/package.json
@@ -0,0 +1,70 @@
+{
+ "description": "NativeScript Application",
+ "license": "SEE LICENSE IN ",
+ "readme": "NativeScript Application",
+ "repository": "",
+ "nativescript": {
+ "id": "org.nativescript.sampleApp",
+ "tns-ios": {
+ "version": "2.5.0"
+ },
+ "tns-android": {
+ "version": "2.5.0"
+ }
+ },
+ "scripts": {
+ "preclean": "npm i rimraf",
+ "clean": "rimraf node_modules lib hooks platforms target 'app/**/*.js' 'app/**/*.js.map'",
+ "postclean": "npm install",
+ "build": "npm run ns-bundle --android --build-app --clean && npm run ns-bundle --ios --build-app --clean",
+ "ns-bundle": "ns-bundle",
+ "start-android-bundle": "npm run ns-bundle --android --start-app",
+ "start-ios-bundle": "npm run ns-bundle --ios --start-app",
+ "build-android-bundle": "npm run ns-bundle --android --build-app",
+ "build-ios-bundle": "npm run ns-bundle --ios --build-app"
+ },
+ "dependencies": {
+ "@angular/common": "2.4.9",
+ "@angular/compiler": "2.4.9",
+ "@angular/core": "2.4.9",
+ "@angular/forms": "2.4.9",
+ "@angular/http": "2.4.9",
+ "@angular/platform-browser": "2.4.9",
+ "@angular/platform-browser-dynamic": "2.4.9",
+ "@angular/router": "3.4.9",
+ "nativescript-angular": "1.4.0",
+ "nativescript-theme-core": "1.0.2",
+ "reflect-metadata": "0.1.8",
+ "rxjs": "5.0.1",
+ "tns-core-modules": "2.5.1"
+ },
+ "devDependencies": {
+ "@angular/compiler-cli": "2.4.9",
+ "@angular/tsc-wrapped": "0.5.0",
+ "@ngtools/webpack": "1.2.10",
+ "@types/jasmine": "2.2.29",
+ "babel-traverse": "6.23.1",
+ "babel-types": "6.23.0",
+ "babylon": "6.16.1",
+ "copy-webpack-plugin": "~3.0.1",
+ "extract-text-webpack-plugin": "~2.0.0-beta.4",
+ "jasmine-core": "2.5.2",
+ "karma": "1.5.0",
+ "karma-coverage": "1.1.1",
+ "karma-jasmine": "1.0.2",
+ "karma-junit-reporter": "1.2.0",
+ "karma-nativescript-launcher": "0.4.0",
+ "karma-typescript-preprocessor": "0.3.1",
+ "lazy": "1.0.11",
+ "nativescript-css-loader": "~0.26.0",
+ "nativescript-dev-android-snapshot": "^0.*.*",
+ "nativescript-dev-typescript": "~0.3.5",
+ "nativescript-dev-webpack": "0.3.5",
+ "raw-loader": "~0.5.1",
+ "resolve-url-loader": "~1.6.0",
+ "typescript": "~2.1.0",
+ "webpack": "2.2.0",
+ "webpack-sources": "~0.1.3",
+ "zone.js": "~0.7.2"
+ }
+}
diff --git a/tests/references.d.ts b/tests/testbed/references.d.ts
similarity index 100%
rename from tests/references.d.ts
rename to tests/testbed/references.d.ts
diff --git a/tests/testbed/tsconfig.aot.json b/tests/testbed/tsconfig.aot.json
new file mode 100644
index 000000000..e93e506b7
--- /dev/null
+++ b/tests/testbed/tsconfig.aot.json
@@ -0,0 +1,94 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "es2015",
+ "moduleResolution": "node",
+ "sourceMap": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "removeComments": false,
+ "noImplicitAny": false,
+ "suppressImplicitAnyIndexErrors": true,
+ "types": [],
+ "baseUrl": ".",
+ "paths": {
+ "ui/*": [
+ "node_modules/tns-core-modules/ui/*"
+ ],
+ "platform": [
+ "node_modules/tns-core-modules/platform"
+ ],
+ "image-source": [
+ "node_modules/tns-core-modules/image-source"
+ ],
+ "xml": [
+ "node_modules/tns-core-modules/xml"
+ ],
+ "xhr": [
+ "node_modules/tns-core-modules/xhr"
+ ],
+ "text": [
+ "node_modules/tns-core-modules/text"
+ ],
+ "data": [
+ "node_modules/tns-core-modules/data"
+ ],
+ "fetch": [
+ "node_modules/tns-core-modules/fetch"
+ ],
+ "trace": [
+ "node_modules/tns-core-modules/trace"
+ ],
+ "fps-meter": [
+ "node_modules/tns-core-modules/fps-meter"
+ ],
+ "color": [
+ "node_modules/tns-core-modules/color"
+ ],
+ "application-settings": [
+ "node_modules/tns-core-modules/application-settings"
+ ],
+ "http": [
+ "node_modules/tns-core-modules/http"
+ ],
+ "camera": [
+ "node_modules/tns-core-modules/camera"
+ ],
+ "console": [
+ "node_modules/tns-core-modules/console"
+ ],
+ "timer": [
+ "node_modules/tns-core-modules/timer"
+ ],
+ "utils": [
+ "node_modules/tns-core-modules/utils"
+ ],
+ "location": [
+ "node_modules/tns-core-modules/location"
+ ],
+ "file-system": [
+ "node_modules/tns-core-modules/file-system"
+ ],
+ "application": [
+ "node_modules/tns-core-modules/application"
+ ],
+ "image-asset": [
+ "node_modules/tns-core-modules/image-asset"
+ ],
+ "connectivity": [
+ "node_modules/tns-core-modules/connectivity"
+ ],
+ "globals": [
+ "node_modules/tns-core-modules/globals"
+ ]
+ }
+ },
+ "exclude": [
+ "node_modules",
+ "platforms"
+ ],
+ "angularCompilerOptions": {
+ "skipMetadataEmit": true,
+ "genDir": "./"
+ }
+}
\ No newline at end of file
diff --git a/tests/testbed/tsconfig.json b/tests/testbed/tsconfig.json
new file mode 100644
index 000000000..a6176a4c6
--- /dev/null
+++ b/tests/testbed/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es5",
+ "experimentalDecorators": true,
+ "emitDecoratorMetadata": true,
+ "noEmitHelpers": true,
+ "noEmitOnError": true,
+ "types": [
+ "jasmine"
+ ]
+ },
+ "exclude": [
+ "node_modules",
+ "platforms",
+ "**/*.aot.ts"
+ ]
+}
\ No newline at end of file
diff --git a/tests/testbed/webpack.android.js b/tests/testbed/webpack.android.js
new file mode 100644
index 000000000..968e93b80
--- /dev/null
+++ b/tests/testbed/webpack.android.js
@@ -0,0 +1,2 @@
+var makeConfig = require("./webpack.common");
+module.exports = makeConfig("android");
diff --git a/tests/testbed/webpack.common.js b/tests/testbed/webpack.common.js
new file mode 100644
index 000000000..b05c860e7
--- /dev/null
+++ b/tests/testbed/webpack.common.js
@@ -0,0 +1,151 @@
+var webpack = require("webpack");
+var nsWebpack = require("nativescript-dev-webpack");
+var nativescriptTarget = require("nativescript-dev-webpack/nativescript-target");
+var path = require("path");
+var CopyWebpackPlugin = require("copy-webpack-plugin");
+var ExtractTextPlugin = require("extract-text-webpack-plugin");
+var AotPlugin = require("@ngtools/webpack").AotPlugin;
+
+module.exports = function (platform, destinationApp) {
+ if (!destinationApp) {
+ //Default destination inside platforms//...
+ destinationApp = nsWebpack.getAppPath(platform);
+ }
+ var entry = {};
+ //Discover entry module from package.json
+ entry.bundle = "./" + nsWebpack.getEntryModule();
+ //Vendor entry with third party libraries.
+ entry.vendor = "./vendor";
+ //app.css bundle
+ entry["app.css"] = "./app.css";
+
+ var plugins = [
+ new ExtractTextPlugin("app.css"),
+ //Vendor libs go to the vendor.js chunk
+ new webpack.optimize.CommonsChunkPlugin({
+ name: ["vendor"]
+ }),
+ //Define useful constants like TNS_WEBPACK
+ new webpack.DefinePlugin({
+ "global.TNS_WEBPACK": "true",
+ }),
+ //Copy assets to out dir. Add your own globs as needed.
+ new CopyWebpackPlugin([
+ { from: "app.css" },
+ { from: "css/**" },
+ { from: "fonts/**" },
+ { from: "**/*.jpg" },
+ { from: "**/*.png" },
+ { from: "**/*.xml" },
+ ], { ignore: ["App_Resources/**"] }),
+ //Generate a bundle starter script and activate it in package.json
+ new nsWebpack.GenerateBundleStarterPlugin([
+ "./vendor",
+ "./bundle",
+ ]),
+
+ //Angular AOT compiler
+ new AotPlugin({
+ tsConfigPath: "tsconfig.aot.json",
+ entryModule: path.resolve(__dirname, "app/app.module#AppModule"),
+ typeChecking: false
+ }),
+ new nsWebpack.StyleUrlResolvePlugin({platform}),
+ ];
+
+ if (process.env.npm_config_uglify) {
+ plugins.push(new webpack.LoaderOptionsPlugin({
+ minimize: true
+ }));
+
+ //Work around an Android issue by setting compress = false
+ var compress = platform !== "android";
+ plugins.push(new webpack.optimize.UglifyJsPlugin({
+ mangle: {
+ except: nsWebpack.uglifyMangleExcludes,
+ },
+ compress: compress,
+ }));
+ }
+
+ return {
+ context: path.resolve("./app"),
+ target: nativescriptTarget,
+ entry: entry,
+ output: {
+ pathinfo: true,
+ path: path.resolve(destinationApp),
+ libraryTarget: "commonjs2",
+ filename: "[name].js",
+ },
+ resolve: {
+ //Resolve platform-specific modules like module.android.js
+ extensions: [
+ ".aot.ts",
+ ".ts",
+ ".js",
+ ".css",
+ "." + platform + ".ts",
+ "." + platform + ".js",
+ "." + platform + ".css",
+ ],
+ //Resolve {N} system modules from tns-core-modules
+ modules: [
+ "node_modules/tns-core-modules",
+ "node_modules"
+ ]
+ },
+ node: {
+ //Disable node shims that conflict with NativeScript
+ "http": false,
+ "timers": false,
+ "setImmediate": false,
+ "fs": "empty",
+ },
+ module: {
+ loaders: [
+ {
+ test: /\.html$|\.xml$/,
+ loaders: [
+ "raw-loader",
+ ]
+ },
+ // Root app.css file gets extracted with bundled dependencies
+ {
+ test: /app\.css$/,
+ loader: ExtractTextPlugin.extract([
+ "resolve-url-loader",
+ "nativescript-css-loader",
+ "nativescript-dev-webpack/platform-css-loader",
+ ]),
+ },
+ // Other CSS files get bundled using the raw loader
+ {
+ test: /\.css$/,
+ exclude: /app\.css$/,
+ loaders: [
+ "raw-loader",
+ ]
+ },
+ // Compile TypeScript files with ahead-of-time compiler.
+ {
+ test: /\.ts$/,
+ loaders: [
+ "nativescript-dev-webpack/tns-aot-loader",
+ "@ngtools/webpack",
+ ]
+ },
+ // SASS support
+ {
+ test: /\.scss$/,
+ loaders: [
+ "raw-loader",
+ "resolve-url-loader",
+ "sass-loader"
+ ]
+ },
+ ]
+ },
+ plugins: plugins,
+ };
+};
diff --git a/tests/testbed/webpack.ios.js b/tests/testbed/webpack.ios.js
new file mode 100644
index 000000000..806f3ef26
--- /dev/null
+++ b/tests/testbed/webpack.ios.js
@@ -0,0 +1,2 @@
+var makeConfig = require("./webpack.common");
+module.exports = makeConfig("ios");
diff --git a/tests/.ctags-exclude b/tests/tns/.ctags-exclude
similarity index 100%
rename from tests/.ctags-exclude
rename to tests/tns/.ctags-exclude
diff --git a/tests/.gitignore b/tests/tns/.gitignore
similarity index 100%
rename from tests/.gitignore
rename to tests/tns/.gitignore
diff --git a/tests/Makefile b/tests/tns/Makefile
similarity index 100%
rename from tests/Makefile
rename to tests/tns/Makefile
diff --git a/tests/README.md b/tests/tns/README.md
similarity index 100%
rename from tests/README.md
rename to tests/tns/README.md
diff --git a/tests/app/App_Resources/Android/AndroidManifest.xml b/tests/tns/app/App_Resources/Android/AndroidManifest.xml
similarity index 100%
rename from tests/app/App_Resources/Android/AndroidManifest.xml
rename to tests/tns/app/App_Resources/Android/AndroidManifest.xml
diff --git a/tests/tns/app/App_Resources/Android/drawable-hdpi/icon.png b/tests/tns/app/App_Resources/Android/drawable-hdpi/icon.png
new file mode 100755
index 000000000..1034356e2
Binary files /dev/null and b/tests/tns/app/App_Resources/Android/drawable-hdpi/icon.png differ
diff --git a/tests/tns/app/App_Resources/Android/drawable-ldpi/icon.png b/tests/tns/app/App_Resources/Android/drawable-ldpi/icon.png
new file mode 100755
index 000000000..ddfc17a71
Binary files /dev/null and b/tests/tns/app/App_Resources/Android/drawable-ldpi/icon.png differ
diff --git a/tests/tns/app/App_Resources/Android/drawable-mdpi/icon.png b/tests/tns/app/App_Resources/Android/drawable-mdpi/icon.png
new file mode 100755
index 000000000..486e41091
Binary files /dev/null and b/tests/tns/app/App_Resources/Android/drawable-mdpi/icon.png differ
diff --git a/tests/app/App_Resources/Android/drawable-nodpi/checkbox_checked.png b/tests/tns/app/App_Resources/Android/drawable-nodpi/checkbox_checked.png
similarity index 100%
rename from tests/app/App_Resources/Android/drawable-nodpi/checkbox_checked.png
rename to tests/tns/app/App_Resources/Android/drawable-nodpi/checkbox_checked.png
diff --git a/tests/app/App_Resources/Android/drawable-nodpi/checkbox_unchecked.png b/tests/tns/app/App_Resources/Android/drawable-nodpi/checkbox_unchecked.png
similarity index 100%
rename from tests/app/App_Resources/Android/drawable-nodpi/checkbox_unchecked.png
rename to tests/tns/app/App_Resources/Android/drawable-nodpi/checkbox_unchecked.png
diff --git a/tests/app/App_Resources/Android/drawable-nodpi/splashscreen.9.png b/tests/tns/app/App_Resources/Android/drawable-nodpi/splashscreen.9.png
similarity index 100%
rename from tests/app/App_Resources/Android/drawable-nodpi/splashscreen.9.png
rename to tests/tns/app/App_Resources/Android/drawable-nodpi/splashscreen.9.png
diff --git a/tests/tns/app/App_Resources/iOS/Default-568h@2x.png b/tests/tns/app/App_Resources/iOS/Default-568h@2x.png
new file mode 100755
index 000000000..d7f17fcd2
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Default-568h@2x.png differ
diff --git a/tests/tns/app/App_Resources/iOS/Default-Landscape.png b/tests/tns/app/App_Resources/iOS/Default-Landscape.png
new file mode 100755
index 000000000..3365ba3cd
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Default-Landscape.png differ
diff --git a/tests/tns/app/App_Resources/iOS/Default-Landscape@2x.png b/tests/tns/app/App_Resources/iOS/Default-Landscape@2x.png
new file mode 100755
index 000000000..a44945c1a
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Default-Landscape@2x.png differ
diff --git a/tests/tns/app/App_Resources/iOS/Default-Portrait.png b/tests/tns/app/App_Resources/iOS/Default-Portrait.png
new file mode 100755
index 000000000..1a5007962
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Default-Portrait.png differ
diff --git a/tests/tns/app/App_Resources/iOS/Default-Portrait@2x.png b/tests/tns/app/App_Resources/iOS/Default-Portrait@2x.png
new file mode 100755
index 000000000..73d8b920f
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Default-Portrait@2x.png differ
diff --git a/tests/tns/app/App_Resources/iOS/Default.png b/tests/tns/app/App_Resources/iOS/Default.png
new file mode 100755
index 000000000..9f1f6ce3e
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Default.png differ
diff --git a/tests/tns/app/App_Resources/iOS/Default@2x.png b/tests/tns/app/App_Resources/iOS/Default@2x.png
new file mode 100755
index 000000000..514fc5cde
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Default@2x.png differ
diff --git a/tests/tns/app/App_Resources/iOS/Icon-Small-50.png b/tests/tns/app/App_Resources/iOS/Icon-Small-50.png
new file mode 100755
index 000000000..4a62478f9
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Icon-Small-50.png differ
diff --git a/tests/tns/app/App_Resources/iOS/Icon-Small-50@2x.png b/tests/tns/app/App_Resources/iOS/Icon-Small-50@2x.png
new file mode 100755
index 000000000..01ff7c16c
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/Icon-Small-50@2x.png differ
diff --git a/tests/app/App_Resources/iOS/Icon-Small.png b/tests/tns/app/App_Resources/iOS/Icon-Small.png
similarity index 100%
rename from tests/app/App_Resources/iOS/Icon-Small.png
rename to tests/tns/app/App_Resources/iOS/Icon-Small.png
diff --git a/tests/app/App_Resources/iOS/Icon-Small@2x.png b/tests/tns/app/App_Resources/iOS/Icon-Small@2x.png
similarity index 100%
rename from tests/app/App_Resources/iOS/Icon-Small@2x.png
rename to tests/tns/app/App_Resources/iOS/Icon-Small@2x.png
diff --git a/tests/app/App_Resources/iOS/Info.plist b/tests/tns/app/App_Resources/iOS/Info.plist
similarity index 100%
rename from tests/app/App_Resources/iOS/Info.plist
rename to tests/tns/app/App_Resources/iOS/Info.plist
diff --git a/tests/app/App_Resources/iOS/checkbox_checked.png b/tests/tns/app/App_Resources/iOS/checkbox_checked.png
similarity index 100%
rename from tests/app/App_Resources/iOS/checkbox_checked.png
rename to tests/tns/app/App_Resources/iOS/checkbox_checked.png
diff --git a/tests/app/App_Resources/iOS/checkbox_unchecked.png b/tests/tns/app/App_Resources/iOS/checkbox_unchecked.png
similarity index 100%
rename from tests/app/App_Resources/iOS/checkbox_unchecked.png
rename to tests/tns/app/App_Resources/iOS/checkbox_unchecked.png
diff --git a/tests/app/App_Resources/iOS/icon-40.png b/tests/tns/app/App_Resources/iOS/icon-40.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon-40.png
rename to tests/tns/app/App_Resources/iOS/icon-40.png
diff --git a/tests/app/App_Resources/iOS/icon-40@2x.png b/tests/tns/app/App_Resources/iOS/icon-40@2x.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon-40@2x.png
rename to tests/tns/app/App_Resources/iOS/icon-40@2x.png
diff --git a/tests/app/App_Resources/iOS/icon-60.png b/tests/tns/app/App_Resources/iOS/icon-60.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon-60.png
rename to tests/tns/app/App_Resources/iOS/icon-60.png
diff --git a/tests/app/App_Resources/iOS/icon-60@2x.png b/tests/tns/app/App_Resources/iOS/icon-60@2x.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon-60@2x.png
rename to tests/tns/app/App_Resources/iOS/icon-60@2x.png
diff --git a/tests/tns/app/App_Resources/iOS/icon-72.png b/tests/tns/app/App_Resources/iOS/icon-72.png
new file mode 100755
index 000000000..556bdd688
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/icon-72.png differ
diff --git a/tests/tns/app/App_Resources/iOS/icon-72@2x.png b/tests/tns/app/App_Resources/iOS/icon-72@2x.png
new file mode 100755
index 000000000..4f69cb25b
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/icon-72@2x.png differ
diff --git a/tests/app/App_Resources/iOS/icon-76.png b/tests/tns/app/App_Resources/iOS/icon-76.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon-76.png
rename to tests/tns/app/App_Resources/iOS/icon-76.png
diff --git a/tests/app/App_Resources/iOS/icon-76@2x.png b/tests/tns/app/App_Resources/iOS/icon-76@2x.png
similarity index 100%
rename from tests/app/App_Resources/iOS/icon-76@2x.png
rename to tests/tns/app/App_Resources/iOS/icon-76@2x.png
diff --git a/tests/tns/app/App_Resources/iOS/icon.png b/tests/tns/app/App_Resources/iOS/icon.png
new file mode 100755
index 000000000..beea81999
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/icon.png differ
diff --git a/tests/tns/app/App_Resources/iOS/icon@2x.png b/tests/tns/app/App_Resources/iOS/icon@2x.png
new file mode 100755
index 000000000..c3dc7b035
Binary files /dev/null and b/tests/tns/app/App_Resources/iOS/icon@2x.png differ
diff --git a/tests/app/LICENSE b/tests/tns/app/LICENSE
similarity index 100%
rename from tests/app/LICENSE
rename to tests/tns/app/LICENSE
diff --git a/tests/app/app.component.ts b/tests/tns/app/app.component.ts
similarity index 100%
rename from tests/app/app.component.ts
rename to tests/tns/app/app.component.ts
diff --git a/tests/app/app.css b/tests/tns/app/app.css
similarity index 100%
rename from tests/app/app.css
rename to tests/tns/app/app.css
diff --git a/tests/app/base.component.ts b/tests/tns/app/base.component.ts
similarity index 100%
rename from tests/app/base.component.ts
rename to tests/tns/app/base.component.ts
diff --git a/tests/app/first.component.ts b/tests/tns/app/first.component.ts
similarity index 100%
rename from tests/app/first.component.ts
rename to tests/tns/app/first.component.ts
diff --git a/tests/app/fonts/icomoon.ttf b/tests/tns/app/fonts/icomoon.ttf
similarity index 100%
rename from tests/app/fonts/icomoon.ttf
rename to tests/tns/app/fonts/icomoon.ttf
diff --git a/tests/app/global.d.ts b/tests/tns/app/global.d.ts
similarity index 100%
rename from tests/app/global.d.ts
rename to tests/tns/app/global.d.ts
diff --git a/tests/app/lazy-load-main.ts b/tests/tns/app/lazy-load-main.ts
similarity index 100%
rename from tests/app/lazy-load-main.ts
rename to tests/tns/app/lazy-load-main.ts
diff --git a/tests/app/lazy-loaded.module.ts b/tests/tns/app/lazy-loaded.module.ts
similarity index 100%
rename from tests/app/lazy-loaded.module.ts
rename to tests/tns/app/lazy-loaded.module.ts
diff --git a/tests/app/main.ts b/tests/tns/app/main.ts
similarity index 100%
rename from tests/app/main.ts
rename to tests/tns/app/main.ts
diff --git a/tests/app/multi-page-main.component.ts b/tests/tns/app/multi-page-main.component.ts
similarity index 100%
rename from tests/app/multi-page-main.component.ts
rename to tests/tns/app/multi-page-main.component.ts
diff --git a/tests/app/package.json b/tests/tns/app/package.json
similarity index 100%
rename from tests/app/package.json
rename to tests/tns/app/package.json
diff --git a/tests/app/second.component.ts b/tests/tns/app/second.component.ts
similarity index 100%
rename from tests/app/second.component.ts
rename to tests/tns/app/second.component.ts
diff --git a/tests/app/single-page-main.component.ts b/tests/tns/app/single-page-main.component.ts
similarity index 100%
rename from tests/app/single-page-main.component.ts
rename to tests/tns/app/single-page-main.component.ts
diff --git a/tests/app/snippets/gestures.component.html b/tests/tns/app/snippets/gestures.component.html
similarity index 100%
rename from tests/app/snippets/gestures.component.html
rename to tests/tns/app/snippets/gestures.component.html
diff --git a/tests/app/snippets/gestures.component.ts b/tests/tns/app/snippets/gestures.component.ts
similarity index 100%
rename from tests/app/snippets/gestures.component.ts
rename to tests/tns/app/snippets/gestures.component.ts
diff --git a/tests/app/snippets/icon-font.component.css b/tests/tns/app/snippets/icon-font.component.css
similarity index 100%
rename from tests/app/snippets/icon-font.component.css
rename to tests/tns/app/snippets/icon-font.component.css
diff --git a/tests/app/snippets/icon-font.component.html b/tests/tns/app/snippets/icon-font.component.html
similarity index 100%
rename from tests/app/snippets/icon-font.component.html
rename to tests/tns/app/snippets/icon-font.component.html
diff --git a/tests/app/snippets/icon-font.component.ts b/tests/tns/app/snippets/icon-font.component.ts
similarity index 100%
rename from tests/app/snippets/icon-font.component.ts
rename to tests/tns/app/snippets/icon-font.component.ts
diff --git a/tests/app/snippets/layouts.component.html b/tests/tns/app/snippets/layouts.component.html
similarity index 100%
rename from tests/app/snippets/layouts.component.html
rename to tests/tns/app/snippets/layouts.component.html
diff --git a/tests/app/snippets/layouts.component.ts b/tests/tns/app/snippets/layouts.component.ts
similarity index 100%
rename from tests/app/snippets/layouts.component.ts
rename to tests/tns/app/snippets/layouts.component.ts
diff --git a/tests/app/snippets/list-view/template-selector.component.html b/tests/tns/app/snippets/list-view/template-selector.component.html
similarity index 100%
rename from tests/app/snippets/list-view/template-selector.component.html
rename to tests/tns/app/snippets/list-view/template-selector.component.html
diff --git a/tests/app/snippets/list-view/template-selector.component.ts b/tests/tns/app/snippets/list-view/template-selector.component.ts
similarity index 100%
rename from tests/app/snippets/list-view/template-selector.component.ts
rename to tests/tns/app/snippets/list-view/template-selector.component.ts
diff --git a/tests/app/snippets/navigation/app.routes.ts b/tests/tns/app/snippets/navigation/app.routes.ts
similarity index 100%
rename from tests/app/snippets/navigation/app.routes.ts
rename to tests/tns/app/snippets/navigation/app.routes.ts
diff --git a/tests/app/snippets/navigation/config-snippets.ts b/tests/tns/app/snippets/navigation/config-snippets.ts
similarity index 100%
rename from tests/app/snippets/navigation/config-snippets.ts
rename to tests/tns/app/snippets/navigation/config-snippets.ts
diff --git a/tests/app/snippets/navigation/navigation-common.css b/tests/tns/app/snippets/navigation/navigation-common.css
similarity index 100%
rename from tests/app/snippets/navigation/navigation-common.css
rename to tests/tns/app/snippets/navigation/navigation-common.css
diff --git a/tests/app/snippets/navigation/navigation-common.ts b/tests/tns/app/snippets/navigation/navigation-common.ts
similarity index 100%
rename from tests/app/snippets/navigation/navigation-common.ts
rename to tests/tns/app/snippets/navigation/navigation-common.ts
diff --git a/tests/app/snippets/navigation/page-outlet.ts b/tests/tns/app/snippets/navigation/page-outlet.ts
similarity index 100%
rename from tests/app/snippets/navigation/page-outlet.ts
rename to tests/tns/app/snippets/navigation/page-outlet.ts
diff --git a/tests/app/snippets/navigation/route-params.ts b/tests/tns/app/snippets/navigation/route-params.ts
similarity index 100%
rename from tests/app/snippets/navigation/route-params.ts
rename to tests/tns/app/snippets/navigation/route-params.ts
diff --git a/tests/app/snippets/navigation/router-extensions.html b/tests/tns/app/snippets/navigation/router-extensions.html
similarity index 100%
rename from tests/app/snippets/navigation/router-extensions.html
rename to tests/tns/app/snippets/navigation/router-extensions.html
diff --git a/tests/app/snippets/navigation/router-extensions.ts b/tests/tns/app/snippets/navigation/router-extensions.ts
similarity index 100%
rename from tests/app/snippets/navigation/router-extensions.ts
rename to tests/tns/app/snippets/navigation/router-extensions.ts
diff --git a/tests/app/snippets/navigation/router-outlet.ts b/tests/tns/app/snippets/navigation/router-outlet.ts
similarity index 100%
rename from tests/app/snippets/navigation/router-outlet.ts
rename to tests/tns/app/snippets/navigation/router-outlet.ts
diff --git a/tests/app/tests/detached-loader-tests.ts b/tests/tns/app/tests/detached-loader-tests.ts
similarity index 100%
rename from tests/app/tests/detached-loader-tests.ts
rename to tests/tns/app/tests/detached-loader-tests.ts
diff --git a/tests/app/tests/http.ts b/tests/tns/app/tests/http.ts
similarity index 100%
rename from tests/app/tests/http.ts
rename to tests/tns/app/tests/http.ts
diff --git a/tests/app/tests/list-view-tests.ts b/tests/tns/app/tests/list-view-tests.ts
similarity index 86%
rename from tests/app/tests/list-view-tests.ts
rename to tests/tns/app/tests/list-view-tests.ts
index 8237d5882..6dfae0c74 100644
--- a/tests/app/tests/list-view-tests.ts
+++ b/tests/tns/app/tests/list-view-tests.ts
@@ -121,19 +121,3 @@ describe("ListView-tests", () => {
.catch(done);
});
});
-
-describe("ListView item templates", () => {
- it("destroy child ng views on unload", () => {
- const childRoot = new ProxyViewContainer();
- let viewDestroyed = false;
- const view: ComponentView = {
- rootNodes: [],
- destroy: () => {
- viewDestroyed = true;
- }
- };
- const itemRoot = getItemViewRoot(view, (_rootNodes, _level) => childRoot);
- itemRoot.notify({eventName: "unloaded", object: itemRoot});
- assert.isTrue(viewDestroyed, "ng view not destroyed");
- });
-});
diff --git a/tests/app/tests/mocks/ns-file-system.mock.ts b/tests/tns/app/tests/mocks/ns-file-system.mock.ts
similarity index 100%
rename from tests/app/tests/mocks/ns-file-system.mock.ts
rename to tests/tns/app/tests/mocks/ns-file-system.mock.ts
diff --git a/tests/app/tests/modal-dialog.ts b/tests/tns/app/tests/modal-dialog.ts
similarity index 100%
rename from tests/app/tests/modal-dialog.ts
rename to tests/tns/app/tests/modal-dialog.ts
diff --git a/tests/app/tests/ns-location-strategy.ts b/tests/tns/app/tests/ns-location-strategy.ts
similarity index 100%
rename from tests/app/tests/ns-location-strategy.ts
rename to tests/tns/app/tests/ns-location-strategy.ts
diff --git a/tests/app/tests/platform-filter-components.ts b/tests/tns/app/tests/platform-filter-components.ts
similarity index 97%
rename from tests/app/tests/platform-filter-components.ts
rename to tests/tns/app/tests/platform-filter-components.ts
index 5665e1364..9cdbf7b60 100644
--- a/tests/app/tests/platform-filter-components.ts
+++ b/tests/tns/app/tests/platform-filter-components.ts
@@ -1,122 +1,122 @@
-// make sure you import mocha-config before @angular/core
-import { assert } from "./test-config";
-import { Component, ElementRef } from "@angular/core";
-import { dumpView, createDevice } from "./test-utils";
-import { TestApp } from "./test-app";
-import { DEVICE } from "nativescript-angular/platform-providers";
-import { platformNames } from "platform";
-
-@Component({
- template: `
-
-
- `
-})
-export class IosSpecificComponent {
- constructor(public elementRef: ElementRef) { }
-}
-
-@Component({
- template: `
-
-
- `
-})
-export class AndroidSpecificComponent {
- constructor(public elementRef: ElementRef) { }
-}
-
-@Component({
- template: `
-
-
- `
-})
-export class PlatformSpecificAttributeComponent {
- constructor(public elementRef: ElementRef) { }
-}
-
-describe("Platform filter directives", () => {
- describe("on IOS device", () => {
- let testApp: TestApp = null;
-
- before(() => {
- return TestApp.create([{ provide: DEVICE, useValue: createDevice(platformNames.ios) }], [
- PlatformSpecificAttributeComponent,
- AndroidSpecificComponent,
- IosSpecificComponent
- ]).then((app) => {
- testApp = app;
- });
- });
-
- after(() => {
- testApp.dispose();
- });
-
- it("does render ios specific content", () => {
- return testApp.loadComponent(IosSpecificComponent).then((componentRef) => {
- const componentRoot = componentRef.instance.elementRef.nativeElement;
- assert.isTrue(dumpView(componentRoot, true).indexOf("(Label[text=IOS])") >= 0);
- });
- });
-
- it("does not render android specific content", () => {
- return testApp.loadComponent(AndroidSpecificComponent).then((componentRef) => {
- const componentRoot = componentRef.instance.elementRef.nativeElement;
- assert.isTrue(dumpView(componentRoot, true).indexOf("Label") < 0);
- });
- });
-
-
- it("applies iOS specific attribute", () => {
- return testApp.loadComponent(PlatformSpecificAttributeComponent).then((componentRef) => {
- const componentRoot = componentRef.instance.elementRef.nativeElement;
- assert.equal(
- "(ProxyViewContainer (StackLayout (Label[text=IOS])))",
- dumpView(componentRoot, true));
- });
- });
- });
-
- describe("on Android device", () => {
- let testApp: TestApp = null;
-
- before(() => {
- return TestApp.create([{ provide: DEVICE, useValue: createDevice(platformNames.android) }], [
- AndroidSpecificComponent,
- IosSpecificComponent,
- PlatformSpecificAttributeComponent
- ]).then((app) => {
- testApp = app;
- });
- });
-
- after(() => {
- testApp.dispose();
- });
-
- it("does render android specific content", () => {
- return testApp.loadComponent(AndroidSpecificComponent).then((componentRef) => {
- const componentRoot = componentRef.instance.elementRef.nativeElement;
- assert.isTrue(dumpView(componentRoot, true).indexOf("(Label[text=ANDROID])") >= 0);
- });
- });
-
- it("does not render ios specific content", () => {
- return testApp.loadComponent(IosSpecificComponent).then((componentRef) => {
- const componentRoot = componentRef.instance.elementRef.nativeElement;
- assert.isTrue(dumpView(componentRoot, true).indexOf("Label") < 0);
- });
- });
-
- it("applies Android specific attribute", () => {
- return testApp.loadComponent(PlatformSpecificAttributeComponent).then((componentRef) => {
- const componentRoot = componentRef.instance.elementRef.nativeElement;
- assert.equal(
- "(ProxyViewContainer (StackLayout (Label[text=ANDROID])))",
- dumpView(componentRoot, true));
- });
- });
- });
-});
+// make sure you import mocha-config before @angular/core
+import { assert } from "./test-config";
+import { Component, ElementRef } from "@angular/core";
+import { dumpView, createDevice } from "./test-utils";
+import { TestApp } from "./test-app";
+import { DEVICE } from "nativescript-angular/platform-providers";
+import { platformNames } from "platform";
+
+@Component({
+ template: `
+
+
+ `
+})
+export class IosSpecificComponent {
+ constructor(public elementRef: ElementRef) { }
+}
+
+@Component({
+ template: `
+
+
+ `
+})
+export class AndroidSpecificComponent {
+ constructor(public elementRef: ElementRef) { }
+}
+
+@Component({
+ template: `
+
+
+ `
+})
+export class PlatformSpecificAttributeComponent {
+ constructor(public elementRef: ElementRef) { }
+}
+
+describe("Platform filter directives", () => {
+ describe("on IOS device", () => {
+ let testApp: TestApp = null;
+
+ before(() => {
+ return TestApp.create([{ provide: DEVICE, useValue: createDevice(platformNames.ios) }], [
+ PlatformSpecificAttributeComponent,
+ AndroidSpecificComponent,
+ IosSpecificComponent
+ ]).then((app) => {
+ testApp = app;
+ });
+ });
+
+ after(() => {
+ testApp.dispose();
+ });
+
+ it("does render ios specific content", () => {
+ return testApp.loadComponent(IosSpecificComponent).then((componentRef) => {
+ const componentRoot = componentRef.instance.elementRef.nativeElement;
+ assert.isTrue(dumpView(componentRoot, true).indexOf("(Label[text=IOS])") >= 0);
+ });
+ });
+
+ it("does not render android specific content", () => {
+ return testApp.loadComponent(AndroidSpecificComponent).then((componentRef) => {
+ const componentRoot = componentRef.instance.elementRef.nativeElement;
+ assert.isTrue(dumpView(componentRoot, true).indexOf("Label") < 0);
+ });
+ });
+
+
+ it("applies iOS specific attribute", () => {
+ return testApp.loadComponent(PlatformSpecificAttributeComponent).then((componentRef) => {
+ const componentRoot = componentRef.instance.elementRef.nativeElement;
+ assert.equal(
+ "(ProxyViewContainer (StackLayout (Label[text=IOS])))",
+ dumpView(componentRoot, true));
+ });
+ });
+ });
+
+ describe("on Android device", () => {
+ let testApp: TestApp = null;
+
+ before(() => {
+ return TestApp.create([{ provide: DEVICE, useValue: createDevice(platformNames.android) }], [
+ AndroidSpecificComponent,
+ IosSpecificComponent,
+ PlatformSpecificAttributeComponent
+ ]).then((app) => {
+ testApp = app;
+ });
+ });
+
+ after(() => {
+ testApp.dispose();
+ });
+
+ it("does render android specific content", () => {
+ return testApp.loadComponent(AndroidSpecificComponent).then((componentRef) => {
+ const componentRoot = componentRef.instance.elementRef.nativeElement;
+ assert.isTrue(dumpView(componentRoot, true).indexOf("(Label[text=ANDROID])") >= 0);
+ });
+ });
+
+ it("does not render ios specific content", () => {
+ return testApp.loadComponent(IosSpecificComponent).then((componentRef) => {
+ const componentRoot = componentRef.instance.elementRef.nativeElement;
+ assert.isTrue(dumpView(componentRoot, true).indexOf("Label") < 0);
+ });
+ });
+
+ it("applies Android specific attribute", () => {
+ return testApp.loadComponent(PlatformSpecificAttributeComponent).then((componentRef) => {
+ const componentRoot = componentRef.instance.elementRef.nativeElement;
+ assert.equal(
+ "(ProxyViewContainer (StackLayout (Label[text=ANDROID])))",
+ dumpView(componentRoot, true));
+ });
+ });
+ });
+});
diff --git a/tests/app/tests/property-sets.ts b/tests/tns/app/tests/property-sets.ts
similarity index 100%
rename from tests/app/tests/property-sets.ts
rename to tests/tns/app/tests/property-sets.ts
diff --git a/tests/app/tests/renderer-tests.ts b/tests/tns/app/tests/renderer-tests.ts
similarity index 100%
rename from tests/app/tests/renderer-tests.ts
rename to tests/tns/app/tests/renderer-tests.ts
diff --git a/tests/app/tests/snippets.ts b/tests/tns/app/tests/snippets.ts
similarity index 100%
rename from tests/app/tests/snippets.ts
rename to tests/tns/app/tests/snippets.ts
diff --git a/tests/app/tests/style-properties.ts b/tests/tns/app/tests/style-properties.ts
similarity index 100%
rename from tests/app/tests/style-properties.ts
rename to tests/tns/app/tests/style-properties.ts
diff --git a/tests/app/tests/test-app.ts b/tests/tns/app/tests/test-app.ts
similarity index 100%
rename from tests/app/tests/test-app.ts
rename to tests/tns/app/tests/test-app.ts
diff --git a/tests/app/tests/test-config.ts b/tests/tns/app/tests/test-config.ts
similarity index 100%
rename from tests/app/tests/test-config.ts
rename to tests/tns/app/tests/test-config.ts
diff --git a/tests/app/tests/test-utils.ts b/tests/tns/app/tests/test-utils.ts
similarity index 96%
rename from tests/app/tests/test-utils.ts
rename to tests/tns/app/tests/test-utils.ts
index 30a4427a1..b664ef2c8 100644
--- a/tests/app/tests/test-utils.ts
+++ b/tests/tns/app/tests/test-utils.ts
@@ -1,45 +1,45 @@
-import { View } from "ui/core/view";
-import { TextBase } from "ui/text-base";
-import { Device } from "platform";
-
-function getChildren(view: View): Array {
- let children: Array = [];
- (view).eachChildView((child) => {
- children.push(child);
- return true;
- });
- return children;
-}
-
-export function dumpView(view: View, verbose: boolean = false): string {
- let nodeName = (view).nodeName || view;
- let output = ["(", nodeName];
- if (verbose) {
- if (view instanceof TextBase) {
- output.push("[text=", view.text, "]");
- }
- }
-
- let children = getChildren(view).map((c) => dumpView(c, verbose)).join(", ");
- if (children) {
- output.push(" ", children);
- }
-
- output.push(")");
- return output.join("");
-}
-
-export function createDevice(os: string): Device {
- return {
- os: os,
- osVersion: "0",
- deviceType: "Phone",
- language: "en",
- uuid: "0000",
- sdkVersion: "0",
- region: "US",
- manufacturer: "tester",
- model: "test device"
- };
-}
-
+import { View } from "ui/core/view";
+import { TextBase } from "ui/text-base";
+import { Device } from "platform";
+
+function getChildren(view: View): Array {
+ let children: Array = [];
+ (view).eachChildView((child) => {
+ children.push(child);
+ return true;
+ });
+ return children;
+}
+
+export function dumpView(view: View, verbose: boolean = false): string {
+ let nodeName = (view).nodeName || view;
+ let output = ["(", nodeName];
+ if (verbose) {
+ if (view instanceof TextBase) {
+ output.push("[text=", view.text, "]");
+ }
+ }
+
+ let children = getChildren(view).map((c) => dumpView(c, verbose)).join(", ");
+ if (children) {
+ output.push(" ", children);
+ }
+
+ output.push(")");
+ return output.join("");
+}
+
+export function createDevice(os: string): Device {
+ return {
+ os: os,
+ osVersion: "0",
+ deviceType: "Phone",
+ language: "en",
+ uuid: "0000",
+ sdkVersion: "0",
+ region: "US",
+ manufacturer: "tester",
+ model: "test device"
+ };
+}
+
diff --git a/tests/app/tests/third-party-view.ts b/tests/tns/app/tests/third-party-view.ts
similarity index 100%
rename from tests/app/tests/third-party-view.ts
rename to tests/tns/app/tests/third-party-view.ts
diff --git a/tests/app/tests/third-party.ts b/tests/tns/app/tests/third-party.ts
similarity index 100%
rename from tests/app/tests/third-party.ts
rename to tests/tns/app/tests/third-party.ts
diff --git a/tests/app/tests/value-accessor-tests.ts b/tests/tns/app/tests/value-accessor-tests.ts
similarity index 100%
rename from tests/app/tests/value-accessor-tests.ts
rename to tests/tns/app/tests/value-accessor-tests.ts
diff --git a/tests/app/tests/xhr-paths.ts b/tests/tns/app/tests/xhr-paths.ts
similarity index 100%
rename from tests/app/tests/xhr-paths.ts
rename to tests/tns/app/tests/xhr-paths.ts
diff --git a/tests/e2e-tests/lazy-load-routing.js b/tests/tns/e2e-tests/lazy-load-routing.js
similarity index 100%
rename from tests/e2e-tests/lazy-load-routing.js
rename to tests/tns/e2e-tests/lazy-load-routing.js
diff --git a/tests/e2e-tests/multi-page-routing.js b/tests/tns/e2e-tests/multi-page-routing.js
similarity index 100%
rename from tests/e2e-tests/multi-page-routing.js
rename to tests/tns/e2e-tests/multi-page-routing.js
diff --git a/tests/e2e-tests/single-page-routing.js b/tests/tns/e2e-tests/single-page-routing.js
similarity index 100%
rename from tests/e2e-tests/single-page-routing.js
rename to tests/tns/e2e-tests/single-page-routing.js
diff --git a/tests/hooks/after-prepare/nativescript-unit-test-runner.js b/tests/tns/hooks/after-prepare/nativescript-unit-test-runner.js
similarity index 100%
rename from tests/hooks/after-prepare/nativescript-unit-test-runner.js
rename to tests/tns/hooks/after-prepare/nativescript-unit-test-runner.js
diff --git a/tests/tns/hooks/before-livesync/nativescript-angular-sync.js b/tests/tns/hooks/before-livesync/nativescript-angular-sync.js
new file mode 100644
index 000000000..5a8510cb2
--- /dev/null
+++ b/tests/tns/hooks/before-livesync/nativescript-angular-sync.js
@@ -0,0 +1 @@
+module.exports = require("nativescript-angular/hooks/before-livesync");
diff --git a/tests/tns/hooks/before-prepare/nativescript-dev-typescript.js b/tests/tns/hooks/before-prepare/nativescript-dev-typescript.js
new file mode 100644
index 000000000..7116ebdb4
--- /dev/null
+++ b/tests/tns/hooks/before-prepare/nativescript-dev-typescript.js
@@ -0,0 +1 @@
+module.exports = require("nativescript-dev-typescript/lib/before-prepare.js");
diff --git a/tests/tns/hooks/before-watch/nativescript-dev-typescript.js b/tests/tns/hooks/before-watch/nativescript-dev-typescript.js
new file mode 100644
index 000000000..9a6ef6600
--- /dev/null
+++ b/tests/tns/hooks/before-watch/nativescript-dev-typescript.js
@@ -0,0 +1 @@
+module.exports = require("nativescript-dev-typescript/lib/watch.js");
diff --git a/tests/karma.conf.js b/tests/tns/karma.conf.js
similarity index 100%
rename from tests/karma.conf.js
rename to tests/tns/karma.conf.js
diff --git a/tests/package.json b/tests/tns/package.json
similarity index 87%
rename from tests/package.json
rename to tests/tns/package.json
index a875f0522..3ff8b0e22 100644
--- a/tests/package.json
+++ b/tests/tns/package.json
@@ -26,14 +26,16 @@
],
"homepage": "http://nativescript.org",
"dependencies": {
+ "@angular/animations": "~4.0.0",
"@angular/common": "~4.0.0",
"@angular/compiler": "~4.0.0",
"@angular/core": "~4.0.0",
+ "@angular/forms": "~4.0.0",
"@angular/http": "~4.0.0",
"@angular/platform-browser": "~4.0.0",
"@angular/platform-browser-dynamic": "~4.0.0",
"@angular/router": "~4.0.0",
- "nativescript-angular": "../nativescript-angular",
+ "nativescript-angular": "../../nativescript-angular",
"nativescript-unit-test-runner": "^0.3.4",
"rxjs": "^5.2.0",
"tns-core-modules": "internal-preview",
@@ -63,6 +65,9 @@
"wd": "0.4.0"
},
"scripts": {
+ "test": "npm run test-android",
+ "test-android": "tns test android --emulator --justlaunch",
+ "test-ios": "tns test ios --emulator --justlaunch",
"updateTests": "grunt updateTests",
"appium-android": "tns build android && npm run run-appium-android",
"run-appium-android": "nativescript-dev-appium android",
diff --git a/tests/tns/references.d.ts b/tests/tns/references.d.ts
new file mode 100644
index 000000000..b14f3837d
--- /dev/null
+++ b/tests/tns/references.d.ts
@@ -0,0 +1 @@
+/// Needed for autocompletion and compilation.
\ No newline at end of file
diff --git a/tests/tsconfig.json b/tests/tns/tsconfig.json
similarity index 100%
rename from tests/tsconfig.json
rename to tests/tns/tsconfig.json
diff --git a/tests/tslint.json b/tests/tns/tslint.json
similarity index 100%
rename from tests/tslint.json
rename to tests/tns/tslint.json
diff --git a/tests/typings/chai.d.ts b/tests/typings/chai.d.ts
deleted file mode 100644
index 113158d83..000000000
--- a/tests/typings/chai.d.ts
+++ /dev/null
@@ -1,283 +0,0 @@
-// Type definitions for chai 1.7.2
-// Project: http://chaijs.com/
-// Definitions by: Jed Hunsaker , Bart van der Schoor
-// Definitions: https://github.com/borisyankov/DefinitelyTyped
-
-declare module chai {
- export class AssertionError {
- constructor(message: string, _props?: any, ssf?: Function);
- name: string;
- message: string;
- showDiff: boolean;
- stack: string;
- }
-
- function expect(target: any, message?: string): Expect;
-
- export var assert: Assert;
- export var config: Config;
-
- export interface Config {
- includeStack: boolean;
- }
-
- // Provides a way to extend the internals of Chai
- function use(fn: (chai: any, utils: any) => void): any;
-
- interface ExpectStatic {
- (target: any): Expect;
- }
-
- interface Assertions {
- attr(name: string, value?: string): any;
- css(name: string, value?: string): any;
- data(name: string, value?: string): any;
- class(className: string): any;
- id(id: string): any;
- html(html: string): any;
- text(text: string): any;
- value(value: string): any;
- visible: any;
- hidden: any;
- selected: any;
- checked: any;
- disabled: any;
- empty: any;
- exist: any;
- }
-
- interface Expect extends LanguageChains, NumericComparison, TypeComparison, Assertions {
- not: Expect;
- deep: Deep;
- a: TypeComparison;
- an: TypeComparison;
- include: Include;
- contain: Include;
- ok: Expect;
- true: Expect;
- false: Expect;
- null: Expect;
- undefined: Expect;
- exist: Expect;
- empty: Expect;
- arguments: Expect;
- Arguments: Expect;
- equal: Equal;
- equals: Equal;
- eq: Equal;
- eql: Equal;
- eqls: Equal;
- property: Property;
- ownProperty: OwnProperty;
- haveOwnProperty: OwnProperty;
- length: Length;
- lengthOf: Length;
- match(RegularExpression: RegExp, message?: string): Expect;
- string(string: string, message?: string): Expect;
- keys: Keys;
- key(string: string): Expect;
- throw: Throw;
- throws: Throw;
- Throw: Throw;
- respondTo(method: string, message?: string): Expect;
- itself: Expect;
- satisfy(matcher: Function, message?: string): Expect;
- closeTo(expected: number, delta: number, message?: string): Expect;
- members: Members;
- }
-
- interface LanguageChains {
- to: Expect;
- be: Expect;
- been: Expect;
- is: Expect;
- that: Expect;
- and: Expect;
- have: Expect;
- with: Expect;
- at: Expect;
- of: Expect;
- same: Expect;
- }
-
- interface NumericComparison {
- above: NumberComparer;
- gt: NumberComparer;
- greaterThan: NumberComparer;
- least: NumberComparer;
- gte: NumberComparer;
- below: NumberComparer;
- lt: NumberComparer;
- lessThan: NumberComparer;
- most: NumberComparer;
- lte: NumberComparer;
- within(start: number, finish: number, message?: string): Expect;
- }
-
- interface NumberComparer {
- (value: number, message?: string): Expect;
- }
-
- interface TypeComparison {
- (type: string, message?: string): Expect;
- instanceof: InstanceOf;
- instanceOf: InstanceOf;
- }
-
- interface InstanceOf {
- (constructor: Object, message?: string): Expect;
- }
-
- interface Deep {
- equal: Equal;
- property: Property;
- }
-
- interface Equal {
- (value: any, message?: string): Expect;
- }
-
- interface Property {
- (name: string, value?: any, message?: string): Expect;
- }
-
- interface OwnProperty {
- (name: string, message?: string): Expect;
- }
-
- interface Length extends LanguageChains, NumericComparison {
- (length: number, message?: string): Expect;
- }
-
- interface Include {
- (value: Object, message?: string): Expect;
- (value: string, message?: string): Expect;
- (value: number, message?: string): Expect;
- keys: Keys;
- members: Members;
- }
-
- interface Keys {
- (...keys: string[]): Expect;
- (keys: any[]): Expect;
- }
-
- interface Members {
- (set: any[], message?: string): Expect;
- }
-
- interface Throw {
- (): Expect;
- (expected: string, message?: string): Expect;
- (expected: RegExp, message?: string): Expect;
- (constructor: Error, expected?: string, message?: string): Expect;
- (constructor: Error, expected?: RegExp, message?: string): Expect;
- (constructor: Function, expected?: string, message?: string): Expect;
- (constructor: Function, expected?: RegExp, message?: string): Expect;
- }
-
- export interface Assert {
- (express: any, msg?: string):void;
-
- fail(actual?: any, expected?: any, msg?: string, operator?: string):void;
-
- ok(val: any, msg?: string):void;
- notOk(val: any, msg?: string):void;
-
- equal(act: any, exp: any, msg?: string):void;
- notEqual(act: any, exp: any, msg?: string):void;
-
- strictEqual(act: any, exp: any, msg?: string):void;
- notStrictEqual(act: any, exp: any, msg?: string):void;
-
- deepEqual(act: any, exp: any, msg?: string):void;
- notDeepEqual(act: any, exp: any, msg?: string):void;
-
- isTrue(val: any, msg?: string):void;
- isFalse(val: any, msg?: string):void;
-
- isNull(val: any, msg?: string):void;
- isNotNull(val: any, msg?: string):void;
-
- isUndefined(val: any, msg?: string):void;
- isDefined(val: any, msg?: string):void;
-
- isFunction(val: any, msg?: string):void;
- isNotFunction(val: any, msg?: string):void;
-
- isObject(val: any, msg?: string):void;
- isNotObject(val: any, msg?: string):void;
-
- isArray(val: any, msg?: string):void;
- isNotArray(val: any, msg?: string):void;
-
- isString(val: any, msg?: string):void;
- isNotString(val: any, msg?: string):void;
-
- isNumber(val: any, msg?: string):void;
- isNotNumber(val: any, msg?: string):void;
-
- isBoolean(val: any, msg?: string):void;
- isNotBoolean(val: any, msg?: string):void;
-
- typeOf(val: any, type: string, msg?: string):void;
- notTypeOf(val: any, type: string, msg?: string):void;
-
- instanceOf(val: any, type: Function, msg?: string):void;
- notInstanceOf(val: any, type: Function, msg?: string):void;
-
- include(exp: string, inc: any, msg?: string):void;
- include(exp: any[], inc: any, msg?: string):void;
-
- notInclude(exp: string, inc: any, msg?: string):void;
- notInclude(exp: any[], inc: any, msg?: string):void;
-
- match(exp: any, re: RegExp, msg?: string):void;
- notMatch(exp: any, re: RegExp, msg?: string):void;
-
- property(obj: Object, prop: string, msg?: string):void;
- notProperty(obj: Object, prop: string, msg?: string):void;
- deepProperty(obj: Object, prop: string, msg?: string):void;
- notDeepProperty(obj: Object, prop: string, msg?: string):void;
-
- propertyVal(obj: Object, prop: string, val: any, msg?: string):void;
- propertyNotVal(obj: Object, prop: string, val: any, msg?: string):void;
-
- deepPropertyVal(obj: Object, prop: string, val: any, msg?: string):void;
- deepPropertyNotVal(obj: Object, prop: string, val: any, msg?: string):void;
-
- lengthOf(exp: any, len: number, msg?: string):void;
- //alias frenzy
- throw(fn: Function, msg?: string):void;
- throw(fn: Function, regExp: RegExp):void;
- throw(fn: Function, errType: Function, msg?: string):void;
- throw(fn: Function, errType: Function, regExp: RegExp):void;
-
- throws(fn: Function, msg?: string):void;
- throws(fn: Function, regExp: RegExp):void;
- throws(fn: Function, errType: Function, msg?: string):void;
- throws(fn: Function, errType: Function, regExp: RegExp):void;
-
- Throw(fn: Function, msg?: string):void;
- Throw(fn: Function, regExp: RegExp):void;
- Throw(fn: Function, errType: Function, msg?: string):void;
- Throw(fn: Function, errType: Function, regExp: RegExp):void;
-
- doesNotThrow(fn: Function, msg?: string):void;
- doesNotThrow(fn: Function, regExp: RegExp):void;
- doesNotThrow(fn: Function, errType: Function, msg?: string):void;
- doesNotThrow(fn: Function, errType: Function, regExp: RegExp):void;
-
- operator(val: any, operator: string, val2: any, msg?: string):void;
- closeTo(act: number, exp: number, delta: number, msg?: string):void;
-
- sameMembers(set1: any[], set2: any[], msg?: string):void;
- includeMembers(set1: any[], set2: any[], msg?: string):void;
-
- ifError(val: any, msg?: string):void;
- }
-}
-
-declare module "chai" {
-export = chai;
-}
diff --git a/tests/typings/mocha.d.ts b/tests/typings/mocha.d.ts
deleted file mode 100644
index 8d49749b7..000000000
--- a/tests/typings/mocha.d.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-// Type definitions for mocha 1.9.0
-// Project: http://visionmedia.github.io/mocha/
-// Definitions by: Kazi Manzur Rashid
-// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
-
-interface Mocha {
- // Setup mocha with the given setting options.
- setup(options: MochaSetupOptions): Mocha;
-
- //Run tests and invoke `fn()` when complete.
- run(callback?: () => void): void;
-
- // Set reporter as function
- reporter(reporter: () => void): Mocha;
-
- // Set reporter, defaults to "dot"
- reporter(reporter: string): Mocha;
-
- // Enable growl support.
- growl(): Mocha
-}
-
-interface MochaSetupOptions {
- //milliseconds to wait before considering a test slow
- slow?: number;
-
- // timeout in milliseconds
- timeout?: number;
-
- // ui name "bdd", "tdd", "exports" etc
- ui?: string;
-
- //array of accepted globals
- globals?: any[];
-
- // reporter instance (function or string), defaults to `mocha.reporters.Dot`
- reporter?: any;
-
- // bail on the first test failure
- bail?: Boolean;
-
- // ignore global leaks
- ignoreLeaks?: Boolean;
-
- // grep string or regexp to filter tests with
- grep?: any;
-}
-
-declare module mocha {
- interface Done {
- (error?: Error): void;
- }
-}
-
-declare var describe : {
- (description: string, spec: () => void): void;
- only(description: string, spec: () => void): void;
- skip(description: string, spec: () => void): void;
- timeout(ms: number): void;
-}
-
-declare var it: {
- (expectation: string, assertion?: () => void): void;
- (expectation: string, assertion?: (done: mocha.Done) => void): void;
- only(expectation: string, assertion?: () => void): void;
- only(expectation: string, assertion?: (done: mocha.Done) => void): void;
- skip(expectation: string, assertion?: () => void): void;
- skip(expectation: string, assertion?: (done: mocha.Done) => void): void;
- timeout(ms: number): void;
-};
-
-declare function before(action: () => void): void;
-
-declare function before(action: (done: mocha.Done) => void): void;
-
-declare function after(action: () => void): void;
-
-declare function after(action: (done: mocha.Done) => void): void;
-
-declare function beforeEach(action: () => void): void;
-
-declare function beforeEach(action: (done: mocha.Done) => void): void;
-
-declare function afterEach(action: () => void): void;
-
-declare function afterEach(action: (done: mocha.Done) => void): void;