Search
Search

Transaction: 38YbLcR...stAp

Signed by
Receiver
Status
Succeeded
Transaction Fee
0.00117 
Deposit Value
0 
Gas Used
11 Tgas
Attached Gas
100 Tgas
Created
May 30, 2024 at 11:06:16am
Hash
38YbLcRSDDEU5TS7k9jDRbAPZFxFygDkwcHr6UsNstAp

Actions

Called method: 'set' in contract: social.near
Arguments:
{ "data": { "dev.near": { "widget": { "op-task": { "": "const USER = \"user\";\nconst AI = \"ai\";\nconst CHAT_DIRECT = \"direct\";\nconst CHAT_REVERSED = \"reversed\";\nconst ACCOUNT_ID = \"fakeaccount.testnet\";\nconst API_URL = \"https://annotation.nearspace.info/api\";\nconst PROBLEM_ID = 1;\nconst STATUS_ANNOTATION_PENDING = 0;\nconst STORAGE_KEY = `task_storage`;\n\nconst editEverythingMode = true;\n\nconst editIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"svg-icon\"\n width=\"20px\"\n height=\"20px\"\n verticalAlign=\"middle\"\n fill=\"darkgrey\"\n viewBox=\"0 0 1024 1024\"\n version=\"1.1\"\n >\n <path d=\"M834.3 705.7c0 82.2-66.8 149-149 149H325.9c-82.2 0-149-66.8-149-149V346.4c0-82.2 66.8-149 149-149h129.8v-42.7H325.9c-105.7 0-191.7 86-191.7 191.7v359.3c0 105.7 86 191.7 191.7 191.7h359.3c105.7 0 191.7-86 191.7-191.7V575.9h-42.7v129.8z\" />\n <path d=\"M889.7 163.4c-22.9-22.9-53-34.4-83.1-34.4s-60.1 11.5-83.1 34.4L312 574.9c-16.9 16.9-27.9 38.8-31.2 62.5l-19 132.8c-1.6 11.4 7.3 21.3 18.4 21.3 0.9 0 1.8-0.1 2.7-0.2l132.8-19c23.7-3.4 45.6-14.3 62.5-31.2l411.5-411.5c45.9-45.9 45.9-120.3 0-166.2zM362 585.3L710.3 237 816 342.8 467.8 691.1 362 585.3zM409.7 730l-101.1 14.4L323 643.3c1.4-9.5 4.8-18.7 9.9-26.7L436.3 720c-8 5.2-17.1 8.7-26.6 10z m449.8-430.7l-13.3 13.3-105.7-105.8 13.3-13.3c14.1-14.1 32.9-21.9 52.9-21.9s38.8 7.8 52.9 21.9c29.1 29.2 29.1 76.7-0.1 105.8z\" />\n </svg>\n);\n\n/* duplicated css for debug. Loads in parent too */\nconst CSS_URL =\n \"https://gist.githubusercontent.com/zavodil/10ed1d07c893e04571332f1cb2408226/raw/8bad3b0836bec04845cdbaa78bbad771a48a23f7/add.style.css\";\nconst css = fetch(CSS_URL).body;\nif (!css) return \"\";\n\nState.init({\n attachConversation: true,\n theme: styled.div`${css}`,\n});\n\nconst {\n apiUrl,\n sessionId,\n annotationId,\n problemId,\n pendingRequest,\n setPendingRequest,\n onRequest,\n} = props;\nconst storageKey = props.storageKey ?? STORAGE_KEY;\n\nif (typeof setPendingRequest !== \"function\") {\n setPendingRequest = (data) => console.log(\"setPendingRequest\", data);\n}\n\nif (typeof onRequest !== \"function\") {\n onRequest = (data) => console.log(\"onRequest\", data);\n}\n\nif (!annotationId) {\n return \"No data\";\n}\n\nif (state.currentAnnotationId && state.currentAnnotationId != annotationId) {\n State.update({\n currentAnnotationId: null,\n taskLoaded: false,\n taskLoading: false,\n });\n}\n\nconst getCurrentState = () => {\n return {\n user_message: state.userMessage,\n spec: state.spec,\n };\n};\n\nconst saveChat = (isNewMessage, onSaveChat) => {\n setPendingRequest(true);\n asyncFetch(`${apiUrl}/submit_annotation/`, {\n method: \"POST\",\n body: JSON.stringify({\n id: annotationId,\n content: JSON.stringify(state.chat),\n current_state: JSON.stringify(getCurrentState()),\n account_id: context.accountId,\n session_id: sessionId,\n problem_id: problemId,\n prompts: getArray(state.userPrompts),\n attach_conversation: state?.attach_conversation ?? true,\n is_new_message: isNewMessage,\n }),\n }).then((res) => {\n if (res.ok) {\n // returns {is_session_valid, annotation_id?}\n onRequest(res.body);\n }\n\n if (typeof onSaveChat == \"function\") {\n onSaveChat(res);\n }\n\n console.log(\"request_annotation resp\", res.ok, res.body);\n setPendingRequest(false);\n });\n};\n\nconst getArray = (items) => (Array.isArray(items) ? items : []);\n\nlet getTaskData = () => {\n setPendingRequest(true);\n asyncFetch(`${apiUrl}/get_annotation_by_id/`, {\n method: \"POST\",\n\n body: JSON.stringify({\n annotation_id: annotationId,\n account_id: context.accountId,\n session_id: sessionId,\n problem_id: problemId,\n }),\n }).then((res) => {\n if (res.ok) {\n console.log(\"request_annotation_by_id\", sessionId, res);\n if (res.body.is_session_valid) {\n let task = res.body.task;\n let currentState = JSON.parse(task.current_state);\n let chat = JSON.parse(task.content);\n const lastAIReply = getLastReplyFromAI(chat.length + 1, chat);\n State.update({\n currentAnnotationId: annotationId,\n taskLoading: false,\n taskLoaded: true,\n chat: getArray(chat),\n spec: lastAIReply?.spec ?? \"\",\n editSpecIndex: lastAIReply?.index ?? 0,\n userMessage: currentState.user_message,\n });\n }\n // returns {is_session_valid, task}\n onRequest(res.body);\n }\n console.log(\"request_annotation_by_id resp\", res.ok, res.body);\n setPendingRequest(false);\n });\n};\n\nif (!state.taskLoaded && !state.taskLoading && !pendingRequest) {\n State.update({ taskLoading: true });\n console.log(\"getTaskData\", state);\n getTaskData();\n}\n\nconst user_pics = {\n [USER]:\n \"https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-chat/ava4-bg.webp\",\n [AI]: \"https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-chat/ava3-bg.webp\",\n};\nconst LOCAL_BACKUP_KEY = \"backup\";\n\nconst spec = `I'm a spec\n\nI'm using [markdown](https://www.markdownguide.org/basic-syntax/), and have some ***nice stuff*** here, like:\n\n- lists\n- with multiple items\n\nOr maybe even images ![image](https://near.org/_next/static/media/near-logo.1416a213.svg \"title\")`;\n\nconst chat = [\n {\n person: USER,\n message: \"How to make an AMM?\",\n },\n {\n person: AI,\n message: \"\",\n spec: spec,\n },\n {\n person: USER,\n message: \"Format the header\",\n },\n {\n person: AI,\n message: \"Format complete\",\n spec: `## ${spec}`,\n },\n];\n\nconst Theme = state.theme;\n\nconst getPreviousSpecFromAI = (index, chat) => {\n return getLastReplyFromAI(index, chat)?.spec ?? \"\";\n};\n\nconst getLastReplyFromAI = (index, chat) => {\n let item = null;\n for (let i = index - 1; i > 0; i--) {\n if (chat[i].person == AI) {\n item = chat[i];\n item.index = i;\n break;\n }\n }\n\n return item;\n};\n\nconst AddUserMessage = () => {\n if (state.userMessage) {\n if (state.userMessage == \"/clear\") {\n resetBackup();\n } else {\n let chat = getArray(state.chat);\n chat.push({\n person: USER,\n spec: state.spec,\n message: state.userMessage,\n });\n let newState = { chat, userMessage: \"\" };\n\n State.update(newState);\n saveChat(true, (res) => {\n console.log(\"onSaveChat\", res);\n if (res.ok && res.body.is_session_valid) {\n let ai_response = res.body.ai_response;\n if (ai_response?.person == AI) {\n console.log(\"ai_response\", ai_response, state);\n const chat = getArray(state.chat);\n chat.push(ai_response);\n State.update({\n chat,\n spec: ai_response.spec,\n editSpecIndex: chat.length,\n });\n console.log(\"ai_response state\", state);\n }\n }\n });\n }\n }\n};\n\nconst getMessage = (item, index) => {\n if (state.editMessageIndex === index) {\n return (\n <div class=\"text-end\">\n <div>\n <textarea\n class=\"form-control mb-1\"\n style={{ minWidth: \"400px\" }}\n value={state.editMessageText}\n onChange={(e) => State.update({ editMessageText: e.target.value })}\n />\n </div>\n <div>\n <button\n class=\"small ms-2 badge bg-secondary p-2\"\n onClick={() => {\n let chat = state.chat;\n let item = state.chat[index];\n item.spec = state.spec;\n item.message = state.editMessageText;\n chat[index] = item;\n State.update({\n chat,\n editMessageIndex: null,\n editMessageText: null,\n });\n saveChat(false, () => {\n console.log(\"Message updated\");\n });\n }}\n >\n {item.person == USER ? \"Update\" : \"Update spec + text\"}\n </button>\n </div>\n </div>\n );\n } else {\n return <div style={{ whiteSpace: \"pre-wrap\" }}>{getMessageText(item)}</div>;\n }\n};\n\nconst getMessageText = (item) => {\n if (!item.message && item.person == AI) {\n const isInitialMessage = !getPreviousSpecFromAI(index, state.chat);\n if (isInitialMessage) {\n return getInitialSpecMessage();\n }\n }\n return item.message;\n};\n\nconst getNextMessageFromAI = (index) => {\n let nextSpecMessage = \"\";\n for (let i = index + 1; i <= state.chat.length; i++) {\n if (state.chat[i].person == AI) {\n nextSpecMessage = state.chat[i].message;\n break;\n }\n }\n\n return nextSpecMessage;\n};\n\nconst isSpecExists = (spec) => spec != \"\" && spec != \"N/A\";\n\nconst getMessageDiff = (item, index) => {\n if (item.person == AI) {\n let prevSpec = getPreviousSpecFromAI(index, state.chat);\n\n if (isSpecExists(prevSpec)) {\n let diffs = codeDiff(prevSpec, item.spec);\n console.log(\"diffs\", diffs);\n let diffContents = (diffs ?? [])\n .filter((line) => line != \"\\n\")\n .map((line) => {\n if (Array.isArray(line)) {\n return (\n <div class=\"p-1\" style={{ backgroundColor: line[1] }}>\n {line[0]}\n </div>\n );\n } else {\n return <div class=\"p-0\">{line}</div>;\n }\n });\n\n return (\n <div\n class={`mt-1 small code-diff rounded-3 ${getMessageDiffClass(item)}`}\n >\n {diffContents}\n </div>\n );\n }\n }\n\n return <></>;\n};\n\nconst onSpecClick = (index) => {\n let newState = { spec: state.chat[index].spec };\n\n newState.editSpecIndex = index;\n\n State.update(newState);\n};\n\nconst setShowSpecEditor = (isShow) => {\n State.update({\n showSpecEditor: isShow,\n });\n};\n\nconst getInitialSpecMessage = () => {\n return \"Initial spec\";\n};\n\nconst getMessageDiffClass = (item) => {\n return item.person != USER ? \"code-diff-start\" : \"pt-1 code-diff-end\";\n};\n\nconst getMessageClass = (item) => {\n return item.person != USER ? \"pt-2 me-1\" : \"pt-2 ms-1\";\n};\n\nconst isExitEditMode = (index) => state.editMessageIndex === index;\n\nconst isEditableMessage = (item) => editEverythingMode || item.person == USER;\n\nconst styleMessage = (item, index) => {\n const rowClass = item.person == USER ? \"flex-row-reverse\" : \"\";\n let textContainerClass = item.person != USER ? \"ms-3\" : \"me-3\";\n let textClass =\n item.person != USER ? \"dialog-system-message\" : \"dialog-user-message\";\n\n return (\n <div class={`d-flex flex-row ${getMessageClass(item)} ${rowClass}`}>\n <img src={user_pics[item.person]} width=\"45\" class=\"h-100\" />\n <div class={`d-flex flex-row ${textContainerClass}`}>\n <div\n class={`small my-auto p-2 rounded-3 ${textClass}`}\n role={item.person == AI ? \"button\" : \"\"}\n onClick={() => {\n if (item.person == AI) {\n onSpecClick(index);\n }\n }}\n >\n {getMessage(item, index)}\n </div>\n {isEditableMessage(item) && (\n <div\n class=\"my-auto ps-1\"\n role=\"button\"\n onClick={() => {\n State.update({\n editMessageText: isExitEditMode(index)\n ? null\n : getMessageText(item),\n editMessageIndex: isExitEditMode(index) ? null : index,\n editSpecIndex: index,\n showSpecEditor: !isExitEditMode(index),\n });\n }}\n >\n {editIcon}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nconst codeDiff = (old_code, new_code) => {\n let newVal;\n let result = [];\n let codes = [old_code, new_code];\n let allLiness = [[], []];\n let liness = [[], []];\n let h = [[], []];\n for (let i = 0; i < 2; ++i) {\n allLiness[i] = codes[i].split(\"\\n\");\n }\n\n let left = 0;\n let right = 0;\n let l1 = allLiness[0].length;\n let l2 = allLiness[1].length;\n while (\n left < l1 &&\n left < l2 &&\n allLiness[0][left].trim() == allLiness[1][left].trim()\n ) {\n ++left;\n }\n while (\n left + right < l1 &&\n left + right < l2 &&\n allLiness[0][l1 - right - 1].trim() == allLiness[1][l2 - right - 1].trim()\n ) {\n ++right;\n }\n if (left == Math.min(l1, l2)) {\n result.push(\"/* no code changes */\");\n return result;\n }\n for (let i = left; i < l1 - right; ++i) {\n liness[0].push(allLiness[0][i]);\n }\n for (let i = left; i < l2 - right; ++i) {\n liness[1].push(allLiness[1][i]);\n }\n\n let dp = [];\n for (let j = 0; j < liness[1].length; ++j) {\n h[1].push(1);\n }\n\n for (let i = 0; i < liness[0].length; ++i) {\n h[0].push(1);\n dp.push([]);\n for (let j = 0; j < liness[1].length; ++j) {\n let val = 0;\n if (i && dp[i - 1][j] > val) {\n val = dp[i - 1][j];\n }\n if (j && dp[i][j - 1] > val) {\n val = dp[i][j - 1];\n }\n if (liness[0][i].trim() == liness[1][j].trim()) {\n if (i && j) newVal = dp[i - 1][j - 1] + 1;\n else newVal = 1;\n if (newVal > val) val = newVal;\n }\n dp[i].push(val);\n }\n }\n\n let i = liness[0].length - 1;\n let j = liness[1].length - 1;\n while (i >= 0 && j >= 0) {\n if (\n liness[0][i].trim() == liness[1][j].trim() &&\n ((i && j && dp[i][j] == dp[i - 1][j - 1] + 1) ||\n ((!i || !j) && dp[i][j] == 1))\n ) {\n h[0][i] = 0;\n h[1][j] = 0;\n --i;\n --j;\n } else if (i && dp[i][j] == dp[i - 1][j]) --i;\n else --j;\n }\n\n if (left > 3) {\n result.push(\"...\\n\");\n }\n\n for (let i = Math.max(0, left - 3); i < left; ++i) {\n result.push(allLiness[0][i] + \"\\n\");\n }\n\n let bgColors = [\"#FFD0D0\", \"#D0FFD0\"];\n let ord1 = 0;\n let ord2 = 0;\n while (ord1 < liness[0].length || ord2 < liness[1].length) {\n if (ord1 < liness[0].length && h[0][ord1]) {\n result.push([liness[0][ord1] + \"\\n\", bgColors[0]]);\n ++ord1;\n } else if (ord2 < liness[1].length && h[1][ord2]) {\n result.push([liness[1][ord2] + \"\\n\", bgColors[1]]);\n ++ord2;\n } else {\n result.push(liness[1][ord2] + \"\\n\");\n ++ord1;\n ++ord2;\n }\n }\n\n for (let i = right - 1; i >= Math.max(right - 3, 0); --i) {\n result.push(allLiness[0][l1 - i - 1] + \"\\n\");\n }\n\n if (right > 3) {\n result.push(\"...\\n\");\n }\n\n return result;\n};\n\nconst isShowSpecEditor = () => {\n return editEverythingMode && state.showSpecEditor;\n};\n\nconst onAuth = (data) => {\n console.log(\"onAuth\", data);\n Storage.privateSet(SESSION_KEY, data.session_id);\n State.update({\n sessionId: data.session_id,\n isSessionValid: data.is_session_valid,\n resetSession: false,\n pendingAuth: false,\n });\n};\n\nconst loadDefaultPrompts = () => {\n if (state?.promptsUnlocked && !getArray(state.defaultPrompts).length) {\n setPendingRequest(true);\n asyncFetch(`${apiUrl}/admin/get_prompts/`, {\n method: \"POST\",\n body: JSON.stringify({\n account_id: context.accountId,\n session_id: sessionId,\n }),\n }).then((res) => {\n if (res.ok) {\n // returns {is_session_valid, prompts?}\n onRequest(res.body);\n\n const defaultPrompts = getArray(res.body.prompts);\n if (defaultPrompts.length) {\n const newState = state;\n newState.promptTabIndex = state.promptTabIndex ?? 0;\n newState.defaultPrompts = defaultPrompts;\n if (!getArray(state.userPrompts).length) {\n newState.userPrompts = defaultPrompts;\n }\n State.update(newState);\n updateUserPromptsInLocalStorage();\n }\n }\n\n console.log(\"get_prompts resp\", res.ok, res.body);\n setPendingRequest(false);\n });\n }\n};\n\nlet storage = Storage.privateGet(storageKey) ?? {};\n\nconsole.log(\"storage\", storage);\n\nif (\n storage?.promptsUnlocked &&\n state?.promptsUnlocked != storage?.promptsUnlocked\n) {\n State.update({\n promptsUnlocked: storage.promptsUnlocked,\n userPrompts: storage.userPrompts,\n });\n loadDefaultPrompts();\n}\n\nconst updateUserPromptsInLocalStorage = () => {\n storage.userPrompts = state.userPrompts;\n storage.promptsUnlocked = state.promptsUnlocked;\n console.log(\"storage update\", storage);\n Storage.privateSet(storageKey, storage);\n};\n\nconst avatarOnClick = () => {\n if (!state?.promptsUnlocked) {\n let promptsUnlocked = false;\n let showPromptsEditor = state.showPromptsEditor;\n let clickTimes = state?.clickTimes ?? [];\n const currentTime = Date.now();\n clickTimes.push(currentTime);\n\n while (clickTimes.length && currentTime - clickTimes[0] > 1000) {\n clickTimes.shift();\n }\n\n if (clickTimes.length >= 3) {\n promptsUnlocked = true;\n showPromptsEditor = true;\n }\n\n console.log(\"clickTimes\", clickTimes);\n\n State.update({\n promptsUnlocked,\n showPromptsEditor,\n clickTimes,\n });\n\n loadDefaultPrompts();\n }\n};\n\nconst ATTACH_CONVERSATION_TAB_INDEX = 5;\n\nconst getPromptsContainer = () => {\n if (state.promptsUnlocked && getArray(state.defaultPrompts).length) {\n const promptHeaders = [\n \"Message Before Specs\",\n \"Specs Before Specs\",\n \"Message After Specs\",\n \"Specs After Specs\",\n ];\n return (\n <div>\n <div class=\"card-header justify-content-between align-items-left pb-0\">\n <h4 class=\"mb-2\">\n Prompts editor{\" \"}\n <button\n class=\"small badge bg-secondary p-2\"\n onClick={() => {\n State.update({\n showPromptsEditor: false,\n });\n }}\n >\n Hide\n </button>\n </h4>\n <ul class=\"nav nav-tabs\">\n {promptHeaders.map((header, index) => {\n return (\n <li class=\"nav-item\">\n <a\n class={`nav-link ${\n state.promptTabIndex == index ? \"active\" : \"\"\n }`}\n href=\"#\"\n onClick={() => {\n State.update({ promptTabIndex: index });\n }}\n >\n {header}\n </a>\n </li>\n );\n })}\n\n <li class=\"nav-item\">\n <a\n class={`nav-link ${\n state.promptTabIndex == ATTACH_CONVERSATION_TAB_INDEX\n ? \"active\"\n : \"\"\n }`}\n href=\"#\"\n onClick={() => {\n State.update({\n promptTabIndex: ATTACH_CONVERSATION_TAB_INDEX,\n });\n }}\n >\n Attach conversation\n </a>\n </li>\n </ul>\n </div>\n <div class=\"card-body main-container w-100 h-100 ps-2 mb-4 pt-2 flex-row align-text-top\">\n {state.promptTabIndex === ATTACH_CONVERSATION_TAB_INDEX && (\n <div style={{ height: \"250px\" }} class=\"mt-2\">\n <div class=\"form-check form-switch\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"mySwitch\"\n name=\"darkmode\"\n value=\"yes\"\n onChange={(e) =>\n State.update({ attachConversation: e.target.checked })\n }\n checked={state.attachConversation}\n />\n <label class=\"form-check-label\" for=\"mySwitch\">\n {\" \"}\n Attach conversation using API\n </label>\n </div>\n\n {!state.attachConversation && (\n <Markdown text=\"Do not attach conversation, use {{ history }} instead\" />\n )}\n </div>\n )}\n {state.promptTabIndex !== ATTACH_CONVERSATION_TAB_INDEX && (\n <>\n <h5 class=\"mt-2 mb-2\">System prompt:</h5>\n <textarea\n style={{ height: \"250px\" }}\n class=\"form-control mb-2 flex-grow-1\"\n onChange={(e) => {\n let userPrompts = getArray(state.userPrompts);\n userPrompts[state.promptTabIndex] = e.target.value;\n State.update({\n userPrompts,\n });\n }}\n value={state.userPrompts[state.promptTabIndex]}\n />\n\n {state.defaultPrompts[state.promptTabIndex].trim() !=\n state.userPrompts[state.promptTabIndex].trim() && (\n <div>\n <h5 class=\"mt-2 mb-2\">Default prompt:</h5>\n <textarea\n style={{ height: \"250px\" }}\n disabled\n class=\"form-control mb-2 flex-grow-1\"\n value={state.defaultPrompts[state.promptTabIndex]}\n />\n </div>\n )}\n\n <div>\n <button\n class=\"btn btn-success mb-2\"\n onClick={() => updateUserPromptsInLocalStorage()}\n >\n Update prompts\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n }\n};\n\nreturn (\n <Theme class=\"d-block main-container h-100\">\n {state.promptsUnlocked && state.showPromptsEditor && getPromptsContainer()}\n <div class=\"row\" style={{ height: \"38px\" }}>\n <div class=\"col\">\n <h4>Task Spec {isShowSpecEditor() ? \"Editor\" : \"\"}</h4>\n </div>\n {state.promptsUnlocked && (\n <div class=\"col w-100 text-end\">\n <button\n class=\"small badge bg-secondary p-2\"\n onClick={() => {\n State.update({\n showPromptsEditor: true,\n });\n }}\n >\n Prompts Editor\n </button>\n </div>\n )}\n </div>\n <div class=\"extension-container h-100 d-flex gap-1\">\n <div\n class=\"container markdown-container col-md-6 h-10 position-relative\"\n id=\"container-markdown\"\n >\n {editEverythingMode && (\n <div class=\"position-absolute top-0 end-0 mt-3 me-3\">\n <button\n class=\"small badge bg-secondary p-2\"\n onClick={() => {\n State.update({\n showSpecEditor: !state.showSpecEditor,\n editMessageIndex: state.editSpecIndex,\n editMessageText: state.chat[state.editSpecIndex].message,\n });\n }}\n >\n {state.showSpecEditor ? \"Render\" : \"Edit\"} spec\n </button>\n </div>\n )}\n\n {!isShowSpecEditor() && (\n <div class=\" markdown-render\">\n <Markdown class=\"card h-100\" text={state.spec} />\n </div>\n )}\n {isShowSpecEditor() && (\n <textarea\n class=\"markdown-textarea h-100 w-100\"\n onChange={(e) => {\n State.update({ spec: e.target.value });\n }}\n value={state.spec}\n />\n )}\n </div>\n <div class=\"container chat-container col-md-6 h-100\" id=\"container-main\">\n <div class=\"row d-flex justify-content-center h-100\">\n <div class=\"h-100\">\n <div class=\"card h-100\" id=\"chat\">\n <div\n class=\"card-header d-flex justify-content-between align-items-center pb-0\"\n id=\"chat-header\"\n >\n <ul class=\"nav nav-tabs top-nav-item\">\n <li class=\"nav-item top-nav-item\" id=\"top-nav-dialog\">\n <a\n class=\"nav-link link-underline-opacity-25 active\"\n role=\"button\"\n id=\"nav-dialog\"\n aria-current=\"page\"\n >\n <h5 class=\"mb-0\">Chat</h5>\n </a>\n </li>\n <li class=\"nav-item top-nav-item hidden\" id=\"top-nav-run\">\n <a class=\"nav-link\" id=\"nav-run\">\n <h5 class=\"mb-0\">▶️ Run</h5>\n </a>\n </li>\n <li class=\"nav-item top-nav-item hidden\" id=\"top-nav-account\">\n <a class=\"nav-link\" id=\"nav-account\">\n <h5 class=\"mb-0\">Account</h5>\n </a>\n </li>\n <li class=\"nav-item top-nav-item hidden\" id=\"top-nav-login\">\n <a class=\"nav-link\" id=\"nav-login\">\n <h5 class=\"mb-0\">Login</h5>\n </a>\n </li>\n </ul>\n <div id=\"account-details\" class=\"hidden\">\n <div class=\"d-inline-block align-top\">\n <div class=\"navbar navbar-light navbar-menu btn-group dropstart\">\n <div class=\"dropdown\" id=\"menu-dropdown\">\n <span\n class=\"navbar-toggler-icon\"\n role=\"button\"\n id=\"dropdown-menu-link\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n ></span>\n\n <ul\n class=\"dropdown-menu\"\n id=\"menu-dropdown-list\"\n aria-labelledby=\"dropdown-menu-link\"\n >\n <li>\n <a\n class=\"dropdown-item\"\n href=\"#\"\n id=\"refresh-button\"\n >\n Refresh\n </a>\n </li>\n <li id=\"menu-load-examples\">\n <a\n class=\"dropdown-item\"\n href=\"#\"\n onClick=\"return loadExamples()\"\n >\n Load Examples\n </a>\n </li>\n <li>\n <a\n class=\"dropdown-item\"\n href=\"#\"\n id=\"sign-out-button\"\n >\n Sign Out\n </a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"card-body main-container main-container-review hidden\"\n id=\"container-account\"\n data-mdb-perfect-scrollbar=\"true\"\n >\n <div class=\"alert alert-warning\" role=\"alert\">\n Account not found. Enter your invite code to proceed.\n </div>\n <div class=\"mb-3\">\n <label for=\"user-invite\" class=\"form-label\">\n Invite code\n </label>\n <input\n type=\"text\"\n class=\"form-control\"\n id=\"user-invite\"\n value=\"\"\n placeholder=\"InviteCode\"\n />\n </div>\n <div\n class=\"alert alert-danger\"\n role=\"alert\"\n id=\"user-invite-error\"\n ></div>\n <div>\n <a\n class=\"btn btn-primary mb-3\"\n onClick=\"return submitInviteCode();\"\n >\n Submit\n </a>\n </div>\n </div>\n <div\n class=\"card-body main-container main-container-review hidden\"\n id=\"container-login\"\n data-mdb-perfect-scrollbar=\"true\"\n >\n <div class=\"alert alert-warning\" role=\"alert\">\n Login with NEAR Account please\n </div>\n <div id=\"login\" class=\"hidden\">\n <input\n type=\"button\"\n class=\"btn btn-primary btn\"\n data-mdb-ripple-color=\"dark\"\n value=\"Login\"\n id=\"login-button\"\n />\n <input\n type=\"button\"\n class=\"btn btn-primary btn hidden\"\n data-mdb-ripple-color=\"dark\"\n value=\"Confirm Login\"\n id=\"confirm-login-button\"\n />\n </div>\n\n <hr />\n <div>Don't have an account yet?</div>\n <div>\n <a\n class=\"btn btn-primary btn-sm mb-3\"\n href=\"https://wallet.near.org/create\"\n >\n Create\n </a>\n </div>\n </div>\n <div\n id=\"container-run\"\n class=\"card-body main-container main-container-review hidden\"\n data-mdb-perfect-scrollbar=\"true\"\n >\n <div class=\"container\">\n <div class=\"row align-items-start h-100\">\n <div class=\"col h-100 run-column ps-0 pe-1\">\n <div class=\"form-floating h-100\">\n <textarea\n class=\"form-control tests-textarea\"\n id=\"tests-inputs\"\n ></textarea>\n <label for=\"tests-inputs\">Input values</label>\n </div>\n </div>\n <div class=\"col hidden h-100\">\n <div class=\"form-floating h-100\">\n <textarea\n class=\"form-control tests-textarea\"\n id=\"tests-outputs\"\n ></textarea>\n <label for=\"tests-outputs\">\n Expected output values\n </label>\n </div>\n </div>\n <div class=\"col h-100 run-column pe-0 ps-1\">\n <div\n class=\"form-floating h-100\"\n id=\"real-output-container\"\n >\n <div\n class=\"form-control tests-textarea real-output\"\n readonly\n id=\"real-output\"\n ></div>\n <div\n class=\"output-popup-button quote disabled\"\n id=\"button-quote-selected-output\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"left\"\n title=\"Quote text from the output screen and include it in your next reply in the dialog\"\n oncontextmenu=\"return false;\"\n >\n <div>”</div>\n </div>\n <div\n class=\"output-popup-button clear disabled\"\n id=\"button-clear-output-qoutes\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"left\"\n title=\"Clear quotes\"\n oncontextmenu=\"return false;\"\n >\n <div>x</div>\n </div>\n <label for=\"real-output\">Output</label>\n </div>\n </div>\n </div>\n <div class=\"row align-items-start mt-2\">\n <div class=\"col\">\n <div class=\"row align-items-start h-100\">\n <div class=\"col h-100 run-column ps-0 pe-1\">\n <div class=\"btn-group\">\n <button\n type=\"button\"\n class=\"btn btn-success long-text-button\"\n id=\"button-run\"\n >\n Run\n </button>\n <button\n type=\"button\"\n class=\"btn btn-success dropdown-toggle dropdown-toggle-split\"\n data-bs-toggle=\"dropdown\"\n id=\"button-run-dropdown-toggle\"\n >\n <span class=\"visually-hidden\">\n Toggle Dropdown\n </span>\n </button>\n\n <div\n class=\"dropdown-menu\"\n id=\"button-run-dropdown-menu\"\n >\n <a\n href=\"#\"\n class=\"dropdown-item\"\n id=\"run-editor-code\"\n >\n Run code from the editor\n </a>\n <a\n href=\"#\"\n class=\"dropdown-item\"\n id=\"run-last-message-code\"\n >\n Run code from the last message\n </a>\n </div>\n </div>\n </div>\n <div class=\"col h-100 run-column pe-0 ps-1\">\n <button\n type=\"button\"\n class=\"btn btn-info disabled\"\n id=\"button-save-output\"\n title=\"Save the output to dialog to assist reviewers\"\n >\n Save output\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"card-body main-container main-container-review\"\n id=\"container-dialog\"\n data-mdb-perfect-scrollbar=\"true\"\n >\n <div\n class=\"task-header-container hidden\"\n id=\"current-task-header-container\"\n >\n <div class=\"task-header\" id=\"current-task-header\"></div>\n <div\n class=\"task-header-content\"\n id=\"current-task-header-content\"\n ></div>\n <div\n class=\"review-reclaim-interval\"\n id=\"review-reclaim-interval\"\n ></div>\n </div>\n <div id=\"user-chat\">\n {getArray(state.chat).map((item, index) => (\n <div class=\"mb-3\">\n {styleMessage(item, index)}\n {getMessageDiff(item, index)}\n </div>\n ))}\n <a name=\"chat-end\"></a>\n </div>\n </div>\n <div class=\"gutter gutter-vertical\" id=\"gutter-vertical\"></div>\n <div\n class=\"card-footer text-muted d-flex justify-content-start align-items-start p-2\"\n id=\"container-footer\"\n >\n <div class=\"align-top\" onClick={() => avatarOnClick()}>\n <img\n src={user_pics[USER]}\n width=\"40\"\n height=\"40\"\n class=\"mr-2\"\n />\n </div>\n\n <div class=\"task-reply-options align-items-center h-100 hidden\">\n <textarea\n class=\"form-control form-control-lg h-100\"\n id=\"task-user-input-textbox\"\n rows=\"1\"\n ></textarea>\n\n <div class=\"dropdown ms-2\" id=\"main-types-dropdown-menu\">\n <button\n id=\"message-type-dropdown\"\n class=\"btn btn-sm btn-secondary dropdown-toggle p2\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n >\n Type\n </button>\n <ul class=\"dropdown-menu\">\n <li>\n <a class=\"dropdown-item\" href=\"#\">\n Answer\n </a>\n </li>\n <li>\n <a class=\"dropdown-item\" href=\"#\">\n Thoughts\n </a>\n </li>\n </ul>\n </div>\n\n <a class=\"ms-2\" href=\"#\">\n <input\n type=\"button\"\n value=\"Send\"\n id=\"send-button\"\n class=\"btn btn-primary btn-sm p-2\"\n data-mdb-ripple-color=\"dark\"\n />\n </a>\n </div>\n\n <div class=\"review-reply-options align-items-center h-100 hidden\">\n <textarea\n class=\"form-control form-control-lg h-100\"\n id=\"review-user-input-textarea\"\n rows=\"1\"\n ></textarea>\n\n <a class=\"ms-2\" href=\"\">\n <input\n type=\"button\"\n value=\"Accept\"\n id=\"review-accept-button\"\n class=\"btn btn-success btn-sm footer-action-button h-100\"\n data-mdb-ripple-color=\"dark\"\n />\n </a>\n\n <a class=\"ms-2\" href=\"\">\n <input\n type=\"button\"\n value=\"Reject\"\n id=\"review-reject-button\"\n class=\"btn btn-danger btn-sm footer-action-button h-100\"\n data-mdb-ripple-color=\"dark\"\n />\n </a>\n </div>\n\n {/* chat send */}\n <div class=\"example-reply-options h-100 ps-2 d-flex flex-row align-text-top\">\n <textarea\n class=\"form-control h-100 flex-grow-1\"\n id=\"example-user-input-textarea\"\n onChange={(e) => {\n State.update({ userMessage: e.target.value });\n }}\n onKeyPress={(e) => {\n if (e.ctrlKey && e.key === \"Enter\") {\n AddUserMessage();\n }\n }}\n value={state.userMessage}\n rows=\"1\"\n ></textarea>\n\n <div class=\"ms-2\">\n <a\n type=\"button\"\n value=\"\"\n id=\"example-send-button\"\n onClick={(e) => AddUserMessage()}\n class=\"btn btn-success btn-sm footer-action-button h-100 text-white\"\n data-mdb-ripple-color=\"dark\"\n href=\"#chat-end\"\n >\n Send\n </a>\n </div>\n </div>\n\n <div class=\"resubmit-rejected-options h-100 w-100 justify-content-center hidden\">\n <a class=\"ms-2\" href=\"#\">\n <input\n type=\"button\"\n value=\"Continue working\"\n id=\"restart-rejected-task-button\"\n class=\"btn btn-success btn-sm footer-action-button h-100\"\n data-mdb-ripple-color=\"dark\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"top\"\n title=\"You will restart this task to update/remove existing messages and fix review issues\"\n />\n </a>\n\n <a class=\"ms-2\" href=\"#\">\n <input\n type=\"button\"\n value=\"Abandon and request new task\"\n id=\"abandon-rejected-task-button\"\n class=\"btn btn-danger btn-sm footer-action-button h-100\"\n data-mdb-ripple-color=\"dark\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"top\"\n title=\"Forget this task\"\n />\n </a>\n </div>\n </div>\n </div>\n\n <div\n class=\"text-center hidden bottom-controls\"\n id=\"bottom-controls\"\n >\n <div class=\"d-flex justify-content-center pt-1\">\n <div id=\"code-filename\" class=\"code-filename\"></div>\n <select\n id=\"select-code-filename\"\n class=\"select-code-filename hidden\"\n ></select>\n <button\n class=\"small ms-2 badge bg-secondary hidden\"\n id=\"confirm-update-current-filename\"\n >\n Confirm\n </button>\n <button\n class=\"small ms-2 badge bg-secondary hidden\"\n id=\"cancel-update-current-filename\"\n >\n Cancel\n </button>\n <button\n class=\"small ms-2 badge bg-secondary\"\n id=\"update-current-filename\"\n >\n Update file\n </button>\n <button\n class=\"small ms-2 badge bg-success hidden\"\n id=\"submit-button\"\n data-mdb-ripple-color=\"dark\"\n >\n Submit\n </button>\n <button\n class=\"small ms-2 badge bg-success hidden\"\n id=\"skip-task-button\"\n data-mdb-ripple-color=\"dark\"\n >\n Skip\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </Theme>\n);\n" } } } } }

Transaction Execution Plan

Convert Transaction To Receipt
Gas Burned:
408 Ggas
Tokens Burned:
0.00004 
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
11 Tgas
Tokens Burned:
0.00113 
Called method: 'set' in contract: social.near
Arguments:
{ "data": { "dev.near": { "widget": { "op-task": { "": "const USER = \"user\";\nconst AI = \"ai\";\nconst CHAT_DIRECT = \"direct\";\nconst CHAT_REVERSED = \"reversed\";\nconst ACCOUNT_ID = \"fakeaccount.testnet\";\nconst API_URL = \"https://annotation.nearspace.info/api\";\nconst PROBLEM_ID = 1;\nconst STATUS_ANNOTATION_PENDING = 0;\nconst STORAGE_KEY = `task_storage`;\n\nconst editEverythingMode = true;\n\nconst editIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"svg-icon\"\n width=\"20px\"\n height=\"20px\"\n verticalAlign=\"middle\"\n fill=\"darkgrey\"\n viewBox=\"0 0 1024 1024\"\n version=\"1.1\"\n >\n <path d=\"M834.3 705.7c0 82.2-66.8 149-149 149H325.9c-82.2 0-149-66.8-149-149V346.4c0-82.2 66.8-149 149-149h129.8v-42.7H325.9c-105.7 0-191.7 86-191.7 191.7v359.3c0 105.7 86 191.7 191.7 191.7h359.3c105.7 0 191.7-86 191.7-191.7V575.9h-42.7v129.8z\" />\n <path d=\"M889.7 163.4c-22.9-22.9-53-34.4-83.1-34.4s-60.1 11.5-83.1 34.4L312 574.9c-16.9 16.9-27.9 38.8-31.2 62.5l-19 132.8c-1.6 11.4 7.3 21.3 18.4 21.3 0.9 0 1.8-0.1 2.7-0.2l132.8-19c23.7-3.4 45.6-14.3 62.5-31.2l411.5-411.5c45.9-45.9 45.9-120.3 0-166.2zM362 585.3L710.3 237 816 342.8 467.8 691.1 362 585.3zM409.7 730l-101.1 14.4L323 643.3c1.4-9.5 4.8-18.7 9.9-26.7L436.3 720c-8 5.2-17.1 8.7-26.6 10z m449.8-430.7l-13.3 13.3-105.7-105.8 13.3-13.3c14.1-14.1 32.9-21.9 52.9-21.9s38.8 7.8 52.9 21.9c29.1 29.2 29.1 76.7-0.1 105.8z\" />\n </svg>\n);\n\n/* duplicated css for debug. Loads in parent too */\nconst CSS_URL =\n \"https://gist.githubusercontent.com/zavodil/10ed1d07c893e04571332f1cb2408226/raw/8bad3b0836bec04845cdbaa78bbad771a48a23f7/add.style.css\";\nconst css = fetch(CSS_URL).body;\nif (!css) return \"\";\n\nState.init({\n attachConversation: true,\n theme: styled.div`${css}`,\n});\n\nconst {\n apiUrl,\n sessionId,\n annotationId,\n problemId,\n pendingRequest,\n setPendingRequest,\n onRequest,\n} = props;\nconst storageKey = props.storageKey ?? STORAGE_KEY;\n\nif (typeof setPendingRequest !== \"function\") {\n setPendingRequest = (data) => console.log(\"setPendingRequest\", data);\n}\n\nif (typeof onRequest !== \"function\") {\n onRequest = (data) => console.log(\"onRequest\", data);\n}\n\nif (!annotationId) {\n return \"No data\";\n}\n\nif (state.currentAnnotationId && state.currentAnnotationId != annotationId) {\n State.update({\n currentAnnotationId: null,\n taskLoaded: false,\n taskLoading: false,\n });\n}\n\nconst getCurrentState = () => {\n return {\n user_message: state.userMessage,\n spec: state.spec,\n };\n};\n\nconst saveChat = (isNewMessage, onSaveChat) => {\n setPendingRequest(true);\n asyncFetch(`${apiUrl}/submit_annotation/`, {\n method: \"POST\",\n body: JSON.stringify({\n id: annotationId,\n content: JSON.stringify(state.chat),\n current_state: JSON.stringify(getCurrentState()),\n account_id: context.accountId,\n session_id: sessionId,\n problem_id: problemId,\n prompts: getArray(state.userPrompts),\n attach_conversation: state?.attach_conversation ?? true,\n is_new_message: isNewMessage,\n }),\n }).then((res) => {\n if (res.ok) {\n // returns {is_session_valid, annotation_id?}\n onRequest(res.body);\n }\n\n if (typeof onSaveChat == \"function\") {\n onSaveChat(res);\n }\n\n console.log(\"request_annotation resp\", res.ok, res.body);\n setPendingRequest(false);\n });\n};\n\nconst getArray = (items) => (Array.isArray(items) ? items : []);\n\nlet getTaskData = () => {\n setPendingRequest(true);\n asyncFetch(`${apiUrl}/get_annotation_by_id/`, {\n method: \"POST\",\n\n body: JSON.stringify({\n annotation_id: annotationId,\n account_id: context.accountId,\n session_id: sessionId,\n problem_id: problemId,\n }),\n }).then((res) => {\n if (res.ok) {\n console.log(\"request_annotation_by_id\", sessionId, res);\n if (res.body.is_session_valid) {\n let task = res.body.task;\n let currentState = JSON.parse(task.current_state);\n let chat = JSON.parse(task.content);\n const lastAIReply = getLastReplyFromAI(chat.length + 1, chat);\n State.update({\n currentAnnotationId: annotationId,\n taskLoading: false,\n taskLoaded: true,\n chat: getArray(chat),\n spec: lastAIReply?.spec ?? \"\",\n editSpecIndex: lastAIReply?.index ?? 0,\n userMessage: currentState.user_message,\n });\n }\n // returns {is_session_valid, task}\n onRequest(res.body);\n }\n console.log(\"request_annotation_by_id resp\", res.ok, res.body);\n setPendingRequest(false);\n });\n};\n\nif (!state.taskLoaded && !state.taskLoading && !pendingRequest) {\n State.update({ taskLoading: true });\n console.log(\"getTaskData\", state);\n getTaskData();\n}\n\nconst user_pics = {\n [USER]:\n \"https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-chat/ava4-bg.webp\",\n [AI]: \"https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-chat/ava3-bg.webp\",\n};\nconst LOCAL_BACKUP_KEY = \"backup\";\n\nconst spec = `I'm a spec\n\nI'm using [markdown](https://www.markdownguide.org/basic-syntax/), and have some ***nice stuff*** here, like:\n\n- lists\n- with multiple items\n\nOr maybe even images ![image](https://near.org/_next/static/media/near-logo.1416a213.svg \"title\")`;\n\nconst chat = [\n {\n person: USER,\n message: \"How to make an AMM?\",\n },\n {\n person: AI,\n message: \"\",\n spec: spec,\n },\n {\n person: USER,\n message: \"Format the header\",\n },\n {\n person: AI,\n message: \"Format complete\",\n spec: `## ${spec}`,\n },\n];\n\nconst Theme = state.theme;\n\nconst getPreviousSpecFromAI = (index, chat) => {\n return getLastReplyFromAI(index, chat)?.spec ?? \"\";\n};\n\nconst getLastReplyFromAI = (index, chat) => {\n let item = null;\n for (let i = index - 1; i > 0; i--) {\n if (chat[i].person == AI) {\n item = chat[i];\n item.index = i;\n break;\n }\n }\n\n return item;\n};\n\nconst AddUserMessage = () => {\n if (state.userMessage) {\n if (state.userMessage == \"/clear\") {\n resetBackup();\n } else {\n let chat = getArray(state.chat);\n chat.push({\n person: USER,\n spec: state.spec,\n message: state.userMessage,\n });\n let newState = { chat, userMessage: \"\" };\n\n State.update(newState);\n saveChat(true, (res) => {\n console.log(\"onSaveChat\", res);\n if (res.ok && res.body.is_session_valid) {\n let ai_response = res.body.ai_response;\n if (ai_response?.person == AI) {\n console.log(\"ai_response\", ai_response, state);\n const chat = getArray(state.chat);\n chat.push(ai_response);\n State.update({\n chat,\n spec: ai_response.spec,\n editSpecIndex: chat.length,\n });\n console.log(\"ai_response state\", state);\n }\n }\n });\n }\n }\n};\n\nconst getMessage = (item, index) => {\n if (state.editMessageIndex === index) {\n return (\n <div class=\"text-end\">\n <div>\n <textarea\n class=\"form-control mb-1\"\n style={{ minWidth: \"400px\" }}\n value={state.editMessageText}\n onChange={(e) => State.update({ editMessageText: e.target.value })}\n />\n </div>\n <div>\n <button\n class=\"small ms-2 badge bg-secondary p-2\"\n onClick={() => {\n let chat = state.chat;\n let item = state.chat[index];\n item.spec = state.spec;\n item.message = state.editMessageText;\n chat[index] = item;\n State.update({\n chat,\n editMessageIndex: null,\n editMessageText: null,\n });\n saveChat(false, () => {\n console.log(\"Message updated\");\n });\n }}\n >\n {item.person == USER ? \"Update\" : \"Update spec + text\"}\n </button>\n </div>\n </div>\n );\n } else {\n return <div style={{ whiteSpace: \"pre-wrap\" }}>{getMessageText(item)}</div>;\n }\n};\n\nconst getMessageText = (item) => {\n if (!item.message && item.person == AI) {\n const isInitialMessage = !getPreviousSpecFromAI(index, state.chat);\n if (isInitialMessage) {\n return getInitialSpecMessage();\n }\n }\n return item.message;\n};\n\nconst getNextMessageFromAI = (index) => {\n let nextSpecMessage = \"\";\n for (let i = index + 1; i <= state.chat.length; i++) {\n if (state.chat[i].person == AI) {\n nextSpecMessage = state.chat[i].message;\n break;\n }\n }\n\n return nextSpecMessage;\n};\n\nconst isSpecExists = (spec) => spec != \"\" && spec != \"N/A\";\n\nconst getMessageDiff = (item, index) => {\n if (item.person == AI) {\n let prevSpec = getPreviousSpecFromAI(index, state.chat);\n\n if (isSpecExists(prevSpec)) {\n let diffs = codeDiff(prevSpec, item.spec);\n console.log(\"diffs\", diffs);\n let diffContents = (diffs ?? [])\n .filter((line) => line != \"\\n\")\n .map((line) => {\n if (Array.isArray(line)) {\n return (\n <div class=\"p-1\" style={{ backgroundColor: line[1] }}>\n {line[0]}\n </div>\n );\n } else {\n return <div class=\"p-0\">{line}</div>;\n }\n });\n\n return (\n <div\n class={`mt-1 small code-diff rounded-3 ${getMessageDiffClass(item)}`}\n >\n {diffContents}\n </div>\n );\n }\n }\n\n return <></>;\n};\n\nconst onSpecClick = (index) => {\n let newState = { spec: state.chat[index].spec };\n\n newState.editSpecIndex = index;\n\n State.update(newState);\n};\n\nconst setShowSpecEditor = (isShow) => {\n State.update({\n showSpecEditor: isShow,\n });\n};\n\nconst getInitialSpecMessage = () => {\n return \"Initial spec\";\n};\n\nconst getMessageDiffClass = (item) => {\n return item.person != USER ? \"code-diff-start\" : \"pt-1 code-diff-end\";\n};\n\nconst getMessageClass = (item) => {\n return item.person != USER ? \"pt-2 me-1\" : \"pt-2 ms-1\";\n};\n\nconst isExitEditMode = (index) => state.editMessageIndex === index;\n\nconst isEditableMessage = (item) => editEverythingMode || item.person == USER;\n\nconst styleMessage = (item, index) => {\n const rowClass = item.person == USER ? \"flex-row-reverse\" : \"\";\n let textContainerClass = item.person != USER ? \"ms-3\" : \"me-3\";\n let textClass =\n item.person != USER ? \"dialog-system-message\" : \"dialog-user-message\";\n\n return (\n <div class={`d-flex flex-row ${getMessageClass(item)} ${rowClass}`}>\n <img src={user_pics[item.person]} width=\"45\" class=\"h-100\" />\n <div class={`d-flex flex-row ${textContainerClass}`}>\n <div\n class={`small my-auto p-2 rounded-3 ${textClass}`}\n role={item.person == AI ? \"button\" : \"\"}\n onClick={() => {\n if (item.person == AI) {\n onSpecClick(index);\n }\n }}\n >\n {getMessage(item, index)}\n </div>\n {isEditableMessage(item) && (\n <div\n class=\"my-auto ps-1\"\n role=\"button\"\n onClick={() => {\n State.update({\n editMessageText: isExitEditMode(index)\n ? null\n : getMessageText(item),\n editMessageIndex: isExitEditMode(index) ? null : index,\n editSpecIndex: index,\n showSpecEditor: !isExitEditMode(index),\n });\n }}\n >\n {editIcon}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nconst codeDiff = (old_code, new_code) => {\n let newVal;\n let result = [];\n let codes = [old_code, new_code];\n let allLiness = [[], []];\n let liness = [[], []];\n let h = [[], []];\n for (let i = 0; i < 2; ++i) {\n allLiness[i] = codes[i].split(\"\\n\");\n }\n\n let left = 0;\n let right = 0;\n let l1 = allLiness[0].length;\n let l2 = allLiness[1].length;\n while (\n left < l1 &&\n left < l2 &&\n allLiness[0][left].trim() == allLiness[1][left].trim()\n ) {\n ++left;\n }\n while (\n left + right < l1 &&\n left + right < l2 &&\n allLiness[0][l1 - right - 1].trim() == allLiness[1][l2 - right - 1].trim()\n ) {\n ++right;\n }\n if (left == Math.min(l1, l2)) {\n result.push(\"/* no code changes */\");\n return result;\n }\n for (let i = left; i < l1 - right; ++i) {\n liness[0].push(allLiness[0][i]);\n }\n for (let i = left; i < l2 - right; ++i) {\n liness[1].push(allLiness[1][i]);\n }\n\n let dp = [];\n for (let j = 0; j < liness[1].length; ++j) {\n h[1].push(1);\n }\n\n for (let i = 0; i < liness[0].length; ++i) {\n h[0].push(1);\n dp.push([]);\n for (let j = 0; j < liness[1].length; ++j) {\n let val = 0;\n if (i && dp[i - 1][j] > val) {\n val = dp[i - 1][j];\n }\n if (j && dp[i][j - 1] > val) {\n val = dp[i][j - 1];\n }\n if (liness[0][i].trim() == liness[1][j].trim()) {\n if (i && j) newVal = dp[i - 1][j - 1] + 1;\n else newVal = 1;\n if (newVal > val) val = newVal;\n }\n dp[i].push(val);\n }\n }\n\n let i = liness[0].length - 1;\n let j = liness[1].length - 1;\n while (i >= 0 && j >= 0) {\n if (\n liness[0][i].trim() == liness[1][j].trim() &&\n ((i && j && dp[i][j] == dp[i - 1][j - 1] + 1) ||\n ((!i || !j) && dp[i][j] == 1))\n ) {\n h[0][i] = 0;\n h[1][j] = 0;\n --i;\n --j;\n } else if (i && dp[i][j] == dp[i - 1][j]) --i;\n else --j;\n }\n\n if (left > 3) {\n result.push(\"...\\n\");\n }\n\n for (let i = Math.max(0, left - 3); i < left; ++i) {\n result.push(allLiness[0][i] + \"\\n\");\n }\n\n let bgColors = [\"#FFD0D0\", \"#D0FFD0\"];\n let ord1 = 0;\n let ord2 = 0;\n while (ord1 < liness[0].length || ord2 < liness[1].length) {\n if (ord1 < liness[0].length && h[0][ord1]) {\n result.push([liness[0][ord1] + \"\\n\", bgColors[0]]);\n ++ord1;\n } else if (ord2 < liness[1].length && h[1][ord2]) {\n result.push([liness[1][ord2] + \"\\n\", bgColors[1]]);\n ++ord2;\n } else {\n result.push(liness[1][ord2] + \"\\n\");\n ++ord1;\n ++ord2;\n }\n }\n\n for (let i = right - 1; i >= Math.max(right - 3, 0); --i) {\n result.push(allLiness[0][l1 - i - 1] + \"\\n\");\n }\n\n if (right > 3) {\n result.push(\"...\\n\");\n }\n\n return result;\n};\n\nconst isShowSpecEditor = () => {\n return editEverythingMode && state.showSpecEditor;\n};\n\nconst onAuth = (data) => {\n console.log(\"onAuth\", data);\n Storage.privateSet(SESSION_KEY, data.session_id);\n State.update({\n sessionId: data.session_id,\n isSessionValid: data.is_session_valid,\n resetSession: false,\n pendingAuth: false,\n });\n};\n\nconst loadDefaultPrompts = () => {\n if (state?.promptsUnlocked && !getArray(state.defaultPrompts).length) {\n setPendingRequest(true);\n asyncFetch(`${apiUrl}/admin/get_prompts/`, {\n method: \"POST\",\n body: JSON.stringify({\n account_id: context.accountId,\n session_id: sessionId,\n }),\n }).then((res) => {\n if (res.ok) {\n // returns {is_session_valid, prompts?}\n onRequest(res.body);\n\n const defaultPrompts = getArray(res.body.prompts);\n if (defaultPrompts.length) {\n const newState = state;\n newState.promptTabIndex = state.promptTabIndex ?? 0;\n newState.defaultPrompts = defaultPrompts;\n if (!getArray(state.userPrompts).length) {\n newState.userPrompts = defaultPrompts;\n }\n State.update(newState);\n updateUserPromptsInLocalStorage();\n }\n }\n\n console.log(\"get_prompts resp\", res.ok, res.body);\n setPendingRequest(false);\n });\n }\n};\n\nlet storage = Storage.privateGet(storageKey) ?? {};\n\nconsole.log(\"storage\", storage);\n\nif (\n storage?.promptsUnlocked &&\n state?.promptsUnlocked != storage?.promptsUnlocked\n) {\n State.update({\n promptsUnlocked: storage.promptsUnlocked,\n userPrompts: storage.userPrompts,\n });\n loadDefaultPrompts();\n}\n\nconst updateUserPromptsInLocalStorage = () => {\n storage.userPrompts = state.userPrompts;\n storage.promptsUnlocked = state.promptsUnlocked;\n console.log(\"storage update\", storage);\n Storage.privateSet(storageKey, storage);\n};\n\nconst avatarOnClick = () => {\n if (!state?.promptsUnlocked) {\n let promptsUnlocked = false;\n let showPromptsEditor = state.showPromptsEditor;\n let clickTimes = state?.clickTimes ?? [];\n const currentTime = Date.now();\n clickTimes.push(currentTime);\n\n while (clickTimes.length && currentTime - clickTimes[0] > 1000) {\n clickTimes.shift();\n }\n\n if (clickTimes.length >= 3) {\n promptsUnlocked = true;\n showPromptsEditor = true;\n }\n\n console.log(\"clickTimes\", clickTimes);\n\n State.update({\n promptsUnlocked,\n showPromptsEditor,\n clickTimes,\n });\n\n loadDefaultPrompts();\n }\n};\n\nconst ATTACH_CONVERSATION_TAB_INDEX = 5;\n\nconst getPromptsContainer = () => {\n if (state.promptsUnlocked && getArray(state.defaultPrompts).length) {\n const promptHeaders = [\n \"Message Before Specs\",\n \"Specs Before Specs\",\n \"Message After Specs\",\n \"Specs After Specs\",\n ];\n return (\n <div>\n <div class=\"card-header justify-content-between align-items-left pb-0\">\n <h4 class=\"mb-2\">\n Prompts editor{\" \"}\n <button\n class=\"small badge bg-secondary p-2\"\n onClick={() => {\n State.update({\n showPromptsEditor: false,\n });\n }}\n >\n Hide\n </button>\n </h4>\n <ul class=\"nav nav-tabs\">\n {promptHeaders.map((header, index) => {\n return (\n <li class=\"nav-item\">\n <a\n class={`nav-link ${\n state.promptTabIndex == index ? \"active\" : \"\"\n }`}\n href=\"#\"\n onClick={() => {\n State.update({ promptTabIndex: index });\n }}\n >\n {header}\n </a>\n </li>\n );\n })}\n\n <li class=\"nav-item\">\n <a\n class={`nav-link ${\n state.promptTabIndex == ATTACH_CONVERSATION_TAB_INDEX\n ? \"active\"\n : \"\"\n }`}\n href=\"#\"\n onClick={() => {\n State.update({\n promptTabIndex: ATTACH_CONVERSATION_TAB_INDEX,\n });\n }}\n >\n Attach conversation\n </a>\n </li>\n </ul>\n </div>\n <div class=\"card-body main-container w-100 h-100 ps-2 mb-4 pt-2 flex-row align-text-top\">\n {state.promptTabIndex === ATTACH_CONVERSATION_TAB_INDEX && (\n <div style={{ height: \"250px\" }} class=\"mt-2\">\n <div class=\"form-check form-switch\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"mySwitch\"\n name=\"darkmode\"\n value=\"yes\"\n onChange={(e) =>\n State.update({ attachConversation: e.target.checked })\n }\n checked={state.attachConversation}\n />\n <label class=\"form-check-label\" for=\"mySwitch\">\n {\" \"}\n Attach conversation using API\n </label>\n </div>\n\n {!state.attachConversation && (\n <Markdown text=\"Do not attach conversation, use {{ history }} instead\" />\n )}\n </div>\n )}\n {state.promptTabIndex !== ATTACH_CONVERSATION_TAB_INDEX && (\n <>\n <h5 class=\"mt-2 mb-2\">System prompt:</h5>\n <textarea\n style={{ height: \"250px\" }}\n class=\"form-control mb-2 flex-grow-1\"\n onChange={(e) => {\n let userPrompts = getArray(state.userPrompts);\n userPrompts[state.promptTabIndex] = e.target.value;\n State.update({\n userPrompts,\n });\n }}\n value={state.userPrompts[state.promptTabIndex]}\n />\n\n {state.defaultPrompts[state.promptTabIndex].trim() !=\n state.userPrompts[state.promptTabIndex].trim() && (\n <div>\n <h5 class=\"mt-2 mb-2\">Default prompt:</h5>\n <textarea\n style={{ height: \"250px\" }}\n disabled\n class=\"form-control mb-2 flex-grow-1\"\n value={state.defaultPrompts[state.promptTabIndex]}\n />\n </div>\n )}\n\n <div>\n <button\n class=\"btn btn-success mb-2\"\n onClick={() => updateUserPromptsInLocalStorage()}\n >\n Update prompts\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n }\n};\n\nreturn (\n <Theme class=\"d-block main-container h-100\">\n {state.promptsUnlocked && state.showPromptsEditor && getPromptsContainer()}\n <div class=\"row\" style={{ height: \"38px\" }}>\n <div class=\"col\">\n <h4>Task Spec {isShowSpecEditor() ? \"Editor\" : \"\"}</h4>\n </div>\n {state.promptsUnlocked && (\n <div class=\"col w-100 text-end\">\n <button\n class=\"small badge bg-secondary p-2\"\n onClick={() => {\n State.update({\n showPromptsEditor: true,\n });\n }}\n >\n Prompts Editor\n </button>\n </div>\n )}\n </div>\n <div class=\"extension-container h-100 d-flex gap-1\">\n <div\n class=\"container markdown-container col-md-6 h-10 position-relative\"\n id=\"container-markdown\"\n >\n {editEverythingMode && (\n <div class=\"position-absolute top-0 end-0 mt-3 me-3\">\n <button\n class=\"small badge bg-secondary p-2\"\n onClick={() => {\n State.update({\n showSpecEditor: !state.showSpecEditor,\n editMessageIndex: state.editSpecIndex,\n editMessageText: state.chat[state.editSpecIndex].message,\n });\n }}\n >\n {state.showSpecEditor ? \"Render\" : \"Edit\"} spec\n </button>\n </div>\n )}\n\n {!isShowSpecEditor() && (\n <div class=\" markdown-render\">\n <Markdown class=\"card h-100\" text={state.spec} />\n </div>\n )}\n {isShowSpecEditor() && (\n <textarea\n class=\"markdown-textarea h-100 w-100\"\n onChange={(e) => {\n State.update({ spec: e.target.value });\n }}\n value={state.spec}\n />\n )}\n </div>\n <div class=\"container chat-container col-md-6 h-100\" id=\"container-main\">\n <div class=\"row d-flex justify-content-center h-100\">\n <div class=\"h-100\">\n <div class=\"card h-100\" id=\"chat\">\n <div\n class=\"card-header d-flex justify-content-between align-items-center pb-0\"\n id=\"chat-header\"\n >\n <ul class=\"nav nav-tabs top-nav-item\">\n <li class=\"nav-item top-nav-item\" id=\"top-nav-dialog\">\n <a\n class=\"nav-link link-underline-opacity-25 active\"\n role=\"button\"\n id=\"nav-dialog\"\n aria-current=\"page\"\n >\n <h5 class=\"mb-0\">Chat</h5>\n </a>\n </li>\n <li class=\"nav-item top-nav-item hidden\" id=\"top-nav-run\">\n <a class=\"nav-link\" id=\"nav-run\">\n <h5 class=\"mb-0\">▶️ Run</h5>\n </a>\n </li>\n <li class=\"nav-item top-nav-item hidden\" id=\"top-nav-account\">\n <a class=\"nav-link\" id=\"nav-account\">\n <h5 class=\"mb-0\">Account</h5>\n </a>\n </li>\n <li class=\"nav-item top-nav-item hidden\" id=\"top-nav-login\">\n <a class=\"nav-link\" id=\"nav-login\">\n <h5 class=\"mb-0\">Login</h5>\n </a>\n </li>\n </ul>\n <div id=\"account-details\" class=\"hidden\">\n <div class=\"d-inline-block align-top\">\n <div class=\"navbar navbar-light navbar-menu btn-group dropstart\">\n <div class=\"dropdown\" id=\"menu-dropdown\">\n <span\n class=\"navbar-toggler-icon\"\n role=\"button\"\n id=\"dropdown-menu-link\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n ></span>\n\n <ul\n class=\"dropdown-menu\"\n id=\"menu-dropdown-list\"\n aria-labelledby=\"dropdown-menu-link\"\n >\n <li>\n <a\n class=\"dropdown-item\"\n href=\"#\"\n id=\"refresh-button\"\n >\n Refresh\n </a>\n </li>\n <li id=\"menu-load-examples\">\n <a\n class=\"dropdown-item\"\n href=\"#\"\n onClick=\"return loadExamples()\"\n >\n Load Examples\n </a>\n </li>\n <li>\n <a\n class=\"dropdown-item\"\n href=\"#\"\n id=\"sign-out-button\"\n >\n Sign Out\n </a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"card-body main-container main-container-review hidden\"\n id=\"container-account\"\n data-mdb-perfect-scrollbar=\"true\"\n >\n <div class=\"alert alert-warning\" role=\"alert\">\n Account not found. Enter your invite code to proceed.\n </div>\n <div class=\"mb-3\">\n <label for=\"user-invite\" class=\"form-label\">\n Invite code\n </label>\n <input\n type=\"text\"\n class=\"form-control\"\n id=\"user-invite\"\n value=\"\"\n placeholder=\"InviteCode\"\n />\n </div>\n <div\n class=\"alert alert-danger\"\n role=\"alert\"\n id=\"user-invite-error\"\n ></div>\n <div>\n <a\n class=\"btn btn-primary mb-3\"\n onClick=\"return submitInviteCode();\"\n >\n Submit\n </a>\n </div>\n </div>\n <div\n class=\"card-body main-container main-container-review hidden\"\n id=\"container-login\"\n data-mdb-perfect-scrollbar=\"true\"\n >\n <div class=\"alert alert-warning\" role=\"alert\">\n Login with NEAR Account please\n </div>\n <div id=\"login\" class=\"hidden\">\n <input\n type=\"button\"\n class=\"btn btn-primary btn\"\n data-mdb-ripple-color=\"dark\"\n value=\"Login\"\n id=\"login-button\"\n />\n <input\n type=\"button\"\n class=\"btn btn-primary btn hidden\"\n data-mdb-ripple-color=\"dark\"\n value=\"Confirm Login\"\n id=\"confirm-login-button\"\n />\n </div>\n\n <hr />\n <div>Don't have an account yet?</div>\n <div>\n <a\n class=\"btn btn-primary btn-sm mb-3\"\n href=\"https://wallet.near.org/create\"\n >\n Create\n </a>\n </div>\n </div>\n <div\n id=\"container-run\"\n class=\"card-body main-container main-container-review hidden\"\n data-mdb-perfect-scrollbar=\"true\"\n >\n <div class=\"container\">\n <div class=\"row align-items-start h-100\">\n <div class=\"col h-100 run-column ps-0 pe-1\">\n <div class=\"form-floating h-100\">\n <textarea\n class=\"form-control tests-textarea\"\n id=\"tests-inputs\"\n ></textarea>\n <label for=\"tests-inputs\">Input values</label>\n </div>\n </div>\n <div class=\"col hidden h-100\">\n <div class=\"form-floating h-100\">\n <textarea\n class=\"form-control tests-textarea\"\n id=\"tests-outputs\"\n ></textarea>\n <label for=\"tests-outputs\">\n Expected output values\n </label>\n </div>\n </div>\n <div class=\"col h-100 run-column pe-0 ps-1\">\n <div\n class=\"form-floating h-100\"\n id=\"real-output-container\"\n >\n <div\n class=\"form-control tests-textarea real-output\"\n readonly\n id=\"real-output\"\n ></div>\n <div\n class=\"output-popup-button quote disabled\"\n id=\"button-quote-selected-output\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"left\"\n title=\"Quote text from the output screen and include it in your next reply in the dialog\"\n oncontextmenu=\"return false;\"\n >\n <div>”</div>\n </div>\n <div\n class=\"output-popup-button clear disabled\"\n id=\"button-clear-output-qoutes\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"left\"\n title=\"Clear quotes\"\n oncontextmenu=\"return false;\"\n >\n <div>x</div>\n </div>\n <label for=\"real-output\">Output</label>\n </div>\n </div>\n </div>\n <div class=\"row align-items-start mt-2\">\n <div class=\"col\">\n <div class=\"row align-items-start h-100\">\n <div class=\"col h-100 run-column ps-0 pe-1\">\n <div class=\"btn-group\">\n <button\n type=\"button\"\n class=\"btn btn-success long-text-button\"\n id=\"button-run\"\n >\n Run\n </button>\n <button\n type=\"button\"\n class=\"btn btn-success dropdown-toggle dropdown-toggle-split\"\n data-bs-toggle=\"dropdown\"\n id=\"button-run-dropdown-toggle\"\n >\n <span class=\"visually-hidden\">\n Toggle Dropdown\n </span>\n </button>\n\n <div\n class=\"dropdown-menu\"\n id=\"button-run-dropdown-menu\"\n >\n <a\n href=\"#\"\n class=\"dropdown-item\"\n id=\"run-editor-code\"\n >\n Run code from the editor\n </a>\n <a\n href=\"#\"\n class=\"dropdown-item\"\n id=\"run-last-message-code\"\n >\n Run code from the last message\n </a>\n </div>\n </div>\n </div>\n <div class=\"col h-100 run-column pe-0 ps-1\">\n <button\n type=\"button\"\n class=\"btn btn-info disabled\"\n id=\"button-save-output\"\n title=\"Save the output to dialog to assist reviewers\"\n >\n Save output\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"card-body main-container main-container-review\"\n id=\"container-dialog\"\n data-mdb-perfect-scrollbar=\"true\"\n >\n <div\n class=\"task-header-container hidden\"\n id=\"current-task-header-container\"\n >\n <div class=\"task-header\" id=\"current-task-header\"></div>\n <div\n class=\"task-header-content\"\n id=\"current-task-header-content\"\n ></div>\n <div\n class=\"review-reclaim-interval\"\n id=\"review-reclaim-interval\"\n ></div>\n </div>\n <div id=\"user-chat\">\n {getArray(state.chat).map((item, index) => (\n <div class=\"mb-3\">\n {styleMessage(item, index)}\n {getMessageDiff(item, index)}\n </div>\n ))}\n <a name=\"chat-end\"></a>\n </div>\n </div>\n <div class=\"gutter gutter-vertical\" id=\"gutter-vertical\"></div>\n <div\n class=\"card-footer text-muted d-flex justify-content-start align-items-start p-2\"\n id=\"container-footer\"\n >\n <div class=\"align-top\" onClick={() => avatarOnClick()}>\n <img\n src={user_pics[USER]}\n width=\"40\"\n height=\"40\"\n class=\"mr-2\"\n />\n </div>\n\n <div class=\"task-reply-options align-items-center h-100 hidden\">\n <textarea\n class=\"form-control form-control-lg h-100\"\n id=\"task-user-input-textbox\"\n rows=\"1\"\n ></textarea>\n\n <div class=\"dropdown ms-2\" id=\"main-types-dropdown-menu\">\n <button\n id=\"message-type-dropdown\"\n class=\"btn btn-sm btn-secondary dropdown-toggle p2\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n >\n Type\n </button>\n <ul class=\"dropdown-menu\">\n <li>\n <a class=\"dropdown-item\" href=\"#\">\n Answer\n </a>\n </li>\n <li>\n <a class=\"dropdown-item\" href=\"#\">\n Thoughts\n </a>\n </li>\n </ul>\n </div>\n\n <a class=\"ms-2\" href=\"#\">\n <input\n type=\"button\"\n value=\"Send\"\n id=\"send-button\"\n class=\"btn btn-primary btn-sm p-2\"\n data-mdb-ripple-color=\"dark\"\n />\n </a>\n </div>\n\n <div class=\"review-reply-options align-items-center h-100 hidden\">\n <textarea\n class=\"form-control form-control-lg h-100\"\n id=\"review-user-input-textarea\"\n rows=\"1\"\n ></textarea>\n\n <a class=\"ms-2\" href=\"\">\n <input\n type=\"button\"\n value=\"Accept\"\n id=\"review-accept-button\"\n class=\"btn btn-success btn-sm footer-action-button h-100\"\n data-mdb-ripple-color=\"dark\"\n />\n </a>\n\n <a class=\"ms-2\" href=\"\">\n <input\n type=\"button\"\n value=\"Reject\"\n id=\"review-reject-button\"\n class=\"btn btn-danger btn-sm footer-action-button h-100\"\n data-mdb-ripple-color=\"dark\"\n />\n </a>\n </div>\n\n {/* chat send */}\n <div class=\"example-reply-options h-100 ps-2 d-flex flex-row align-text-top\">\n <textarea\n class=\"form-control h-100 flex-grow-1\"\n id=\"example-user-input-textarea\"\n onChange={(e) => {\n State.update({ userMessage: e.target.value });\n }}\n onKeyPress={(e) => {\n if (e.ctrlKey && e.key === \"Enter\") {\n AddUserMessage();\n }\n }}\n value={state.userMessage}\n rows=\"1\"\n ></textarea>\n\n <div class=\"ms-2\">\n <a\n type=\"button\"\n value=\"\"\n id=\"example-send-button\"\n onClick={(e) => AddUserMessage()}\n class=\"btn btn-success btn-sm footer-action-button h-100 text-white\"\n data-mdb-ripple-color=\"dark\"\n href=\"#chat-end\"\n >\n Send\n </a>\n </div>\n </div>\n\n <div class=\"resubmit-rejected-options h-100 w-100 justify-content-center hidden\">\n <a class=\"ms-2\" href=\"#\">\n <input\n type=\"button\"\n value=\"Continue working\"\n id=\"restart-rejected-task-button\"\n class=\"btn btn-success btn-sm footer-action-button h-100\"\n data-mdb-ripple-color=\"dark\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"top\"\n title=\"You will restart this task to update/remove existing messages and fix review issues\"\n />\n </a>\n\n <a class=\"ms-2\" href=\"#\">\n <input\n type=\"button\"\n value=\"Abandon and request new task\"\n id=\"abandon-rejected-task-button\"\n class=\"btn btn-danger btn-sm footer-action-button h-100\"\n data-mdb-ripple-color=\"dark\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"top\"\n title=\"Forget this task\"\n />\n </a>\n </div>\n </div>\n </div>\n\n <div\n class=\"text-center hidden bottom-controls\"\n id=\"bottom-controls\"\n >\n <div class=\"d-flex justify-content-center pt-1\">\n <div id=\"code-filename\" class=\"code-filename\"></div>\n <select\n id=\"select-code-filename\"\n class=\"select-code-filename hidden\"\n ></select>\n <button\n class=\"small ms-2 badge bg-secondary hidden\"\n id=\"confirm-update-current-filename\"\n >\n Confirm\n </button>\n <button\n class=\"small ms-2 badge bg-secondary hidden\"\n id=\"cancel-update-current-filename\"\n >\n Cancel\n </button>\n <button\n class=\"small ms-2 badge bg-secondary\"\n id=\"update-current-filename\"\n >\n Update file\n </button>\n <button\n class=\"small ms-2 badge bg-success hidden\"\n id=\"submit-button\"\n data-mdb-ripple-color=\"dark\"\n >\n Submit\n </button>\n <button\n class=\"small ms-2 badge bg-success hidden\"\n id=\"skip-task-button\"\n data-mdb-ripple-color=\"dark\"\n >\n Skip\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </Theme>\n);\n" } } } } }
Result:
{ "block_height": "120060223" }
No logs
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
223 Ggas
Tokens Burned:
0 
Transferred 0.01765  to dev.near
Empty result
No logs