diff --git a/.idea/dictionaries/Tom.xml b/.idea/dictionaries/Tom.xml index 05ad3b8..084fc1d 100644 --- a/.idea/dictionaries/Tom.xml +++ b/.idea/dictionaries/Tom.xml @@ -2,6 +2,8 @@ deparse + gameplay + pegjs \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 42a9cca..b43a6ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1916,6 +1916,11 @@ "integrity": "sha512-jRHfWsvyMtXdbhnz5CVHxaBgnV6duZnPlQuRSo/dm/GnmikNcmZhxIES4E9OZjUmQ8C+HCl4KJux+cXN/ErGDQ==", "dev": true }, + "@types/pegjs": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@types/pegjs/-/pegjs-0.10.1.tgz", + "integrity": "sha512-ra8IchO9odGQmYKbm+94K58UyKCEKdZh9y0vxhG4pIpOJOBlC1C+ZtBVr6jLs+/oJ4pl+1p/4t3JtBA8J10Vvw==" + }, "@types/q": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", @@ -8633,6 +8638,11 @@ "sha.js": "^2.4.8" } }, + "pegjs": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", + "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -10916,6 +10926,14 @@ "yn": "^2.0.0" } }, + "ts-pegjs": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/ts-pegjs/-/ts-pegjs-0.2.6.tgz", + "integrity": "sha512-mIX/dMQ6a1EHAEhvCLS6Z41+O700zlLiwB4V5ZSlKFLZKLDE93reik5IFw/HJsKgs488UiLx144yeEWWyu7YIw==", + "requires": { + "pegjs": "^0.10.0" + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", diff --git a/package.json b/package.json index 35f8385..a30b1a6 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,11 @@ "@angular/platform-browser-dynamic": "~8.2.11", "@angular/router": "~8.2.11", "@ng-bootstrap/ng-bootstrap": "^5.1.1", + "@types/pegjs": "^0.10.1", "ace-builds": "^1.4.7", "bootstrap": "^4.3.1", "rxjs": "~6.4.0", + "ts-pegjs": "^0.2.6", "tslib": "^1.10.0", "zone.js": "~0.9.1" }, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7c20a87..6a0d6ec 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -9,6 +9,7 @@ import { CodeEditorComponent } from './components/code-editor/code-editor.compon import { ConfigComponent } from './pages/config/config.component'; import { FormsModule } from "@angular/forms"; import { Server } from "./server"; +import { PegjsService } from "./services/pegjs.service"; @NgModule({ declarations: [ @@ -23,7 +24,7 @@ import { Server } from "./server"; NgbModule, FormsModule ], - providers: [Server], + providers: [Server, PegjsService], bootstrap: [AppComponent] }) export class AppModule { diff --git a/src/app/models/atlasData/blueprintGeneratedClass.ts b/src/app/models/atlasData/blueprintGeneratedClass.ts new file mode 100644 index 0000000..b910c00 --- /dev/null +++ b/src/app/models/atlasData/blueprintGeneratedClass.ts @@ -0,0 +1,14 @@ +import { ToJSON } from "../util/toJson"; + +export class BlueprintGeneratedClass implements ToJSON { + public texture: string; + + constructor(raw: object) { + if( raw[0] !== 'BlueprintGeneratedClass') Error('wrong type, expecting BlueprintGeneratedClass, got [' + raw[0] + ']!'); + this.texture = raw[1]; + }; + + public toJSON(): object { + return [ 'BlueprintGeneratedClass', this.texture ]; + } +} diff --git a/src/app/models/atlasData/questEntry.ts b/src/app/models/atlasData/questEntry.ts new file mode 100644 index 0000000..a02863e --- /dev/null +++ b/src/app/models/atlasData/questEntry.ts @@ -0,0 +1,46 @@ +import { Texture2D } from "./texture2D"; + +export class QuestEntry { + public QuestID: number; + public CompletedIcon: Texture2D; + public UncompletedIcon: Texture2D; + public QuestName: string; + public QuestDescription: string; + public UnlockFeatNames: Array; + public CompleteGiveEngramClasses: object; + public QuestPointsOfInterest: Array; + + constructor(raw?: Partial) { + Object.assign(this, raw); + this.CompletedIcon = new Texture2D(raw.CompletedIcon); + this.UncompletedIcon = new Texture2D(raw.UncompletedIcon); + } + + public toJSON() { + let output = {}; + + const JsonSubModels = [ + 'CompletedIcon', + 'UncompletedIcon' + ]; + + JsonSubModels.forEach(item => { + output[item] = this[item].toJSON(); + }); + + const RawSubData = [ + 'QuestID', + 'QuestName', + 'QuestDescription', + 'UnlockFeatNames', + 'CompleteGiveEngramClasses', + 'QuestPointsOfInterest' + ]; + + RawSubData.forEach(item => { + output[item] = this[item]; + }); + + return output; + } +} diff --git a/src/app/models/atlasData/texture2D.ts b/src/app/models/atlasData/texture2D.ts new file mode 100644 index 0000000..96470bd --- /dev/null +++ b/src/app/models/atlasData/texture2D.ts @@ -0,0 +1,14 @@ +import { ToJSON } from "../util/toJson"; + +export class Texture2D implements ToJSON { + public texture: string; + + constructor(raw: object) { + if( raw[0] !== 'Texture2D') Error('wrong type, expecting Texture2D, got [' + raw[0] + ']!'); + this.texture = raw[1]; + }; + + public toJSON(): object { + return [ 'Texture2D', this.texture ]; + } +} diff --git a/src/app/models/globalGameplaySetupModel.ts b/src/app/models/globalGameplaySetupModel.ts new file mode 100644 index 0000000..a72c314 --- /dev/null +++ b/src/app/models/globalGameplaySetupModel.ts @@ -0,0 +1,25 @@ +import { PegjsService } from "../services/pegjs.service"; +import { ToAtlas } from "./util/toAtlas"; +import { QuestEntry } from "./atlasData/questEntry"; + +export class GlobalGameplaySetupModel implements ToAtlas { + public QuestEntries: Array = []; + + constructor(raw: any = "()") { + const rawData = PegjsService.parse(raw); + Object.assign(this, rawData); + let tempQuestEntries = []; + this.QuestEntries.forEach(item => { + tempQuestEntries.push(new QuestEntry(item)); + }); + this.QuestEntries = tempQuestEntries; + } + + public toAtlas(): string { + const output = []; + this.QuestEntries.forEach(item => { + output.push(item.toJSON()); + }); + return PegjsService.format({QuestEntries: output}); + } +} diff --git a/src/app/models/serverGrid.model.ts b/src/app/models/serverGrid.model.ts index f1b6549..ef71d2a 100644 --- a/src/app/models/serverGrid.model.ts +++ b/src/app/models/serverGrid.model.ts @@ -1,8 +1,10 @@ import { TribeLogConfigModel } from "./tribeLogConfig.model"; import { SharedLogConfigModel } from "./sharedLogConfig.model"; import { TravelDataConfigModel } from "./travelDataConfig.model"; +import { ToJSON } from "./util/toJson"; +import { GlobalGameplaySetupModel } from "./GlobalGameplaySetupModel"; -export class ServerGridModel { +export class ServerGridModel implements ToJSON { // Server Argument Section public BaseServerArgs: string = ""; public AdditionalCmdLineParams: string = ""; @@ -51,21 +53,106 @@ export class ServerGridModel { public LocalS3Region: string = ""; // Unsorted... - public globalGameplaySetup: string = ""; public shipPathsIdGenerator: number = 1; public idGenerator: number = 127; public regionsIdGenerator: number = 0; // Log Configs - public TribeLogConfig: TribeLogConfigModel; - public SharedLogConfig: SharedLogConfigModel; - public TravelDataConfig: TravelDataConfigModel; + public TribeLogConfig: TribeLogConfigModel = new TribeLogConfigModel(); + public SharedLogConfig: SharedLogConfigModel = new SharedLogConfigModel(); + public TravelDataConfig: TravelDataConfigModel = new TravelDataConfigModel(); - constructor(raw?:Partial) { + // Large Objects of Doom + public globalGameplaySetup: GlobalGameplaySetupModel = new GlobalGameplaySetupModel(); + + constructor(raw?: Partial) { Object.assign(this, raw); this.SharedLogConfig = new SharedLogConfigModel(raw.SharedLogConfig); this.TribeLogConfig = new TribeLogConfigModel(raw.TribeLogConfig); this.TravelDataConfig = new TravelDataConfigModel(raw.TravelDataConfig); + this.globalGameplaySetup = new GlobalGameplaySetupModel(raw.globalGameplaySetup); console.log(this); } + + public toJSON() { + let output = {}; + + // All full models of this object for deflation + const JsonSubModels = [ + 'SharedLogConfig', + 'TribeLogConfig', + 'TravelDataConfig', + ]; + + JsonSubModels.forEach(item => { + output[item] = this[item].toJSON(); + }); + + const AtlasSubModels = [ + 'globalGameplaySetup' + ]; + + AtlasSubModels.forEach(item => { + output[item] = this[item].toAtlas(); + }); + + const RawSubData = [ + 'BaseServerArgs', + 'AdditionalCmdLineParams', + + // World Options + 'WorldFriendlyName', + 'WorldAtlasId', + 'WorldAtlasPassword', + 'ModIDs', + + // Grid Options + 'gridSize', + 'totalGridsX', + 'totalGridsY', + 'coordsScaling', + 'globalTransitionMinZ', + + // Image Paths + 'backgroundImgPath', + 'discoZonesImagePath', + + // URL Options + 'MetaWorldURL', + 'AuthListURL', + 'MapImageURL', + + // Time Options + 'Day0', + 'bUseUTCTime', + 'columnUTCOffset', + 'lastImageOverride', + + // Info Options + 'showServerInfo', + 'showDiscoZoneInfo', + 'showShipPathsInfo', + 'showIslandNames', + 'showLines', + 'showBackground', + + // S3 Options + 'LocalS3URL', + 'LocalS3AccessKeyId', + 'LocalS3SecretKey', + 'LocalS3BucketName', + 'LocalS3Region', + + // Unsorted... + 'shipPathsIdGenerator', + 'idGenerator', + 'regionsIdGenerator', + ]; + + RawSubData.forEach(item => { + output[item] = this[item]; + }); + + return output; + } } diff --git a/src/app/models/sharedLogConfig.model.ts b/src/app/models/sharedLogConfig.model.ts index c0ef5a4..f060d3c 100644 --- a/src/app/models/sharedLogConfig.model.ts +++ b/src/app/models/sharedLogConfig.model.ts @@ -1,6 +1,7 @@ import {BaseConfig} from "./abstract/baseConfig.model"; +import { ToJSON } from "./util/toJson"; -export class SharedLogConfigModel extends BaseConfig { +export class SharedLogConfigModel extends BaseConfig implements ToJSON { public FetchRateSec: number = 60; public SnapshotCleanupSec: number = 900; public SnapshotRateSec: number = 1800; @@ -10,4 +11,8 @@ export class SharedLogConfigModel extends BaseConfig { super(); Object.assign(this, raw); } + + public toJSON() { + return this; + } } diff --git a/src/app/models/travelDataConfig.model.ts b/src/app/models/travelDataConfig.model.ts index a96a4a8..4337f1f 100644 --- a/src/app/models/travelDataConfig.model.ts +++ b/src/app/models/travelDataConfig.model.ts @@ -1,9 +1,14 @@ import {BaseConfig} from "./abstract/baseConfig.model"; +import { ToJSON } from "./util/toJson"; -export class TravelDataConfigModel extends BaseConfig { +export class TravelDataConfigModel extends BaseConfig implements ToJSON { constructor(raw?:Partial) { super(); Object.assign(this, raw); } + + public toJSON() { + return this; + } } diff --git a/src/app/models/tribeLogConfig.model.ts b/src/app/models/tribeLogConfig.model.ts index 5f79838..d46f7a6 100644 --- a/src/app/models/tribeLogConfig.model.ts +++ b/src/app/models/tribeLogConfig.model.ts @@ -1,10 +1,15 @@ import {BaseConfig} from "./abstract/baseConfig.model"; +import { ToJSON } from "./util/toJson"; -export class TribeLogConfigModel extends BaseConfig { +export class TribeLogConfigModel extends BaseConfig implements ToJSON { public MaxRedisEntries: number = 1000; constructor(raw?:Partial) { super(); Object.assign(this, raw); } + + public toJSON() { + return this; + } } diff --git a/src/app/models/util/toAtlas.ts b/src/app/models/util/toAtlas.ts new file mode 100644 index 0000000..475c335 --- /dev/null +++ b/src/app/models/util/toAtlas.ts @@ -0,0 +1,3 @@ +export interface ToAtlas { + toString(): string; +} diff --git a/src/app/models/util/toJson.ts b/src/app/models/util/toJson.ts new file mode 100644 index 0000000..562e306 --- /dev/null +++ b/src/app/models/util/toJson.ts @@ -0,0 +1,3 @@ +export interface ToJSON { + toJSON(): object; +} diff --git a/src/app/pages/config/config.component.html b/src/app/pages/config/config.component.html index 5ee024a..16a4ec6 100644 --- a/src/app/pages/config/config.component.html +++ b/src/app/pages/config/config.component.html @@ -1 +1,2 @@

config works!

+ diff --git a/src/app/pages/config/config.component.ts b/src/app/pages/config/config.component.ts index ecb631a..ca31f91 100644 --- a/src/app/pages/config/config.component.ts +++ b/src/app/pages/config/config.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { Server } from "../../server"; @Component({ selector: 'app-config', @@ -7,7 +8,8 @@ import { Component, OnInit } from '@angular/core'; }) export class ConfigComponent implements OnInit { - constructor() { } + constructor(private server: Server) { + } ngOnInit() { } diff --git a/src/app/server.ts b/src/app/server.ts index af3baef..54d65f1 100644 --- a/src/app/server.ts +++ b/src/app/server.ts @@ -5,7 +5,7 @@ import { ServerGridModel } from "./models/serverGrid.model"; export class Server { private rawData: string = ""; private jsonData: object = {}; - serverGrid: ServerGridModel; + public serverGrid: ServerGridModel = new ServerGridModel({}); public load(raw) { this.rawData = raw; @@ -18,6 +18,7 @@ export class Server { } public save() { + this.jsonData = this.serverGrid.toJSON(); this.rawData = JSON.stringify(this.jsonData); return this.rawData; } diff --git a/src/app/services/atlas.pegjs.ts b/src/app/services/atlas.pegjs.ts new file mode 100644 index 0000000..3678f4d --- /dev/null +++ b/src/app/services/atlas.pegjs.ts @@ -0,0 +1,1624 @@ +// tslint:disable:only-arrow-functions +// tslint:disable:object-literal-shorthand +// tslint:disable:trailing-comma +// tslint:disable:object-literal-sort-keys +// tslint:disable:one-variable-per-declaration +// tslint:disable:max-line-length +// tslint:disable:no-consecutive-blank-lines +// tslint:disable:align + + +// Generated by PEG.js v. 0.10.0 (ts-pegjs plugin v. 0.2.6 ) +// +// https://pegjs.org/ https://github.com/metadevpro/ts-pegjs + +"use strict"; + +export interface IFilePosition { + offset: number; + line: number; + column: number; +} + +export interface IFileRange { + start: IFilePosition; + end: IFilePosition; +} + +export interface ILiteralExpectation { + type: "literal"; + text: string; + ignoreCase: boolean; +} + +export interface IClassParts extends Array {} + +export interface IClassExpectation { + type: "class"; + parts: IClassParts; + inverted: boolean; + ignoreCase: boolean; +} + +export interface IAnyExpectation { + type: "any"; +} + +export interface IEndExpectation { + type: "end"; +} + +export interface IOtherExpectation { + type: "other"; + description: string; +} + +export type Expectation = ILiteralExpectation | IClassExpectation | IAnyExpectation | IEndExpectation | IOtherExpectation; + +export class SyntaxError extends Error { + public static buildMessage(expected: Expectation[], found: string | null) { + function hex(ch: string): string { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s: string): string { + return s + .replace(/\\/g, "\\\\") + .replace(/"/g, "\\\"") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, (ch) => "\\x0" + hex(ch) ) + .replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => "\\x" + hex(ch) ); + } + + function classEscape(s: string): string { + return s + .replace(/\\/g, "\\\\") + .replace(/\]/g, "\\]") + .replace(/\^/g, "\\^") + .replace(/-/g, "\\-") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, (ch) => "\\x0" + hex(ch) ) + .replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => "\\x" + hex(ch) ); + } + + function describeExpectation(expectation: Expectation) { + switch (expectation.type) { + case "literal": + return "\"" + literalEscape(expectation.text) + "\""; + case "class": + const escapedParts = expectation.parts.map((part) => { + return Array.isArray(part) + ? classEscape(part[0] as string) + "-" + classEscape(part[1] as string) + : classEscape(part); + }); + + return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; + case "any": + return "any character"; + case "end": + return "end of input"; + case "other": + return expectation.description; + } + } + + function describeExpected(expected1: Expectation[]) { + const descriptions = expected1.map(describeExpectation); + let i: number; + let j: number; + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found1: string | null) { + return found1 ? "\"" + literalEscape(found1) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; + } + + public message: string; + public expected: Expectation[]; + public found: string | null; + public location: IFileRange; + public name: string; + + constructor(message: string, expected: Expectation[], found: string | null, location: IFileRange) { + super(); + this.message = message; + this.expected = expected; + this.found = found; + this.location = location; + this.name = "SyntaxError"; + + if (typeof (Error as any).captureStackTrace === "function") { + (Error as any).captureStackTrace(this, SyntaxError); + } + } +} + +function peg$parse(input: string, options?: IParseOptions) { + options = options !== undefined ? options : {}; + + const peg$FAILED: Readonly<{}> = {}; + + const peg$startRuleFunctions: {[id: string]: any} = { Atlas_text: peg$parseAtlas_text }; + let peg$startRuleFunction: () => any = peg$parseAtlas_text; + + const peg$c0 = function(value: any): any { return value; }; + const peg$c1 = "("; + const peg$c2 = peg$literalExpectation("(", false); + const peg$c3 = ")"; + const peg$c4 = peg$literalExpectation(")", false); + const peg$c5 = "="; + const peg$c6 = peg$literalExpectation("=", false); + const peg$c7 = ","; + const peg$c8 = peg$literalExpectation(",", false); + const peg$c9 = peg$otherExpectation("whitespace"); + const peg$c10 = /^[ \t\n\r]/; + const peg$c11 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false); + const peg$c12 = ""; + const peg$c13 = function(): any { return undefined; }; + const peg$c14 = "None"; + const peg$c15 = peg$literalExpectation("None", false); + const peg$c16 = function(): any { return null; }; + const peg$c17 = "False"; + const peg$c18 = peg$literalExpectation("False", false); + const peg$c19 = function(): any { return false; }; + const peg$c20 = "True"; + const peg$c21 = peg$literalExpectation("True", false); + const peg$c22 = function(): any { return true; }; + const peg$c23 = function(head: any, m: any): any { return m; }; + const peg$c24 = function(head: any, tail: any): any { + var result = {}; + + [head].concat(tail).forEach(function(element) { + result[element.name] = element.value; + }); + + return result; + }; + const peg$c25 = function(members: any): any { return members !== null ? members: {}; }; + const peg$c26 = function(name: any, value: any): any { + return { name: name, value: value }; + }; + const peg$c27 = function(head: any, v: any): any { return v; }; + const peg$c28 = function(head: any, tail: any): any { return [head].concat(tail); }; + const peg$c29 = function(values: any): any { return values !== null ? values : []; }; + const peg$c30 = peg$otherExpectation("number"); + const peg$c31 = function(): any { return parseFloat(text()); }; + const peg$c32 = "."; + const peg$c33 = peg$literalExpectation(".", false); + const peg$c34 = /^[1-9]/; + const peg$c35 = peg$classExpectation([["1", "9"]], false, false); + const peg$c36 = /^[eE]/; + const peg$c37 = peg$classExpectation(["e", "E"], false, false); + const peg$c38 = "-"; + const peg$c39 = peg$literalExpectation("-", false); + const peg$c40 = "+"; + const peg$c41 = peg$literalExpectation("+", false); + const peg$c42 = "0"; + const peg$c43 = peg$literalExpectation("0", false); + const peg$c44 = peg$otherExpectation("string key"); + const peg$c45 = function(sequence: any): any { return sequence.join(""); }; + const peg$c46 = peg$otherExpectation("string value"); + const peg$c47 = function(chars: any): any { return chars.join(""); }; + const peg$c48 = function(key: any, chars: any): any { return [ key, chars.join("") ]; }; + const peg$c49 = /^[a-zA-Z0-9]/; + const peg$c50 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false); + const peg$c51 = "_"; + const peg$c52 = peg$literalExpectation("_", false); + const peg$c53 = function(sequence: any): any { return sequence; }; + const peg$c54 = "/"; + const peg$c55 = peg$literalExpectation("/", false); + const peg$c56 = "\""; + const peg$c57 = peg$literalExpectation("\"", false); + const peg$c58 = "\\"; + const peg$c59 = peg$literalExpectation("\\", false); + const peg$c60 = "b"; + const peg$c61 = peg$literalExpectation("b", false); + const peg$c62 = function(): any { return "\b"; }; + const peg$c63 = "f"; + const peg$c64 = peg$literalExpectation("f", false); + const peg$c65 = function(): any { return "\f"; }; + const peg$c66 = "n"; + const peg$c67 = peg$literalExpectation("n", false); + const peg$c68 = function(): any { return "\n"; }; + const peg$c69 = "r"; + const peg$c70 = peg$literalExpectation("r", false); + const peg$c71 = function(): any { return "\r"; }; + const peg$c72 = "t"; + const peg$c73 = peg$literalExpectation("t", false); + const peg$c74 = function(): any { return "\t"; }; + const peg$c75 = "u"; + const peg$c76 = peg$literalExpectation("u", false); + const peg$c77 = function(digits: any): any { + return String.fromCharCode(parseInt(digits, 16)); + }; + const peg$c78 = "'"; + const peg$c79 = peg$literalExpectation("'", false); + const peg$c80 = /^[^\0-\x1F"\\]/; + const peg$c81 = peg$classExpectation([["\0", "\x1F"], "\"", "\\"], true, false); + const peg$c82 = /^[0-9]/; + const peg$c83 = peg$classExpectation([["0", "9"]], false, false); + const peg$c84 = /^[0-9a-f]/i; + const peg$c85 = peg$classExpectation([["0", "9"], ["a", "f"]], false, true); + + let peg$currPos = 0; + let peg$savedPos = 0; + const peg$posDetailsCache = [{ line: 1, column: 1 }]; + let peg$maxFailPos = 0; + let peg$maxFailExpected: Expectation[] = []; + let peg$silentFails = 0; + + let peg$result; + + if (options.startRule !== undefined) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text(): string { + return input.substring(peg$savedPos, peg$currPos); + } + + function location(): IFileRange { + return peg$computeLocation(peg$savedPos, peg$currPos); + } + + function expected(description: string, location1?: IFileRange) { + location1 = location1 !== undefined + ? location1 + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildStructuredError( + [peg$otherExpectation(description)], + input.substring(peg$savedPos, peg$currPos), + location1 + ); + } + + function error(message: string, location1?: IFileRange) { + location1 = location1 !== undefined + ? location1 + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildSimpleError(message, location1); + } + + function peg$literalExpectation(text1: string, ignoreCase: boolean): ILiteralExpectation { + return { type: "literal", text: text1, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts: IClassParts, inverted: boolean, ignoreCase: boolean): IClassExpectation { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation(): IAnyExpectation { + return { type: "any" }; + } + + function peg$endExpectation(): IEndExpectation { + return { type: "end" }; + } + + function peg$otherExpectation(description: string): IOtherExpectation { + return { type: "other", description: description }; + } + + function peg$computePosDetails(pos: number) { + let details = peg$posDetailsCache[pos]; + let p; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + + return details; + } + } + + function peg$computeLocation(startPos: number, endPos: number): IFileRange { + const startPosDetails = peg$computePosDetails(startPos); + const endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + } + + function peg$fail(expected1: Expectation) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected1); + } + + function peg$buildSimpleError(message: string, location1: IFileRange) { + return new SyntaxError(message, [], "", location1); + } + + function peg$buildStructuredError(expected1: Expectation[], found: string | null, location1: IFileRange) { + return new SyntaxError( + SyntaxError.buildMessage(expected1, found), + expected1, + found, + location1 + ); + } + + function peg$parseAtlas_text(): any { + let s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsews(); + if (s1 !== peg$FAILED) { + s2 = peg$parsevalue(); + if (s2 !== peg$FAILED) { + s3 = peg$parsews(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c0(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsebegin_object(): any { + let s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsews(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 40) { + s2 = peg$c1; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parsews(); + if (s3 !== peg$FAILED) { + s1 = [s1, s2, s3]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseend_object(): any { + let s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsews(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s2 = peg$c3; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c4); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parsews(); + if (s3 !== peg$FAILED) { + s1 = [s1, s2, s3]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsename_separator(): any { + let s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsews(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s2 = peg$c5; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parsews(); + if (s3 !== peg$FAILED) { + s1 = [s1, s2, s3]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsevalue_separator(): any { + let s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsews(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s2 = peg$c7; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parsews(); + if (s3 !== peg$FAILED) { + s1 = [s1, s2, s3]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsews(): any { + let s0, s1; + + peg$silentFails++; + s0 = []; + if (peg$c10.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c11); } + } + while (s1 !== peg$FAILED) { + s0.push(s1); + if (peg$c10.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c11); } + } + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c9); } + } + + return s0; + } + + function peg$parsevalue(): any { + let s0; + + s0 = peg$parsefalse(); + if (s0 === peg$FAILED) { + s0 = peg$parsenull(); + if (s0 === peg$FAILED) { + s0 = peg$parsetrue(); + if (s0 === peg$FAILED) { + s0 = peg$parseobject(); + if (s0 === peg$FAILED) { + s0 = peg$parsearray(); + if (s0 === peg$FAILED) { + s0 = peg$parsenumber(); + if (s0 === peg$FAILED) { + s0 = peg$parsestringval(); + if (s0 === peg$FAILED) { + s0 = peg$parseclass(); + if (s0 === peg$FAILED) { + s0 = peg$parseempty(); + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parseempty(): any { + let s0, s1; + + s0 = peg$currPos; + s1 = peg$c12; + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c13(); + } + s0 = s1; + + return s0; + } + + function peg$parsenull(): any { + let s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c14) { + s1 = peg$c14; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c15); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c16(); + } + s0 = s1; + + return s0; + } + + function peg$parsefalse(): any { + let s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 5) === peg$c17) { + s1 = peg$c17; + peg$currPos += 5; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c19(); + } + s0 = s1; + + return s0; + } + + function peg$parsetrue(): any { + let s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c20) { + s1 = peg$c20; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c21); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c22(); + } + s0 = s1; + + return s0; + } + + function peg$parseobject(): any { + let s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsebegin_object(); + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = peg$parsemember(); + if (s3 !== peg$FAILED) { + s4 = []; + s5 = peg$currPos; + s6 = peg$parsevalue_separator(); + if (s6 !== peg$FAILED) { + s7 = peg$parsemember(); + if (s7 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c23(s3, s7); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$currPos; + s6 = peg$parsevalue_separator(); + if (s6 !== peg$FAILED) { + s7 = peg$parsemember(); + if (s7 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c23(s3, s7); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } + if (s4 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c24(s3, s4); + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s3 = peg$parseend_object(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c25(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsemember(): any { + let s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsestringkey(); + if (s1 !== peg$FAILED) { + s2 = peg$parsename_separator(); + if (s2 !== peg$FAILED) { + s3 = peg$parsevalue(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c26(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsearray(): any { + let s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsebegin_object(); + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = peg$parsevalue(); + if (s3 !== peg$FAILED) { + s4 = []; + s5 = peg$currPos; + s6 = peg$parsevalue_separator(); + if (s6 !== peg$FAILED) { + s7 = peg$parsevalue(); + if (s7 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c27(s3, s7); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$currPos; + s6 = peg$parsevalue_separator(); + if (s6 !== peg$FAILED) { + s7 = peg$parsevalue(); + if (s7 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c27(s3, s7); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } + if (s4 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c28(s3, s4); + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s3 = peg$parseend_object(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c29(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsenumber(): any { + let s0, s1, s2, s3, s4; + + peg$silentFails++; + s0 = peg$currPos; + s1 = peg$parseminus(); + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseint(); + if (s2 !== peg$FAILED) { + s3 = peg$parsefrac(); + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = peg$parseexp(); + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c31(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c30); } + } + + return s0; + } + + function peg$parsedecimal_point(): any { + let s0; + + if (input.charCodeAt(peg$currPos) === 46) { + s0 = peg$c32; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c33); } + } + + return s0; + } + + function peg$parsedigit1_9(): any { + let s0; + + if (peg$c34.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c35); } + } + + return s0; + } + + function peg$parsee(): any { + let s0; + + if (peg$c36.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c37); } + } + + return s0; + } + + function peg$parseexp(): any { + let s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = peg$parsee(); + if (s1 !== peg$FAILED) { + s2 = peg$parseminus(); + if (s2 === peg$FAILED) { + s2 = peg$parseplus(); + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$parseDIGIT(); + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$parseDIGIT(); + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s1 = [s1, s2, s3]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefrac(): any { + let s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsedecimal_point(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parseDIGIT(); + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parseDIGIT(); + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseint(): any { + let s0, s1, s2, s3; + + s0 = peg$parsezero(); + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsedigit1_9(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parseDIGIT(); + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parseDIGIT(); + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + return s0; + } + + function peg$parseminus(): any { + let s0; + + if (input.charCodeAt(peg$currPos) === 45) { + s0 = peg$c38; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c39); } + } + + return s0; + } + + function peg$parseplus(): any { + let s0; + + if (input.charCodeAt(peg$currPos) === 43) { + s0 = peg$c40; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c41); } + } + + return s0; + } + + function peg$parsezero(): any { + let s0; + + if (input.charCodeAt(peg$currPos) === 48) { + s0 = peg$c42; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c43); } + } + + return s0; + } + + function peg$parsestringkey(): any { + let s0, s1, s2; + + peg$silentFails++; + s0 = peg$currPos; + s1 = []; + s2 = peg$parsekeychar(); + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$parsekeychar(); + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c45(s1); + } + s0 = s1; + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c44); } + } + + return s0; + } + + function peg$parsestringval(): any { + let s0, s1, s2, s3; + + peg$silentFails++; + s0 = peg$currPos; + s1 = peg$parsequotation_mark(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parsechar(); + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parsechar(); + } + if (s2 !== peg$FAILED) { + s3 = peg$parsequotation_mark(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c47(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c46); } + } + + return s0; + } + + function peg$parseclass(): any { + let s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = peg$parsestringkey(); + if (s1 !== peg$FAILED) { + s2 = peg$parsesinglequote_mark(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$parsepathchar(); + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$parsepathchar(); + } + if (s3 !== peg$FAILED) { + s4 = peg$parsesinglequote_mark(); + if (s4 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c48(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsekeychar(): any { + let s0, s1; + + s0 = peg$currPos; + if (peg$c49.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c50); } + } + if (s1 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 95) { + s1 = peg$c51; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c52); } + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c53(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsepathchar(): any { + let s0, s1; + + s0 = peg$currPos; + if (peg$c49.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c50); } + } + if (s1 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 95) { + s1 = peg$c51; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c52); } + } + if (s1 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s1 = peg$c32; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c33); } + } + if (s1 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 47) { + s1 = peg$c54; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c55); } + } + } + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c53(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsechar(): any { + let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$parseunescaped(); + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseescape(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s2 = peg$c56; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c57); } + } + if (s2 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 92) { + s2 = peg$c58; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c59); } + } + if (s2 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 47) { + s2 = peg$c54; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c55); } + } + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 98) { + s3 = peg$c60; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c61); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c62(); + } + s2 = s3; + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 102) { + s3 = peg$c63; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c64); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c65(); + } + s2 = s3; + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 110) { + s3 = peg$c66; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c67); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c68(); + } + s2 = s3; + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 114) { + s3 = peg$c69; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c70); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c71(); + } + s2 = s3; + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 116) { + s3 = peg$c72; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c73); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c74(); + } + s2 = s3; + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 117) { + s3 = peg$c75; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c76); } + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + s5 = peg$currPos; + s6 = peg$parseHEXDIG(); + if (s6 !== peg$FAILED) { + s7 = peg$parseHEXDIG(); + if (s7 !== peg$FAILED) { + s8 = peg$parseHEXDIG(); + if (s8 !== peg$FAILED) { + s9 = peg$parseHEXDIG(); + if (s9 !== peg$FAILED) { + s6 = [s6, s7, s8, s9]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + if (s5 !== peg$FAILED) { + s4 = input.substring(s4, peg$currPos); + } else { + s4 = s5; + } + if (s4 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c77(s4); + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + } + } + } + } + } + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c53(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + return s0; + } + + function peg$parseescape(): any { + let s0; + + if (input.charCodeAt(peg$currPos) === 92) { + s0 = peg$c58; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c59); } + } + + return s0; + } + + function peg$parsequotation_mark(): any { + let s0; + + if (input.charCodeAt(peg$currPos) === 34) { + s0 = peg$c56; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c57); } + } + + return s0; + } + + function peg$parsesinglequote_mark(): any { + let s0; + + if (input.charCodeAt(peg$currPos) === 39) { + s0 = peg$c78; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c79); } + } + + return s0; + } + + function peg$parseunescaped(): any { + let s0; + + if (peg$c80.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c81); } + } + + return s0; + } + + function peg$parseDIGIT(): any { + let s0; + + if (peg$c82.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + + return s0; + } + + function peg$parseHEXDIG(): any { + let s0; + + if (peg$c84.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c85); } + } + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +export interface IParseOptions { + filename?: string; + startRule?: string; + tracer?: any; + [key: string]: any; +} +export type ParseFunction = (input: string, options?: IParseOptions) => any; +export const parse: ParseFunction = peg$parse; + diff --git a/src/app/services/pegjs.service.ts b/src/app/services/pegjs.service.ts new file mode 100644 index 0000000..b32c93b --- /dev/null +++ b/src/app/services/pegjs.service.ts @@ -0,0 +1,133 @@ +import { Injectable } from '@angular/core'; +import { parse } from './atlas.pegjs'; + +const beginObject = '('; +const endObject = ')'; +const nameSeparator = '='; +const valueSeparator = ','; + +@Injectable({ + providedIn: 'root' +}) +export class PegjsService { + + constructor() {} + + public static parse(input: string): object { + let output = {}; + try { + output = parse(input); + } catch (e) { + // TODO put a popover somewhere with a location of the error + console.log(e); + console.log(e.location); + } + return output; + } + + public static format(input: object): string { + return PegjsService.deparseJson(input) + } + + private static deparseJson(input, key?) { + switch (typeof input) { + case "object": + return PegjsService.deparseObject(input); + case "number": + return PegjsService.deparseNumber(input, key); + case "string": + return PegjsService.deparseString(input); + case "undefined": + return ""; + case "boolean": + return PegjsService.deparseBoolean(input); + default: + console.log("Unknown type for input", input); + return ""; + } + } + + private static deparseObject(input) { + if (Array.isArray(input)) { + return this.deparseArray(input); + } + if (input === null) { + return "None"; + } + + let output = ''; + output += beginObject; + + Object.keys(input).forEach(function (key, idx, array) { + output += key; + output += nameSeparator; + output += PegjsService.deparseJson(input[key], key); + + if (idx !== array.length - 1) { + // Not the last item + output += valueSeparator + } + }); + output += endObject; + + return output; + } + + private static deparseArray(input) { + // We have one funky array option, where its 2 values and one of them is a recognised class. + // These are here for easier maintenance, as adding any new ones should just work. These all + // Work off string equality, see found below. + const specialCases = [ + 'BlueprintGeneratedClass', + 'Blueprint', + 'SoundWave', + 'Texture2D' + ]; + + const found = specialCases.indexOf(input[0]); + if (found > -1) { + // We found one of our special cases! + const val = specialCases[found]; + return val + "'" + input[1] + "'"; + } + + let output = ''; + output += beginObject; + + input.forEach(function (data, idx, array) { + output += PegjsService.deparseJson(data); + + if (idx !== array.length - 1) { + output += valueSeparator; + } + }); + output += endObject; + + return output; + } + + private static deparseNumber(input, key) { + // Any number which has a decimal is stored to 6 decimal places + // Except for IDs. Unless they actually have such a number... erm... + if (key.substr(key.length - 2, 2) === "ID") { + if (input % 1 === 0) { + return Number(input).toString(); + } + // Else drop out and return as normal + } + return Number(input).toFixed(6); + } + + private static deparseString(input) { + // We need to re-encode the strings properly + return JSON.stringify(input); + } + + private static deparseBoolean(input) { + if ( input ) { + return 'True'; + } else { + return 'False'; + } + } +}