diff --git a/.gitignore b/.gitignore
index 6d9446a..7404c57 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,9 @@
*~
.idea/
*.iml
+atlassian-ide-plugin.xml
+node_modules/
+typings/
+app/**/*.js
+app/**/*.js.map
+npm-debug.log
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 916c442..faf8a09 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,9 +1,6 @@
-#variables:
-# NPMPATH: "node_modules/.bin"
-
stages:
-# - build
-# - cleanup_build
+ - build
+ - cleanup_build
- deploy
# - cleanup
@@ -11,32 +8,50 @@ stages:
script:
- chmod +x ./deploy.sh
- ./deploy.sh
+ dependencies:
+ - build_job
-#build_job:
-# stage: build
-# script:
-# - npm install
-# - $NPMPATH/bower install
-# - $NPMPATH/grunt
-# tags:
-# - javascript
-# except:
-# - tags
-# artifacts:
-# paths:
-# - dist/*.min.*
-# - info/
-# - resources/
-# - index.html
-# - manifest.appcache
+build_job:
+ stage: build
+ script:
+ - npm install
+ - npm run tsc
+ tags:
+ - javascript
+ except:
+ - tags
+ artifacts:
+ paths:
+ - app/*.css
+ - app/*.html
+ - app/*.js
+ - app/*.js.map
+ - app/converter/*.js
+ - app/converter/*.js.map
+ - node_modules/@angular/
+ - node_modules/core-js/client/shim.js
+ - node_modules/zone.js/dist/zone.js
+ - node_modules/reflect-metadata/Reflect.js
+ - node_modules/rxjs/
+ - node_modules/systemjs/dist/system.src.js
+ - node_modules/utf8/utf8.js
+ - node_modules/quoted-printable/quoted-printable.js
+ - abeezee-regular.woff
+ - freemono.eot
+ - freemono.svg
+ - freemono.ttf
+ - freemono.woff
+ - index.html
+ - package.json
+ - systemjs.config.js
+ expire_in: 30 min
-#cleanup_build_job:
-# stage: cleanup_build
-# script:
-# - rm -rf node_modules
-# - rm -rf bower_components
-# - rm -rf dist
-# when: on_failure
+cleanup_build_job:
+ stage: cleanup_build
+ script:
+ - rm -rf node_modules
+ - rm -rf typings
+ when: on_failure
develop:
stage: deploy
@@ -74,5 +89,5 @@ production:
# stage: cleanup
# script:
# - rm -rf node_modules
-# - rm -rf bower_components
+# - rm -rf typings
# when: always
diff --git a/abeezee-regular.woff b/abeezee-regular.woff
new file mode 100644
index 0000000..86a7468
Binary files /dev/null and b/abeezee-regular.woff differ
diff --git a/app/app.component.css b/app/app.component.css
new file mode 100644
index 0000000..a1f448b
--- /dev/null
+++ b/app/app.component.css
@@ -0,0 +1,127 @@
+@font-face {
+ font-family: "ABeeZee";
+ font-stretch: normal;
+ font-style: normal;
+ font-variant: normal;
+ font-weight: normal;
+ src: local("ABeeZee Regular"),
+ local("ABeeZee-Regular"),
+ local("ABeeZee"),
+ url("../abeezee-regular.woff") format("woff");
+}
+
+@font-face {
+ font-family: "Free Monospaced";
+ src: url("../freemono.eot?") format("eot"),
+ url("../freemono.woff") format("woff"),
+ url("../freemono.ttf") format("truetype"),
+ url("../freemono.svg#FreeMono") format("svg");
+ font-weight: normal;
+ font-style: normal;
+}
+
+.inputwrapper {
+ font-family: "ABeeZee", sans-serif;
+ margin: 0 1em 1em 1em;
+}
+
+.textwrapper {
+ margin: 0 0 1em 0;
+ padding: 0 1em 0 0;
+}
+
+.arrow_box {
+ position: relative;
+ background: #fff;
+ border: 1px solid #ddd;
+}
+
+.arrow_box:focus {
+ border-color: #888;
+}
+
+.arrow_box:hover {
+ border-color: #333;
+}
+
+.arrow_box:after, .arrow_box:before {
+ top: 100%;
+ left: 50%;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+}
+
+.arrow_box:after {
+ border-color: rgba(255, 255, 255, 0);
+ border-top-color: #fff;
+ border-width: 1em;
+ margin-left: -1em;
+}
+
+.arrow_box:before {
+ border-color: rgba(221, 221, 221, 0);
+ border-top-color: #ddd;
+ border-width: calc(1em + 1px);
+ margin-left: calc(-1em - 1px);
+}
+
+.arrow_box:focus:before {
+ border-color: rgba(136, 136, 136, 0);
+ border-top-color: #888;
+}
+
+.arrow_box:hover:before {
+ border-color: rgba(51, 51, 51, 0);
+ border-top-color: #333;
+}
+
+.selectwrapper > .arrow_box {
+ display: inline-block;
+}
+
+.textinput {
+ background-color: #fff;
+ border: none;
+ color: #000;
+ font-family: "Free Monospaced", monospace;
+ height: 10em;
+ margin: 0;
+ padding: 0.5em;
+ resize: vertical;
+ width: 100%;
+}
+
+.textinput:focus {
+ border-color: #888;
+}
+
+.textinput:hover {
+ border-color: #333;
+}
+
+.selectwrapper {
+ margin: 0 0 1em 0;
+ padding: 0;
+ text-align: center;
+}
+
+.select {
+ background-color: #fff;
+ border: none;
+ color: #000;
+ font-family: "ABeeZee", sans-serif;
+ margin: 0;
+ padding: 0.5em;
+}
+
+.option {
+ /* font-family: "ABeeZee", sans-serif;*/
+}
+
+.errormessage {
+ /* font-family: "ABeeZee", sans-serif;*/
+}
diff --git a/app/app.component.html b/app/app.component.html
new file mode 100644
index 0000000..22b15e3
--- /dev/null
+++ b/app/app.component.html
@@ -0,0 +1,16 @@
+
diff --git a/app/app.component.ts b/app/app.component.ts
new file mode 100644
index 0000000..79d9816
--- /dev/null
+++ b/app/app.component.ts
@@ -0,0 +1,61 @@
+import {Component, OnInit} from "@angular/core";
+import {ConverterRegistryService} from "./converterregistry.service";
+import {InputComponentManagerService} from "./inputcomponentmanager.service";
+import {Converter} from "./converter/converter";
+import {NativeLibraryWrapperService} from "./nativelibrarywrapper.service";
+
+@Component({
+ moduleId: module.id,
+ selector: "den-app",
+ templateUrl: "app.component.html",
+ styleUrls: ["app.component.css"],
+ providers: [ConverterRegistryService, InputComponentManagerService, NativeLibraryWrapperService]
+})
+export class AppComponent extends OnInit {
+ public steps:any[] = [];
+ public converters:Converter[] = [];
+
+ constructor(private converterRegistryService:ConverterRegistryService, private inputComponentManagerService:InputComponentManagerService) {
+ super();
+ }
+
+ convert(step:any, $event:any):void {
+ step.selectedConverter = this.converterRegistryService.getConverter($event.target.selectedOptions[0].id);
+ this.update(step);
+ }
+
+ update(step:any):void {
+ let converter:Converter = step.selectedConverter;
+
+ if (converter !== undefined) {
+ let content:string = step.content;
+ let result:string;
+ try {
+ result = converter.convert(content);
+ } catch (error) {
+ if (typeof console === "object" && typeof console.log === "function") {
+ console.log(error);
+ }
+ result = null;
+ }
+ if (result === null) {
+ step.message = "Error converting. Not applicable?";
+ step.error = true;
+ } else {
+ step.message = "";
+ step.error = false;
+ if (result !== "") {
+ let nextComponent:any = this.inputComponentManagerService.getNext(step);
+ nextComponent.content = result;
+ this.update(nextComponent);
+ }
+ }
+ }
+ }
+
+ ngOnInit():void {
+ this.converters = this.converterRegistryService.getAllConverters();
+ this.steps = this.inputComponentManagerService.getAllComponents();
+ this.inputComponentManagerService.getFirst();
+ }
+}
diff --git a/app/app.module.ts b/app/app.module.ts
new file mode 100644
index 0000000..8988169
--- /dev/null
+++ b/app/app.module.ts
@@ -0,0 +1,19 @@
+import {NgModule} from "@angular/core";
+import {BrowserModule} from "@angular/platform-browser";
+import {FormsModule} from "@angular/forms";
+import {AppComponent} from "./app.component";
+import {InputareaComponent} from "./inputarea.component";
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ FormsModule
+ ],
+ declarations: [
+ AppComponent,
+ InputareaComponent
+ ],
+ bootstrap: [AppComponent]
+})
+export class AppModule {
+}
diff --git a/app/conversioninput.ts b/app/conversioninput.ts
new file mode 100644
index 0000000..9f52cca
--- /dev/null
+++ b/app/conversioninput.ts
@@ -0,0 +1,6 @@
+import {ConversionType} from "./conversiontype";
+
+export class ConversionInput {
+ public content:string;
+ public type:ConversionType;
+}
diff --git a/app/conversiontype.ts b/app/conversiontype.ts
new file mode 100644
index 0000000..4f34586
--- /dev/null
+++ b/app/conversiontype.ts
@@ -0,0 +1,28 @@
+export enum ConversionType {
+ ENCODE_BASE64,
+ DECODE_BASE64
+}
+
+export namespace ConversionType {
+ export function getName(type:ConversionType):string {
+ switch (type) {
+ case ConversionType.DECODE_BASE64:
+ return "Decode BASE64";
+ case ConversionType.ENCODE_BASE64:
+ return "Encode BASE64";
+ default:
+ return "Unknown";
+ }
+ }
+
+ export function of(id:number):ConversionType {
+ switch (id) {
+ case 0:
+ return ConversionType.ENCODE_BASE64;
+ case 1:
+ return ConversionType.DECODE_BASE64;
+ default:
+ return undefined;
+ }
+ }
+}
diff --git a/app/converter/base64decoder.ts b/app/converter/base64decoder.ts
new file mode 100644
index 0000000..1b4e5b1
--- /dev/null
+++ b/app/converter/base64decoder.ts
@@ -0,0 +1,15 @@
+import {Converter} from "./converter";
+
+export class Base64Decoder implements Converter {
+ getDisplayname():string {
+ return "Decode Base 64";
+ }
+
+ getId():string {
+ return "base64decode";
+ }
+
+ convert(input:string):string {
+ return atob(input);
+ }
+}
diff --git a/app/converter/base64encoder.ts b/app/converter/base64encoder.ts
new file mode 100644
index 0000000..409636d
--- /dev/null
+++ b/app/converter/base64encoder.ts
@@ -0,0 +1,15 @@
+import {Converter} from "./converter";
+
+export class Base64Encoder implements Converter {
+ getDisplayname():string {
+ return "Encode Base 64";
+ }
+
+ getId():string {
+ return "base64encode";
+ }
+
+ convert(input:string):string {
+ return btoa(input);
+ }
+}
diff --git a/app/converter/bintodecconverter.ts b/app/converter/bintodecconverter.ts
new file mode 100644
index 0000000..2c73959
--- /dev/null
+++ b/app/converter/bintodecconverter.ts
@@ -0,0 +1,14 @@
+import {Converter} from "./converter";
+export class BinToDecConverter implements Converter {
+ getDisplayname():string {
+ return "Convert binary to decimal";
+ }
+
+ getId():string {
+ return "bintodec";
+ }
+
+ convert(input:string):string {
+ return parseInt(input, 2).toString(10);
+ }
+}
diff --git a/app/converter/converter.ts b/app/converter/converter.ts
new file mode 100644
index 0000000..66706f9
--- /dev/null
+++ b/app/converter/converter.ts
@@ -0,0 +1,5 @@
+export interface Converter {
+ getDisplayname():string;
+ getId():string;
+ convert(input:string):string;
+}
diff --git a/app/converter/dectobinconverter.ts b/app/converter/dectobinconverter.ts
new file mode 100644
index 0000000..8cc2b0d
--- /dev/null
+++ b/app/converter/dectobinconverter.ts
@@ -0,0 +1,14 @@
+import {Converter} from "./converter";
+export class DecToBinConverter implements Converter {
+ getDisplayname():string {
+ return "Convert decimal to binary";
+ }
+
+ getId():string {
+ return "dectobin";
+ }
+
+ convert(input:string):string {
+ return parseInt(input, 10).toString(2);
+ }
+}
diff --git a/app/converter/dectohexconverter.ts b/app/converter/dectohexconverter.ts
new file mode 100644
index 0000000..c0be47f
--- /dev/null
+++ b/app/converter/dectohexconverter.ts
@@ -0,0 +1,14 @@
+import {Converter} from "./converter";
+export class DecToHexConverter implements Converter {
+ getDisplayname():string {
+ return "Convert decimal to heximal";
+ }
+
+ getId():string {
+ return "dectohex";
+ }
+
+ convert(input:string):string {
+ return parseInt(input, 10).toString(16);
+ }
+}
diff --git a/app/converter/hextodecconverter.ts b/app/converter/hextodecconverter.ts
new file mode 100644
index 0000000..c6b3dba
--- /dev/null
+++ b/app/converter/hextodecconverter.ts
@@ -0,0 +1,14 @@
+import {Converter} from "./converter";
+export class HexToDecConverter implements Converter {
+ getDisplayname():string {
+ return "Convert heximal to decimal";
+ }
+
+ getId():string {
+ return "hextodec";
+ }
+
+ convert(input:string):string {
+ return parseInt(input, 16).toString(10);
+ }
+}
diff --git a/app/converter/htmlentitiesdecoder.ts b/app/converter/htmlentitiesdecoder.ts
new file mode 100644
index 0000000..2a793ce
--- /dev/null
+++ b/app/converter/htmlentitiesdecoder.ts
@@ -0,0 +1,19 @@
+import {Converter} from "./converter";
+
+export class HTMLEntitiesDecoder implements Converter {
+ getDisplayname():string {
+ return "Decode HTML entities";
+ }
+
+ getId():string {
+ return "decodehtmlentities";
+ }
+
+ convert(input:string):string {
+ return input
+ .replace(/\"\;/g, "\"")
+ .replace(/\>\;/g, ">")
+ .replace(/\<\;/g, "<")
+ .replace(/\&\;/g, "&");
+ }
+}
diff --git a/app/converter/htmlentitiesencoder.ts b/app/converter/htmlentitiesencoder.ts
new file mode 100644
index 0000000..cf626b6
--- /dev/null
+++ b/app/converter/htmlentitiesencoder.ts
@@ -0,0 +1,19 @@
+import {Converter} from "./converter";
+
+export class HTMLEntitiesEncoder implements Converter {
+ getDisplayname():string {
+ return "Encode HTML entities";
+ }
+
+ getId():string {
+ return "encodehtmlentities";
+ }
+
+ convert(input:string):string {
+ return input
+ .replace(/\&/g, "&")
+ .replace(/\/g, ">")
+ .replace(/\"/g, """);
+ }
+}
diff --git a/app/converter/quotedprintabledecoder.ts b/app/converter/quotedprintabledecoder.ts
new file mode 100644
index 0000000..6787ff1
--- /dev/null
+++ b/app/converter/quotedprintabledecoder.ts
@@ -0,0 +1,19 @@
+import {Converter} from "./converter";
+import {NativeLibraryWrapperService} from "../nativelibrarywrapper.service";
+
+export class QuotedPrintableDecoder implements Converter {
+ constructor(private nativeLibraryWrapperService:NativeLibraryWrapperService) {
+ }
+
+ getDisplayname():string {
+ return "Decode quoted printable";
+ }
+
+ getId():string {
+ return "decodequotedprintable";
+ }
+
+ convert(input:string):string {
+ return this.nativeLibraryWrapperService.utf8.decode(this.nativeLibraryWrapperService.quotedPrintable.decode(input));
+ }
+}
diff --git a/app/converter/quotedprintableencoder.ts b/app/converter/quotedprintableencoder.ts
new file mode 100644
index 0000000..048dbc6
--- /dev/null
+++ b/app/converter/quotedprintableencoder.ts
@@ -0,0 +1,19 @@
+import {Converter} from "./converter";
+import {NativeLibraryWrapperService} from "../nativelibrarywrapper.service";
+
+export class QuotedPrintableEncoder implements Converter {
+ constructor(private nativeLibraryWrapperService:NativeLibraryWrapperService) {
+ }
+
+ getDisplayname():string {
+ return "Encode quoted printable";
+ }
+
+ getId():string {
+ return "encodequotedprintable";
+ }
+
+ convert(input:string):string {
+ return this.nativeLibraryWrapperService.quotedPrintable.encode(this.nativeLibraryWrapperService.utf8.encode(input));
+ }
+}
diff --git a/app/converter/uricomponentdecoder.ts b/app/converter/uricomponentdecoder.ts
new file mode 100644
index 0000000..ee96e28
--- /dev/null
+++ b/app/converter/uricomponentdecoder.ts
@@ -0,0 +1,15 @@
+import {Converter} from "./converter";
+
+export class URIComponentDecoder implements Converter {
+ getDisplayname():string {
+ return "Decode URI component";
+ }
+
+ getId():string {
+ return "uricomponentdecode";
+ }
+
+ convert(input:string):string {
+ return decodeURIComponent(input);
+ }
+}
diff --git a/app/converter/uricomponentencoder.ts b/app/converter/uricomponentencoder.ts
new file mode 100644
index 0000000..b4fb478
--- /dev/null
+++ b/app/converter/uricomponentencoder.ts
@@ -0,0 +1,17 @@
+import {Converter} from "./converter";
+
+export class URIComponentEncoder implements Converter {
+ getDisplayname():string {
+ return "Encode URI component";
+ }
+
+ getId():string {
+ return "uricomponentencode";
+ }
+
+ convert(input:string):string {
+ return encodeURIComponent(input).replace(/[!'()*]/g, function (c) {
+ return '%' + c.charCodeAt(0).toString(16);
+ });
+ }
+}
diff --git a/app/converter/uridecoder.ts b/app/converter/uridecoder.ts
new file mode 100644
index 0000000..1949940
--- /dev/null
+++ b/app/converter/uridecoder.ts
@@ -0,0 +1,15 @@
+import {Converter} from "./converter";
+
+export class URIDecoder implements Converter {
+ getDisplayname():string {
+ return "Decode URI";
+ }
+
+ getId():string {
+ return "uridecode";
+ }
+
+ convert(input:string):string {
+ return decodeURI(input);
+ }
+}
diff --git a/app/converter/uriencoder.ts b/app/converter/uriencoder.ts
new file mode 100644
index 0000000..b56c747
--- /dev/null
+++ b/app/converter/uriencoder.ts
@@ -0,0 +1,15 @@
+import {Converter} from "./converter";
+
+export class URIEncoder implements Converter {
+ getDisplayname():string {
+ return "Encode URI";
+ }
+
+ getId():string {
+ return "uriencode";
+ }
+
+ convert(input:string):string {
+ return encodeURI(input).replace(/%5B/g, '[').replace(/%5D/g, ']');
+ }
+}
diff --git a/app/converterregistry.service.ts b/app/converterregistry.service.ts
new file mode 100644
index 0000000..48817b7
--- /dev/null
+++ b/app/converterregistry.service.ts
@@ -0,0 +1,65 @@
+import {Injectable} from "@angular/core";
+import {Converter} from "./converter/converter";
+import {Base64Encoder} from "./converter/base64encoder";
+import {Base64Decoder} from "./converter/base64decoder";
+import {URIEncoder} from "./converter/uriencoder";
+import {URIDecoder} from "./converter/uridecoder";
+import {URIComponentEncoder} from "./converter/uricomponentencoder";
+import {URIComponentDecoder} from "./converter/uricomponentdecoder";
+import {HTMLEntitiesEncoder} from "./converter/htmlentitiesencoder";
+import {HTMLEntitiesDecoder} from "./converter/htmlentitiesdecoder";
+import {DecToHexConverter} from "./converter/dectohexconverter";
+import {HexToDecConverter} from "./converter/hextodecconverter";
+import {DecToBinConverter} from "./converter/dectobinconverter";
+import {BinToDecConverter} from "./converter/bintodecconverter";
+import {QuotedPrintableDecoder} from "./converter/quotedprintabledecoder";
+import {QuotedPrintableEncoder} from "./converter/quotedprintableencoder";
+import {NativeLibraryWrapperService} from "./nativelibrarywrapper.service";
+
+@Injectable()
+export class ConverterRegistryService {
+ private converters:Converter[] = [];
+
+ constructor(private wrapper:NativeLibraryWrapperService) {
+ this.init();
+ }
+
+ public getAllConverters():Converter[] {
+ return this.converters;
+ }
+
+ public getConverter(id:string):Converter {
+ for (let i = 0; i < this.converters.length; i++) {
+ if (this.converters[i].getId() == id) {
+ return this.converters[i];
+ }
+ }
+ return undefined;
+ }
+
+ private init():void {
+ this.registerConverter(new Base64Encoder());
+ this.registerConverter(new Base64Decoder());
+ this.registerConverter(new URIEncoder());
+ this.registerConverter(new URIDecoder());
+ this.registerConverter(new URIComponentEncoder());
+ this.registerConverter(new URIComponentDecoder());
+ this.registerConverter(new HTMLEntitiesEncoder());
+ this.registerConverter(new HTMLEntitiesDecoder());
+ this.registerConverter(new QuotedPrintableEncoder(this.wrapper));
+ this.registerConverter(new QuotedPrintableDecoder(this.wrapper));
+ this.registerConverter(new DecToHexConverter());
+ this.registerConverter(new HexToDecConverter());
+ this.registerConverter(new DecToBinConverter());
+ this.registerConverter(new BinToDecConverter());
+ }
+
+ private registerConverter(converter:Converter):void {
+ this.converters.forEach((c:Converter) => {
+ if (c.getId() == converter.getId()) {
+ throw new Error("Converter-ID " + converter.getId() + " is already registered!");
+ }
+ });
+ this.converters.push(converter);
+ }
+}
diff --git a/app/inputarea.component.css b/app/inputarea.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/app/inputarea.component.html b/app/inputarea.component.html
new file mode 100644
index 0000000..d8e65ee
--- /dev/null
+++ b/app/inputarea.component.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/inputarea.component.ts b/app/inputarea.component.ts
new file mode 100644
index 0000000..d6164ad
--- /dev/null
+++ b/app/inputarea.component.ts
@@ -0,0 +1,47 @@
+import {Component, OnInit} from "@angular/core";
+import {ConverterRegistryService} from "./converterregistry.service";
+import {Converter} from "./converter/converter";
+import {InputComponentManagerService} from "./inputcomponentmanager.service";
+
+
+@Component({
+ moduleId: module.id,
+ selector: "den-inputarea",
+ templateUrl: "inputarea.component.html",
+ styleUrls: ["inputarea.component.css"]
+})
+export class InputareaComponent extends OnInit {
+ public converters:Converter[] = [];
+ public content:string = '';
+ private selectedConverter:Converter;
+
+ constructor(private converterRegistryService:ConverterRegistryService, private inputComponentManagerService:InputComponentManagerService) {
+ super();
+ }
+
+ public convert(e):void {
+ this.selectedConverter = this.converterRegistryService.getConverter(e.target.selectedOptions[0].id);
+ this.update();
+ }
+
+ public update():void {
+ if (this.selectedConverter !== undefined) {
+ let result:string = this.selectedConverter.convert(this.content);
+ let nextComponent:InputareaComponent = this.inputComponentManagerService.getNext(this);
+ if (nextComponent !== undefined) {
+ nextComponent.setContent(result);
+ }
+ }
+ }
+
+ public setContent(content:string):void {
+ this.content = content;
+ this.update();
+ }
+
+ ngOnInit():void {
+ this.converters = this.converterRegistryService.getAllConverters();
+ this.selectedConverter = undefined;
+ this.inputComponentManagerService.register(this);
+ }
+}
diff --git a/app/inputcomponentmanager.service.ts b/app/inputcomponentmanager.service.ts
new file mode 100644
index 0000000..a15b97c
--- /dev/null
+++ b/app/inputcomponentmanager.service.ts
@@ -0,0 +1,42 @@
+import {Injectable} from "@angular/core";
+
+@Injectable()
+export class InputComponentManagerService {
+ private components:any[] = [];
+
+ public constructor() {
+ }
+
+ public register(component:any):void {
+ this.components.push(component);
+ }
+
+ public getAllComponents():any[] {
+ return this.components;
+ }
+
+ public getNext(component:any):any {
+ let index:number = component.index;
+ if (index == this.components.length - 1) {
+ this.addComponent();
+ }
+ return this.components[index + 1];
+ }
+
+ public getFirst():any {
+ if (this.components.length == 0) {
+ this.addComponent();
+ }
+ return this.components[0];
+ }
+
+ private addComponent():void {
+ this.register({
+ content: "",
+ selectedConverter: undefined,
+ index: this.components.length,
+ error: false,
+ message: ""
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/main.ts b/app/main.ts
new file mode 100644
index 0000000..c31c26f
--- /dev/null
+++ b/app/main.ts
@@ -0,0 +1,4 @@
+import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
+import {AppModule} from "./app.module";
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/app/nativelibrarywrapper.service.ts b/app/nativelibrarywrapper.service.ts
new file mode 100644
index 0000000..6a7d840
--- /dev/null
+++ b/app/nativelibrarywrapper.service.ts
@@ -0,0 +1,15 @@
+import {Injectable} from "@angular/core";
+
+declare var utf8:any;
+declare var quotedPrintable:any;
+
+@Injectable()
+export class NativeLibraryWrapperService {
+ public utf8:any;
+ public quotedPrintable:any;
+
+ constructor() {
+ this.utf8 = utf8;
+ this.quotedPrintable = quotedPrintable;
+ }
+}
\ No newline at end of file
diff --git a/app/option.component._t_s_ b/app/option.component._t_s_
new file mode 100644
index 0000000..1398f21
--- /dev/null
+++ b/app/option.component._t_s_
@@ -0,0 +1,12 @@
+//import {Component} from "@angular/core";
+//
+//@Component({
+// selector: "den-option",
+// template: `
+//
+// `
+//})
+//export class OptionComponent {
+// public id:string;
+// public displayName:string;
+//}
\ No newline at end of file
diff --git a/app/selector.component._t_s_ b/app/selector.component._t_s_
new file mode 100644
index 0000000..0c17a7e
--- /dev/null
+++ b/app/selector.component._t_s_
@@ -0,0 +1,19 @@
+//import {Component} from "@angular/core";
+//
+//import {OptionComponent} from "./option.component";
+//
+//@Component({
+// selector: "den-selector",
+// template: `
+//
+// `,
+// directives: [OptionComponent]
+//})
+//export class SelectorComponent {
+// private options:OptionComponent[];
+//
+//}
\ No newline at end of file
diff --git a/dencode.css b/dencode.css
deleted file mode 100644
index 8fadfda..0000000
--- a/dencode.css
+++ /dev/null
@@ -1,113 +0,0 @@
-@import url(//fonts.googleapis.com/css?family=Open+Sans:300,600&subset=latin,latin-ext);
-
-@media (max-width: 980px) {
- body {
- margin: 0;
- padding: 0;
- }
-
- h1 {
- font-size: 120%;
- margin: 0;
- }
-
- div.wrapper {
- border-radius: 0;
- margin-left: 0;
- margin-right: 0;
- }
-
- textarea.input {
- border-radius: 0;
- }
-}
-
-@media (min-width: 981px) {
- div.wrapper {
- border-radius: 0.5em;
- margin-left: auto;
- margin-right: auto;
- width: 50%;
- }
-
- textarea.input {
- border-radius: 0.5em;
- }
-}
-body {
- font-family: 'Open Sans', sans-serif;
- font-weight: 300;
-}
-
-h1 {
- text-align: center;
- font-weight: 600;
-}
-
-strong {
- font-weight: 600;
-}
-
-div.wrapper {
- background-color: #fc0;
- border-color: #da0;
- border-style: solid;
- border-width: 1px;
- box-shadow: 0 0 1px 1px #ea0 inset;
- color: #000;
- margin-bottom: 0.5em;
- padding: 0.5em;
-}
-
-textarea.input {
- border-style: solid;
- border-width: 1px;
- display: block;
- font-family: 'Open Sans', sans-serif;
- font-weight: 300;
- font-size: 80%;
- height: 150px;
- padding: 0.1em 0.3em;
- resize: vertical;
- width: -moz-available;
- width: -webkit-fill-available;
-}
-
-textarea.input.error {
- background-color: #f88;
- border-color: #f00;
- color: #000;
-}
-
-textarea.input.error:focus, textarea.input.error:hover {
- background-color: #faa;
- border-color: #f00;
- color: #000;
-}
-
-select.conversion {
- border-radius: 0.2em;
- border-style: solid;
- border-width: 1px;
- font-family: 'Open Sans', sans-serif;
- font-weight: 300;
- margin-top: 0.5em;
-}
-
-textarea.input, select.conversion {
- background-color: #fdfbf0;
- border-color: #fae8e7;
- color: #000;
-}
-
-textarea.input:focus, textarea.input:hover,
-select.conversion:focus, select.conversion:hover {
- background-color: #fff;
- border-color: #fdfbf0;
- color: #000;
-}
-
-textarea.input:hover,
-select.conversion:hover {
- box-shadow: 0 0 6px 4px #c90;
-}
diff --git a/dencode.js b/dencode.js
deleted file mode 100644
index a076423..0000000
--- a/dencode.js
+++ /dev/null
@@ -1,321 +0,0 @@
-(function($) {
- var plugins = [
- {
- "id": "CHOOSE",
- "name": "Please choose your conversion ...",
- "convert": function (input) {
- return {
- "status": "OK",
- "content": ""
- };
- }
- },
- {
- "id": "base64decode",
- "name": "Decode Base64",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": atob(input)
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid base64 input string."
- };
- }
- }
- },
- {
- "id": "decodeuri",
- "name": "Decode URI",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": decodeURI(input)
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid URI input string."
- };
- }
- }
- },
- {
- "id": "decodeuricomponent",
- "name": "Decode URI component",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": decodeURIComponent(input)
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid URI component input string."
- };
- }
- }
- },
- {
- "id": "decodehtmlentities",
- "name": "Decode HTML entities",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": input
- .replace(/\"\;/g, "\"")
- .replace(/\>\;/g, ">")
- .replace(/\<\;/g, "<")
- .replace(/\&\;/g, "&")
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid HTML entity string."
- };
- }
- }
- },
- {
- "id": "decodequotedprintable",
- "name": "Decode quoted printable",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": utf8.decode(quotedPrintable.decode(input))
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid quoted printable string."
- };
- }
- }
- },
- {
- "id": "hextodec",
- "name": "Decode hex as decimal",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": parseInt(input, 16).toString(10)
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid number (integer) string."
- };
- }
- }
- },
- {
- "id": "bintodec",
- "name": "Decode binary as decimal",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": parseInt(input, 2).toString(10)
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid number (integer) string."
- };
- }
- }
- },
- {
- "id": "base64encode",
- "name": "Encode Base64",
- "convert": function (input) {
- return {
- "status": "OK",
- "content": btoa(input)
- };
- }
- },
- {
- "id": "encodeuri",
- "name": "Encode URI",
- "convert": function (input) {
- return {
- "status": "OK",
- "content": encodeURI(input).replace(/%5B/g, '[').replace(/%5D/g, ']')
- };
- }
- },
- {
- "id": "encodeuricomponent",
- "name": "Encode URI component",
- "convert": function (input) {
- return {
- "status": "OK",
- "content": encodeURIComponent(input).replace(/[!'()*]/g, function(c) {
- return '%' + c.charCodeAt(0).toString(16);
- })
- };
- }
- },
- {
- "id": "encodehtmlentities",
- "name": "Encode HTML entities",
- "convert": function (input) {
- return {
- "status": "OK",
- "content": input
- .replace(/\&/g, "&")
- .replace(/\/g, ">")
- .replace(/\"/g, """)
- };
- }
- },
- {
- "id": "encodequotedprintable",
- "name": "Encode quoted printable",
- "convert": function (input) {
- return {
- "status": "OK",
- "content": quotedPrintable.encode(utf8.encode(input))
- };
- }
- },
- {
- "id": "dectohex",
- "name": "Encode decimal as hex",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": parseInt(input).toString(16)
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid number (integer) string."
- };
- }
- }
- },
- {
- "id": "dectobin",
- "name": "Encode decimal as binary",
- "convert": function (input) {
- try {
- return {
- "status": "OK",
- "content": parseInt(input).toString(2)
- };
- } catch (exception) {
- return {
- "status": "ERROR",
- "content": "Invalid number (integer) string."
- };
- }
- }
- }
- ];
-
- var optiontemplate = "";
- var template = ""
- + "
";
- var options = "";
- var i, plugin, option;
- for (i = 0; i < plugins.length; i++) {
- plugin = plugins[i];
- option = optiontemplate.replace(/\{identifier\}/g, plugin.id).replace(/\{name\}/g, plugin.name);
- if (plugin.disabled) {
- option = $(option).attr("disabled", "disabled")[0].outerHTML;
- }
- options += option;
- }
- template = template.replace(/\{options\}/g, options);
-
- $(document).ready(function() {
- var $new = $(template.replace(/\{index\}/g, "0").replace(/\{content\}/g, ""));
- $("body").append($new);
- });
-
- function getPluginById(id) {
- for (i = 0; i < plugins.length; i++) {
- if (plugins[i].id === id) {
- return plugins[i];
- }
- }
- return null;
- }
-
- function convert(select) {
- var $select = $(select);
- var selectid = $select.attr("id");
- var inputIndex = +selectid.split("-")[1];
- var outputIndex = inputIndex + 1;
- var $input = $("#input-" + inputIndex);
- var $output = $("#input-" + outputIndex);
- var appendNewOutput = false;
- var input = $input.val();
- var conversion = $select.find(":selected").attr("name");
- var result;
- var status;
- var output;
- var plugin;
- if ($output.length == 0) {
- appendNewOutput = true;
- }
- plugin = getPluginById(conversion);
- if (plugin !== null) {
- result = plugin.convert(input);
- output = result.content;
- status = result.status
- } else {
- output = "Internal error. Sorry.";
- status = "ERROR";
- }
- if (appendNewOutput) {
- if (output !== "") {
- $output = $(template.replace(/\{index\}/g, "" + outputIndex).replace(/\{content\}/g, output.replace(/\&/g, "&")));
- if (status === "ERROR") {
- $output.find("textarea").addClass("error");
- }
- $("body").append($output);
- }
- } else {
- $output.val(output);
- if (status === "ERROR") {
- $output.addClass("error");
- } else {
- $output.removeClass("error");
- }
- update($output);
- }
- }
-
- function update(textarea) {
- var $textarea = $(textarea);
- var areaid = $textarea.attr("id");
- var inputindex = +areaid.split("-")[1];
- var $select = $("#type-" + inputindex);
- var conversion = $select.find(":selected").attr("name");
- var plugin = getPluginById(conversion);
- if (plugin !== null) {
- convert($select);
- }
- }
-
- var den = {};
- den.convert = convert;
- den.update = update;
- window.den = window.den || den;
-
-})(jQuery);
diff --git a/deploy.sh b/deploy.sh
index ab6faf6..06374f3 100644
--- a/deploy.sh
+++ b/deploy.sh
@@ -1,5 +1,10 @@
#!/bin/sh
+function die() {
+ echo $*
+ exit 1
+}
+
declare destination
case "${TARGET}" in
"${WWW_DEPLOY_ROOT_DEVELOP}")
@@ -9,17 +14,45 @@ case "${TARGET}" in
destination="${TARGET}"
;;
*)
- echo "Invalid TARGET specified. Aborting deployment."
- exit 1
+ die "Invalid TARGET specified. Aborting deployment."
;;
esac
if [[ ! -d "${destination}" ]] ; then
- mkdir -p "${destination}" || echo "Failed to create target directory for deployment!"
+ mkdir -p "${destination}" || die "Failed to create target directory for deployment!"
fi
-rm -rf "${destination}/*"
-rm -rf "${destination}/.??*"
-cp -a dencode.css dencode.js index.html quoted-printable.js utf8.js "${destination}"
+rm -rf "${destination}"/* || die "Failed to clean destination directory (step 1)"
+rm -rf "${destination}"/.??* || die "Failed to clean destination directory (step 2)"
+
+cp -a index.html abeezee-regular.woff freemono.* package.json systemjs.config.js "${destination}" || die "Failed to copy resources to dest/"
+
+mkdir -p "${destination}/app/converter" || die "Failed to create dest/app/converter directory"
+cp -a app/*.css app/*.html app/*.js app/*.js.map "${destination}/app" || die "Failed to copy resources to dest/app"
+cp -a app/converter/*.js app/converter/*.js.map "${destination}/app/converter" || die "Failed to copy resources to dest/app/converter"
+
+mkdir -p "${destination}/node_modules/@angular" || die "Failed to create dest/node_modules/@angular"
+cp -a node_modules/@angular/* "${destination}/node_modules/@angular/" || die "Failed to copy @angular"
+
+mkdir -p "${destination}/node_modules/core-js/client" || die "Failed to create dest/node_modules/core-js"
+cp -a node_modules/core-js/client/shim.js "${destination}/node_modules/core-js/client/" || die "Failed to copy core-js"
+
+mkdir -p "${destination}/node_modules/zone.js/dist" || die "Failed to create dest/node_modules/zone.js"
+cp -a node_modules/zone.js/dist/zone.js "${destination}/node_modules/zone.js/dist/" || die "Failed to copy zone.js"
+
+mkdir -p "${destination}/node_modules/reflect-metadata" || die "Failed to create dest/node_modules/reflect-metadata"
+cp -a node_modules/reflect-metadata/Reflect.js "${destination}/node_modules/reflect-metadata/" || die "Failed to copy Reflect.js"
+
+mkdir -p "${destination}/node_modules/rxjs" || die "Failed to create dest/node_modules/rxjs"
+cp -a node_modules/rxjs/* "${destination}/node_modules/rxjs/" || die "Failed to copy rxjs"
+
+mkdir -p "${destination}/node_modules/systemjs/dist" || die "Failed to create dest/node_modules/systemjs"
+cp -a node_modules/systemjs/dist/system.src.js "${destination}/node_modules/systemjs/dist/" || die "Failed to copy system.src.js"
+
+mkdir -p "${destination}/node_modules/utf8" || die "Failed to create dest/node_modules/utf8"
+cp -a node_modules/utf8/utf8.js "${destination}/node_modules/utf8/" || die "Failed to copy utf8.js"
+
+mkdir -p "${destination}/node_modules/quoted-printable" || die "Failed to create dest/node_modules/quoted-printable"
+cp -a node_modules/quoted-printable/quoted-printable.js "${destination}/node_modules/quoted-printable/" || die "Failed to copy quoted-printable.js"
echo "Deployment successful."
diff --git a/freemono.eot b/freemono.eot
new file mode 100644
index 0000000..2646fe5
Binary files /dev/null and b/freemono.eot differ
diff --git a/freemono.svg b/freemono.svg
new file mode 100644
index 0000000..68fb46a
--- /dev/null
+++ b/freemono.svg
@@ -0,0 +1,635 @@
+
+
+
diff --git a/freemono.ttf b/freemono.ttf
new file mode 100644
index 0000000..3a661a3
Binary files /dev/null and b/freemono.ttf differ
diff --git a/freemono.woff b/freemono.woff
new file mode 100644
index 0000000..97fe047
Binary files /dev/null and b/freemono.woff differ
diff --git a/index.html b/index.html
index dadf298..0481aa4 100644
--- a/index.html
+++ b/index.html
@@ -1,19 +1,54 @@
-
-
- Decode? Encode? DENcode!
-
-
-
-
-
+
+
+ Decode? Encode? DENcode!
+
+
+
+
+
+
+
+
+
+
- Decode? Encode? DENcode!
-
+Decode? Encode? DENcode!
+
+
+ Please hold on, we're starting the turbines ...
+
-
\ No newline at end of file
+