{"version":3,"sources":["jsdelivr-header.js","/npm/hackchain-debugger@4.0.0/lib/debugger.js"],"names":[],"mappings":"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","file":"/npm/hackchain-debugger@4.0.0/lib/debugger.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/hackchain-debugger@4.0.0/lib/debugger.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","'use strict';\n\nconst assert = require('assert');\nconst blessed = require('blessed');\nconst Buffer = require('buffer').Buffer;\nconst OBuf = require('obuf');\n\nconst hackchain = require('hackchain-core');\nconst Interpreter = hackchain.Interpreter;\nconst Disassembler = Interpreter.Disassembler;\nconst TX = hackchain.TX;\nconst Script = TX.Script;\n\nfunction Debugger(title, data) {\n  assert(data && typeof data === 'object', 'Debugger: data must be an object');\n  assert.equal(typeof data.hash, 'string',\n               'Debugger: `data.hash` must be a string');\n  assert(Array.isArray(data.output) || Buffer.isBuffer(data.output),\n         'Debugger: `data.output` must be an Array or Buffer');\n  assert(Array.isArray(data.input) || Buffer.isBuffer(data.input),\n         'Debugger: `data.input` must be an Array or Buffer');\n\n  this.data = {\n    hash: Buffer.from(data.hash, 'hex'),\n    output: Array.isArray(data.output) ?\n        Script.compileTextArray(data.output, Interpreter.outputOffset).opcodes :\n        data.output,\n    input: Array.isArray(data.input) ?\n        Script.compileTextArray(data.input, Interpreter.inputOffset).opcodes :\n        data.input\n  };\n\n  this.interpreter = new Interpreter();\n  this.state = 'output';\n  this.counter = 0;\n\n  this.initUI(title);\n}\nexports.Debugger = Debugger;\n\nDebugger.prototype.run = function run() {\n  this.restart();\n};\n\nDebugger.prototype.restart = function restart() {\n  this.state = 'output';\n  this.counter = 0;\n\n  this.interpreter.clear();\n  this.interpreter.prepareOutput(this.data);\n\n  this.update();\n};\n\nDebugger.prototype.exit = function exit() {\n  process.exit(0);\n};\n\nDebugger.prototype.step = function step() {\n  if (this.state === 'output') {\n    this._stepOutput();\n  } else if (this.state === 'both') {\n    this._stepBoth();\n  } else {\n    // ...failure\n  }\n\n  this.update();\n};\n\nDebugger.prototype._stepOutput = function _stepOutput() {\n  if (!this.interpreter.prerunOneOutput()) {\n    this.counter++;\n    if (this.counter >= Interpreter.maxInitTicks)\n      this.finish(false);\n\n    return;\n  }\n\n  // TODO(indutny): should be a function of interpreter\n  this.interpreter.threads.output.clearYield();\n\n  if (this.interpreter.threads.output.isDone())\n    return this.finish(true);\n\n  this.interpreter.prepareInput(this.data);\n  this.counter = 0;\n  this.state = 'both';\n};\n\nDebugger.prototype._stepBoth = function _stepBoth() {\n  if (!this.interpreter.runOneBoth()) {\n    this.counter++;\n    if (this.counter >= Interpreter.maxTicks)\n      this.finish(true);\n    return;\n  }\n\n  this.finish(true);\n};\n\nDebugger.prototype.finish = function finish(result) {\n  this.state = result ? 'success' : 'failure';\n  this.counter = 0;\n};\n\nDebugger.prototype.update = function update() {\n  this.updateThread(this.output, this.outputRegs,\n                    this.interpreter.threads.output);\n  this.updateThread(this.input, this.inputRegs, this.interpreter.threads.input);\n\n  this.screen.render();\n};\n\nDebugger.prototype.updateThread = function updateThread(box, bar, thread) {\n  const contextBefore = (box.height - 1) >> 1;\n  const contextAfter = box.height - 1 - contextBefore;\n\n  const start = thread.pc - 2 * contextBefore;\n  const end = thread.pc + 2 * contextAfter;\n\n  const code = start < 0 ?\n    this.interpreter.memory.slice(0, end) :\n    this.interpreter.memory.slice(start, end);\n  const buf = new OBuf();\n  buf.push(code);\n\n  const disasm = new Disassembler(buf);\n  let lines = Disassembler.stringify(disasm.run()).split('\\n');\n\n  const addr = (i) => {\n    let r = i.toString(16);\n    if (r.length === 1)\n      return `0x000${r}`;\n    else if (r.length === 2)\n      return `0x00${r}`;\n    else if (r.length === 3)\n      return `0x0${r}`;\n    else if (r.length === 4)\n      return `0x${r}`;\n    return '0x....';\n  };\n\n  while (lines.length < box.height - 1)\n    lines.unshift('...');\n\n  lines = lines.map((line, i) => {\n    const mem = Math.max(0, (start >> 1) + i);\n    const prefix = i === contextBefore ? '* ' : '  ';\n    return `${prefix}${addr(mem)}: ${line}`;\n  });\n\n  box.setItems(lines);\n  box.select(contextBefore);\n\n  if (this.state === 'success')\n    box.style.selected.bg = 'green';\n  else if (this.state === 'failure')\n    box.style.selected.bg = 'red';\n  else\n    box.style.selected.bg = 'grey';\n\n  const regs = [];\n  for (let i = 1; i < thread.regs.length; i++) {\n    const value = thread.regs[i];\n    regs.push(`{bold}r${i}:{/bold}${addr(value)}`);\n  }\n\n  bar.setContent(regs.join(' '));\n};\n\n//\n// UI - Can be separated later\n//\n\nDebugger.prototype.initUI = function initUI(title) {\n  this.screen = blessed.screen({\n    smartCSR: true\n  });\n  this.screen.title = `HC debug - \"${title}\"`;\n\n  this.initMenu();\n\n  this.left = blessed.box({\n    top: 1,\n    left: '0%',\n    width: '50%'\n  });\n\n  this.right = blessed.box({\n    top: 1,\n    left: '50%',\n    width: '50%'\n  });\n\n  const codeStyle = {\n    selected: {\n      fg: 'white',\n      bg: 'blue'\n    }\n  };\n\n  this.output = blessed.list({\n    bottom: 1,\n    label: 'Output',\n    border: { type: 'line' },\n    style: codeStyle\n  });\n\n  this.outputRegs = blessed.box({\n    tags: true,\n    height: 1,\n    left: 1,\n    right: 1,\n    bottom: 0,\n    style: { bg: 'grey', fg: 'white' }\n  });\n\n  this.input = blessed.list({\n    bottom: 1,\n    label: 'Input',\n    border: { type: 'line' },\n    style: codeStyle\n  });\n\n  this.inputRegs = blessed.box({\n    tags: true,\n    height: 1,\n    left: 1,\n    right: 1,\n    bottom: 0,\n    style: { bg: 'grey', fg: 'white' }\n  });\n\n  this.screen.append(this.menu);\n  this.screen.append(this.left);\n  this.screen.append(this.right);\n  this.left.append(this.output);\n  this.left.append(this.outputRegs);\n  this.right.append(this.input);\n  this.right.append(this.inputRegs);\n\n  this.menu.focus();\n};\n\nDebugger.prototype.initMenu = function initMenu() {\n  this.menu = blessed.listbar({\n    autoCommandKeys: false,\n    keys: true,\n\n    top: '0%',\n    left: '0%',\n    width: '100%',\n    height: 1,\n    style: {\n      bg: 'black',\n      item: {\n        bg: 'white',\n        fg: 'black'\n      },\n      selected: {\n        bg: 'white',\n        fg: 'black'\n      }\n    }\n  });\n\n  this.menu.addItem({\n    text: 'Exit',\n    keys: [ 'q', 'C-c' ],\n    callback: () => {\n      this.exit();\n    }\n  });\n\n  this.menu.addItem({\n    text: 'Step',\n    keys: [ 'f10', 'f11'],\n    callback: () => {\n      this.step();\n    }\n  });\n\n  this.menu.addItem({\n    text: 'Restart',\n    keys: [ 'f5' ],\n    callback: () => {\n      this.restart();\n    }\n  });\n};\n"]}