function Cobalt(x) {
    try {
        self.cobalt._ instanceof Cobalt
    } catch(exception) {
        self.cobalt = {
            _: this
        }
        

self.cobalt.blueprint = {
    blueprints: [],
    draw: function _(name, code) {
        for (let i = 0; i < self.cobalt.blueprint.blueprints.length; i++) {
            if (self.cobalt.blueprint.blueprints[i].name == name) {
              return false
            }
        }
        code = code.toString()
        if (code.indexOf('_ => {') == 0) {
            code = code.replace('_ => {', '')
            code = code.split('').reverse().join('').replace('}', '').split('').reverse().join('')
        }
        blueprint = {
            name: name,
            code: code
        }
        self.cobalt.blueprint.blueprints.push(blueprint)
        return true
    },
    sketch: function _(contexts, parent, code) {
      code = code.toString()
      if (code.indexOf('_ => {') == 0) {
          code = code.replace('_ => {', '')
          code = code.split('').reverse().join('').replace('}', '').split('').reverse().join('')
      }
      for (let i = 0; i < self.cobalt.blueprint.blueprints.length; i++) {
        if (self.cobalt.blueprint.blueprints[i].code == code) {
          self.cobalt.object.build(self.cobalt.blueprint.blueprints[i].name, contexts, parent)
          return
        }
      }
      random = self.cobalt.tools.random(0, 1000000)
      self.cobalt.blueprint.draw(random, code)
      self.cobalt.object.build(random, contexts, parent)
    },
    require: function _(blueprints, updateAfter) {
        for (let i = 0; i < blueprints.length; i++) {
          let customContext = blueprints[i][0]
          if (updateAfter === true) {
            customContext = customContext + ',' + blueprints.length
          }
          self.cobalt.request.get(blueprints[i][1], [], true, function(response) {
            self.cobalt.blueprint.draw(response.customContext.split(',')[0], response.response)
            if (response.customContext.split(',').length > 0) {
              if (self.cobalt.blueprint.blueprints.length == parseInt(response.customContext.split(',')[1])) {
                self.cobalt.update()
              }
            }
          }, customContext)
        }
    },
    update: function _(name, updatedCode) {
        for (let i = 0; i < self.cobalt.blueprint.blueprints.length; i++) {
            if (self.cobalt.blueprint.blueprints[i].name == name) {
                self.cobalt.blueprint.blueprints = self.cobalt.blueprint.blueprints[i].splice(i, 1)
                self.cobalt.blueprint.draw(name, updatedCode)
            }
        }
    }
}

self.cobalt.cobalt = function _() {
    return true
}

self.cobalt.component = {
    components: [],
    create: function _(name, code, labels) {
        for (let i = 0; i < self.cobalt.component.components.length; i++) {
            if (self.cobalt.component.components[i].name == name) {
                return false
            }
        }
        code = code.toString()
        if (code.indexOf('function() ') == 0) {
            code = code.replace('function() {', '')
            code = code.split('').reverse().join('').replace('}', '').split('').reverse().join('')
        }
        if (code.indexOf('function()') == 0) {
            code = code.replace('function(){', '')
            code = code.split('').reverse().join('').replace('}', '').split('').reverse().join('')
        }
        component = {
            name: name,
            code: code,
            labels: labels
        }
        self.cobalt.component.components.push(component)
        return true
    },
    replace: function _(name, newCode, newLabels) {
        for (let i = 0; i < self.cobalt.component.components.length; i++) {
            if (self.cobalt.component.components[i].name == name) {
                self.cobalt.component.components = self.cobalt.component.components[i].splice(i, 1)
                self.cobalt.component.create(name, newCode, newLabels)
            }
        }
    }
}

self.cobalt.data = {
    extract: function _(data) {
        return JSON.parse(data)
    },
    package: function _(data) {
        return JSON.stringify(data)
    },
    parser: function _(data, query) {
        parser = new DOMParser()
        document = parser.parseFromString(data, 'text/html')
        return document.querySelectorAll(query)
    }            
}

self.cobalt.document = {
    root: document.querySelector('body'),
    scroll: (to) => {
      window.scroll(0, to)
    },
    size: _ => {
      return {
        width: window.innerWidth,
        height: window.innerHeight
      }
    },
    icon: (location) => {
      let link = document.createElement('link')
      link.setAttribute('cobalt', 'icon')
      link.setAttribute('href', location)
      document.head.appendChild(link)
      self.cobalt.import.badges.push('icon')
    },
    path: function _(newPath) {
        if (!(newPath == '')) {
          history.pushState({},'', window.location.href.replace('//', '%%').split('/')[0].replace('%%', '//') + newPath)
        } else {
          return window.location.href.replace('//', '').replace('/', '%').split('%')[1]
        }
    },
    moveRoot: function _(newRoot) {
        if (typeof newRoot === 'string') {
            newRoot = document.querySelector(newRoot)
        }
        self.cobalt.document.root = newRoot
    },
    title: function _(newTitle) {
        if (!(newTitle == '')) {
          if (document.querySelectorAll('head > title').length == 0) {
            title = document.createElement('title')
            title.innerHTML = newTitle
            document.head.appendChild(title)
          } else {
            document.querySelectorAll('head > title')[0].innerHTML = newTitle
          }
        } else {
          return document.querySelectorAll('head > title')[0].innerHTML
        }
    },
    clear: _ => {
      self.cobalt.object.objects = []
    }            
}

self.cobalt.get = {
    label: function _(label) {
        list = []
        for (let i = 0; i < self.cobalt.object.objects.length; i++) {
            let currentLabels = self.cobalt.object.objects[i].labels
            for (let ii = 0; ii < currentLabels.length; ii++) {
                if (currentLabels[ii] == label) {
                    list.push(self.cobalt.object.objects[i].id)
                }
            }
        }
        return list
    },
    node: function _(id) {
        result = {
            exists: false,
            node: undefined
        }
        nodes = document.querySelectorAll('*[cobalt~="' + id + '"]')
        if (nodes.length == 1) {
            result.node = nodes[0]
            result.exists = true
        }
        return result
    },
    object: function _(id) {
        if (Array.isArray(id)) {
            objects = []
            for (let i = 0; i < id.length; i++) {
                currentID = id[i]
                for (let ii = 0; ii < self.cobalt.object.objects.length; ii++) {
                    if (self.cobalt.object.objects[ii].id == id) {
                        objects.push(self.cobalt.object.objects[ii])
                    }
                }
            }
            return objects
        }
        result = {
            exists: false,
            object: undefined
        }
        for (let i = 0; i < self.cobalt.object.objects.length; i++) {
            if (self.cobalt.object.objects[i].id == id) {
                result.object = self.cobalt.object.objects[i]
                result.exists = true
            }
        }
        return result
    }    
}

self.cobalt.identify = {
    authentication: {
        token: '',
        fingerprint: '',
    },
    initialize: function _(execute) {
        if (self.cobalt.memory.storage === undefined) {
            console.log('[Cobalt] WARN  | Tried to set up identification without first setting up the database.')
            return false
        }
        transaction = self.cobalt.memory.storage.transaction(['authentication'], 'readwrite')
        store = transaction.objectStore('authentication')
        request = store.add({
          'property': 'fingerprint',
          'value': ''
        })
        request.onsuccess = function() {
            secondRequest = store.add({
                'property': 'token',
                'value': ''
            })
            secondRequest.onsucces = function() {
                tokenTransaction = self.cobalt.memory.storage.transaction(['authentication'])
                tokenStore = tokenTransaction.objectStore('authentication')
                tokenRequest = tokenStore.get('token')
                tokenRequest.onsuccess = function(tokenEvent) {
                    self.cobalt.identify.authentication.token = tokenEvent.target.result.value
                    fingerprintTransaction = self.cobalt.memory.storage.transaction(['authentication'])
                    fingerprintStore = fingerprintTransaction.objectStore('authentication')
                    fingerprintRequest = fingerprintStore.get('fingerprint')
                    fingerprintRequest.onsuccess = function(fingerprintEvent) {
                        self.cobalt.identify.authentication.fingerprint = fingerprintEvent.target.result.value
                        if (!(execute === undefined)) {
                            execute()
                        }
                    }
                }
            }
        }
    },
    integrity: function _(execute, customContext) {
        self.cobalt.request.get('/_/integrity', [], true, execute, customContext)
    },
    setToken: function _(token, execute) {
        transaction = self.cobalt.memory.storage.transaction(['authentication'], 'readwrite')
        store = transaction.objectStore('authentication')
        request = store.put({
            property: 'token',
            value: token
        })
        request.onsuccess = function() {
            if (!(execute === undefined)) {
                execute()
            }
        }
    },
    setFingerprint: function _(execute) {
        transaction = self.cobalt.memory.storage.transaction(['authentication'], 'readwrite')
        store = transaction.objectStore('authentication')
        request = store.put({
            property: 'fingerprint',
            value: Math.floor(Math.random() * Math.floor(99999)).toString()
        })
        request.onsuccess = function() {
            if (!(execute === undefined)) {
                execute()
            }
        }
    }
}


self.cobalt.import = {
    badges: [],
    export: function _(badge) {
        for (let i = 0; i < self.cobalt.import.badges.length; i++) {
            if (self.cobalt.import.badges[i] == badge) {
                self.cobalt.import.badges.splice(i, 1)
                document.querySelectorAll('head *[cobalt="' + badge + '"]')[0].remove()
            }
        }
    },
    font: function _(badge, source) {
        current = document.querySelectorAll('head > style')
        for (let i = 0; i < current.length; i++) {
          if (current[i].getAttribute('font') == badge) {
            current.innerHTML = '@font-face{font-family:' + badge + ';src:url(\'' + source + '\');}'
            return
          }
        }
        element = document.createElement('style')
        element.setAttribute('cobalt', 'font:' + badge)
        element.innerHTML = '@font-face{font-family:' + badge + ';src:url(\'' + source + '\');}'
        document.head.appendChild(element)
        self.cobalt.import.badges.push('font:' + badge)
    },
    script: function _(badge, script, external, wait) {
        newScript = document.createElement('script')
        newScript.setAttribute('cobalt', 'script:' + badge)
        if (wait) {
            newScript.setAttribute('defer', 'defer')
        }
        if (external) {
            newScript.setAttribute('src', script)
        } else {
            newScript.innerHTML = script
        }
        document.head.appendChild(newScript)
        self.cobalt.import.badges.push('script:' + badge)
    },
    style: function _(badge, style, external) {
        for (let i = 0; i < self.cobalt.import.badges.length; i++) {
            if (self.cobalt.import.badges[i] == 'style:' + badge) {
                return
            }
        }
        if (external) {
            newStyle = document.createElement('link')
            newStyle.setAttribute('href', style)
            newStyle.setAttribute('rel', 'stylesheet')
        } else {
            newStyle = document.createElement('style')
            newStyle.innerHTML = style
        }
        newStyle.setAttribute('cobalt', 'style:' + badge)
        document.head.appendChild(newStyle)
        self.cobalt.import.badges.push('style:' + badge)
    }      
}

self.cobalt.include = {
    blueprint: function _(name) {
        self.cobalt.request.get('/_/include/blueprints', [['name', name]], true, function(response) {
            if (response.success) {
                if (response.code == 200) {
                    self.cobalt.blueprint.draw('cobalt.' + name, response.response)
                }
            }
        })
    },
    component: function _(name, labels) {
        self.cobalt.request.get('/_/include/components', [['name', name]], true, function(response) {
            if (response.success) {
                if (response.code == 200) {
                    self.cobalt.component.create('cobalt.' + name, response.response, labels)
                }
            }
        })
    },
    manifest: function _(parameters) {
        element = document.createElement('link')
        element.setAttribute('rel', 'manifest')
        query = '?'
        for (let i = 0; i < parameters.length; i++) {
            query = query + '&' + parameters[i][0] + '=' + parameters[i][1]
        }
        query = query.replace('?&', '?')
        element.setAttribute('href', '/_/manifest' + query)
        element.setAttribute('cobalt', 'manifest')
        document.head.appendChild(element)
        self.cobalt.import.badges.push('manifest')
    },
    styleKit: function _() {
        foundFont = 0
        for (let i = 0; i < self.cobalt.import.badges.length; i++) {
            if (self.cobalt.import.badges[i] == 'font:cobalt-display') {
                foundFont++
            }
            if (self.cobalt.import.badges[i] == 'font:cobalt-text') {
                foundFont++
            }
        }
        if (foundFont < 2) {
            self.cobalt.import.font('cobalt-display', '/_/library/asset?location=fonts/display&type=font/ttf')
            self.cobalt.import.font('cobalt-text', '/_/library/asset?location=fonts/text&type=font/ttf')
        }
        styleKit = document.createElement('link')
        styleKit.setAttribute('href', '/_/styleKit')
        styleKit.setAttribute('rel', 'stylesheet')
        styleKit.setAttribute('cobalt', 'styleKit')
        document.head.appendChild(styleKit)
        self.cobalt.import.badges.push('styleKit')
    },
    worker: function _() {
        try {
            navigator.serviceWorker.register('/?worker=*')
        } catch (exception) {}
    }
}

self.cobalt.memory = {
    storage: undefined,
    global: {},
    add: function _(key, value, execute) {
        transaction = self.cobalt.memory.storage.transaction(['memory'], 'readwrite')
        store = transaction.objectStore('memory')
        request = store.add({
          'memoryKey': key,
          'memoryValue': value
        })
        request.onsuccess = function() {
          if (!(execute === undefined)) {
              execute()
          }
        }
    },
    clear: function _(execute) {
        transaction = self.cobalt.memory.storage.transaction(['memory'], 'readwrite')
        store = transaction.objectStore('memory')
        request = store.clear()
        request.onsuccess = function() {
          if (!(execute === undefined)) {
              execute()
          }
        }
    },
    delete: function _(key, execute) {
        transaction = self.cobalt.memory.storage.transaction(['memory'], 'readwrite')
        store = transaction.objectStore('memory')
        request = store.delete(key)
        request.onsuccess = function() {
          if (!(execute === undefined)) {
              execute()
          }
        }
    },
    get: function _(key, execute) {
        transaction = self.cobalt.memory.storage.transaction(['memory'])
        store = transaction.objectStore('memory')
        request = store.get(key)
        request.onsuccess = function(event) {
          if (!(execute === undefined)) {
              try {
                execute(event.target.result.memoryValue)
              } catch(exception) {
                execute()
              }
          }
        }
    },
    setup: function _(execute) {
        if (execute === undefined) {
            execute = function() {}
        }
        try {
          databaseRequest = window.indexedDB.open('cobalt', 1)
          databaseRequest.onupgradeneeded = function(event) {
            database = event.target.result
            database.createObjectStore('memory', {keyPath: "memoryKey"})
            database.createObjectStore('authentication', {keyPath: "property"})
            self.cobalt.memory.storage = database
          }
          databaseRequest.onsuccess = function(event) {
            self.cobalt.memory.storage = event.target.result
            execute()
          }
        } catch(exception) {}
    },
    update: function _(key, newValue, execute) {
        transaction = self.cobalt.memory.storage.transaction(['memory'], 'readwrite')
        store = transaction.objectStore('memory')
        request = store.put({
            memoryKey: key,
            memoryValue: newValue
        })
        request.onsuccess = function() {
            if (!(execute === undefined)) {
                execute()
            }
        }
    },
}

self.cobalt.navigation = {
    redirect: function _(location) {
        window.location.href = location
    },
    scroll: function _(position) {
        destination = {
            top: position,
            left: 0,
            behaviour: 'smooth'
        }
        window.scroll(destination)
    },
    switch: function _(page) {
        window.location.href = page
    }
}

self.cobalt.object = {
    objects: [],
    build: function _(blueprint, contexts, parent) {
        if (parent === undefined) {
            parent = 0
        }
        if (!(Array.isArray(contexts))) {
            if (contexts === undefined) {
                contexts = ['']
            } else {
                contexts = [contexts]
            }
        }
        for (let i = 0; i < contexts.length; i++) {
            valid = true
            invalidReason = 0
            for (let ii = 0; ii < self.cobalt.object.objects.length; ii++) {
                if (self.cobalt.object.objects[ii].blueprint == blueprint) {
                    objectContext = self.cobalt.object.objects[ii].context
                    if (typeof objectContext === 'object') {
                        objectContext = self.cobalt.data.package(objectContext)
                    }
                    compareContext = contexts[i]
                    if (typeof compareContext === 'object') {  
                        compareContext = self.cobalt.data.package(contexts[i])
                    }
                    if (objectContext == compareContext) {
                        if (self.cobalt.object.objects[ii].data.parent == parent) {
                            valid = false
                            invalidReason = self.cobalt.object.objects[ii].id
                        }
                    }
                }
            }
            if (!(valid)) {
                if (contexts.length == 1) {
                    return invalidReason
                }
                continue
            }
            newObject = {
                id: 0,
                labels: [],
                blueprint: blueprint,
                context: contexts[i],
                data: {
                    value: '',
                    style: [],
                    properties: [],
                    parent: parent,
                    type: 'cobalt'
                }
            }
            while (true) {
                randomID = Math.floor(Math.random() * 1000000)
                if (document.querySelectorAll('*[cobalt~="' + randomID  + '"]').length == 0) {
                    newObject.id = randomID
                    break
                }
            }
            self.cobalt.object.objects.push(newObject)
            if (contexts.length == 1) {
                return newObject.id
            }
        }   
    },
    destroy: function _(id) {
        killList = []
        addToKillList(id)
    
        function addToKillList(id) {
            for (let i = 0; i < self.cobalt.object.objects.length; i++) {
                if (self.cobalt.object.objects[i].id == id) {
                    killList.push(i)
                }
                if (self.cobalt.object.objects[i].data.parent == id) {
                    addToKillList(self.cobalt.object.objects[i].id)
                }
            }
        }
        for (let i = 0; i < killList.length; i++) {
    
            self.cobalt.object.objects.splice(killList[i], 1)
    
        }
    },
}

self.cobalt.request = {
    get: function _(to, query, secure, execute, customContext) {
        if (secure) {
          fingerprint = self.cobalt.identify.authentication.fingerprint
          token = self.cobalt.identify.authentication.token
          query.push(['cobalt', fingerprint + '::' + token])
        }
        compiledQuery = '?'
        for (let i = 0; i < query.length; i++) {
          compiledQuery = compiledQuery + query[i][0] + '=' + query[i][1]
          if (!(i + 2 > query.length)) {
            compiledQuery = compiledQuery + '&'
          }
        }
        try {
          var request = new XMLHttpRequest()
          request.onreadystatechange = function() {
            if (request.readyState == 4) {
              execute({response: request.response, code: request.status, success: true, customContext: customContext})
            }
          }
          request.open('GET', to + compiledQuery)
          request.send()
        } catch(exception) {
          return {response: exception, code: 0, success: false, customContext: customContext}
        }
    },
    post: function _(to, query, body, secure, execute, customContext) {
        if (secure) {
          fingerprint = self.cobalt.identify.authentication.fingerprint
          token = self.cobalt.identify.authentication.token
          query.push(['cobalt', fingerprint + '::' + token])
        }
        compiledQuery = '?'
        for (let i = 0; i < query.length; i++) {
          compiledQuery = compiledQuery + query[i][0] + '=' + query[i][1]
          if (!(i + 2 > query.length)) {
            compiledQuery = compiledQuery + '&'
          }
        }
        try {
          var request = new XMLHttpRequest()
          request.onreadystatechange = function() {
            if (request.readyState == 4) {
              execute({response: request.response, code: request.status, success: true, customContext: customContext})
            }
          }
          request.open('POST', to + compiledQuery)
          request.send(body)
        } catch(exception) {
          return {response: exception, code: 0, success: false, customContext: customContext}
        }
    } 
}

self.cobalt.socket = {
    call: function _(body, execute, customContext) {
        body = self.cobalt.data.package(body)
        self.cobalt.request.post('/_/socket', [], body, true, execute, customContext)
    },
    authorize: function _(userID, key, execute, customContext) {
        body = {
            _: "cobalt-authentication",
            action: "authorize",
            credentials: {
                userID: userID,
                key: key
            }
        }
        self.cobalt.request.post('/_/socket', [], self.cobalt.data.parse(body), execute, customContext)
    }
}


self.cobalt.tools = {
    print: function _(message) {
        console.log('[Cobalt] => ' + message)
    },
    random: function _(minimum, maximum) {
        return Math.floor((Math.random() * maximum) + minimum)
    }      
}

self.cobalt.update = function _() {
  
  valueToProperty()
  importProperties()
  updateObjects()
  applyComponents()
  updateNodes()
  propertyToValue()
  exportProperties()

  function valueToProperty() {
    nodes = self.cobalt.document.root.querySelectorAll('*')
    for (let i = 0; i < nodes.length; i++) {
        if (!(nodes[i].value === null)) {
            if (!(nodes[i].getAttribute('cobalt') == '_')) {
                nodes[i].setAttribute('value', nodes[i].value)
            }
        }
    }
  }

  function importProperties() {
    nodes = self.cobalt.document.root.querySelectorAll('*')
    for (let i = 0; i < nodes.length; i++) {
        id = nodes[i].getAttribute('cobalt')
        if (!(id == '_')) {
            for (let ii = 0; ii < self.cobalt.object.objects.length; ii++) {
                if (self.cobalt.object.objects[ii].id == id) {
                    self.cobalt.object.objects[ii].data.properties = []
                    for (let iii = 0; iii < nodes[i].attributes.length; iii++) {
                        validProperty = true
                        if (nodes[i].attributes[iii].name == 'cobalt') {
                            validProperty = false
                        }
                        if (nodes[i].attributes[iii].name == 'style') {
                            validProperty = false
                        }
                        if (validProperty) {
                            newProperty = []
                            newProperty.push(nodes[i].attributes[iii].name)
                            newProperty.push(nodes[i].attributes[iii].value)
                            self.cobalt.object.objects[ii].data.properties.push(newProperty)
                        }
                    }
                }
            }
        }
    }
  }

  function updateObjects() {
    for (let i = 0; i < self.cobalt.object.objects.length; i++) {
      for (let ii = 0; ii < self.cobalt.blueprint.blueprints.length; ii++) {
        if (self.cobalt.blueprint.blueprints[ii].name == self.cobalt.object.objects[i].blueprint) {
          objectFunction = new Function('$', 'x', self.cobalt.blueprint.blueprints[ii].code + '\nreturn x')
          self.cobalt.object.objects[i] = objectFunction(self.cobalt, self.cobalt.object.objects[i])
        }
      }
    }
  }

  function applyComponents() {
    for (let i = 0; i < self.cobalt.object.objects.length; i++) {
      for (let ii = 0; ii < self.cobalt.component.components.length; ii++) {
        for (let iii = 0; iii < self.cobalt.object.objects[i].labels.length; iii++) {
            if ('~' + self.cobalt.component.components[ii].labels.join('~') + '~'.indexOf(self.cobalt.object.objects[i].labels[iii]) > -1) {
                componentFunction = new Function('$', 'x', self.cobalt.component.components[ii].code + '\nreturn x')
                self.cobalt.object.objects[i] = componentFunction(self.cobalt, self.cobalt.object.objects[i])
            }
        }
      }
    }
  }

  function updateNodes() {
    root = self.cobalt.document.root
    nodes = root.querySelectorAll('*')
    objects = self.cobalt.object.objects
    for (let i = 0; i < nodes.length; i++) {
      id = nodes[i].getAttribute('cobalt')
      if (!(id == "_")) {
        found = false
        for (let ii = 0; ii < objects.length; ii++) {
            if (id == objects[ii].id) {
                found = true
                if (!(objects[ii].data.type.toUpperCase() == nodes[i].nodeName)) {
                    console.log('[Cobalt] WARN  | Node type change detected. This is unsupported.')
                }
                compiledStyle = ''
                for (let iii = 0; iii < objects[ii].data.style.length; iii++) {
                    sep = ' '
                    if (objects[ii].data.style[iii][0] == 'cobalt') {
                      sep = '+'
                    }
                    compiledStyle = compiledStyle + objects[ii].data.style[iii][0] + ':' + objects[ii].data.style[iii].slice(1).join(sep) + ';'
                }
                if (!(compiledStyle == nodes[i].getAttribute('style'))) {
                    nodes[i].setAttribute('style', compiledStyle)
                }
                if (objects[ii].data.parent > 0) {
                    if (!(parseInt(nodes[i].parentNode.getAttribute('cobalt')) == objects[ii].data.parent)) {
                        console.log('[Cobalt] WARN  | Parental change detected. This is unsupported.')
                    }
                }
                if (nodes[i].childNodes.length < 1) {
                    if (!(nodes[i].innerHTML == objects[ii].data.value)) {
                        nodes[i].innerHTML = objects[ii].data.value
                    }
                } else {
                    if (nodes[i].childNodes[0].nodeName == '#text') {
                        if (!(nodes[i].innerHTML == objects[ii].data.value)) {
                            nodes[i].innerHTML = objects[ii].data.value
                        } 
                    }
                }
            }
        }
        if (!(found)) {
          nodes[i].remove()
        }
      }
    }
    for (let i = 0; i < self.cobalt.object.objects.length; i++) {
        if (!(document.querySelectorAll('*[cobalt~="' + objects[i].id + '"]').length == 1)) {
            newNode = document.createElement(objects[i].data.type)
            newNode.setAttribute('cobalt', objects[i].id)
            compiledStyle = ''
            for (let ii = 0; ii < objects[i].data.style.length; ii++) {
                sep = ' '
                if (objects[i].data.style[ii][0] == 'cobalt') {
                  sep = '+'
                }
                compiledStyle = compiledStyle + objects[i].data.style[ii][0] + ':' + objects[i].data.style[ii].slice(1).join(sep) + ';'
            }
            newNode.setAttribute('style', compiledStyle)
            newNode.innerHTML = objects[i].data.value
            newNode = processEvents(newNode, objects[i])
            for (let ii = 0; ii < objects[i].data.properties.length; ii++) {
                newNode.setAttribute(objects[i].data.properties[ii][0], objects[i].data.properties[ii][1])
            }
            if (objects[i].data.parent == 0) {
                self.cobalt.document.root.appendChild(newNode)
            } else {
                try {
                    document.querySelectorAll('*[cobalt~="' + objects[i].data.parent + '"]')[0].appendChild(newNode)
                } catch (exception) {
                    console.log('[Cobalt] ERROR | Object has an invalid or non-existent parent!')
                }
            }
        }
    }
  }

  function processEvents(newNode, currentObject) {
      if (currentObject.data.events == undefined) {
        return newNode
      }
      for (let i = 0; i < currentObject.data.events.length; i++) {
          currentEvent = currentObject.data.events[i].event
          action = currentObject.data.events[i].action
          if (currentEvent == 'click') {
            newNode.addEventListener('click', {
              do: action,
              handleEvent: function() {
                this.do()
              }
            })
          } if (currentEvent == 'resize') {
            window.addEventListener('resize', {
              do: action,
              handleEvent: function() {
                this.do()
              }
            })
          } else if (currentEvent == 'key') {
            newNode.addEventListener('keydown', {
              do: action,
              handleEvent: function(event) {
                this.do(true, event.key)
              }
            })
            newNode.addEventListener('keyup', {
              do: action,
              handleEvent: function(event) {
                this.do(false, event.key)
              }
            })
          } else if (currentEvent == 'mouse') {
            target.addEventListener('mouseover', {
              do: action,
              handleEvent: function() {
                this.do(true)
              }
            })
            target.addEventListener('mouseenter', {
              do: action,
              handleEvent: function() {
                this.do(true)
              }
            })
            target.addEventListener('mouseout', {
              do: action,
              handleEvent: function() {
                this.do(false)
              }
            })
            target.addEventListener('mouseleave', {
              do: action,
              handleEvent: function() {
                this.do(false)
              }
            })
          }
      }
      return newNode
  }

  function propertyToValue() {
    nodes = self.cobalt.document.root.querySelectorAll('*')
    for (let i = 0; i < nodes.length; i++) {
        nodes[i].value = nodes[i].getAttribute('value')
    }
  }

  function exportProperties() {
    for (let i = 0; i < self.cobalt.object.objects.length; i++) {
        id = self.cobalt.object.objects[i].id
        nodes = self.cobalt.document.root.querySelectorAll('*')
        for (let ii = 0; ii < nodes.length; ii++) {
            if (nodes[ii].getAttribute('cobalt') == id) {
                for (let iii = 0; iii < self.cobalt.object.objects[i].data.properties.length; iii++) {
                    nodes[ii].setAttribute(self.cobalt.object.objects[i].data.properties[iii][0], self.cobalt.object.objects[i].data.properties[iii][1])
                }
            }
        }
    }
  }
}

    }
    if (!(x === undefined)) {
        try {
            x(self.cobalt)
        } catch(exception) {
            console.log('[Cobalt] ERROR | An error occured in the executed script.\n=> ', exception)
        }
    }
}