diff --git a/.gitignore b/.gitignore
index 6704566..561d018 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,3 +102,6 @@ dist
 
 # TernJS port file
 .tern-port
+
+# ignore plugin build
+main.js
\ No newline at end of file
diff --git a/main.js b/main.js
deleted file mode 100644
index ed8b515..0000000
--- a/main.js
+++ /dev/null
@@ -1,162 +0,0 @@
-'use strict';
-
-var obsidian = require('obsidian');
-
-/*! *****************************************************************************
-Copyright (c) Microsoft Corporation.
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-***************************************************************************** */
-/* global Reflect, Promise */
-
-var extendStatics = function(d, b) {
-    extendStatics = Object.setPrototypeOf ||
-        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
-    return extendStatics(d, b);
-};
-
-function __extends(d, b) {
-    extendStatics(d, b);
-    function __() { this.constructor = d; }
-    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-}
-
-var TaskType;
-(function (TaskType) {
-    TaskType[TaskType["TODO"] = 0] = "TODO";
-    TaskType[TaskType["DONE"] = 1] = "DONE";
-    TaskType[TaskType["DOING"] = 2] = "DOING";
-    TaskType[TaskType["LATER"] = 3] = "LATER";
-    TaskType[TaskType["CANCELED"] = 4] = "CANCELED";
-    TaskType[TaskType["UNKNOWN"] = 5] = "UNKNOWN";
-})(TaskType || (TaskType = {}));
-var HEADING_REGEX = {
-    h1: /(?:\s+)?- # (?:.*)$/gms,
-    h2: /(?:\s+)?- ## (?:.*)$/gms,
-    h3: /(?:\s+)?- ### (?:.*)$/gms,
-    h4: /(?:\s+)?- #### (?:.*)$/gms,
-    h5: /(?:\s+)?- ##### (?:.*)$/gms,
-};
-var VERSION = "0.0.3";
-function parseTaskType(content) {
-    if (content.startsWith("DONE ")) {
-        return TaskType.DONE;
-    }
-    else if (content.startsWith("TODO ")) {
-        return TaskType.TODO;
-    }
-    else if (content.startsWith("DOING ")) {
-        return TaskType.DOING;
-    }
-    else if (content.startsWith("LATER ")) {
-        return TaskType.LATER;
-    }
-    else if (content.startsWith("CANCELED ")) {
-        return TaskType.CANCELED;
-    }
-    else {
-        return TaskType.UNKNOWN;
-    }
-}
-function removeTimestamps(content) {
-    return content
-        .replace(/doing:: (?:\d{13})/gms, "")
-        .replace(/done:: (?:\d{13})/gms, "")
-        .replace(/todo:: (?:\d{13})/gms, "")
-        .replace(/doing:: (?:\d{13})/gms, "")
-        .replace(/later:: (?:\d{13})/gms, "")
-        .replace(/canceled:: (?:\d{13})/gms, "")
-        .replace(/id:: (?:[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12})/gims, "")
-        .replace(/collapsed:: (?:true|false)/gms, "")
-        .replace("<br>", "");
-}
-var blockTest = new RegExp(/\#\+BEGIN_(WARNING|IMPORTANT|QUOTE|CAUTION)/gms);
-function isBlock(content) {
-    return blockTest.test(content);
-}
-function cmHeadingOverlay(cm) {
-    cm.addOverlay({
-        token: function (stream) {
-            if (stream.match(HEADING_REGEX["h1"])) {
-                return "header-1";
-            }
-            else if (stream.match(HEADING_REGEX["h2"])) {
-                return "header-2";
-            }
-            else if (stream.match(HEADING_REGEX["h3"])) {
-                return "header-3";
-            }
-            else if (stream.match(HEADING_REGEX["h4"])) {
-                return "header-4";
-            }
-            else if (stream.match(HEADING_REGEX["h5"])) {
-                return "header-5";
-            }
-            else {
-                stream.next();
-            }
-        },
-    });
-}
-var LogSeqPlugin = /** @class */ (function (_super) {
-    __extends(LogSeqPlugin, _super);
-    function LogSeqPlugin() {
-        return _super !== null && _super.apply(this, arguments) || this;
-    }
-    LogSeqPlugin.prototype.onload = function () {
-        console.log("Loading LogSeq plugin " + VERSION);
-        obsidian.MarkdownPreviewRenderer.registerPostProcessor(LogSeqPlugin.postprocessor);
-        // Style headings in source editing
-        this.registerCodeMirror(cmHeadingOverlay);
-    };
-    LogSeqPlugin.prototype.onunload = function () {
-        console.log("unloading LogSeq plugin " + VERSION);
-        obsidian.MarkdownPreviewRenderer.unregisterPostProcessor(LogSeqPlugin.postprocessor);
-    };
-    LogSeqPlugin.postprocessor = function (el, ctx) {
-        var entries = el.querySelectorAll("li[data-line]");
-        entries.forEach(function (entry) {
-            var taskType = parseTaskType(entry.textContent);
-            // Check if the entry is a org-mode block
-            if (isBlock(entry.innerHTML)) {
-                var replacedBlock = entry.innerHTML.replace(/\#\+BEGIN_(WARNING|IMPORTANT|QUOTE|CAUTION)/, "<blockquote> &#9759;");
-                replacedBlock = replacedBlock.replace(/\#\+END_(WARNING|IMPORTANT|QUOTE|CAUTION)/, "</blockquote>");
-                entry.innerHTML = replacedBlock;
-            }
-            if (taskType == TaskType.DONE) {
-                var replacedHTML = removeTimestamps(entry.innerHTML.replace("DONE", ""));
-                entry.innerHTML = "<span class=\"logseq-done-task\"><input type=\"checkbox\" checked> " + replacedHTML + "</span>";
-            }
-            else if (taskType == TaskType.TODO) {
-                var replacedHTML = removeTimestamps(entry.innerHTML.replace("TODO", ""));
-                entry.innerHTML = "<input type=\"checkbox\"> <span class=\"logseq-status-task\">TODO</span> " + replacedHTML;
-            }
-            else if (taskType == TaskType.DOING) {
-                var replacedHTML = removeTimestamps(entry.innerHTML.replace("DOING", ""));
-                entry.innerHTML = "<input type=\"checkbox\"> <span class=\"logseq-status-task\">DOING</span> " + replacedHTML;
-            }
-            else if (taskType == TaskType.LATER) {
-                var replacedHTML = removeTimestamps(entry.innerHTML.replace("LATER", ""));
-                entry.innerHTML = "<input type=\"checkbox\"> <span class=\"logseq-status-task\">LATER</span> " + replacedHTML;
-            }
-            else if (taskType == TaskType.CANCELED) {
-                var replacedHTML = removeTimestamps(entry.innerHTML.replace("CANCELED", ""));
-                entry.innerHTML = "<span class=\"logseq-done-task\">" + replacedHTML + "</span>";
-            }
-        });
-    };
-    return LogSeqPlugin;
-}(obsidian.Plugin));
-
-module.exports = LogSeqPlugin;
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfSk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgcHJpdmF0ZU1hcCkge1xyXG4gICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIGdldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcml2YXRlTWFwLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBwcml2YXRlTWFwLCB2YWx1ZSkge1xyXG4gICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIHNldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcclxuICAgIH1cclxuICAgIHByaXZhdGVNYXAuc2V0KHJlY2VpdmVyLCB2YWx1ZSk7XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cclxuIiwiaW1wb3J0IHtcclxuICBNYXJrZG93blBvc3RQcm9jZXNzb3IsXHJcbiAgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCxcclxuICBNYXJrZG93blByZXZpZXdSZW5kZXJlcixcclxuICBQbHVnaW4sXHJcbn0gZnJvbSBcIm9ic2lkaWFuXCI7XHJcblxyXG5lbnVtIFRhc2tUeXBlIHtcclxuICBUT0RPLFxyXG4gIERPTkUsXHJcbiAgRE9JTkcsXHJcbiAgTEFURVIsXHJcbiAgQ0FOQ0VMRUQsXHJcbiAgVU5LTk9XTixcclxufVxyXG5cclxuY29uc3QgSEVBRElOR19SRUdFWCA9IHtcclxuICBoMTogLyg/OlxccyspPy0gIyAoPzouKikkL2dtcyxcclxuICBoMjogLyg/OlxccyspPy0gIyMgKD86LiopJC9nbXMsXHJcbiAgaDM6IC8oPzpcXHMrKT8tICMjIyAoPzouKikkL2dtcyxcclxuICBoNDogLyg/OlxccyspPy0gIyMjIyAoPzouKikkL2dtcyxcclxuICBoNTogLyg/OlxccyspPy0gIyMjIyMgKD86LiopJC9nbXMsXHJcbn07XHJcblxyXG5jb25zdCBWRVJTSU9OID0gXCIwLjAuM1wiO1xyXG5cclxuZnVuY3Rpb24gcGFyc2VUYXNrVHlwZShjb250ZW50OiBzdHJpbmcpOiBUYXNrVHlwZSB8IG51bGwge1xyXG4gIGlmIChjb250ZW50LnN0YXJ0c1dpdGgoXCJET05FIFwiKSkge1xyXG4gICAgcmV0dXJuIFRhc2tUeXBlLkRPTkU7XHJcbiAgfSBlbHNlIGlmIChjb250ZW50LnN0YXJ0c1dpdGgoXCJUT0RPIFwiKSkge1xyXG4gICAgcmV0dXJuIFRhc2tUeXBlLlRPRE87XHJcbiAgfSBlbHNlIGlmIChjb250ZW50LnN0YXJ0c1dpdGgoXCJET0lORyBcIikpIHtcclxuICAgIHJldHVybiBUYXNrVHlwZS5ET0lORztcclxuICB9IGVsc2UgaWYgKGNvbnRlbnQuc3RhcnRzV2l0aChcIkxBVEVSIFwiKSkge1xyXG4gICAgcmV0dXJuIFRhc2tUeXBlLkxBVEVSO1xyXG4gIH0gZWxzZSBpZiAoY29udGVudC5zdGFydHNXaXRoKFwiQ0FOQ0VMRUQgXCIpKSB7XHJcbiAgICByZXR1cm4gVGFza1R5cGUuQ0FOQ0VMRUQ7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBUYXNrVHlwZS5VTktOT1dOO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlVGltZXN0YW1wcyhjb250ZW50OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gIHJldHVybiBjb250ZW50XHJcbiAgICAucmVwbGFjZSgvZG9pbmc6OiAoPzpcXGR7MTN9KS9nbXMsIFwiXCIpXHJcbiAgICAucmVwbGFjZSgvZG9uZTo6ICg/OlxcZHsxM30pL2dtcywgXCJcIilcclxuICAgIC5yZXBsYWNlKC90b2RvOjogKD86XFxkezEzfSkvZ21zLCBcIlwiKVxyXG4gICAgLnJlcGxhY2UoL2RvaW5nOjogKD86XFxkezEzfSkvZ21zLCBcIlwiKVxyXG4gICAgLnJlcGxhY2UoL2xhdGVyOjogKD86XFxkezEzfSkvZ21zLCBcIlwiKVxyXG4gICAgLnJlcGxhY2UoL2NhbmNlbGVkOjogKD86XFxkezEzfSkvZ21zLCBcIlwiKVxyXG4gICAgLnJlcGxhY2UoXHJcbiAgICAgIC9pZDo6ICg/OlswLTlBLUZdezh9LVswLTlBLUZdezR9LTRbMC05QS1GXXszfS1bODlBQl1bMC05QS1GXXszfS1bMC05QS1GXXsxMn0pL2dpbXMsXHJcbiAgICAgIFwiXCJcclxuICAgIClcclxuICAgIC5yZXBsYWNlKC9jb2xsYXBzZWQ6OiAoPzp0cnVlfGZhbHNlKS9nbXMsIFwiXCIpXHJcbiAgICAucmVwbGFjZShcIjxicj5cIiwgXCJcIik7XHJcbn1cclxuXHJcbmNvbnN0IGJsb2NrVGVzdCA9IG5ldyBSZWdFeHAoL1xcI1xcK0JFR0lOXyhXQVJOSU5HfElNUE9SVEFOVHxRVU9URXxDQVVUSU9OKS9nbXMpO1xyXG5cclxuZnVuY3Rpb24gaXNCbG9jayhjb250ZW50OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICByZXR1cm4gYmxvY2tUZXN0LnRlc3QoY29udGVudCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNtSGVhZGluZ092ZXJsYXkoY206IENvZGVNaXJyb3IuRWRpdG9yKSB7XHJcbiAgY20uYWRkT3ZlcmxheSh7XHJcbiAgICB0b2tlbjogKHN0cmVhbTogYW55KSA9PiB7XHJcbiAgICAgIGlmIChzdHJlYW0ubWF0Y2goSEVBRElOR19SRUdFWFtcImgxXCJdKSkge1xyXG4gICAgICAgIHJldHVybiBcImhlYWRlci0xXCI7XHJcbiAgICAgIH0gZWxzZSBpZiAoc3RyZWFtLm1hdGNoKEhFQURJTkdfUkVHRVhbXCJoMlwiXSkpIHtcclxuICAgICAgICByZXR1cm4gXCJoZWFkZXItMlwiO1xyXG4gICAgICB9IGVsc2UgaWYgKHN0cmVhbS5tYXRjaChIRUFESU5HX1JFR0VYW1wiaDNcIl0pKSB7XHJcbiAgICAgICAgcmV0dXJuIFwiaGVhZGVyLTNcIjtcclxuICAgICAgfSBlbHNlIGlmIChzdHJlYW0ubWF0Y2goSEVBRElOR19SRUdFWFtcImg0XCJdKSkge1xyXG4gICAgICAgIHJldHVybiBcImhlYWRlci00XCI7XHJcbiAgICAgIH0gZWxzZSBpZiAoc3RyZWFtLm1hdGNoKEhFQURJTkdfUkVHRVhbXCJoNVwiXSkpIHtcclxuICAgICAgICByZXR1cm4gXCJoZWFkZXItNVwiO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHN0cmVhbS5uZXh0KCk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcbiAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExvZ1NlcVBsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcbiAgc3RhdGljIHBvc3Rwcm9jZXNzb3I6IE1hcmtkb3duUG9zdFByb2Nlc3NvciA9IChcclxuICAgIGVsOiBIVE1MRWxlbWVudCxcclxuICAgIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dFxyXG4gICkgPT4ge1xyXG4gICAgY29uc3QgZW50cmllcyA9IGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJsaVtkYXRhLWxpbmVdXCIpO1xyXG5cclxuICAgIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcclxuICAgICAgY29uc3QgdGFza1R5cGUgPSBwYXJzZVRhc2tUeXBlKGVudHJ5LnRleHRDb250ZW50KTtcclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIHRoZSBlbnRyeSBpcyBhIG9yZy1tb2RlIGJsb2NrXHJcbiAgICAgIGlmIChpc0Jsb2NrKGVudHJ5LmlubmVySFRNTCkpIHtcclxuICAgICAgICBsZXQgcmVwbGFjZWRCbG9jayA9IGVudHJ5LmlubmVySFRNTC5yZXBsYWNlKFxyXG4gICAgICAgICAgL1xcI1xcK0JFR0lOXyhXQVJOSU5HfElNUE9SVEFOVHxRVU9URXxDQVVUSU9OKS8sXHJcbiAgICAgICAgICBcIjxibG9ja3F1b3RlPiAmIzk3NTk7XCJcclxuICAgICAgICApO1xyXG4gICAgICAgIHJlcGxhY2VkQmxvY2sgPSByZXBsYWNlZEJsb2NrLnJlcGxhY2UoXHJcbiAgICAgICAgICAvXFwjXFwrRU5EXyhXQVJOSU5HfElNUE9SVEFOVHxRVU9URXxDQVVUSU9OKS8sXHJcbiAgICAgICAgICBcIjwvYmxvY2txdW90ZT5cIlxyXG4gICAgICAgICk7XHJcbiAgICAgICAgZW50cnkuaW5uZXJIVE1MID0gcmVwbGFjZWRCbG9jaztcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHRhc2tUeXBlID09IFRhc2tUeXBlLkRPTkUpIHtcclxuICAgICAgICBjb25zdCByZXBsYWNlZEhUTUwgPSByZW1vdmVUaW1lc3RhbXBzKFxyXG4gICAgICAgICAgZW50cnkuaW5uZXJIVE1MLnJlcGxhY2UoXCJET05FXCIsIFwiXCIpXHJcbiAgICAgICAgKTtcclxuICAgICAgICBlbnRyeS5pbm5lckhUTUwgPSBgPHNwYW4gY2xhc3M9XCJsb2dzZXEtZG9uZS10YXNrXCI+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNoZWNrZWQ+ICR7cmVwbGFjZWRIVE1MfTwvc3Bhbj5gO1xyXG4gICAgICB9IGVsc2UgaWYgKHRhc2tUeXBlID09IFRhc2tUeXBlLlRPRE8pIHtcclxuICAgICAgICBjb25zdCByZXBsYWNlZEhUTUwgPSByZW1vdmVUaW1lc3RhbXBzKFxyXG4gICAgICAgICAgZW50cnkuaW5uZXJIVE1MLnJlcGxhY2UoXCJUT0RPXCIsIFwiXCIpXHJcbiAgICAgICAgKTtcclxuICAgICAgICBlbnRyeS5pbm5lckhUTUwgPSBgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiPiA8c3BhbiBjbGFzcz1cImxvZ3NlcS1zdGF0dXMtdGFza1wiPlRPRE88L3NwYW4+ICR7cmVwbGFjZWRIVE1MfWA7XHJcbiAgICAgIH0gZWxzZSBpZiAodGFza1R5cGUgPT0gVGFza1R5cGUuRE9JTkcpIHtcclxuICAgICAgICBjb25zdCByZXBsYWNlZEhUTUwgPSByZW1vdmVUaW1lc3RhbXBzKFxyXG4gICAgICAgICAgZW50cnkuaW5uZXJIVE1MLnJlcGxhY2UoXCJET0lOR1wiLCBcIlwiKVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgZW50cnkuaW5uZXJIVE1MID0gYDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIj4gPHNwYW4gY2xhc3M9XCJsb2dzZXEtc3RhdHVzLXRhc2tcIj5ET0lORzwvc3Bhbj4gJHtyZXBsYWNlZEhUTUx9YDtcclxuICAgICAgfSBlbHNlIGlmICh0YXNrVHlwZSA9PSBUYXNrVHlwZS5MQVRFUikge1xyXG4gICAgICAgIGNvbnN0IHJlcGxhY2VkSFRNTCA9IHJlbW92ZVRpbWVzdGFtcHMoXHJcbiAgICAgICAgICBlbnRyeS5pbm5lckhUTUwucmVwbGFjZShcIkxBVEVSXCIsIFwiXCIpXHJcbiAgICAgICAgKTtcclxuICAgICAgICBlbnRyeS5pbm5lckhUTUwgPSBgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiPiA8c3BhbiBjbGFzcz1cImxvZ3NlcS1zdGF0dXMtdGFza1wiPkxBVEVSPC9zcGFuPiAke3JlcGxhY2VkSFRNTH1gO1xyXG4gICAgICB9IGVsc2UgaWYgKHRhc2tUeXBlID09IFRhc2tUeXBlLkNBTkNFTEVEKSB7XHJcbiAgICAgICAgY29uc3QgcmVwbGFjZWRIVE1MID0gcmVtb3ZlVGltZXN0YW1wcyhcclxuICAgICAgICAgIGVudHJ5LmlubmVySFRNTC5yZXBsYWNlKFwiQ0FOQ0VMRURcIiwgXCJcIilcclxuICAgICAgICApO1xyXG4gICAgICAgIGVudHJ5LmlubmVySFRNTCA9IGA8c3BhbiBjbGFzcz1cImxvZ3NlcS1kb25lLXRhc2tcIj4ke3JlcGxhY2VkSFRNTH08L3NwYW4+YDtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgb25sb2FkKCkge1xyXG4gICAgY29uc29sZS5sb2coYExvYWRpbmcgTG9nU2VxIHBsdWdpbiAke1ZFUlNJT059YCk7XHJcbiAgICBNYXJrZG93blByZXZpZXdSZW5kZXJlci5yZWdpc3RlclBvc3RQcm9jZXNzb3IoTG9nU2VxUGx1Z2luLnBvc3Rwcm9jZXNzb3IpO1xyXG4gICAgLy8gU3R5bGUgaGVhZGluZ3MgaW4gc291cmNlIGVkaXRpbmdcclxuICAgIHRoaXMucmVnaXN0ZXJDb2RlTWlycm9yKGNtSGVhZGluZ092ZXJsYXkpO1xyXG4gIH1cclxuXHJcbiAgb251bmxvYWQoKSB7XHJcbiAgICBjb25zb2xlLmxvZyhgdW5sb2FkaW5nIExvZ1NlcSBwbHVnaW4gJHtWRVJTSU9OfWApO1xyXG4gICAgTWFya2Rvd25QcmV2aWV3UmVuZGVyZXIudW5yZWdpc3RlclBvc3RQcm9jZXNzb3IoTG9nU2VxUGx1Z2luLnBvc3Rwcm9jZXNzb3IpO1xyXG4gIH1cclxufVxyXG4iXSwibmFtZXMiOlsiTWFya2Rvd25QcmV2aWV3UmVuZGVyZXIiLCJQbHVnaW4iXSwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksYUFBYSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNuQyxJQUFJLGFBQWEsR0FBRyxNQUFNLENBQUMsY0FBYztBQUN6QyxTQUFTLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxZQUFZLEtBQUssSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDcEYsUUFBUSxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDMUcsSUFBSSxPQUFPLGFBQWEsQ0FB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
diff --git a/main.ts b/main.ts
index d9d45a7..663c1f3 100644
--- a/main.ts
+++ b/main.ts
@@ -1,88 +1,139 @@
 import {
   MarkdownPostProcessor,
   MarkdownPostProcessorContext,
-  MarkdownPreviewRenderer,
   Plugin,
 } from "obsidian";
 
 enum TaskType {
-  TODO,
-  DONE,
-  DOING,
-  LATER,
-  CANCELED,
-  UNKNOWN,
+  TODO = "TODO",
+  DONE = "DONE",
+  DOING = "DOING",
+  LATER = "LATER",
+  CANCELED = "CANCELED",
+  UNKNOWN = "UNKNOWN",
 }
 
-const HEADING_REGEX = {
-  h1: /(?:\s+)?- # (?:.*)$/gms,
-  h2: /(?:\s+)?- ## (?:.*)$/gms,
-  h3: /(?:\s+)?- ### (?:.*)$/gms,
-  h4: /(?:\s+)?- #### (?:.*)$/gms,
-  h5: /(?:\s+)?- ##### (?:.*)$/gms,
-};
-
-const VERSION = "0.0.3";
-
-function parseTaskType(content: string): TaskType | null {
-  if (content.startsWith("DONE ")) {
-    return TaskType.DONE;
-  } else if (content.startsWith("TODO ")) {
-    return TaskType.TODO;
-  } else if (content.startsWith("DOING ")) {
-    return TaskType.DOING;
-  } else if (content.startsWith("LATER ")) {
-    return TaskType.LATER;
-  } else if (content.startsWith("CANCELED ")) {
-    return TaskType.CANCELED;
-  } else {
-    return TaskType.UNKNOWN;
-  }
+enum TaskCSSClass {
+  COMPLETE = "logseq-complete-task",
+  INCOMPLETE = "logseq-incomplete-task",
+  KEYWORD = "logseq-keyword",
 }
 
-function removeTimestamps(content: string): string {
-  return content
-    .replace(/doing:: (?:\d{13})/gms, "")
-    .replace(/done:: (?:\d{13})/gms, "")
-    .replace(/todo:: (?:\d{13})/gms, "")
-    .replace(/doing:: (?:\d{13})/gms, "")
-    .replace(/later:: (?:\d{13})/gms, "")
-    .replace(/canceled:: (?:\d{13})/gms, "")
-    .replace(
-      /id:: (?:[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12})/gims,
-      ""
-    )
-    .replace(/collapsed:: (?:true|false)/gms, "")
-    .replace("<br>", "");
-}
+const VERSION = "0.0.4";
 
-const blockTest = new RegExp(/\#\+BEGIN_(WARNING|IMPORTANT|QUOTE|CAUTION)/gms);
+class LogSeqRegExes {
+  static parseTaskType(content: string): TaskType {
+    if (content.startsWith("DONE ")) {
+      return TaskType.DONE;
+    } else if (content.startsWith("TODO ")) {
+      return TaskType.TODO;
+    } else if (content.startsWith("DOING ")) {
+      return TaskType.DOING;
+    } else if (content.startsWith("LATER ")) {
+      return TaskType.LATER;
+    } else if (content.startsWith("CANCELED ")) {
+      return TaskType.CANCELED;
+    } else {
+      return TaskType.UNKNOWN;
+    }
+  }
+
+  static HEADING_REGEX = {
+    h1: /(?:\s+)?- # (?:.*)$/gms,
+    h2: /(?:\s+)?- ## (?:.*)$/gms,
+    h3: /(?:\s+)?- ### (?:.*)$/gms,
+    h4: /(?:\s+)?- #### (?:.*)$/gms,
+    h5: /(?:\s+)?- ##### (?:.*)$/gms,
+  };
 
-function isBlock(content: string): boolean {
-  return blockTest.test(content);
+  static BEGIN_BLOCK_REGEX = new RegExp(
+    /\#\+BEGIN_(WARNING|IMPORTANT|QUOTE|CAUTION)/gms
+  );
+  static END_BLOCK_REGEX = new RegExp(
+    /\#\+END_(WARNING|IMPORTANT|QUOTE|CAUTION)/gms
+  );
+
+  static isBlock(content: string): boolean {
+    return LogSeqRegExes.BEGIN_BLOCK_REGEX.test(content);
+  }
 }
 
-function cmHeadingOverlay(cm: CodeMirror.Editor) {
-  cm.addOverlay({
+class CodeMirrorOverlays {
+  static headingsOverlay = {
     token: (stream: any) => {
-      if (stream.match(HEADING_REGEX["h1"])) {
+      if (stream.match(LogSeqRegExes.HEADING_REGEX["h1"])) {
         return "header-1";
-      } else if (stream.match(HEADING_REGEX["h2"])) {
+      } else if (stream.match(LogSeqRegExes.HEADING_REGEX["h2"])) {
         return "header-2";
-      } else if (stream.match(HEADING_REGEX["h3"])) {
+      } else if (stream.match(LogSeqRegExes.HEADING_REGEX["h3"])) {
         return "header-3";
-      } else if (stream.match(HEADING_REGEX["h4"])) {
+      } else if (stream.match(LogSeqRegExes.HEADING_REGEX["h4"])) {
         return "header-4";
-      } else if (stream.match(HEADING_REGEX["h5"])) {
+      } else if (stream.match(LogSeqRegExes.HEADING_REGEX["h5"])) {
         return "header-5";
       } else {
         stream.next();
       }
     },
-  });
+  };
+  static cmAddHeadingOverlay(cm: CodeMirror.Editor) {
+    cm.addOverlay(CodeMirrorOverlays.headingsOverlay);
+  }
+
+  static cmRemoveHeadingOverlay(cm: CodeMirror.Editor) {
+    cm.removeOverlay(CodeMirrorOverlays.headingsOverlay);
+  }
+}
+
+function createKeywordElement(keyword: string): HTMLElement {
+  const element = document.createElement("span");
+  element.classList.add(TaskCSSClass.KEYWORD);
+  element.textContent = keyword;
+  return element;
+}
+
+function createCheckboxElement(checked: boolean = false): HTMLElement {
+  const element = document.createElement("input");
+  element.type = "checkbox";
+  element.checked = checked;
+  return element;
 }
 
 export default class LogSeqPlugin extends Plugin {
+  static removeProperties(content: string): string {
+    return content
+      .replace(/doing:: (?:\d{13})/, "")
+      .replace(/done:: (?:\d{13})/, "")
+      .replace(/todo:: (?:\d{13})/, "")
+      .replace(/doing:: (?:\d{13})/, "")
+      .replace(/later:: (?:\d{13})/, "")
+      .replace(/canceled:: (?:\d{13})/, "")
+      .replace(
+        /id:: (?:[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12})/i,
+        ""
+      )
+      .replace(/collapsed:: (?:true|false)/gms, "");
+  }
+
+  static processChildren(el: Element, keyword: string) {
+    el.childNodes.forEach((child) => {
+      if (child.nodeType == Node.TEXT_NODE) {
+        if (child.nodeValue.startsWith(keyword)) {
+          child.nodeValue = child.nodeValue.replace(keyword, "");
+        }
+        child.nodeValue = LogSeqPlugin.removeProperties(child.nodeValue);
+      }
+    });
+  }
+
+  static styleNode(el: Element, classname: TaskCSSClass) {
+    el.querySelectorAll("li[data-line]").forEach((child) => {
+      // Do not "complete" the child tasks, since this is LogSeq's behaviour
+      child.classList.add(TaskCSSClass.INCOMPLETE);
+    });
+    el.classList.add(classname);
+  }
+
   static postprocessor: MarkdownPostProcessor = (
     el: HTMLElement,
     ctx: MarkdownPostProcessorContext
@@ -90,59 +141,70 @@ export default class LogSeqPlugin extends Plugin {
     const entries = el.querySelectorAll("li[data-line]");
 
     entries.forEach((entry) => {
-      const taskType = parseTaskType(entry.textContent);
-
       // Check if the entry is a org-mode block
-      if (isBlock(entry.innerHTML)) {
+      if (LogSeqRegExes.isBlock(entry.innerHTML)) {
         let replacedBlock = entry.innerHTML.replace(
-          /\#\+BEGIN_(WARNING|IMPORTANT|QUOTE|CAUTION)/,
+          LogSeqRegExes.BEGIN_BLOCK_REGEX,
           "<blockquote> &#9759;"
         );
         replacedBlock = replacedBlock.replace(
-          /\#\+END_(WARNING|IMPORTANT|QUOTE|CAUTION)/,
+          LogSeqRegExes.END_BLOCK_REGEX,
           "</blockquote>"
         );
         entry.innerHTML = replacedBlock;
       }
+      const taskType = LogSeqRegExes.parseTaskType(entry.textContent);
 
       if (taskType == TaskType.DONE) {
-        const replacedHTML = removeTimestamps(
-          entry.innerHTML.replace("DONE", "")
-        );
-        entry.innerHTML = `<span class="logseq-done-task"><input type="checkbox" checked> ${replacedHTML}</span>`;
+        LogSeqPlugin.processChildren(entry, TaskType.DONE);
+
+        entry.insertAdjacentElement("afterbegin", createCheckboxElement(true));
+        LogSeqPlugin.styleNode(entry, TaskCSSClass.COMPLETE);
       } else if (taskType == TaskType.TODO) {
-        const replacedHTML = removeTimestamps(
-          entry.innerHTML.replace("TODO", "")
+        LogSeqPlugin.processChildren(entry, TaskType.TODO);
+
+        entry.insertAdjacentElement(
+          "afterbegin",
+          createKeywordElement(TaskType.TODO)
         );
-        entry.innerHTML = `<input type="checkbox"> <span class="logseq-status-task">TODO</span> ${replacedHTML}`;
+
+        entry.insertAdjacentElement("afterbegin", createCheckboxElement());
+        LogSeqPlugin.styleNode(entry, TaskCSSClass.INCOMPLETE);
       } else if (taskType == TaskType.DOING) {
-        const replacedHTML = removeTimestamps(
-          entry.innerHTML.replace("DOING", "")
+        LogSeqPlugin.processChildren(entry, TaskType.DOING);
+
+        entry.insertAdjacentElement(
+          "afterbegin",
+          createKeywordElement(TaskType.DOING)
         );
-        entry.innerHTML = `<input type="checkbox"> <span class="logseq-status-task">DOING</span> ${replacedHTML}`;
+
+        entry.insertAdjacentElement("afterbegin", createCheckboxElement());
       } else if (taskType == TaskType.LATER) {
-        const replacedHTML = removeTimestamps(
-          entry.innerHTML.replace("LATER", "")
+        LogSeqPlugin.processChildren(entry, TaskType.LATER);
+
+        entry.insertAdjacentElement(
+          "afterbegin",
+          createKeywordElement(TaskType.LATER)
         );
-        entry.innerHTML = `<input type="checkbox"> <span class="logseq-status-task">LATER</span> ${replacedHTML}`;
+
+        entry.insertAdjacentElement("afterbegin", createCheckboxElement());
+        LogSeqPlugin.styleNode(entry, TaskCSSClass.INCOMPLETE);
       } else if (taskType == TaskType.CANCELED) {
-        const replacedHTML = removeTimestamps(
-          entry.innerHTML.replace("CANCELED", "")
-        );
-        entry.innerHTML = `<span class="logseq-done-task">${replacedHTML}</span>`;
+        LogSeqPlugin.processChildren(entry, TaskType.CANCELED);
+        LogSeqPlugin.styleNode(entry, TaskCSSClass.COMPLETE);
       }
     });
   };
 
   onload() {
-    console.log(`Loading LogSeq plugin ${VERSION}`);
-    MarkdownPreviewRenderer.registerPostProcessor(LogSeqPlugin.postprocessor);
+    console.log(`Loading logseq-compat plugin ${VERSION}`);
+    this.registerMarkdownPostProcessor(LogSeqPlugin.postprocessor);
     // Style headings in source editing
-    this.registerCodeMirror(cmHeadingOverlay);
+    this.registerCodeMirror(CodeMirrorOverlays.cmAddHeadingOverlay);
   }
 
   onunload() {
-    console.log(`unloading LogSeq plugin ${VERSION}`);
-    MarkdownPreviewRenderer.unregisterPostProcessor(LogSeqPlugin.postprocessor);
+    console.log(`unloading logseq-compat plugin ${VERSION}`);
+    this.registerCodeMirror(CodeMirrorOverlays.cmRemoveHeadingOverlay);
   }
 }
diff --git a/manifest.json b/manifest.json
index 8fe4d44..69a03df 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,11 +1,11 @@
 {
-	"id": "logseq-format",
-	"name": "LogSeq markdown formatting",
-	"version": "0.0.3",
-	"minAppVersion": "0.9.15",
-	"description": "Render LogSeq-specific markdown",
-	"author": "Rui Vieira",
-	"authorUrl": "https://github.com/ruivieira/obsidian-plugin-logseq",
-	"isDesktopOnly": false,
-	"css": "style.css"
+  "id": "logseq-compat",
+  "name": "LogSeq markdown compatibility plugin",
+  "version": "0.0.4",
+  "minAppVersion": "0.9.15",
+  "description": "Render LogSeq-specific markdown",
+  "author": "Rui Vieira",
+  "authorUrl": "https://github.com/ruivieira/obsidian-plugin-logseq",
+  "isDesktopOnly": false,
+  "css": "style.css"
 }
diff --git a/package.json b/package.json
index 2d9224e..46e8828 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
-  "name": "obsidian-plugin-logseq",
-  "version": "0.0.3",
+  "name": "logseq-compat",
+  "version": "0.0.4",
   "description": "Render LogSeq-specific markdown.",
   "main": "main.js",
   "scripts": {
diff --git a/styles.css b/styles.css
index a7dc991..cbc1997 100644
--- a/styles.css
+++ b/styles.css
@@ -1,14 +1,27 @@
-.logseq-done-task {
-  text-decoration: line-through;
+li.logseq-complete-task:not(ul) {
+  text-decoration: line-through !important;
   opacity: 0.5;
+  display: inline-block;
 }
 
-.logseq-status-task {
+li.logseq-incomplete-task {
+  text-decoration: none !important;
+  display: inline-block;
+  opacity: 1.0;
+}
+
+
+span.logseq-keyword {
   font-weight: bold;
   font-size: 0.9rem;
+  margin-left: 0.5rem;
+  margin-right: 0.5rem;
   color: var(--text-a);
 }
 
-a[href="#A"],a[href="#B"],a[href="#C"],a[href="#D"] {
+a[href="#A"],
+a[href="#B"],
+a[href="#C"],
+a[href="#D"] {
   color: var(--faded-blue) !important;
 }
diff --git a/versions.json b/versions.json
index 329a14f..fc6fd7b 100644
--- a/versions.json
+++ b/versions.json
@@ -1,5 +1,6 @@
 {
 	"0.0.1": "0.9.15",
 	"0.0.2": "0.9.15",
-	"0.0.3": "0.9.15"
+	"0.0.3": "0.9.15",
+	"0.0.4": "0.9.15"
 }