{
    "data": {
        "classname": "JSONEditor4Menu",
        "superclassname": " ",
        "comment": "JSON Editor for creating HTML5 menus with CSS and HTML Templates for Hamburger Menus - based on JSON Editor of Jeremy Dorn",
        "reposinfo": {
            "JSCC_type": "CLASS",
            "JSCC_version": "2",
            "UML_editor": "https://niebert.github.io/ClassEditorUML",
            "repository": "git+https://gitlab.com/niehausbert/jsoneditor4menu.git",
            "static": "no",
            "debugheader": "no",
            "require_classes": "yes",
            "author": "Engelbert Niehaus",
            "email": "user on GitLab",
            "created": "2020/09/28 17:35:39",
            "modified": "2020/09/28 17:35:39",
            "configcode": "// the configuration code will be used to create some constants",
            "requirelist": []
        },
        "attributes": [
            {
                "visibility": "public",
                "name": "aLinkParam",
                "init": "{}",
                "class": "object",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "aDoc",
                "init": "null",
                "class": "null",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "aJSON",
                "init": "{}",
                "class": "object",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "aZIP",
                "init": "{}",
                "class": "object",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "aDefaultJSON",
                "init": "{}",
                "class": "object",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "aSchema",
                "init": "null",
                "class": "null",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "aOptions",
                "init": "{\n    \"editor_id\": \"editor_holder\",\n    \"validator_id\": \"valid_indicator\",\n    \"load_file_id\": \"load_filename\",\n    \"filename_id\": \"display_filename\",\n    \"filename_key\": \"filepath\",\n    \"out_json\": \"tOutJSON\",\n    \"out_code\": \"tOutput\",\n    \"out_errors\": \"tErrors\",\n    \"theme\": \"bootstrap3\",\n    \"iconlib\": \"fontawesome4\",\n    \"plugins\": {\n        \"ace\": {\n            \"theme\": \"xcode\"\n        }\n    }\n}",
                "class": "object",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "aSettingsBOOL",
                "init": "false",
                "class": "boolean",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "aEditor",
                "init": "null",
                "class": "null",
                "comment": "the attribute stores ..."
            },
            {
                "visibility": "public",
                "name": "compileCode",
                "init": "{}",
                "class": "object",
                "comment": "the attribute stores ..."
            }
        ],
        "methods": [
            {
                "visibility": "public",
                "name": "initDoc",
                "parameter": [
                    {
                        "name": "pDoc",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    this.aDoc = pDoc;\n    //this.aDoc.JSONEditor = JSONEditor;\n  "
            },
            {
                "visibility": "public",
                "name": "initJSON",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vName = vFileBase;\n    console.log(\"Init with aDefaultJSON in JSON Editor stored in 'docs/db/menu_default.js'\");\n    this.aEditor.setValue(this.aDefaultJSON);\n  "
            },
            {
                "visibility": "public",
                "name": "initZIP",
                "parameter": [
                    {
                        "name": "pZIP",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // the aZIP will be populated with the generated HTML, CSS and Javascript files\n    console.log(\"Init Output ZIP in JSON Editor\");\n    this.aZIP = pZIP;\n  "
            },
            {
                "visibility": "public",
                "name": "getLS4JSON",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      console.log(\"CALL: initLS4JSON() init JSON from Local Storage\");\n      var vName = vFileBase || \"JSON4LS\";\n      var vJSON_LS = null;\n      var vLS_ID = this.url2id();\n      if (typeof(localStorage.getItem(vLS_ID)) !== undefined) {\n          console.log(\"CALL: initLS4JSON() - try init JSON Editor from Local Storage \");\n          var vJSONstring = localStorage.getItem(vLS_ID);\n          if (!vJSONstring) {\n            console.log(\"CALL: initLS4JSON() - JSON-DB '\"+vName+\"' undefined in Local Storage.\\nSave default as JSON\");\n          } else {\n            console.log(\"CALL: initLS4JSON() - parse DB '\"+vName+\"') from LocalStorage JSONstring='\"+vJSONstring.substr(0,120)+\"...'\");\n            try {\n                vJSON_LS = JSON.parse(vJSONstring);\n                if (vJSON_LS) {\n                  console.log(\"CALL: initLS4JSON() - Successful update of JSON Editor from Localstorage ID='\" + vLS_ID + \"'\");\n                } else {\n                  console.error(\"CALL: initLS4JSON() - parsed JSON in initJSON4LS() undefined 'vJSON_JS' from LocalStorage\");\n                }\n            } catch(e) {\n                alert(\"ERROR CALL initLS4JSON():\" + e);\n            }\n          }\n        }\n        return vJSON_LS;\n  "
            },
            {
                "visibility": "public",
                "name": "init",
                "parameter": [
                    {
                        "name": "pInitJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pDefaultJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pSchema",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pTemplates",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      // LOAD PRIORITY\n      // (1) jsondata in Link Parameter\n      // (2) vJSON is loaded from LocalStorage\n      // (3) pInitJSON if init/demo data provide by constructor\n      // (4) pDefaultJSON as initialized with default data on delete\n      this.aLinkParam.init(this.aDoc);\n      var vJSON = pDefaultJSON;\n      var vJSON4LinkParam = this.loadLinkParam(\"jsondata\");\n      var vJSON4LS = this.getLS4JSON();\n      if (vJSON4LinkParam) {\n        // (1) highest priority: jsondata in Link Parameter\n        console.log(\"CALL: JSONEditor4Menu.init() - init with LinkParam JSON data\");\n        vJSON = vJSON4LinkParam;\n      } else if (vJSON4LS) {\n        // (2) medium priority: jsondata loaded from LocalStorage if saved\n        console.log(\"CALL: JSONEditor4Menu.init() - init JSON Editor with LocalStorga JSON data\");\n        vJSON = vJSON4LS;\n      } else if (pInitJSON) {\n        // (3) pInitJSON if init/demo data provide by constructor init call\n        console.log(\"CALL: JSONEditor4Menu.init() - use init data in pJSON for JSON editor\");\n        vJSON = pInitJSON;\n      } else {\n        // (3) pJSON as initialized with default data\n        console.log(\"CALL: JSONEditor4Menu.init() - use default data in pDefaultJSON - also used by init_ask() method.\");\n        if (pDefaultJSON) {\n          vJSON = pDefaultJSON;\n          console.log(\"pDefaultJSON defined in JSONEditor4Menu.init()\");\n        } else {}\n          console.error(\"WARNING: pDefaultJSON undefined - use an empty JSON\");\n          vJSON = {\n            data: {},\n            settings: {}\n          };\n      }\n      this.aJSON = vJSON;\n      console.log(\"HTML-INIT init_definitions(pJSON,pSchema)): \"+JSON.stringify(vJSON,null,4));\n      this.aDefaultJSON = pDefaultJSON;\n      // extend/overwrite options\n      this.aOptions = pOptions;\n      this.aTemplates = pTemplates;\n      this.aSchema = pSchema;\n\n      console.log(\"HTML-INIT (1) JSONEditor4Menu.init(...)): vJSON.settings=\"+JSON.stringify(vJSON.settings,null,4));\n      //PARMETER SCOPEERROR: do not provide attributes with parameter of methods - use aSchema and aJSON instead\n      //DO NOT USE: this.aSchema = this.init_definitions(vJSON,pSchema);\n      this.init_definitions();\n      // Extend aOptions with settings in pOption\n      for (var iKey in pOptions) {\n        if (pOptions.hasOwnProperty(iKey)) {\n          this.aOptions[iKey] = pOptions[iKey];\n        }\n      }\n      // COMPILE the templates with Handlebars\n      //this.aSchema = vSchema;\n      this.create_compiler4tpl();\n      this.create_editor();\n      this.aDoc.JSONEditor = JSONEditor; //assign to document.JSONEditor\n      this.update_filename();\n    "
            },
            {
                "visibility": "public",
                "name": "loadLinkParam",
                "parameter": [
                    {
                        "name": "pLSID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vDataID = pLSID || \"jsondata\";\n    var vJSON = null;\n    var vJSONstring = \"\";\n    console.log(\"loadLinkParam('\"+vDataID+\"')\");\n    //console.log(\"Start JSON:\\n\"+JSON.stringify(vJSON,null,3));\n    //-------------------------------------------------------\n    // LOCAL STORAGE: Check JSON Data is available in LocalStorage\n    //console.log(\"loadParamStorage(pInitJSON,'\"+vLSID+\"' - JSON:\\n\"+(JSON.stringify(vJSON,null,3)).substr(0,120)+\"...\");\n    //-------------------------------------------------------\n    // LINK PARAMETER: Evaluation link parameter in JSON Path\n    if (this.aLinkParam.exists(vDataID)) {\n       console.log(\"LinkParameter provides '\"+vDataID+\"'  with value\");\n       vJSONstring = this.aLinkParam.getValue(vDataID);\n       try {\n         vJSON = JSON.parse(vJSONstring);\n       } catch (e) {\n         console.log(\"ERROR (JSON in LinkParam['\"+vDataID+\"']: \"+e);\n         vJSON = null;\n       }\n       if (vJSON) {\n         console.log(\"LinkParam['\"+vDataID+\"']: JSON set to this.aJSON:\\n\"+JSON.stringify(vJSON.settings,null,4));\n       }\n     } else {\n       console.log(\"LinkParam['\"+vDataID+\"'] does not contain data.\");\n    }\n    return vJSON;\n  "
            },
            {
                "visibility": "public",
                "name": "submit2callback",
                "parameter": [
                    {
                        "name": "pLink",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vJSONstring = JSON.stringify(this.getValue());\n    var vLink = \"receiver.html\"; // is a default HTML as callback\n    // to check the LinkParam communication between HTML documents\n    if (pLink) {\n      vLink = pLink;\n    } else {\n      if (this.aLinkParam.exists(\"callback\")) {\n        vLink = this.aLinkParam.getValue(\"callback\");\n        console.log(\"Callback defined in LinkParam:\\n  \"+vLink);\n      }\n    }\n    this.aLinkParam.setValue(\"jsondata\",vJSONstring);\n    this.aLinkParam.deleteValue(\"callback\");\n    // send current JSON data back to callback URL\n    document.location.href = vLink + this.aLinkParam.getParam4URL();\n  "
            },
            {
                "visibility": "public",
                "name": "el",
                "parameter": [
                    {
                        "name": "pID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    return this.aDoc.getElementById(pID);\n  "
            },
            {
                "visibility": "public",
                "name": "getEditor",
                "parameter": [
                    {
                        "name": "pEditorID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      var vEditor = null;\n      if (this.aEditor) {\n        e = this.aEditor.getEditor(pEditorID);\n        if (e) {\n          vEditor = e;\n        } else {\n          console.log(\"ERROR: JSONEditor4Menu.getEditor('\"+pEditor+\"') - Editor not found!\");\n        }\n      }\n      // return the editor with the ID pEditorID\n      return vEditor;\n  "
            },
            {
                "visibility": "public",
                "name": "append_classlist",
                "parameter": [
                    {
                        "name": "pList",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pAppendList",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      if (isArray(pList)) {\n        if (isArray(pAppendList)) {\n          if (pAppendList) {\n            for (var i = 0; i < pAppendList.length; i++) {\n              if (isHash(pAppendList[i])) {\n                if (pAppendList[i].hasOwnProperty('name')) {\n                  pList.push(pAppendList[i].name);\n                } else {\n                  console.log(\"ERROR: pAppendList[i].name has no 'name' property!\");\n                }\n              } else {\n                pList.push(pAppendList[i]);\n                console.log(\"WARNING: pAppendList[i] is not a hash with attribute 'name'!\");\n              }\n            }\n          } else {\n          console.log(\"ERROR: append_classlist() - pAppendList is not an array!\");\n          }\n        } else {\n          console.log(\"ERROR: append_classlist() - pList is not an array!\");\n        }\n      }\n    "
            },
            {
                "visibility": "public",
                "name": "init_definitions",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      var vJSON = this.aJSON;\n      if (this.aEditor) {\n        vJSON = cloneJSON(this.aEditor.getValue());\n      } else {\n        console.log(\"JSONEditor undefined\");\n      };\n      console.log(\"Call: init_definitions() Update Filename in Schema - update filename\");\n        this.update_filename(); // update the filename in the DOM node with id \"load_filename\"\n        console.log(\"HTML-INIT init_definitions(pJSON,pSchema)): vJSON.settings=\"+JSON.stringify(vJSON.settings,null,4));\n        if (!vJSON) {\n          console.log(\"WARNING: src/exportmod.js - init_definitions() - vJSON undefined!\");\n          alert(\"WARNING: src/exportmod.js - init_definitions() - vJSON undefined!\");\n        } else if (!(vJSON.settings)) {\n          console.log(\"WARNING: src/exportmod.js - init_definitions() - vJSON.settings undefined!\");\n          alert(\"WARNING: src/exportmod.js - init_definitions() - vJSON.settings undefined!\");\n        } else {\n            // use always one blank for \"no class\" otherwise value is regarded as undefined.\n            var watchclasses = [\" \"]; //\n            var i = 0;\n            console.log(\"Call: init_definitions() \");\n            // BASIC CLASSES: push all basic classes\n            var cl = vJSON.settings.baseclasslist;\n            console.log(\"Call: init_definitions() - BaseClassList: \"+JSON.stringify(cl,null,4));\n            this.append_classlist(watchclasses,cl);\n            // LOCAL CLASSES: push all local classes\n            cl = vJSON.settings.localclasslist;\n            console.log(\"Call: init_definitions() - LocalClassList: \"+JSON.stringify(cl,null,4));\n            this.append_classlist(watchclasses,cl);\n            // REMOTE CLASSES: push all remote classes\n            console.log(\"Call: init_definitions() - RemoteClassList: \"+JSON.stringify(cl,null,4));\n            cl = vJSON.settings.remoteclasslist;\n            this.append_classlist(watchclasses,cl);\n            watchclasses.sort();\n            console.log(\"Call: init_definitions() - watchclasses=('\"+watchclasses.join(\"','\")+\"')\");\n            this.aSchema.definitions.selectorclass.enum = watchclasses;\n        }\n        //PARAM SCOPE WARNING: do not return an attribute of \"this\" instance - operated on this.aSchema instead;\n        //DO NOT: return pSchema\n  "
            },
            {
                "visibility": "public",
                "name": "create_compiler4tpl",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vTemplate = \" \";\n    for (var tplID in this.aTemplates) {\n      if (this.aTemplates.hasOwnProperty(tplID)) {\n        console.log(\"Compile Template [\"+tplID+\"]\");\n        vTemplate = this.aTemplates[tplID];\n        //vTemplate = preProcessHandlebars(vTemplate,this.aJSON);\n        this.compileCode[tplID] = Handlebars.compile(vTemplate);\n      }\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "create_editor",
                "parameter": [
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    if (pJSON) {\n      this.aJSON = pJSON;\n    }\n    // If an old editor exists - destroy the Editor to free resources\n    if (this.aEditor) {\n        /*\n        this.aJSON = this.aEditor.getValue();\n        this.saveLS(\"jsondata\");\n        */\n        // this.update_watchclasslist();\n        // free some resources if the editor already exists\n        this.aEditor.destroy();\n        console.log(\"Destroy JSONEditor in JSONEditor4Menu\");\n    } else {\n      console.log(\"REMARK: instance of JSON Editor does not exist!\");\n    }\n\n    console.log(\"CALL: create_editor() - create a new JSONEditor() in JSONEditor4Menu\");\n    // update schema\n    console.log(\"Start Editor with JSON:\\n\"+JSON.stringify(this.aJSON,null,3));\n    var vEditorNode = this.el(this.aOptions.editor_id);\n    if (vEditorNode) {\n      //vEditorNode.innerHTML = \" \";\n      console.log(\"CALL: Editor Node cleaned innerHTML\");\n    } else {\n      console.log(\"CALL: Editor Node does not exist!\");\n    }\n    this.aEditor = new JSONEditor(vEditorNode,{\n            // Enable fetching schemas via ajax\n            ajax: true,\n\n            // The schema for the editor\n            schema: this.aSchema,\n\n            // Seed the form with a starting value\n            startval: this.aJSON,\n\n            // theme of JSON editor\n            theme: this.aOptions.theme || \"bootstrap3\",\n            // iconlib\n            iconlib: this.aOptions.iconlib || \"fontawesome4\",\n            // theme of ACE code editor\n            plugins: this.aOptions.plugins || {\n                ace: {\n                  theme: 'xcode'\n                }\n            },\n            // Disable additional properties\n            no_additional_properties: true,\n\n            // Require all properties by default\n            required_by_default: true\n          });\n    this.parent_editor = this;\n    this.init_buttons();\n    this.init_watch();\n    this.update_filename();\n    this.update_modified();\n    this.saveLS(\"jsondata\");\n    this.aDoc.JSONEditor = JSONEditor; //assign to document.JSONEditor\n\n  "
            },
            {
                "visibility": "public",
                "name": "init_ask",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vOK = confirm(\"DELETE: Do you really want to initialize the JSON data for '\" + this.getAppName() + \"'?\");\n    if (vOK == true) {\n    \t\tvar vSaveOK = confirm(\"SAVE: Do you want to SAVE the current JSON data of '\" + this.getAppName() + \"' first?\");\n    \t\tif (vSaveOK == true) {\n    \t\t\tthis.saveJSON();\n    \t\t\tconsole.log(\"JSON-DB initalized with data for '\"+this.getAppName()+\"'!\");\n    \t\t} else {\n    \t\t\tconsole.log(\"JSON-DB for  '\"+this.getAppName()+\"' not saved - data deleted!\");\n        }\n        var vInitOK = confirm(\"DEMO-DATA: Do you want to initalize with a DEMO of '\"+getAppName(this.aInitJSON)+\"' first?\");\n    \t\tif (vInitOK == true) {\n    \t\t\tthis.aEditor.setValue(this.aInitJSON);\n    \t\t\tconsole.log(\"JSON-DB initalized with Demo JSON '\"+this.getAppName(this.aInitJSON)+\"'!\");\n    \t\t} else {\n          this.aEditor.setValue(this.aDefaultJSON); // defined e.g. in /db/uml_default.js\n      \t\tconsole.log(\"JSON-DB for '\"+this.getAppName(this.aDefaultJSON)+\"' initialized with default values - data deleted!\");\n        }\n        this.saveLS(\"jsondata\");\n        this.update_filename();\n        this.update_modified();\n    } else {\n        console.log(\"initialize JSON-DB cancelled\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "delete_ask",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vOK = confirm(\"DELETE: Do you want to delete all data?\");\n    if (vOK == true) {\n        var vSaveOK = confirm(\"SAVE: Do you want to save the current data for '\"+this.getAppName()+\"' first?\");\n        if (vSaveOK == true) {\n          this.saveJSON();\n          console.log(\"JSON-DB initalized with data for '\"+this.getAppName()+\"'!\");\n        } else {\n          console.log(\"JSON-DB for app '\"+this.getAppName()+\"' not saved - data deleted!\");\n        }\n        var vInitOK = confirm(\"DEMO-DATA: Do you want to initalize with a DEMO of '\"+getAppName(this.aInitJSON)+\"' first?\");\n        if (vInitOK == true) {\n          this.aEditor.setValue(this.aInitJSON);\n          console.log(\"JSON-DB initalized with Demo JSON '\"+this.getAppName(this.aInitJSON)+\"'!\");\n        } else {\n          var vEmptyJSON = {\n              \"data\":{\n                \"appname\":\"MyWebApp\"\n              },\n              \"settings\":(this.aJSON.settings || {})\n          };\n          this.aEditor.setValue(vEmptyJSON);\n          console.log(\"JSON-DB for UML class '\"+this.getAppName(vEmptyJSON)+\"' not saved - data deleted!\");\n        }\n        localStorage.clear();\n        this.saveLS(\"jsondata\");\n        this.update_filename();\n        this.update_modified();\n        console.log(\"JSON-DB deleted'!\");\n        //save changes to Local Storage\n    } else {\n        console.log(\"initialize JSON-DB cancelled\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "showEditor",
                "parameter": [
                    {
                        "name": "pEditorID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pBoolean",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var self = this.getEditor(pEditorID);\n    //if (self.collapsed) {\n    if (self) {\n      if (pBoolean == true) {\n        self.editor_holder.style.display = '';\n        self.collapsed = false;\n        self.setButtonText(self.toggle_button, '', 'collapse', self.translate('button_collapse'));\n      } else {\n        self.editor_holder.style.display = 'none';\n        self.collapsed = true;\n        self.setButtonText(self.toggle_button, '', 'expand', self.translate('button_expand'));\n      }\n    } else {\n      console.log(\"ERROR: showEditor('\"+pEditor+\"',pBoolean) Editor for ['\"+pEditorID+\"'] not found\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "toggleSettings",
                "parameter": [
                    {
                        "name": "pSettingsID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pDataID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // if(editor.getEditor('root.location').isEnabled()) alert(\"It's editable!\");\n    // Check if Settings are enabled\n    //if (this.options.collapsed) {\n    //  $trigger(this.toggle_button,'click');\n    //}\n    this.update_modified();\n    // update the class watchlist stored in Schema at \"definitions.selectorclass\"\n    this.init_definitions();\n    // restart the editor\n    var vJSON = cloneJSON(this.aEditor.getValue());\n    this.create_editor(vJSON);\n    //this.init(this.aJSON,this.aDefaultJSON,this.aSchema,this.aTemplates,this.aOptions);\n    console.log(\"CALL: this.create_editor() in toggleSettings('\" + pSettingsID + \"','\" + pDataID + \"')\");\n    // set the Editor properly\n    if (this.aSettingsBOOL == false) {\n      alert(\"JSON-Editor: Show Settings\");\n      this.showEditor(pSettingsID,true);\n      this.showEditor(pDataID,false);\n    } else {\n      alert(\"JSON-Editor: Hide Settings\");\n      this.showEditor(pSettingsID,false);\n      this.showEditor(pDataID,true);\n    }\n    this.aSettingsBOOL = !this.aSettingsBOOL;\n  "
            },
            {
                "visibility": "public",
                "name": "toggleEnable",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    if (this.aEditor.isEnabled()) {\n      this.aEditor.disable();\n    } else {\n      this.aEditor.enable();\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "enable",
                "parameter": [
                    {
                        "name": "pID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    if (pID) {\n      this.aEditor.getEditor(pID).enable();\n    } else {\n      this.aEditor.enable();\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "disable",
                "parameter": [
                    {
                        "name": "pID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    if (pID) {\n      this.aEditor.getEditor(pID).disable();\n    } else {\n      this.aEditor.disable();\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "init_buttons",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vThis = this; // \"vThis\" used because \"this\" is not available in function\n    this.set_button_click(\"submit\",function() {\n        // Get the value from the editor\n        var vContent = JSON.stringify(vThis.aEditor.getValue(),null,4);\n        vThis.el(\"tJSON\");\n        console.log(\"JSON Data:\\n\"+vContent);\n    });\n    this.set_button_click(\"enable_disable\",function() {\n        if (vThis.aEditor) {\n            // Enable form\n            if(!vThis.aEditor.isEnabled()) {\n                vThis.aEditor.enable();\n            }\n            // Disable form\n            else {\n                vThis.aEditor.disable();\n            }\n        }\n    });\n  "
            },
            {
                "visibility": "public",
                "name": "init_watch",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    console.log(\"CALL: init_watch() \");\n    // watch event is fired before the value is changed,\n    // so getValue() provides the value before alteration of JSON.\n    // USE: onchange event with editor.on\n    var vThis = this; // \"vThis\" used because \"this\" is not available in function\n    if (this.aEditor) {\n      this.aEditor.watch('root.data.appname',function() {\n        console.log(\"Watch-Event 'root.data.appname'\");\n        vThis.update_filename();\n        //update_editor();\n      });\n      /*\n      var vEditor = this.aEditor;\n      if (vEditor) {\n        if (typeof vEditor.on === 'function') {\n          vEditor.on('change',function() {\n            console.log(\"onchange-Event 'root.data.appname'\");\n            vThis.update_filename();\n          });\n        } else {\n          console.log(\"WARNING: In JSON-Editor ['\"+vEditID+\"'] on-Method not defined!\");\n        }\n      };\n\n      this.aEditor.watch('root.data.appname',function() {\n        console.log(\"Watch-Event 'root.data.appname'\");\n        vThis.update_filename();\n        //update_editor();\n      });\n\n      this.aEditor.watch('root.settings.baseclasslist',function() {\n        vThis.update_watchclasslist();\n        //update_editor();\n      });\n      this.aEditor.watch('root.settings.localclasslist',function() {\n        vThis.update_watchclasslist();\n        //update_editor();\n      });\n      this.aEditor.watch('root.settings.remoteclasslist',function() {\n        vThis.update_watchclasslist();\n        //update_editor();\n      });\n      */\n      //this.start_watch()\n    } else {\n      console.log(\"aEditor not defined in init_watch()-call\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "start_watch",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vThis = this; // \"vThis\" used because \"this\" is not available in function\n    if (this.aEditor) {\n      console.log(\"start_watch()-call\");\n      this.aEditor.on('change',function() {\n        vThis.validate_errors();\n        //vThis.saveLS(\"jsondata\");\n        vThis.update_filename();\n        //update_editor();\n        vThis.update_modified();\n        // update_modified date\n      });\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "stop_watch",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vThis = this; // \"vThis\" used because \"this\" is not available in function\n    console.log(\"stop_watch()-call\");\n    if (this.aEditor) {\n      this.aEditor.on('change',function() {\n        //update_editor();\n      });\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "set_button_click",
                "parameter": [
                    {
                        "name": "pID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pFunction",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vNode = this.el(pID);\n    if (vNode) {\n        vNode.addEventListener('click',pFunction);\n    } else {\n        console.log(\"DOM node [\"+pID+\"] does not exist. Could not assign\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "update",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    alert(\"update Schema changes for the JSONEditor4Menu\");\n    this.create_editor();\n  "
            },
            {
                "visibility": "public",
                "name": "getValue",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vJSON = this.aJSON;\n    if (this.aEditor) {\n      vJSON = cloneJSON(this.aEditor.getValue());\n    } else {\n      console.log(\"this.aEditor undefined in JSONEditor4Menu.getValue()\");\n    }\n    return vJSON;\n  "
            },
            {
                "visibility": "public",
                "name": "setValue",
                "parameter": [
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    this.aJSON = pJSON;\n    if (this.aEditor) {\n      this.aEditor.setValue(pJSON);\n      console.log(\"setValue() executed!\\n\"+JSON.stringify(pJSON,null,4));\n    } else {\n      console.log(\"this.aEditor undefined in JSONEditor4Menu.setValue(pJSON)\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "update_modified",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      this.aJSON = this.getValue();\n      if (this.aJSON) {\n        if (this.aJSON.settings) {\n          this.aJSON.settings.modified = getDateTime();\n          this.setValue(this.aJSON);\n          console.log(\"settings.modified updated with: '\"+this.aJSON.settings.modified+\"'\");\n        } else {\n          console.log(\"this.aJSON.settings.modified was undefined - src/libs/exportmod.js:518\");\n        }\n        this.update_filename();\n      }\n  "
            },
            {
                "visibility": "public",
                "name": "update_filename",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n\n    if (this.aOptions.hasOwnProperty(\"filename_id\")) {\n      var vNode = this.el(this.aOptions.filename_id); // e.g. filename_id = \"load_filename\";\n      var vJSON = this.aJSON;\n      if (vNode) {\n        if (this.aEditor) {\n          console.log(\"CALL: update_filename() - use vJSON = this.aEditor.getValue()!\");\n          vJSON = cloneJSON(this.aEditor.getValue());\n        } else {\n          console.log(\"CALL: update_filename() - this.aEditor not defined!\");\n        }\n      }\n\n      var vDOMID = this.aOptions.filename_id;\n      if (this.el(vDOMID)) {\n        if (vJSON.data) {\n          if (vJSON.data.hasOwnProperty(\"appname\")) {\n            console.log(\"CALL: update_filename('\"+vJSON.data.appname+\"') - Name of class was updated in DOM node [\"+vDOMID+\"]!\");\n            vNode.innerHTML = app2filename(vJSON.data.appname)+vJSON.settings.extension4json;\n          } else {\n            console.log(\"WARNING: update_filename() - Attribute 'appname' in 'this.aJSON.data.appname' - was not defined!\");\n          }\n        } else {\n          console.log(\"WARNING: update_filename() - this.aJSON does not contain the hash 'this.aJSON.data' for access to classname 'this.aJSON.data.appname' - update of classname in DOM was not performed!\");\n        }\n      } else {\n        console.log(\"WARNING: update_filename() - DOM node [\"+vDOMID+\"] does not exist!\");\n      }\n    } else {\n      console.log(\"WARNING: update_filename() - DOM-ID is not defined in this.aOptions['filename_id']\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "update_subeditor",
                "parameter": [
                    {
                        "name": "pEditPath",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var ed_classlist =  this.getEditor(pEditPath);\n    // `getEditor` will return null if the path is invalid\n    var s = this.aJSON.settings;\n    if (ed_classlist) {\n      ed_classlist.setValue(pJSON);\n      console.log(\"update_subeditor('\"+pEditPath+\"',pJSON) \"+ed_classlist.getValue());\n    } else {\n      console.log(\"update_subeditor('\"+pEditPath+\"',pJSON) editor undefined - wrong Edit Path\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "validate_errors",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // Get an array of errors from the validator\n    var errors = this.aEditor.validate();\n\n    var indicator = this.el(this.aOptions.validator_id);\n\n    // Not valid\n    if(errors.length) {\n      indicator.style.color = 'red';\n      indicator.textContent = \"not valid\";\n    }\n    // Valid\n    else {\n      indicator.style.color = 'green';\n      indicator.textContent = \"valid\";\n    }\n    var vErrors = \"\";\n    var vCR = \"\";\n    for (var i = 0; i < errors.length; i++) {\n      vErrors +=  vCR + errors[i].path + \" - \" +errors[i].property +\" - \"+errors[i].message;\n      vCR = \"\\n\";\n    }\n    this.el(\"tErrors\").value = vErrors;\n  "
            },
            {
                "visibility": "public",
                "name": "url2id",
                "parameter": [
                    {
                        "name": "pPrefix",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      var vPrefix = pPrefix || \"\";\n      var url = document.location.href;\n      var id = url.replace(/^https:\\/\\//g,\"\");\n      id = id.replace(/^http:\\/\\//g,\"\");\n      id = id.replace(/^file:\\/\\//g,\"\");\n      id = id.replace(/[^A-Za-z0-9]/g,\"x\");\n      console.log(\"url2id='\" + id + \"'\");\n      return id;\n  "
            },
            {
                "visibility": "public",
                "name": "loadLS",
                "parameter": [
                    {
                        "name": "pLSID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vLSID = this.url2id() || pLSID || \"jsondatra\"; //this.aJSON.data.appname;\n    var vJSONstring = \"\";\n    if (typeof(Storage) != \"undefined\") {\n        // Store\n        if (typeof(localStorage.getItem(vLSID)) !== undefined) {\n          console.log(\"CALL: loadLS() - LocalStorage: '\"+vLSID+\"' try loading from Local Storage\");\n          vJSONstring = localStorage.getItem(vLSID);\n          if (!vJSONstring) {\n            console.log(\"CALL: loadLS() - LocalStorage: '\"+vLSID+\"' undefined in Local Storage.\\nSave default as JSON\");\n            //vJSONstring = JSON.stringify(this.getValue());\n            //console.log(\"LocalStorage: loadLS('\"+vLSID+\"') - init with JSONstring='\"+vJSONstring.substr(0,120)+\"...'\");\n            //localStorage.setItem(vLSID, vJSONstring);\n          } else {\n            console.log(\"CALL: loadLS() - parse JSON '\"+vLSID+\"') from LocalStorage JSONstring='\"+vJSONstring.substr(0,120)+\"...'\");\n            try {\n                this.aJSON = JSON.parse(vJSONstring);\n            } catch(e) {\n                alert(\"ERROR loadLS(): \"+ e);\n            }\n          }\n        } else {\n          console.log(\"CALL: loadLS() - JSON-Data '\"+vLSID+\"' is undefined in Local Storage.\\nUse default as JSON\");\n          //localStorage.setItem(vLSID, JSON.stringify(this.aEditor.getValue()));\n        }\n    }\t else {\n        console.log(\"WARNING: Sorry, your browser does not support Local Storage of JSON Database. Use Firefox ...\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "saveLS",
                "parameter": [
                    {
                        "name": "pLSID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vLSID = this.url2id() || pLSID || \"jsondata\";\n    console.log(\"saveLS('\"+vLSID+\"')-Call\");\n    var vJSON = pJSON || this.getValue();\n    var vJSONstring = \"\";\n    if (typeof(Storage) != \"undefined\") {\n        // Store\n        if (typeof(vJSON) != undefined) {\n          console.log(\"LocalStorage: '\"+vLSID+\"' is defined, JSONDB in  Local Storage\");\n          if (vJSON) {\n            //console.log(\"pJSONDB '\"+vLSID+\"' is saved to Local Storage\");\n            vJSONstring = JSON.stringify(vJSON);\n            console.log(\"LocalStorage: saveLS('\"+vLSID+\"') JSONstring='\"+vJSONstring.substr(0,240)+\"...' DONE\");\n            localStorage.setItem(vLSID,vJSONstring);\n          } else {\n            console.log(\"vJSON with JSON is NOT defined\");\n          }\n        } else {\n          console.log(\"JSON Data '\"+vLSID+\"' is undefined\");\n        }\n      }\t else {\n        console.log(\"WARNING: Sorry, your browser does not support Local Storage of JSON Database. Use Firefox ...\");\n      }\n  "
            },
            {
                "visibility": "public",
                "name": "loadJSON",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vThis = this;\n    var fileToLoad = this.el(this.aOptions.filejson_id).files[0]; //for input type=file\n    if (fileToLoad) {\n      console.log(\"loader4JSON() - File '\"+fileToLoad.name+\"' exists.\");\n      $('#load_filename').html(fileToLoad.name); // this.value.replace(/.*[\\/\\\\]/, '')\n      var fileReader = new FileReader();\n      // set the onload handler\n      fileReader.onload = function(fileLoadedEvent){\n          var vTextFromFileLoaded = fileLoadedEvent.target.result;\n          //document.getElementById(\"inputTextToSave\").value = textFromFileLoaded;\n          //alert(\"textFromFileLoaded=\"+textFromFileLoaded);\n          try {\n            var vLoadedJSON = JSON.parse(vTextFromFileLoaded);\n            vThis.json2editor(vLoadedJSON);\n            vThis.update_filename();\n            alert(\"File JSON '\"+fileToLoad.name+\"' loaded successfully!\");\n            vThis.validate_errors();\n          } catch(e) {\n            vThis.aEditor.setValue(vThis.aDefaultJSON); // Init with an empty class\n            alert(e); // error in the above string (in this case, yes)!\n          }\n        };\n      //onload handler set now start loading the file\n      fileReader.readAsText(fileToLoad, \"UTF-8\");\n    } else {\n      alert(\"File is missing\");\n    }\n    this.saveLS(\"jsondata\");\n  "
            },
            {
                "visibility": "public",
                "name": "json2editor",
                "parameter": [
                    {
                        "name": "pLoadedJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vJSON = null;\n    if (pLoadedJSON) {\n      // json2editor has a JSON as paramter\n      if (pLoadedJSON.hasOwnProperty('data') && pLoadedJSON.hasOwnProperty('settings')) {\n        // load menu DEFINITION AND menu TEMPLATE/layout\n        vJSON = pLoadedJSON;\n      } else {\n        vJSON = cloneJSON(this.aDefaultJSON);\n        // here either \"data\" or \"settings\" is missing\n        if (pLoadedJSON.hasOwnProperty('data')) {\n          //  load menu DEFINITION only > settings / layout / templates are missing\n          vJSON.data = pLoadedJSON.data;\n          console.log(\"JSON update of 'data' in json2editor()\");\n        } else if (pLoadedJSON.hasOwnProperty('settings')) {\n          // load menu TEMPLATE/layout > data for menu structure is missing\n          vJSON.settings = pLoadedJSON.settings;\n          console.log(\"JSON update of 'settings' in json2editor()\");\n        }\n      }\n      this.aEditor.setValue(vJSON);\n    } else {\n      console.error(\"CALL: json2editor(pLoadedJSON) pLoadedJSON was undefined!\");\n      this.aEditor.setValue(this.pDefaultJSON);\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "getAppName4File",
                "parameter": [
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    return app2filename(this.getAppName(pJSON),\"_menu.json\");\n  "
            },
            {
                "visibility": "public",
                "name": "getAppName",
                "parameter": [
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    if (this.aEditor) {\n      console.log(\"CALL: getAppName() aEditor defined - this.aJSON was set!\");\n      this.aJSON = this.aEditor.getValue();\n    }\n    if (pJSON) {\n      console.log(\"CALL: getAppName() initialized with pJSON!\");\n      this.aJSON = pJSON;\n    }\n    var vAppName =  this.aJSON.data.appname || \"Undefined App\";\n    return vAppName;\n  "
            },
            {
                "visibility": "public",
                "name": "getFilename",
                "parameter": [
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vAppName = \"Undefined App\";\n    var vExtension = pJSON.settings.extension4json || \"_menu.json\";\n    if (pJSON) {\n      if (pJSON.data) {\n        if (pJSON.data.appname) {\n          vAppName  = pJSON.data.appname;\n        } else {\n          console.log(\"WARNING: pJSON.data.appname undefined in JSONEditor4Menu.getFilename()\");\n        }\n      } else {\n        console.log(\"WARNING: pJSON.data undefined in JSONEditor4Menu.getFilename()\");\n      }\n    } else {\n      console.log(\"WARNING: pJSON undefined in JSONEditor4Menu.getFilename()\");\n    }\n    var vFilename = app2filename(vAppName) + vExtension;\n    return vFilename;\n  "
            },
            {
                "visibility": "public",
                "name": "setAppName",
                "parameter": [
                    {
                        "name": "pAppName",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    if (this.aJSON) {\n      if (this.aJSON.data) {\n        if (this.aJSON.data.appname) {\n          this.aJSON.data.appname = pAppName;\n        } else {\n          console.error(\"this.aJSON.data.appname is undefined\");\n        }\n      } else {\n        console.error(\"this.aJSON.data is undefined\");\n      }\n    } else {\n      console.error(\"this.aJSON is undefined\");\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "saveJSON",
                "parameter": [
                    {
                        "name": "pkey",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // Get the value from the editor\n    //alert(\"saveJSON()-Call\");\n    var vPrefix = \"\";\n    var vJSON = this.aEditor.getValue();\n    if (pkey) {\n      if (vJSON.hasOwnProperty(pkey)) {\n        vJSON = {\n          pkey : vJSON[pkey]\n        };\n        vPrefix = pkey + \"_\";\n      }\n    }\n    this.saveLS(\"jsondata\");\n    var vFile = vPrefix + this.getFilename(vJSON);\n   // set modified date in reposinfo.modified\n    this.update_modified();\n    var vContent = JSON.stringify(vJSON,null,4);\n    saveFile2HDD(vFile,vContent);\n    console.log(\"JSON output '\"+vFile+\"':\\n\"+vContent);\n    alert(\"JSON File: '\"+vFile+\"' saved!\");\n  "
            },
            {
                "visibility": "public",
                "name": "saveSchema",
                "parameter": [
                    {
                        "name": "pOutformatJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vContent = JSON.stringify(this.aSchema,null,4);\n    var vExt = \".json\";\n    var vBasename = \"menu_schema\";\n    if (!pOutformatJSON) {\n      vExt = \".js\";\n      vContent = '// Store \"' + vBasename + vExt + '\" in \"docs/schema/\"\\n\\n' + 'vDataJSON[\"' + vBasename + '\"] = ' + vContent;\n    }\n    var vFile = vBasename + vExt;\n    saveFile2HDD(vFile,vContent);\n    console.log(\"JSON Schema '\"+vFile+\"' saved!\");\n    alert(\"JSON Schema File: '\"+vFile+\"' saved!\");\n  "
            },
            {
                "visibility": "public",
                "name": "saveDocumentation",
                "parameter": [],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // see e.g. template tpl/docu4github_tpl.js\n    // stored  vDataJSON[\"tpl\"][\"docu4github\"]\n    this.save4Template(\"docu4github\",\"_github.md\",\"Github MarkDown Documentation\");\n  "
            },
            {
                "visibility": "public",
                "name": "viewOutput",
                "parameter": [
                    {
                        "name": "pContent",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    //--Textarea Output----------------\n    var vOutNode = this.el(\"tOutput\");\n    if (vOutNode) {\n      vOutNode.value = pContent;\n    } else {\n      console.log(\"WARNING: JSONEditor4Menu.viewOutput()-call - textarea 'tOutput' not defined in DOM\");\n    }\n    //---------------------------------\n  "
            },
            {
                "visibility": "public",
                "name": "getOutput4Template",
                "parameter": [
                    {
                        "name": "pTplID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      console.log(\"getOutput4Template('\"+pTplID+\"')\");\n      this.update_modified();\n      var vJSON = this.aEditor.getValue();\n      //-- HandleBars: Compile with javascript-template ---\n      // vDataJSON[\"out\"][\"javascript\"] is HandleBars compiler function\n      // Compile functions was generated from \"tpl/docu4github_tpl.js\"\n      var vContent = \"Undefined Handlebars Compiler TplID='\"+pTplID+\"'\";\n      if (this.compileCode[pTplID]) {\n        vContent = this.compileCode[pTplID](vJSON);\n        //--Textarea Output----------------\n        this.viewOutput(vContent);\n        //---------------------------------\n      } else {\n        console.error(\"Handlebars4Code template compiler this.compileCode.\"+pTplID+\"() undefined\");\n      }\n\n      return vContent;\n  "
            },
            {
                "visibility": "public",
                "name": "save4Template",
                "parameter": [
                    {
                        "name": "pTplID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pExtension",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pMessage",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n      console.log(\"save4Template('\"+pTplID+\"'.'\"+pExtension+\"','\"+pMessage+\"')\");\n      var vMessage = pMessage || \"Code for Template generated\";\n      //vContent = postProcessHandlebars(vContent,vJSON);\n      var vContent = this.getOutput4Template(pTplID);\n      console.log(\"save4Template() vContent=\"+vContent.substr(0,120)+\"...\");\n      //--Textarea Output----------------\n      this.viewOutput(vContent);\n      //---------------------------------\n      //--JSON Output--------------------\n      var vJSON = this.getValue();\n      var vFile = app2filename(vJSON.data.appname,pExtension);\n      saveFile2HDD(vFile,vContent);\n      //alert(\"File '\"+vFile+\"' saved - \"+vMessage);\n      console.log(\"File '\"+vFile+\"' saved - \"+vMessage);\n  "
            },
            {
                "visibility": "public",
                "name": "logContentZIP",
                "parameter": [
                    {
                        "name": "pZIP",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    pZIP.forEach(function (relativePath, file){\n        console.log(\"File in ZIP: \", relativePath);\n    });\n  "
            },
            {
                "visibility": "public",
                "name": "setAppFolderZIP",
                "parameter": [
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // app_folder is a global variable -\n    var vPosSlash = 0;\n    var vAppFolderFound = false;\n    this.aZIP.forEach(function (relativePath, file){\n      // extract App Folder only once if AppFolder was not found yet.\n      if (!vAppFolderFound) {\n        vPosSlash = relativePath.indexOf(\"/\");\n        if (vPosSlash > 0) {\n          //console.log(\"CALL: getAppFolder(pZIP,pOptions) App Folder found and extracted from file path '\"+relativePath+\"'\");\n          vAppFolderFound = true;\n          pOptions.app_folder = relativePath.substr(0,vPosSlash); // include the slash in app_folder\n          console.log(\"CALL: getAppFolder(pZIP,pOptions) App Folder '\" + pOptions.app_folder + \"' found.\");\n\n        }\n      }\n        //vNode.innerHTML = vNode.innerHTML + \"<li>\" + relativePath + \"</li>\";\n    });\n  "
            },
            {
                "visibility": "public",
                "name": "updateFileList4ZIP",
                "parameter": [
                    {
                        "name": "pID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    console.log(\"CALL: updateFileList4ZIP('\" + pID + \"',pOptions)\");\n    var vJSON = this.getExpandedJSON(pOptions);\n    var vFileList = vJSON.settings[pID];\n    var vContent = \"\";\n    var vFilename = \"\";\n    var vTemplate = \"\";\n    var vPath = \"\";\n    for (var i = 0; i < vFileList.length; i++) {\n      // generate content for JSON with HandleBars4Code template\n      /* e.g. for pID = \"jsfiles\" vFileList contains array of templates\n      jsfiles =\n       [\n          {\n            \"filepath\": \"js/menu.js\",\n            \"istemplate\": \"yes\",\n            \"code\": \"// Content of imported Javascript library\\n\\nThis is the template content of the JavaScript js/menu.js\"\n          }\n       ]\n      */\n      if (vFileList[i].istemplate != \"no\") {\n        vTemplate = vFileList[i].code;\n        var generator4file  = Handlebars4Code.compile(vTemplate);\n        vContent = generator4file(vJSON);\n        if (!vContent)  {\n          vContent = \"ERROR: undefined template for '\" + pID + i + \"' - File: \" +  vFileList[i].filepath;\n          console.error(vContent);\n        }\n      } else {\n        // file is not a HandleBars4Code template, so store file directly in ZIP\n        vContent = vFileList[i].code;\n      }\n      //console.log(\"File Content: \"+vContent + \"\\nof file \"+JSON.stringify(vFileList[i],null,4));\n      // write generated content into ZIP-file 'this.aZIP'\n      if (vFileList[i].hasOwnProperty(\"filepath\")) {\n        vPath = vFileList[i].filepath;\n      } else {\n        vPath = \"undef_path/\" + vID + i + \".txt\";\n        console.warn(\"WARNING: Attribute 'filepath' undefined for '\" + pID + \"' - Debug Filename: '\" + vPath + \"' \");\n      }\n      vFilename = pOptions.app_folder + \"/\" +vPath;\n      console.log(\"Add2ZIP: \"+vFilename);\n      this.aZIP.file(vFilename, vContent , {base64: false});\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "addMenuJSON2ZIP",
                "parameter": [
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // app2filename(vJSON.data.appname,pExtension);\n      var vFilename = pOptions.app_folder + \"/db/\" + app2filename(pJSON.data.appname,pJSON.settings.extension4json);\n      var vContent = JSON.stringify(pJSON,null,4);\n      this.aZIP.file(vFilename, vContent , {base64: false});\n  "
            },
            {
                "visibility": "public",
                "name": "expandMenuPages4JSON",
                "parameter": [
                    {
                        "name": "pJSON",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // app2filename(vJSON.data.appname,pExtension);\n    var vMenuList = [];\n    if (pJSON.hasOwnProperty(\"data\")) {\n      if (pJSON.data.hasOwnProperty(\"menuitems\")) {\n        console.log(\"CALL: expandMenuPages4JSON() - Menu Items found in pJSON \");\n        vMenuList = pJSON.data.menuitems;\n      } else {\n        console.warn(\"WARNING: 'pJSON.data.menuitems' undefined in expandMenuPages4JSON()\");\n      }\n    } else {\n      console.warn(\"WARNING: 'pJSON.data' undefined in expandMenuPages4JSON()\");\n    }\n    // iterate over menuitems and expand the page content with Handlebars4Code\n    for (var i = 0; i < vMenuList.length; i++) {\n      if (vMenuList[i].menutype == \"page\") {\n        console.log(\"Expand Menu Page '\" + vMenuList[i].title + \"' with expandMenuPages4JSON()\");\n        var vMenTpl = vMenuList[i].content;\n        var generator4file  = Handlebars4Code.compile(vMenTpl);\n        vMenuList[i].content = generator4file(pJSON);\n      }\n    };\n    return pJSON;\n  "
            },
            {
                "visibility": "public",
                "name": "getExpandedJSON",
                "parameter": [
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    // this function expands the Handlebars variables in the\n    var vJSON = cloneJSON(this.aEditor.getValue());\n    vJSON = this.expandMenuPages4JSON(vJSON,pOptions);\n    return vJSON;\n  "
            },
            {
                "visibility": "public",
                "name": "addFiles2ZIP",
                "parameter": [
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    var vJSON = this.getExpandedJSON(pOptions);\n    this.addMenuJSON2ZIP(vJSON,pOptions);\n    var vArrID = pOptions.file_list_id || [];\n    var vID = \"\";\n    for (var i = 0; i < vArrID.length; i++) {\n      vID = vArrID[i];\n      if (vJSON.settings.hasOwnProperty(vID)) {\n        if (vJSON.settings[vID]) {\n          //console.log(\"CALL: updateFileList4ZIP('\" + vID + \"',pOptions)\");\n          this.updateFileList4ZIP(vID,pOptions);\n        } else {\n          console.error(\"ERROR: File List '\" + vID + \"' in vJSON.settings  undefined\");\n        }\n      } else {\n        console.error(\"ERROR: addFiles2ZIP() in JSON settings.\" + vID + \" is undefined\");\n      }\n    }\n  "
            },
            {
                "visibility": "public",
                "name": "exportAppZIP",
                "parameter": [
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    //this.logContentZIP(pZIP);\n    this.setAppFolderZIP(pOptions);\n    this.addFiles2ZIP(pOptions);\n    var vFilename = pOptions.app_folder + \".zip\";\n    this.aZIP.generateAsync({type:\"blob\"}).then(function (blob) { // 1) generate the zip file\n      alert(\"ZIP file '\"+pOptions.app_folder + \".zip' generated.\\nZIP-file contains the generate WebApp with the defined menu!\");\n      saveAs(blob, vFilename);                          // 2) trigger the download\n      console.log(\"Save ZIP File: '\" + vFilename + \"'\");\n    }, function (err) {\n      console.error(\"ERROR: generation of zip-file '\" + vFilename + \"' - \"+err);\n    });\n  "
            },
            {
                "visibility": "public",
                "name": "save4ZIP",
                "parameter": [
                    {
                        "name": "pOptions",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n    if (isHash(pOptions)) {\n      // vArrID resp. pOptions.file_list_id contains the ID for the handlebars4code templates or raw files\n      var vArrID = [\"htmlfiles\",\"cssfiles\",\"jsfiles\"];\n      // for output generate an array ID string\n      var vArrID_string = \"['\" + vArrID.join(\"','\") + \"']\";\n      // vArrID_string:  ['htmlfiles','cssfiles','jsfiles']\n      if (pOptions.hasOwnProperty(\"file_list_id\")) {\n          console.log(\"CALL save4ZIP(): pOptions.file_list_id exists\");\n          vArrID_string = \"['\" + pOptions.file_list_id.join(\"','\") + \"']\";\n      } else {\n          console.log(\"WARNING save4ZIP(): pOptions.file_list_id undefined - use default \" + vArrID_string);\n          pOptions.file_list_id = vArrID;\n      }\n      // check if an output message is defined in pOptions - otherwise set default message\n      if (!pOptions.hasOwnProperty(\"message\")) {\n        console.log(\"Output Message defined: '\" + pOptions.message + \"'\");\n      } else {\n        pOptions.message = \"ZIP for WebApp with Menue was generated\";\n      }\n      console.log(\"CALL: save4ZIP(pZIP,pOptions) with file list IDs=\" +vArrID_string + \" exported with Handlebars4Code\");\n      this.exportAppZIP(pOptions);\n    } else {\n      console.error(\"WARNING save4ZIP(pZIP): pOptions was not provided as parameter\");\n    }\n\n  "
            },
            {
                "visibility": "public",
                "name": "saveCode",
                "parameter": [
                    {
                        "name": "pTplID",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pExt",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    },
                    {
                        "name": "pMessage",
                        "class": " ",
                        "comment": "the parameter provides ..."
                    }
                ],
                "return": " ",
                "comment": "the method performs ...",
                "code": "\n\n    var vTplID = pTplID || \"javascript\";\n    var vExt = pExt || \".js\";\n    var vMessage = pMessage || \"Javascript Code for Class\";\n    // see e.g. template tpl/javascript_class_tpl.js\n    // stored  vDataJSON[\"tpl\"][\"javascript\"]\n    this.save4Template(vTplID,vExt,vMessage);\n  "
            }
        ]
    },
    "settings": {
        "extension4code": ".js",
        "extension4json": "_uml.json",
        "localclasslist": [
            {
                "name": "JSONEditor",
                "initvalue": "new JSONEditor()",
                "repo": "jsoneditor"
            }
        ],
        "remoteclasslist": [
            {
                "name": "LoadFile4DOM",
                "initvalue": "new LoadFile4DOM()",
                "repo": "loadfile4dom"
            },
            {
                "name": "LinkParam",
                "initvalue": "new LinkParam()",
                "repo": "linkparam"
            }
        ],
        "baseclasslist": [
            {
                "name": "Array",
                "initvalue": "[]"
            },
            {
                "name": "Boolean",
                "initvalue": "true"
            },
            {
                "name": "Float",
                "initvalue": "0.0"
            },
            {
                "name": "Function",
                "initvalue": "function my_fun() {}"
            },
            {
                "name": "Document",
                "initvalue": "document"
            },
            {
                "name": "Integer",
                "initvalue": "0"
            },
            {
                "name": "String",
                "initvalue": "\"\""
            },
            {
                "name": "Hash",
                "initvalue": "{}"
            },
            {
                "name": "Object",
                "initvalue": "null"
            },
            {
                "name": "RegularExp",
                "initvalue": "/search/g"
            }
        ]
    }
}