[
  {
    "path": ".eslintrc",
    "content": "// {\n//   // Settings\n//   \"esversion\"     : 6,\n//   \"passfail\"      : false,  // Stop on first error.\n//   \"maxerr\"        : 100,    // Maximum errors before stopping.\n\n//   // Predefined globals whom JSHint will ignore.\n//   \"browser\"       : true,   // Standard browser globals e.g. `window`, `document`.\n\n//   \"node\"          : true,\n//   \"rhino\"         : false,\n//   \"couch\"         : false,\n//   \"wsh\"           : false,   // Windows Scripting Host.\n\n//   \"jquery\"        : false,\n//   \"prototypejs\"   : false,\n//   \"mootools\"      : false,\n//   \"dojo\"          : false,\n\n//   \"predef\"        : [  // Extra globals.\n//     \"require\",\n//     \"define\",\n//     \"notify\",\n//     \"expect\",\n//     \"it\",\n//     \"afterEach\",\n//     \"describe\",\n//     \"jest\"\n//   ],\n\n//   // Development.\n//   \"debug\"         : false,   // Allow debugger statements e.g. browser breakpoints.\n//   \"devel\"         : false,   // Allow development statements e.g. `console.log();`.\n\n//   // EcmaScript 5.\n//   \"strict\"        : true,   // Require `use strict` pragma in every file.\n//   \"globalstrict\"  : false,  // Allow global \"use strict\" (also enables 'strict').\n\n//   // The Good Parts.\n//   \"asi\"           : false,  // Tolerate Automatic Semicolon Insertion (no semicolons).\n//   \"laxbreak\"      : false,  // Tolerate unsafe line breaks e.g. `return [\\n] x` without semicolons.\n//   \"bitwise\"       : true,   // Prohibit bitwise operators (&, |, ^, etc.).\n//   \"boss\"          : false,  // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments.\n//   \"curly\"         : true,   // Require {} for every new block or scope.\n//   \"eqeqeq\"        : false,  // Require triple equals i.e. `===`.\n//   \"eqnull\"        : false,  // Tolerate use of `== null`.\n//   \"evil\"          : true,  // Tolerate use of `eval`.\n//   \"expr\"          : false,  // Tolerate `ExpressionStatement` as Programs.\n//   \"forin\"         : false,   // Tolerate `for in` loops without `hasOwnPrototype`.\n//   \"immed\"         : true,   // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`\n//   \"latedef\"       : false,  // Prohibit variable use before definition.\n//   \"loopfunc\"      : true,  // Allow functions to be defined within loops.\n//   \"noarg\"         : true,   // Prohibit use of `arguments.caller` and `arguments.callee`.\n//   \"regexp\"        : true,   // Prohibit `.` and `[^...]` in regular expressions.\n//   \"regexdash\"     : false,  // Tolerate unescaped last dash i.e. `[-...]`.\n//   \"scripturl\"     : true,   // Tolerate script-targeted URLs.\n//   \"shadow\"        : false,  // Allows re-define variables later in code e.g. `var x=1; x=2;`.\n//   \"supernew\"      : true,  // Tolerate `new function () { ... };` and `new Object;`.\n//   \"undef\"         : true,   // Require all non-global variables be declared before they are used.\n\n//   // Styling prefrences.\n//   \"newcap\"        : false,  // Require capitalization of all constructor functions e.g. `new F()`.\n//   \"noempty\"       : false,  // Prohibit use of empty blocks.\n//   \"nonew\"         : false,  // Prohibit use of constructors for side-effects.\n//   \"nomen\"         : false,  // Prohibit use of initial or trailing underbars in names.\n//   \"onevar\"        : false,  // Allow only one `var` statement per function.\n//   \"plusplus\"      : false,  // Prohibit use of `++` & `--`.\n//   \"sub\"           : true,   // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.\n//   \"trailing\"      : false,  // Prohibit trailing whitespaces.\n//   \"white\"         : false   // Check against strict whitespace and indentation rules.\n// }\n\n{\n  \"parserOptions\": {\n    \"ecmaVersion\": 2018,\n  },\n  \"env\": {\n    \"browser\": true,\n    \"node\": true,\n    \"es6\": true,\n  },\n  \"globals\": {\n    \"require\": true,\n    \"define\": true,\n    \"notify\": true,\n    \"expect\": true,\n    \"it\": true,\n    \"afterEach\": true,\n    \"describe\": true,\n    \"jest\": true,\n  },\n  \"rules\": {\n    \"no-debugger\": \"error\",\n    \"no-console\": \"error\",\n    \"strict\": [\"error\", \"global\"],\n    \"no-bitwise\": \"error\",\n    \"curly\": \"error\",\n    \"eqeqeq\": \"off\",\n    \"no-eval\": \"error\",\n    \"no-undef\": \"error\",\n    \"no-redeclare\": \"error\",\n    \"no-caller\": \"error\",\n    \"no-unused-vars\": [\n      \"error\",\n      {\n        \"argsIgnorePattern\": \"_\",\n      },\n    ],\n    \"no-empty\": \"off\",\n    \"no-new\": \"off\",\n    \"no-underscore-dangle\": \"off\",\n    \"one-var\": \"off\",\n    \"no-plusplus\": \"off\",\n    \"no-sub\": \"off\",\n    \"no-trailing-spaces\": \"off\",\n    \"no-tabs\": \"off\",\n  },\n}\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# .github/dependabot.yml\n\nversion: 2\nupdates:\n  - package-ecosystem: \"npm\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    labels:\n      - \"dependencies\"\n    assignees:\n      - \"colonelpopcorn\"\n    reviewers:\n      - \"colonelpopcorn\"\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 90\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 14\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - pinned\n  - security\n# Label to use when marking an issue as stale\nstaleLabel: stale\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not received\n  any attention in 90 days. It will be closed in 14 days if no further activity occurs.\n  Thank you for your contribution!\n  (I'm a bot.)\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: >\n  This issue has been automatically closed due to inactivity.\n  (I'm a bot.)\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "# GitHub Actions (.github/workflows/main.yml)\nname: Node.js CI\non:\n  pull_request:\n    branches:\n      - main\n      - master\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node-version: [\"22\", \"21\", \"20\", \"19\", \"18\"]\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v2\n      - name: Setup Node.js\n        uses: actions/setup-node@v3\n        with:\n          node-version: ${{ matrix.node-version }}\n      - name: Install project dependencies\n        run: npm install\n      - name: Run tests\n        run: npm test\n      - name: Run linting\n        run: npm run lint\n"
  },
  {
    "path": ".gitignore",
    "content": "######################\n# OS-generated files\n######################\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n\n######################\n# IDE & Tools files\n######################\n# IntelliJ IDEA, WebStorm, phpStorm\n.idea/\n*.iml\n*.iws\n\n# Eclipse\n.classpath\n.project\n.settings/\n\n# Sublime Text\n*.sublime-project\n*.sublime-workspace\n\n# vi buffers\n*~\n*.swp\n*.swo\n\n# Emacs buffers\n\\#*\n.\\#*\n\n# TextMate\n*.tmproj\ntmtags\n\n# Build & testing tools\nnode_modules\n.vagrant\n\n######################\n# Logs and databases\n######################\n*.log\n*.sql\n*.sqlite\n\n######################\n# Projects checked out to this root\n######################\n\n\\.vscode/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# CONTRIBUTING\n\nPlease familiarize yourself with the [Contributor Code of Conduct](https://github.com/Node-Virtualization/node-virtualbox/blob/master/code_of_conduct.md)\n\n## Filing Issues\n\n- Please file issues using the issue templates.\n\n- Please follow the issue template exactly and provide as much meaningful detail as you can.\n\n## Testing Your Work\n\nPlease test your work thoroughly before submitting a PR.\n\nUnderstand that Node-Virtualbox is used on a wide variety of platforms; avoid code that applies only to one host operating system and make it as generic as possible.\n\n## Submitting Pull Requests\n\n1. Pull requests *must* be tied to an issue. If no issue exists, please file one (see above).\n1. Before starting work, please claim the issue by commenting on it and letting _everyone_ know you'll be working on it. This helps prevent duplicate PRs.\n1. Please try to let us know if you abandon an issue so we can remove the `in-progress` label.\n1. Mention the issue number in a commit.\n1. Fix any issues in the automated PR checks, or explain why they're not relevant.\n\n## Code Quality Tools\n\nChecking tools are there as guidance. Use your judgement.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Azer Koçulu, Michael Sanford\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# node-virtualbox\n\n![NPM version](https://badge.fury.io/js/virtualbox.svg)\n[![Build Status](https://travis-ci.org/Node-Virtualization/node-virtualbox.svg?branch=master)](https://travis-ci.org/Node-Virtualization/node-virtualbox)\n[![DepShield Badge](https://depshield.sonatype.org/badges/Node-Virtualization/node-virtualbox/depshield.svg)](https://depshield.github.io)\n\nA JavaScript library to interact with [VirtualBox](https://www.virtualbox.org/) virtual machines.\n\n# Table of Contents\n\n- [Installation](#installation)\n- [Controlling Power and State](#controlling-power-and-state) - [Starting a cold machine: Two ways](#starting-a-cold-machine-two-ways) - [Stopping a machine](#stopping-a-machine) - [Pausing, Saving and Resuming a machine](#pausing-saving-and-resuming-a-machine)\n- [Import a Machine](#import-a-machine)\n- [Export a Machine](#export-a-machine)\n- [Snapshot Manage](#snapshot-manage)\n- [Cloning a VM](#cloning-vms)\n- [Storage](#storage) - [Manage the IDE controller](#manage-the-ide-controller) - [Attach a disk image file](#attach-a-disk-image-file)\n- [Controlling the guest OS](#controlling-the-guest-os) - [A note about security :warning:](#a-note-about-security) - [Running programs in the guest](#running-programs-in-the-guest) - [Executing commands as Administrators on Windows guests](#executing-commands-as-administrators-on-windows-guests) - [Killing programs in the guest](#killing-programs-in-the-guest) - [Sending keystrokes to a virtual machine](#sending-keystrokes-to-a-virtual-machine)\n- [Meta information about machine](#meta-information-about-machine)\n- [Putting it all together](#putting-it-all-together)\n- [Available Methods](#available-methods)\n- [Troubleshooting](#troubleshooting)\n- [More Examples](#more-examples)\n- [License (MIT)](#license)\n- [Contributing](#contributing)\n  - [Testing](#testing)\n\n# Installation\n\nObtain the package\n\n```bash\n$ npm install virtualbox [--save] [-g]\n```\n\nand then use it\n\n```javascript\nvar virtualbox = require('virtualbox');\n```\n\nThe general formula for commands is:\n\n> virtualbox. **API command** ( \"**registered vm name**\", **[parameters]**, **callback** );\n\nAvailable API commands are listed at the end of this document.\n\n# Controlling Power and State\n\n`node-virtualbox` provides convenience methods to command the guest machine's power state in the customary ways.\n\n## Starting a cold machine: Two ways\n\nVirtual machines will _start headless by default_, but you can pass a boolean parameter to start them with a GUI:\n\n```javascript\nvirtualbox.start('machine_name', true, function start_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine has started WITH A GUI!');\n});\n```\n\nSo as not to break pre-0.1.0 implementations, the old method still works (which also defaults to headless):\n\n```javascript\nvirtualbox.start('machine_name', function start_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine has started HEADLESS!');\n});\n```\n\n## Stopping a machine\n\n**Note:** For historical reasons, `.stop` is an alias to `.savestate`.\n\n```javascript\nvirtualbox.stop('machine_name', function stop_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine has been saved');\n});\n```\n\nTo halt a machine completely, you can use `poweroff` or `acpipowerbutton`:\n\n```javascript\nvirtualbox.poweroff('machine_name', function poweroff_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine has been powered off!');\n});\n```\n\n```javascript\nvirtualbox.acpipowerbutton('machine_name', function acpipower_callback(error) {\n  if (error) throw error;\n  console.log(\"Virtual Machine's ACPI power button was pressed.\");\n});\n```\n\n## Pausing, Saving and Resuming a machine\n\nNoting the caveat above that `.stop` is actually an alias to `.savestate`...\n\n```javascript\nvirtualbox.pause('machine_name', function pause_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine is now paused!');\n});\n```\n\n```javascript\nvirtualbox.savestate('machine_name', function save_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine is now paused!');\n});\n```\n\nAnd, in the same family, `acpisleepbutton`:\n\n```javascript\nvirtualbox.acpisleepbutton('machine_name', function acpisleep_callback(error) {\n  if (error) throw error;\n  console.log(\"Virtual Machine's ACPI sleep button signal was sent.\");\n});\n```\n\nNote that you should probably _resume_ a machine which is in one of the above three states.\n\n```javascript\nvirtualbox.resume('machine_name', function resume_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine is now paused!');\n});\n```\n\nAnd, of course, a reset button method:\n\n```javascript\nvirtualbox.reset('machine_name', function reset_callback(error) {\n  if (error) throw error;\n  console.log(\"Virtual Machine's reset button was pressed!\");\n});\n```\n\n## Import a machine\n\nYou can import an OVA or OVF file with the `vmImport` method:\n\n```javascript\nvirtualbox.vmImport('ova_file_path', options, function import_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine was imported!');\n});\n```\n\nThe options object may contain optional parameters:\n* `vmname`: the name of the new VM.\n* `cpus`: the number of CPUs.\n* `memory`: the amount of memory in megabytes.\n\n## Export a machine\n\nYou can export with `vmExport` method:\n\n```javascript\nvirtualbox.vmExport('machine_name', 'output', function export_callback(error) {\n  if (error) throw error;\n  console.log('Virtual Machine was exported!');\n});\n```\n\n## Snapshot Manage\n\nYou can show snapshot list with `snapshotList` method:\n\n```javascript\nvirtualbox.snapshotList('machine_name', function (\n  error,\n  snapshotList,\n  currentSnapshotUUID\n) {\n  if (error) throw error;\n  if (snapshotList) {\n    console.log(\n      JSON.stringify(snapshotList),\n      JSON.stringify(currentSnapshotUUID)\n    );\n  }\n});\n```\n\nAnd, you can take a snapshot:\n\n```javascript\nvirtualbox.snapshotTake('machine_name', 'snapshot_name', function (\n  error,\n  uuid\n) {\n  if (error) throw error;\n  console.log('Snapshot has been taken!');\n  console.log('UUID: ', uuid);\n});\n```\n\nOr, delete a snapshot:\n\n```javascript\nvirtualbox.snapshotDelete('machine_name', 'snapshot_name', function (error) {\n  if (error) throw error;\n  console.log('Snapshot has been deleted!');\n});\n```\n\nOr, restore a snapshot:\n\n```javascript\nvirtualbox.snapshotRestore('machine_name', 'snapshot_name', function (error) {\n  if (error) throw error;\n  console.log('Snapshot has been restored!');\n});\n```\n\n## Cloning VMs\n\nMake a full clone (duplicate virtual hard drive) of a machine:\n\n```javascript\nvirtualbox.clone('source_machine_name', 'new_machine_name', function (error) {\n  if (error) throw error;\n  console.log('Done fully cloning the virtual machine!');\n});\n```\n\nMake a linked clone (interdependent-differentially stored virtual hard drive) of a machine:\n\n```javascript\nvirtualbox.snapshotTake('machine_name', 'snapshot_name', function (\n  error,\n  uuid\n) {\n  if (error) throw error;\n  console.log('Snapshot has been taken!');\n  console.log('UUID: ', uuid);\n  virtualbox.clone(\n    'machine_name',\n    'new_machine_name',\n    'snapshot_name',\n    function (error) {\n      if (error) throw error;\n      console.log('Done making a linked clone of the virtual machine!');\n    }\n  );\n});\n```\n\n## Storage\n\n### Manage the IDE controller\n\nIn case the VM doesn't have an IDE controller you can use the storagectl command to add one:\n\n```javascript\nvirtualbox.storage.addCtl(\n  {\n    vm: 'machine_name',\n    perhiperal_name: 'IDE', //optional\n    type: 'ide', //optional\n  },\n  function () {\n    console.log('Controller has been added!');\n  }\n);\n```\n\n### Attach a disk image file\n\nMount an ISO file to the added controller:\n\n```javascript\nvirtualbox.storage.attach(\n  {\n    vm: 'machine_name',\n    perhiperal_name: 'IDE', //optional\n    port: '0', //optional\n    device: '0', //optional\n    type: 'dvddrive', //optional\n    medium: 'X:Foldercontaining\\the.iso',\n  },\n  function () {\n    console.log('Image has been mounted!');\n  }\n);\n```\n\nThe _medium_ parameter of the options object can be set to the **none** value to unmount.\n\n# Controlling the guest OS\n\n## A note about security :warning:\n\n`node-virtualbox` is not opinionated: we believe that _you know best_ what _you_ need to do with _your_ virtual machine. Maybe that includes issuing `sudo rm -rf /` for some reason.\n\nTo that end, the `virtualbox` APIs provided by this module _take absolutely no steps_ to prevent you shooting yourself in the foot.\n\n:warning: Therefore, if you accept user input and pass it to the virtual machine, you should take your own steps to filter input before it gets passed to `virtualbox`.\n\nFor more details and discussion, see [issue #29](https://github.com/Node-Virtualization/node-virtualbox/issues/29).\n\n## Running programs in the guest\n\nThis method takes an options object with the name of the virtual machine, the path to the binary to be executed and any parameters to pass:\n\n```javascript\nvar options = {\n  vm: 'machine_name',\n  cmd: 'C:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe',\n  params: 'https://google.com',\n};\n\nvirtualbox.exec(options, function exec_callback(error, stdout) {\n  if (error) throw error;\n  console.log('Started Internet Explorer...');\n});\n```\n\n### Executing commands as Administrators on Windows guests\n\nPass username and password information in an `options` object:\n\n```javascript\nvar options = {\n  vm: 'machine_name',\n  user: 'Administrator',\n  password: '123456',\n  cmd: 'C:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe',\n  params: 'https://google.com',\n};\n```\n\n## Killing programs in the guest\n\nTasks can be killed in the guest as well. In Windows guests this calls `taskkill.exe /im` and on Linux, BSD and OS X (Darwin) guests, it calls `sudo killall`:\n\n```javascript\nvirtualbox.kill(\n  {\n    vm: 'machine_name',\n    cmd: 'iexplore.exe',\n  },\n  function kill_callback(error) {\n    if (error) throw error;\n    console.log('Terminated Internet Explorer.');\n  }\n);\n```\n\n## Sending keystrokes to a virtual machine\n\nKeyboard scan code sequences can be piped directly to a virtual machine's console:\n\n```javascript\nvar SCAN_CODES = virtualbox.SCAN_CODES;\nvar sequence = [\n  { key: 'SHIFT', type: 'make', code: SCAN_CODES['SHIFT'] },\n  { key: 'A', type: 'make', code: SCAN_CODES['A'] },\n  { key: 'SHIFT', type: 'break', code: SCAN_CODES.getBreakCode('SHIFT') },\n  { key: 'A', type: 'break', code: SCAN_CODES.getBreakCode('A') },\n];\n\nvirtualbox.keyboardputscancode(\n  'machine_name',\n  sequence,\n  function keyscan_callback(err) {\n    if (error) throw error;\n    console.log('Sent SHIFT A');\n  }\n);\n```\n\n# Meta information about machine\n\nList all registered machines, returns an array:\n\n```javascript\nvirtualbox.list(function list_callback(machines, error) {\n  if (error) throw error;\n  // Act on machines\n});\n```\n\nObtaining a guest property by [key name](https://www.virtualbox.org/manual/ch04.html#guestadd-guestprops):\n\n```javascript\nvar options = {\n  vm: 'machine_name',\n  key: '/VirtualBox/GuestInfo/Net/0/V4/IP',\n};\n\nvirtualbox.guestproperty.get(options, function guestproperty_callback(machines, error) {\n  if (error) throw error;\n  // Act on machines\n});\n```\n\nObtaining an extra property by key name:\n\n```javascript\nvar options = {\n  vm: 'machine_name',\n  key: 'GUI/Fullscreen',\n};\n\nvirtualbox.extradata.get(options, function extradataget_callback(error, value) {\n  if (error) throw error;\n  console.log(\n    'Virtual Machine \"%s\" extra \"%s\" value is \"%s\"',\n    options.vm,\n    options.key,\n    value\n  );\n});\n```\n\nWriting an extra property by key name:\n\n```javascript\nvar options = {\n  vm: 'machine_name',\n  key: 'GUI/Fullscreen',\n  value: 'true',\n};\n\nvirtualbox.extradata.set(options, function extradataset_callback(error) {\n  if (error) throw error;\n  console.log(\n    'Set Virtual Machine \"%s\" extra \"%s\" value to \"%s\"',\n    options.vm,\n    options.key,\n    options.value\n  );\n});\n```\n\n_Note: some properties are only available/effective if the Guest OS has the (https://www.virtualbox.org/manual/ch04.html)[Guest Additions] installed and running._\n\n# Putting it all together\n\n```javascript\nvar virtualbox = require('virtualbox');\n\nvirtualbox.start('machine_name', function start_callback(error) {\n  if (error) throw error;\n\n  console.log('VM \"w7\" has been successfully started');\n\n  virtualbox.exec(\n    {\n      vm: 'machine_name',\n      cmd: 'C:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe',\n      params: 'http://google.com',\n    },\n    function (error) {\n      if (error) throw error;\n      console.log('Running Internet Explorer...');\n    }\n  );\n});\n```\n\n# Available Methods\n\n`virtualbox`\n\n- `.pause({vm:\"machine_name\"}, callback)`\n- `.reset({vm:\"machine_name\"}, callback)`\n- `.resume({vm:\"machine_name\"}, callback)`\n- `.start({vm:\"machine_name\"}, callback)` and `.start({vm:\"machine_name\"}, true, callback)`\n- `.stop({vm:\"machine_name\"}, callback)`\n- `.savestate({vm:\"machine_name\"}, callback)`\n- `.vmImport({input: \"input\"}, {options: \"options\"}, callback)`\n- `.vmExport({vm:\"machine_name\"}, {output: \"output\"}, callback)`\n- `.poweroff({vm:\"machine_name\"}, callback)`\n- `.acpisleepbutton({vm:\"machine_name\"}, callback)`\n- `.acpipowerbutton({vm:\"machine_name\"}, callback)`\n- `.guestproperty.get({vm:\"machine_name\", property: \"propname\"}, callback)`\n- `.exec(){vm: \"machine_name\", cmd: \"C:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe\", params: \"http://google.com\"}, callback)`\n- `.exec(){vm: \"machine_name\", user:\"Administrator\", password: \"123456\", cmd: \"C:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe\", params: \"http://google.com\"}, callback)`\n- `.keyboardputscancode(\"machine_name\", [scan_codes], callback)`\n- `.kill({vm:\"machine_name\"}, callback)`\n- `.list(callback)`\n- `.isRunning({vm:\"machine_name\"}, callback)`\n- `.snapshotList({vm:\"machine_name\"}, callback)`\n- `.snapshotTake({vm:\"machine_name\"}, {vm:\"snapshot_name\"}, callback)`\n- `.snapshotDelete({vm:\"machine_name\"}, {vm:\"snapshot_UUID\"}, callback)`\n- `.snapshotRestore({vm:\"machine_name\"}, {vm:\"snapshot_UUID\"}, callback)`\n- `.clone({vm:\"machine_name\"}, {vm:\"new_machine_name\"}, callback)`\n- `.storage.addCtl({vm: \"machine_name\", perhiperal_name: \"IDE\", type: \"ide\"}, callback)`\n- `.storage.attach({vm: \"machine_name\", perhiperal_name: \"IDE\", port: \"0\", device: \"0\", type: \"dvddrive\", medium: \"X:\\Folder\\containing\\the.iso\"}, callback)`\n- `.extradata.get({vm:\"machine_name\", key:\"keyname\"}, callback)`\n- `.extradata.set({vm:\"machine_name\", key:\"keyname\", value:\"val\"}, callback)`\n\n# Troubleshooting\n\n- Make sure that Guest account is enabled on the VM.\n- Make sure your linux guest can `sudo` with `NOPASSWD` (at least for now).\n- VMs start headlessly by default: if you're having trouble with executing a command, start the VM with GUI and observe the screen after executing same command.\n- To avoid having \"Concurrent guest process limit is reached\" error message, execute your commands as an administrator.\n- Don't forget that this whole thing is asynchronous, and depends on the return of `vboxmanage` _not_ the actual running state/runlevel of services within the guest. See <https://github.com/Node-Virtualization/node-virtualbox/issues/9>\n\n# More Examples\n\n- [npm tests](https://github.com/Node-Virtualization/node-virtualbox/tree/master/test)\n\n# License\n\n[MIT](https://github.com/Node-Virtualization/node-virtualbox/blob/master/LICENSE)\n\n# Contributing\n\nPlease do!\n\n- [File an issue](https://github.com/Node-Virtualization/node-virtualbox/issues)\n- [Fork](https://github.com/Node-Virtualization/node-virtualbox#fork-destination-box) and send a pull request.\n\nPlease abide by the [Contributor Code of Conduct](https://github.com/Node-Virtualization/node-virtualbox/blob/master/code_of_conduct.md).\n\n## Testing\n\nWe currently do not have a complete unit testing suite. However, example scripts and a Vagrantfile are provided. Test your changes by writing a new script and/or running through all the test scripts to make sure they behave as expected. To do this [install vagrant](https://www.vagrantup.com/docs/installation) and run `vagrant up` in this repository's root directory. Then run the example scripts by using node: `node test/integration/<script-name>.js`. Please be ready to provide test output upon opening a pull request.\n"
  },
  {
    "path": "Vagrantfile",
    "content": "Vagrant.configure(\"2\") do |config|\n  config.vm.box = \"generic/alpine38\"\n  config.vm.provider \"virtualbox\" do |vbox|\n    vbox.name = \"node-virtualbox-test-machine\"\n  end\nend\n"
  },
  {
    "path": "code_of_conduct.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\nadvances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "lib/scan-codes.js",
    "content": "\"use strict\";\n\nvar codes;\n\ncodes = {\n  ESCAPE: [0x01],\n  NUMBER_1: [0x02],\n  NUMBER_2: [0x03],\n  NUMBER_3: [0x04],\n  NUMBER_4: [0x05],\n  NUMBER_5: [0x06],\n  NUMBER_6: [0x07],\n  NUMBER_7: [0x08],\n  NUMBER_8: [0x09],\n  NUMBER_9: [0x0a],\n  NUMBER_0: [0x0b],\n  MINUS: [0x0c],\n  EQUAL: [0x0d],\n  BACKSPACE: [0x0e],\n  TAB: [0x0f],\n  Q: [0x10],\n  W: [0x11],\n  E: [0x12],\n  R: [0x13],\n  T: [0x14],\n  Y: [0x15],\n  U: [0x16],\n  I: [0x17],\n  O: [0x18],\n  P: [0x19],\n  LEFTBRACKET: [0x1a],\n  RIGHTBRACKET: [0x1b],\n  ENTER: [0x1c],\n  CTRL: [0x1d],\n  A: [0x1e],\n  S: [0x1f],\n  D: [0x20],\n  F: [0x21],\n  G: [0x22],\n  H: [0x23],\n  J: [0x24],\n  K: [0x25],\n  L: [0x26],\n  SEMICOLON: [0x27],\n  QUOTE: [0x28],\n  BACKQUOTE: [0x29],\n  SHIFT: [0x2a],\n  BACKSLASH: [0x2b],\n  Z: [0x2c],\n  X: [0x2d],\n  C: [0x2e],\n  V: [0x2f],\n  B: [0x30],\n  N: [0x31],\n  M: [0x32],\n  COMMA: [0x33],\n  PERIOD: [0x34],\n  SLASH: [0x35],\n  R_SHIFT: [0x36],\n  PRT_SC: [0x37],\n  ALT: [0x38],\n  SPACE: [0x39],\n  CAPS_LOCK: [0x3a],\n  F1: [0x3b],\n  F2: [0x3c],\n  F3: [0x3d],\n  F4: [0x3e],\n  F5: [0x3f],\n  F6: [0x40],\n  F7: [0x41],\n  F8: [0x42],\n  F9: [0x43],\n  F10: [0x44],\n  NUM_LOCK: [0x45], // May be [0x45, 0xC5],\n  SCROLL_LOCK: [0x46],\n  NUMPAD_7: [0x47],\n  NUMPAD_8: [0x48],\n  NUMPAD_9: [0x49],\n  NUMPAD_SUBTRACT: [0x4a],\n  NUMPAD_4: [0x4b],\n  NUMPAD_5: [0x4c],\n  NUMPAD_6: [0x4d],\n  NUMPAD_ADD: [0x4e],\n  NUMPAD_1: [0x4f],\n  NUMPAD_2: [0x50],\n  NUMPAD_3: [0x51],\n  NUMPAD_0: [0x52],\n  NUMPAD_DECIMAL: [0x53],\n  F11: [0x57],\n  F12: [0x58],\n  // Same as other Enter key\n  // 'NUMBER_Enter'    : [0xE0, 0x1C],\n  R_CTRL: [0xe0, 0x1d],\n  NUMBER_DIVIDE: [0xe0, 0x35],\n  // 'NUMBER_*'        : [0xE0, 0x37],\n  R_ALT: [0xe0, 0x38],\n  HOME: [0xe0, 0x47],\n  UP: [0xe0, 0x48],\n  PAGE_UP: [0xe0, 0x49],\n  LEFT: [0xe0, 0x4b],\n  RIGHT: [0xe0, 0x4d],\n  END: [0xe0, 0x4f],\n  DOWN: [0xe0, 0x50],\n  PAGE_DOWN: [0xe0, 0x51],\n  INSERT: [0xe0, 0x52],\n  DELETE: [0xe0, 0x53],\n  WINDOW: [0xe0, 0x5b],\n  R_WINDOW: [0xe0, 0x5c],\n  MENU: [0xe0, 0x5d],\n  PAUSE: [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5],\n};\n\ncodes.getBreakCode = function (key) {\n  var makeCode = codes[key];\n  if (makeCode === undefined) {\n    throw new Error(\"Undefined key: \" + key);\n  }\n\n  if (key === \"PAUSE\") {\n    return [];\n  }\n\n  if (makeCode[0] === 0xe0) {\n    return [0xe0, makeCode[1] + 0x80];\n  } else {\n    return [makeCode[0] + 0x80];\n  }\n};\n\nmodule.exports = codes;\n"
  },
  {
    "path": "lib/virtualbox.js",
    "content": "\"use strict\";\n\nconst execFile = require(\"child_process\").execFile,\n  log4js = require(\"log4js\"),\n  host_platform = process.platform,\n  known_OS_types = {\n    WINDOWS: \"windows\",\n    MAC: \"mac\",\n    LINUX: \"linux\",\n  },\n  defaultExecutor = (bin, cmd) => {\n    return new Promise((resolve, reject) => {\n      if (!allowedBinaries.includes(bin)) {\n        reject(new Error(\"Not an allowed binary\"));\n      } else {\n        execFile(bin, cmd, function (err, stdout, stderr) {\n          if (\n            !err &&\n            stderr &&\n            cmd.indexOf(\"pause\") !== -1 &&\n            cmd.indexOf(\"savestate\") !== -1\n          ) {\n            reject(new Error(stderr));\n          }\n\n          resolve({ err, stdout, stderr });\n        });\n      }\n    });\n  },\n  defaultLoggingConfig = {\n    appenders: {\n      out: {\n        type: \"stdout\",\n        layout: {\n          type: \"pattern\",\n          pattern: \"%[[%d{yyyy-MM-dd hh:mm:ss.SSS}] [%p] %c - %]%m\",\n        },\n      },\n    },\n    categories: { default: { appenders: [\"out\"], level: \"info\" } },\n  },\n  defaultLoggerFn = () => {\n    log4js.configure(defaultLoggingConfig);\n    return log4js.getLogger(\"VirtualBox\");\n  },\n  defaultLogger = defaultLoggerFn(),\n  defaultvboxmanage = function (cmd, callback) {\n    try {\n      this._executor(this._vBoxManageBinary, cmd)\n        .then(({ err, stdout, stderr }) => callback(err, stdout, stderr))\n        .catch(defaultErrorHandler);\n    } catch (err) {\n      this._logging.error(err);\n    }\n  },\n  defaultErrorHandler = (err) => {\n    defaultLogger.error(err);\n  },\n  allowedBinaries = [\"VBoxControl\"];\n\nclass Virtualbox {\n  constructor(logging = defaultLogger, executor = defaultExecutor) {\n    this._logging = logging;\n    this._executor = executor;\n    this._setVboxManageBinary();\n    allowedBinaries.push(this._vBoxManageBinary);\n    this._logging.debug(allowedBinaries);\n    this._detectVboxVersion();\n    this.storage = new VboxStorage(\n      this._logging,\n      this._executor,\n      this._vBoxManageBinary\n    );\n    this.guestproperty = new VboxGuestProperty(\n      this._logging,\n      this._executor,\n      this._vBoxManageBinary\n    );\n    this.extradata = new VboxExtraData(\n      this._logging,\n      this._executor,\n      this._vBoxManageBinary\n    );\n    this.vboxmanage = defaultvboxmanage;\n    this.SCAN_CODES = require(\"./scan-codes\");\n  }\n\n  static create(logging, executor) {\n    const logger = !!logging ? logging : defaultLogger;\n    return new Virtualbox(logger, executor);\n  }\n\n  pause(vmname, callback) {\n    this._logging.info('Pausing VM \"%s\"', vmname);\n    this.vboxmanage([\"controlvm\", vmname, \"pause\"], function (error, _) {\n      callback(error);\n    });\n  }\n\n  list(callback) {\n    const parse_listdata = (raw_data) => {\n      var _raw = raw_data.split(/\\r?\\n/g);\n      var _data = {};\n      if (_raw.length > 0) {\n        for (var _i = 0; _i < _raw.length; _i += 1) {\n          var _line = _raw[_i];\n          if (_line === \"\") {\n            continue;\n          }\n          // \"centos6\" {64ec13bb-5889-4352-aee9-0f1c2a17923d}\n          var rePattern = /^\"(.+)\" \\{(.+)\\}$/;\n          var arrMatches = _line.match(rePattern);\n          // {'64ec13bb-5889-4352-aee9-0f1c2a17923d': 'centos6'}\n          if (arrMatches && arrMatches.length === 3) {\n            _data[arrMatches[2].toString()] = {\n              name: arrMatches[1].toString(),\n            };\n          }\n        }\n      }\n      return _data;\n    };\n\n    this._logging.info(\"Listing VMs\");\n    this.vboxmanage([\"list\", \"runningvms\"], (_, stdout) => {\n      var _runningvms = parse_listdata(stdout);\n      this.vboxmanage([\"list\", \"vms\"], function (error, fullStdout) {\n        var _all = parse_listdata(fullStdout);\n        var _keys = Object.keys(_all);\n        for (var _i = 0; _i < _keys.length; _i += 1) {\n          var _key = _keys[_i];\n          if (_runningvms[_key]) {\n            _all[_key].running = true;\n          } else {\n            _all[_key].running = false;\n          }\n        }\n        callback(_all, error);\n      });\n    });\n  }\n\n  reset(vmname, callback) {\n    this._logging.info('Resetting VM \"%s\"', vmname);\n    this.vboxmanage([\"controlvm\", vmname, \"reset\"], function (error, _) {\n      callback(error);\n    });\n  }\n\n  resume(vmname, callback) {\n    this._logging.info('Resuming VM \"%s\"', vmname);\n    this.vboxmanage([\"controlvm\", vmname, \"resume\"], function (error, _) {\n      callback(error);\n    });\n  }\n\n  start(vmname, useGui, callback) {\n    if (typeof useGui === \"function\") {\n      callback = useGui;\n      useGui = false;\n    }\n    var vmType = useGui ? \"gui\" : \"headless\";\n\n    this._logging.info('Starting VM \"%s\" with options: ', vmname, vmType);\n\n    this.vboxmanage(\n      [\"-nologo\", \"startvm\", vmname, \"--type\", vmType],\n      function (error, _) {\n        if (error && /VBOX_E_INVALID_OBJECT_STATE/.test(error.message)) {\n          error = undefined;\n        }\n        callback(error);\n      }\n    );\n  }\n\n  stop(vmname, callback) {\n    this._logging.info('Stopping VM \"%s\"', vmname);\n    this.vboxmanage([\"controlvm\", vmname, \"savestate\"], function (error, _) {\n      callback(error);\n    });\n  }\n\n  savestate(vmname, callback) {\n    this._logging.info('Saving State (alias to stop) VM \"%s\"', vmname);\n    this.stop(vmname, callback);\n  }\n\n  vmExport(vmname, output, callback) {\n    this._logging.info('Exporting VM \"%s\"', vmname);\n    this.vboxmanage(\n      [\"export\", vmname, \"--output\", output],\n      function (error, _) {\n        callback(error);\n      }\n    );\n  }\n\n  vmImport(input, options, callback) {\n    if (typeof options === \"function\") {\n      callback = options;\n      options = {};\n    }\n\n    var cmd = [\"import\", \"--vsys\", \"0\"];\n\n    if (options.vmname !== undefined) {\n      cmd.push(\"--vmname\");\n      cmd.push(options.vmname);\n    }\n\n    if (options.cpus !== undefined) {\n      cmd.push(\"--cpus\");\n      cmd.push(options.cpus.toString());\n    }\n\n    if (options.memory !== undefined) {\n      cmd.push(\"--memory\");\n      cmd.push(options.memory.toString());\n    }\n\n    cmd.push(input);\n\n    this._logging.info('Importing VM \"%s\"', input);\n    this.vboxmanage(cmd, function (error, _) {\n      callback(error);\n    });\n  }\n\n  poweroff(vmname, callback) {\n    this._logging.info('Powering off VM \"%s\"', vmname);\n    this.vboxmanage([\"controlvm\", vmname, \"poweroff\"], function (error, _) {\n      callback(error);\n    });\n  }\n\n  acpipowerbutton(vmname, callback) {\n    this._logging.info('ACPI power button VM \"%s\"', vmname);\n    this.vboxmanage([\"controlvm\", vmname, \"acpipowerbutton\"], function (error) {\n      callback(error);\n    });\n  }\n\n  acpisleepbutton(vmname, callback) {\n    this._logging.info('ACPI sleep button VM \"%s\"', vmname);\n    this.vboxmanage(\n      [\"controlvm\", vmname, \"acpisleepbutton\"],\n      function (error, _) {\n        callback(error);\n      }\n    );\n  }\n\n  modify(vname, properties, callback) {\n    this._logging.info(\"Modifying VM %s\", vname);\n    var args = [vname];\n\n    for (var property in properties) {\n      if (properties.hasOwnProperty(property)) {\n        var value = properties[property];\n        args.push(\"--\" + property);\n\n        if (Array.isArray(value)) {\n          Array.prototype.push.apply(args, value);\n        } else {\n          args.push(value.toString());\n        }\n      }\n    }\n\n    this.vboxmanage([\"modifyvm\", ...args], function (error, _) {\n      callback(error);\n    });\n  }\n\n  snapshotList(vmname, callback) {\n    this._logging.info('Listing snapshots for VM \"%s\"', vmname);\n    this.vboxmanage(\n      [\"snapshot\", vmname, \"list\", \"--machinereadable\"],\n      function (error, stdout) {\n        if (error) {\n          callback(error);\n          return;\n        }\n\n        var s;\n        var snapshots = [];\n        var currentSnapshot;\n        var lines = (stdout || \"\").split(require(\"os\").EOL);\n\n        lines.forEach(function (line) {\n          line\n            .trim()\n            .replace(\n              /^(CurrentSnapshotUUID|SnapshotName|SnapshotUUID).*\\=\"(.*)\"$/,\n              function (l, k, v) {\n                if (k === \"CurrentSnapshotUUID\") {\n                  currentSnapshot = v;\n                } else if (k === \"SnapshotName\") {\n                  s = {\n                    name: v,\n                  };\n                  snapshots.push(s);\n                } else {\n                  s.uuid = v;\n                }\n              }\n            );\n        });\n\n        callback(null, snapshots, currentSnapshot);\n      }\n    );\n  }\n\n  snapshotTake(\n    vmname,\n    name,\n    /*optional*/ description,\n    /*optional*/ live,\n    callback\n  ) {\n    this._logging.info('Taking snapshot for VM \"%s\"', vmname);\n\n    if (typeof description === \"function\") {\n      callback = description;\n      description = undefined;\n    } else if (typeof live === \"function\") {\n      callback = live;\n      live = false;\n    }\n\n    var cmd = [\"snapshot\", vmname, \"take\", name];\n\n    if (description) {\n      cmd.push(\"--description\");\n      cmd.push(description);\n    }\n\n    if (live === true) {\n      cmd.push(\"--live\");\n    }\n\n    this.vboxmanage(cmd, function (error, stdout) {\n      var uuid;\n      stdout.trim().replace(/UUID\\: ([a-f0-9\\-]+)$/, function (l, u) {\n        uuid = u;\n      });\n      callback(error, uuid);\n    });\n  }\n\n  snapshotDelete(vmname, uuid, callback) {\n    this._logging.info('Deleting snapshot \"%s\" for VM \"%s\"', uuid, vmname);\n    this.vboxmanage([\"snapshot\", vmname, \"delete\", uuid], callback);\n  }\n\n  snapshotRestore(vmname, uuid, callback) {\n    this._logging.info('Restoring snapshot \"%s\" for VM \"%s\"', uuid, vmname);\n    this.vboxmanage([\"snapshot\", vmname, \"restore\", uuid], callback);\n  }\n\n  clone(vmname, clonevmname, /*optional*/ snapshot, callback) {\n    this._logging.info('Cloning machine \"%s\" to \"%s\"', vmname, clonevmname);\n    var cmd = [\"clonevm\", vmname, \"--name\", clonevmname, \"--register\"];\n    if (typeof snapshot === \"function\") {\n      callback = snapshot;\n      snapshot = undefined;\n    } else {\n      cmd.push(\"--options\");\n      cmd.push(\"link\");\n      cmd.push(\"--snapshot\");\n      cmd.push(snapshot);\n    }\n    this.vboxmanage(cmd, callback);\n  }\n\n  isRunning(vmname, callback) {\n    this.vboxmanage([\"list\", \"runningvms\"], (error, stdout) => {\n      this._logging.info(\n        'Checking virtual machine \"%s\" is running or not',\n        vmname\n      );\n      if (stdout.indexOf(vmname) === -1) {\n        callback(error, false);\n      } else {\n        callback(error, true);\n      }\n    });\n  }\n\n  keyboardputscancode(vmname, codes, callback) {\n    var codeStr = codes\n      .map(function (code) {\n        var s = code.toString(16);\n\n        if (s.length === 1) {\n          s = \"0\" + s;\n        }\n        return s;\n      })\n      .join(\" \");\n    this._logging.info(\n      'Sending VM \"%s\" keyboard scan codes \"%s\"',\n      vmname,\n      codeStr\n    );\n    this.vboxmanage(\n      [\"controlvm\", vmname, \"keyboardputscancode\", codeStr],\n      function (error, stdout) {\n        callback(error, stdout);\n      }\n    );\n  }\n\n  exec(options, callback) {\n    var vm = options.vm || options.name || options.vmname || options.title,\n      username = options.user || options.username || \"Guest\",\n      password = options.pass || options.passwd || options.password,\n      path =\n        options.path ||\n        options.cmd ||\n        options.command ||\n        options.exec ||\n        options.execute ||\n        options.run,\n      params = options.params || options.parameters || options.args;\n\n    if (Array.isArray(params)) {\n      params = params.join(\" \");\n    }\n\n    if (params === undefined) {\n      params = \"\";\n    }\n\n    const getOSTypeCb = (os_type) => {\n      var cmd = [\"guestcontrol\", vm];\n      var runcmd = this._vboxVersion > 5 ? [\"run\"] : [\"execute\", \"--image\"];\n      cmd = [...cmd, ...runcmd];\n      switch (os_type) {\n        case known_OS_types.WINDOWS:\n          path = path.replace(/\\\\/g, \"\\\\\\\\\");\n          cmd.push(\"cmd.exe\", \"--username\", username);\n          break;\n        case known_OS_types.MAC:\n          cmd.push(\"/usr/bin/open\", \"-a\", \"--username\", username);\n          break;\n        case known_OS_types.LINUX:\n          cmd.push(\"/bin/sh\", \"--username\", username);\n          break;\n        default:\n          break;\n      }\n\n      if (password) {\n        cmd.push(\"--password\", password);\n      }\n      cmd.push(\"--\", \"/c\", path, params);\n\n      this._logging.info(\n        'Executing command \"vboxmanage %s\" on VM \"%s\" detected OS type \"%s\"',\n        cmd,\n        vm,\n        os_type\n      );\n\n      this.vboxmanage(cmd, function (error, stdout) {\n        callback(error, stdout);\n      });\n    };\n\n    this.guestproperty.os(vm, getOSTypeCb);\n  }\n\n  kill(options, callback) {\n    options = options || {};\n    var vm = options.vm || options.name || options.vmname || options.title,\n      path =\n        options.path ||\n        options.cmd ||\n        options.command ||\n        options.exec ||\n        options.execute ||\n        options.run,\n      image_name = options.image_name || path;\n\n    this.guestproperty.os(vm, (os_type) => {\n      switch (os_type) {\n        case known_OS_types.WINDOWS:\n          this._executor(\n            {\n              vm: vm,\n              user: options.user,\n              password: options.password,\n              path: \"C:\\\\Windows\\\\System32\\\\taskkill.exe /im \",\n              params: image_name,\n            },\n            callback\n          );\n          break;\n        case known_OS_types.MAC:\n        case known_OS_types.LINUX:\n          this._executor(\n            {\n              vm: vm,\n              user: options.user,\n              password: options.password,\n              path: \"sudo killall \",\n              params: image_name,\n            },\n            callback\n          );\n          break;\n      }\n    });\n  }\n\n  _setVboxManageBinary() {\n    this._logging.info(host_platform);\n    if (/^win/.test(host_platform)) {\n      // Path may not contain VBoxManage.exe but it provides this environment variable\n      const vBoxInstallPath =\n        process.env.VBOX_INSTALL_PATH || process.env.VBOX_MSI_INSTALL_PATH;\n      this._vBoxManageBinary = `${vBoxInstallPath}VBoxManage.exe`;\n    } else if (/^darwin/.test(host_platform) || /^linux/.test(host_platform)) {\n      // Mac OS X and most Linux use the same binary name, in the path\n      this._vBoxManageBinary = \"vboxmanage\";\n    } else {\n      // Otherwise (e.g., SunOS) hope it's in the path\n      this._vBoxManageBinary = \"vboxmanage\";\n    }\n  }\n\n  _detectVboxVersion() {\n    this._executor(this._vBoxManageBinary, [\"--version\"]).then(\n      ({ error, stdout }) => {\n        if (error) {\n          throw error;\n        } else {\n          this._vboxVersion = stdout.split(\".\")[0];\n          this._logging.info(\n            \"Virtualbox version detected as %s\",\n            this._vboxVersion\n          );\n        }\n      }\n    );\n  }\n}\n\nclass VboxStorage {\n  constructor(logging, executor, vBoxManageBinary) {\n    this._logging = logging;\n    this._executor = executor;\n    this._vBoxManageBinary = vBoxManageBinary;\n    this.vboxmanage = defaultvboxmanage;\n  }\n\n  addCtl(options, callback) {\n    var vm = options.vm || options.name || options.vmname || options.title,\n      device_name = options.perhiperal_name || \"IDE\",\n      type = options.type || \"ide\";\n    this._logging.info(\n      'Adding \"%s\" controller named \"%s\" to %s',\n      type,\n      device_name,\n      vm\n    );\n    var cmd = [\"storagectl\", vm, \"--name\", device_name, \"--add\", type];\n    this.vboxmanage(cmd, callback);\n  }\n\n  attach(options, callback) {\n    var vm = options.vm || options.name || options.vmname || options.title,\n      device_name = options.perhiperal_name || \"IDE\",\n      port = options.port || \"0\",\n      device = options.device || \"0\",\n      type = options.type || \"dvddrive\",\n      medium = options.medium;\n    this._logging.info(\n      'Mounting \"%s\" to controller named \"%s\" on %s',\n      medium,\n      device_name,\n      vm\n    );\n    var cmd = [\n      \"storageattach\",\n      vm,\n      \"--storagectl\",\n      device_name,\n      \"--port\",\n      port,\n      \"--device\",\n      device,\n      \"--type\",\n      type,\n      \"--medium\",\n      medium,\n    ];\n    this.vboxmanage(cmd, callback);\n  }\n}\n\nclass VboxGuestProperty {\n  constructor(logging, executor, vBoxManageBinary) {\n    this._logging = logging;\n    this._executor = executor;\n    this._vBoxManageBinary = vBoxManageBinary;\n    this.os_type = null;\n    this.vboxmanage = defaultvboxmanage;\n  }\n\n  get(options, callback) {\n    var vm = options.vm || options.name || options.vmname || options.title,\n      key = options.key,\n      defaultValue = options.defaultValue || options.value;\n\n    this.os(vm, (_) => {\n      this.vboxmanage(\n        [\"guestproperty\", \"get\", vm, key],\n        function (error, stdout) {\n          var value;\n          if (error) {\n            throw error;\n          }\n          try {\n            value = stdout.substr(stdout.indexOf(\":\") + 1).trim();\n          } catch (ex) {\n            this._logging.error(ex);\n            callback(defaultValue);\n          }\n          if (value === \"No value set!\") {\n            value = defaultValue || undefined;\n          }\n          callback(value);\n        }\n      );\n    });\n  }\n\n  os(vmname, callback) {\n    if (this.os_type) {\n      return callback(this.os_type);\n    }\n\n    try {\n      this.vboxmanage(\n        [\"showvminfo\", \"--machinereadable\", vmname],\n        (error, stdout, _) => {\n          if (error) {\n            throw error;\n          }\n\n          // The ostype is matched against the ID attribute of 'vboxmanage list ostypes'\n          if (stdout.indexOf('ostype=\"Windows') !== -1) {\n            this.os_type = known_OS_types.WINDOWS;\n          } else if (\n            ['ostype=\"MacOS', 'ostype=\"Mac OS machine'].includes(stdout)\n          ) {\n            this.os_type = known_OS_types.MAC;\n          } else {\n            this.os_type = known_OS_types.LINUX;\n          }\n          this._logging.debug(\"Detected guest OS as: \" + this.os_type);\n          callback(this.os_type);\n        }\n      );\n    } catch (e) {\n      this._logging.error(e);\n      this._logging.info(\"Could not showvminfo for %s\", vmname);\n    }\n  }\n\n  /**\n   * Function to return an array of this object:\n   * {\n   *    \"key\": \"ResumeCounter\",\n   *    \"value\": 0,\n   *    \"namespace\": \"VMInfo\",\n   *    \"timestamp\": 1596902741176896000,\n   *    \"flags\": [\"TRANSIENT\", \"RDONLYGUEST\"]\n   * }\n   * @param {String} vmname The name of the VM to enumerate guest properties on.\n   * @param {Function} callback The callback to handle the output.\n   * @returns {void} The output of stdout will be an array of properties objects.\n   */\n  enumerate(vmname, callback) {\n    this.vboxmanage(\n      [\"guestproperty\", \"enumerate\", vmname],\n      (err, stdout, _) => {\n        if (err) {\n          throw err;\n        }\n        const arrOfProps = stdout.split(\"\\n\");\n        const nameRegex = /(?<=Name: ).+?(?=\\,)/;\n        const valueRegex = /(?<=value: ).+?(?=\\,)/;\n        const timestampRegex = /(?<=timestamp: ).+?(?=\\,)/;\n        const flagsRegex = /(?<=flags: ).*/;\n\n        const arrOfPropsParsed = [];\n        arrOfProps\n          .filter((prop) => !!prop)\n          .forEach((prop) => {\n            const nameMatch = prop.match(nameRegex).shift(),\n              value = prop.match(valueRegex).shift(),\n              timestamp = prop.match(timestampRegex).shift(),\n              flags = prop\n                .match(flagsRegex)\n                .shift()\n                .split(\",\")\n                .map((flag) => flag.replace(\" \", \"\")),\n              nameMatchSplit = nameMatch\n                .split(\"/\")\n                .filter((name) => name !== \"\"),\n              key = nameMatchSplit[2],\n              namespace = nameMatchSplit[1];\n            arrOfPropsParsed.push({\n              key,\n              value,\n              namespace,\n              timestamp,\n              flags,\n            });\n          });\n        callback(err, arrOfPropsParsed);\n      }\n    );\n  }\n}\n\nclass VboxExtraData {\n  constructor(logging, executor, vBoxManageBinary) {\n    this._logging = logging;\n    this._executor = executor;\n    this._vBoxManageBinary = vBoxManageBinary;\n    this.vboxmanage = defaultvboxmanage;\n  }\n\n  get(options, callback) {\n    var vm = options.vm || options.name || options.vmname || options.title,\n      key = options.key,\n      defaultValue = options.defaultValue || options.value;\n\n    this.vboxmanage([\"getextradata\", vm, key], function (error, stdout) {\n      var value;\n      if (error) {\n        callback(error);\n        return;\n      }\n      try {\n        value = stdout.substr(stdout.indexOf(\":\") + 1).trim();\n      } catch (ex) {\n        this._logging.error(ex);\n        callback(ex, defaultValue);\n      }\n      if (value === \"No value set!\") {\n        value = defaultValue || undefined;\n      }\n      callback(null, value);\n    });\n  }\n\n  set(options, callback) {\n    var vm = options.vm || options.name || options.vmname || options.title,\n      key = options.key,\n      value = options.defaultValue || options.value;\n\n    var cmd = [\"setextradata\", vm, key, value];\n    this.vboxmanage(cmd, function (error, _) {\n      callback(error);\n    });\n  }\n}\n\n// module.exports = {\n//   'exec': vmExec,\n//   'kill': vmKill,\n//   'list': list,\n//   'pause': pause,\n//   'reset': reset,\n//   'resume': resume,\n//   'start': start,\n//   'stop': stop,\n//   'savestate': savestate,\n//   'import': vmImport,\n//   'export': vmExport,\n//   'poweroff': poweroff,\n//   'acpisleepbutton': acpisleepbutton,\n//   'acpipowerbutton': acpipowerbutton,\n//   'modify': modify,\n//   'guestproperty': guestproperty,\n//   'keyboardputscancode': keyboardputscancode,\n//   'snapshotList': snapshotList,\n//   'snapshotTake': snapshotTake,\n//   'snapshotDelete': snapshotDelete,\n//   'snapshotRestore': snapshotRestore,\n//   'isRunning': isRunning,\n//   'extradata': extradata,\n//   'clone': clone,\n//   'storage': storage,\n\n//   'SCAN_CODES': require('./scan-codes')\n// };\n\nmodule.exports = new Virtualbox();\nmodule.exports.create = Virtualbox.create;\nmodule.exports.Virtualbox = Virtualbox;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"virtualbox\",\n  \"version\": \"1.1.2\",\n  \"description\": \"A library to interact with VirtualBox.\",\n  \"author\": \"Azer Koculu <azer@kodfabrik.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": \"https://github.com/Node-Virtualization/node-virtualbox/issues\",\n  \"contributors\": [\n    {\n      \"name\": \"Azer Koculu\",\n      \"url\": \"http://azer.bike\",\n      \"email\": \"azer@kodfabrik.com\"\n    },\n    {\n      \"name\": \"Michael Sanford\",\n      \"url\": \"http://accidentalbeard.com\"\n    },\n    {\n      \"name\": \"Jonathan Ling\",\n      \"url\": \"https://jonathanling.net\"\n    },\n    {\n      \"name\": \"Steffen Roegner\",\n      \"url\": \"http://www.sroegner.org\"\n    },\n    {\n      \"name\": \"Jakub Lekstan\",\n      \"url\": \"https://github.com/kuebk\"\n    },\n    {\n      \"name\": \"Christopher'chief' Najewicz\",\n      \"url\": \"http://chiefy.github.io\"\n    },\n    {\n      \"name\": \"Cédric Belin\",\n      \"url\": \"http://belin.io\"\n    },\n    {\n      \"name\": \"bschaepper\",\n      \"url\": \"https://github.com/bschaepper\"\n    },\n    {\n      \"name\": \"2roy999\",\n      \"url\": \"https://github.com/2roy999\"\n    },\n    {\n      \"name\": \"Felipe Miranda\",\n      \"url\": \"https://github.com/felipemdrs\"\n    }\n  ],\n  \"keywords\": [\n    \"virtualbox\",\n    \"vboxmanage\",\n    \"vboxheadless\"\n  ],\n  \"directories\": {\n    \"lib\": \"./lib\"\n  },\n  \"scripts\": {\n    \"test\": \"jest ./test/*.spec.js\",\n    \"lint\": \"eslint ./lib ./test\"\n  },\n  \"main\": \"./lib/virtualbox\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Node-Virtualization/node-virtualbox.git\"\n  },\n  \"devDependencies\": {\n    \"async\": \"^3.2.5\",\n    \"eslint\": \"^8.57.0\",\n    \"jest\": \"^26.0.1\",\n    \"jsdoc\": \"^4.0.2\",\n    \"prettier\": \"^3.2.5\"\n  },\n  \"engines\": {\n    \"engine\": \"node >= 18\"\n  },\n  \"dependencies\": {\n    \"log4js\": \"^6.9.1\"\n  }\n}\n"
  },
  {
    "path": "test/guestproperty.spec.js",
    "content": "'use strict';\n\nconst { logger } = require('./helpers/logger');\nconst { create } = require('../lib/virtualbox');\n\ndescribe('Virtualbox#guestproperty', () => {\n  it('should not throw an error when getting a guest property with ostype of MacOS', (done) => {\n    const executor = jest\n      .fn()\n      .mockReturnValueOnce(\n        new Promise((resolve) =>\n          resolve({ err: null, stdout: 'somevalue', stderr: '' })\n        )\n      )\n      .mockReturnValueOnce(\n        new Promise((resolve) =>\n          resolve({ err: null, stdout: 'ostype=\"MacOS', stderr: '' })\n        )\n      )\n      .mockReturnValueOnce(\n        new Promise((resolve) =>\n          resolve({\n            err: null,\n            stdout: 'somevalue',\n            stderr: '',\n          })\n        )\n      );\n    const virtualbox = create(logger, executor);\n    virtualbox.guestproperty.get(\n      { vm: 'testmachine', key: 'someProperty' },\n      function (value) {\n        expect(value).toBeTruthy();\n        expect(virtualbox.guestproperty.os_type).toBe('mac');\n        done();\n      }\n    );\n  });\n\n  it('should not throw an error when getting a guest property with ostype of Mac OS machine', (done) => {\n    const executor = jest\n      .fn()\n      .mockReturnValueOnce(\n        new Promise((resolve) =>\n          resolve({\n            err: null,\n            stdout: 'somevalue',\n            stderr: '',\n          })\n        )\n      )\n      .mockReturnValueOnce(\n        new Promise((resolve) =>\n          resolve({\n            err: null,\n            stdout: 'ostype=\"Mac OS machine',\n            stderr: '',\n          })\n        )\n      )\n      .mockReturnValueOnce(\n        new Promise((resolve) =>\n          resolve({\n            err: null,\n            stdout: 'somevalue',\n            stderr: '',\n          })\n        )\n      );\n    const virtualbox = create(logger, executor);\n    virtualbox.guestproperty.get(\n      { vm: 'testmachine', key: 'someProperty' },\n      function (value) {\n        expect(value).toBeTruthy();\n        expect(virtualbox.guestproperty.os_type).toBe('mac');\n        done();\n      }\n    );\n  });\n});\n"
  },
  {
    "path": "test/helpers/logger.js",
    "content": "\"use strict\";\nconst log4js = require(\"log4js\"),\n  defaultLoggingConfig = {\n    appenders: {\n      out: {\n        type: \"stdout\",\n        layout: {\n          type: \"pattern\",\n          pattern: \"%[[%d{yyyy-MM-dd hh:mm:ss.SSS}] [%p] %c - %]%m\",\n        },\n      },\n    },\n    categories: { default: { appenders: [\"out\"], level: \"debug\" } },\n  };\n\nlog4js.configure(defaultLoggingConfig);\n\nmodule.exports.logger = log4js.getLogger(\"VboxTestLogger\");\n"
  },
  {
    "path": "test/integration/acpipowerbutton.js",
    "content": "'use strict';\n\nconst virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.acpipowerbutton(vmName, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/acpisleepbutton.js",
    "content": "'use strict';\n\nconst virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.acpisleepbutton(vmName, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/exec.js",
    "content": "\"use strict\";\n\nconst virtualbox = require(\"../../lib/virtualbox\"),\n  vm = \"node-virtualbox-test-machine\",\n  user = \"vagrant\",\n  pass = \"vagrant\",\n  { logger } = require(\"../helpers/logger\"),\n  ostype = virtualbox.guestproperty.os(vm);\nlet path;\n\nif (ostype === \"windows\") {\n  path = \"C:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe\";\n} else if (ostype === \"mac\") {\n  path = \"Safari.app\";\n} else {\n  path = \"ping\";\n}\n\nvirtualbox.start(vm, function () {\n  virtualbox.exec(\n    {\n      vm: vm,\n      user: user,\n      passwd: pass,\n      path: path,\n      params: [\"http://google.com\"],\n    },\n    function (error, stdout) {\n      if (error) {\n        throw error;\n      }\n      logger.debug(stdout);\n    }\n  );\n});\n"
  },
  {
    "path": "test/integration/export.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.export(vmName, 'test-export', function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/getextradata.js",
    "content": "\"use strict\";\n\nvar virtualbox = require(\"../../lib/virtualbox\"),\n  vmname = \"node-virtualbox-test-machine\",\n  { logger } = require(\"../helpers/logger\"),\n  key = \"some-data-key\";\n\nvirtualbox.extradata.get({ vmname, key }, function (error, value) {\n  if (error) {\n    throw error;\n  }\n\n  logger.debug(\n    'Virtual Machine \"%s\" extra \"%s\" value is \"%s\"',\n    vmname,\n    key,\n    value\n  );\n});\n"
  },
  {
    "path": "test/integration/guestproperty-enumerate.js",
    "content": "\"use strict\";\n\nconst virtualbox = require(\"../../lib/virtualbox\"),\n  { logger } = require(\"../helpers/logger\"),\n  vm = \"node-virtualbox-test-machine\";\n\nvirtualbox.guestproperty.enumerate(vm, (err, arr) => {\n  logger.debug(arr);\n});\n"
  },
  {
    "path": "test/integration/guestproperty.js",
    "content": "\"use strict\";\n\nconst virtualbox = require(\"../../lib/virtualbox\"),\n  { logger } = require(\"../helpers/logger\"),\n  options = {\n    vm: \"node-virtualbox-test-machine\",\n    key: \"/VirtualBox/GuestInfo/Net/0/V4/IP\",\n  };\n\nvirtualbox.guestproperty.get(options, (error, stdout, _) => {\n  if (error) {\n    throw error;\n  }\n  logger.debug(error, stdout, _);\n  logger.debug(stdout);\n});\n"
  },
  {
    "path": "test/integration/isRunning.js",
    "content": "\"use strict\";\n\nvar virtualbox = require(\"../../lib/virtualbox\"),\n  { logger } = require(\"../helpers/logger\"),\n  vm = \"node-virtualbox-test-machine\";\n\nvirtualbox.isRunning(vm, function (error, isRunning) {\n  if (error) {\n    throw error;\n  }\n  if (isRunning) {\n    logger.log('Virtual Machine \"%s\" is Running', vm);\n  } else {\n    logger.log('Virtual Machine \"%s\" is Poweroff', vm);\n  }\n});\n"
  },
  {
    "path": "test/integration/keyboardputscancode.js",
    "content": "\"use strict\";\n\nvar virtualbox = require(\"../../lib/virtualbox\"),\n  { logger } = require(\"../helpers/logger\"),\n  async = require(\"async\"),\n  args = process.argv.slice(2),\n  vm = \"node-virtualbox-test-machine\",\n  key = args.length > 1 && args[1],\n  delay = 250,\n  sequence;\n\nvar SCAN_CODES = virtualbox.SCAN_CODES;\n\nvar fns = [];\n\n/**\n *\n * Uncomment the following if you want to\n * test a particular key down/up (make/break)\n * sequence.\n *\n **/\n\n// SHIFT + A Sequence\nsequence = [\n  { key: \"SHIFT\", type: \"make\", code: SCAN_CODES[\"SHIFT\"] },\n  { key: \"A\", type: \"make\", code: SCAN_CODES[\"A\"] },\n  { key: \"SHIFT\", type: \"break\", code: SCAN_CODES.getBreakCode(\"SHIFT\") },\n  { key: \"A\", type: \"break\", code: SCAN_CODES.getBreakCode(\"A\") },\n];\n\nfunction onResponse(err) {\n  if (err) {\n    throw err;\n  }\n}\n\nfunction generateFunc(key, type, code) {\n  return function (cb) {\n    setTimeout(function () {\n      logger.info(\"Sending %s %s code\", key, type);\n      virtualbox.keyboardputscancode(vm, code, function (err) {\n        onResponse(err);\n        cb();\n      });\n    }, delay);\n  };\n}\n\nfunction addKeyFuncs(key) {\n  var makeCode = SCAN_CODES[key];\n  var breakCode = SCAN_CODES.getBreakCode(key);\n\n  if (makeCode && makeCode.length) {\n    fns.push(generateFunc(key, \"make\", makeCode));\n\n    if (breakCode && breakCode.length) {\n      fns.push(generateFunc(key, \"break\", breakCode));\n    }\n  }\n}\n\nif (sequence) {\n  fns = sequence.map(function (s) {\n    return generateFunc(s.key, s.type, s.code);\n  });\n} else if (key) {\n  addKeyFuncs(key);\n} else {\n  for (var codeKey in SCAN_CODES) {\n    if (codeKey === \"getBreakCode\") {\n      continue;\n    }\n    addKeyFuncs(key);\n  }\n}\n\nasync.series(fns, function () {\n  logger.info(\"Keyboard Put Scan Code Test Complete\");\n});\n"
  },
  {
    "path": "test/integration/list.js",
    "content": "'use strict';\n\nvar util = require('util');\nvar virtualbox = require('../../lib/virtualbox');\n\nvirtualbox.list(function (list_data, error) {\n  if (error) {\n    throw error;\n  }\n\n  if (list_data) {\n    virtualbox._logging.log(util.inspect(list_data));\n    //logger.log(list_data);\n  }\n});\n"
  },
  {
    "path": "test/integration/modify.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.modify(vmName, { memory: 64 }, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/pause.js",
    "content": "'use strict';\n\nconst virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.pause(vmName, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/poweroff.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.poweroff(vmName, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/resume.js",
    "content": "'use strict';\n\nconst virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.resume(vmName, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/savestate.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.savestate(vmName, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/setextradata.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vmname = 'node-virtualbox-test-machine',\n  key = 'some_value',\n  value = 'kind of value';\n\nvirtualbox.extradata.set({ vmname, key, value }, function (error, result) {\n  if (error) {\n    throw error;\n  }\n\n  virtualbox._logging.log(\n    'Set Virtual Machine \"%s\" extra \"%s\" value to \"%s\"; result is \"%s\"',\n    vmname,\n    key,\n    value,\n    result\n  );\n});\n"
  },
  {
    "path": "test/integration/snapshot-delete.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vm = 'node-virtualbox-test-machine',\n  uuid = '44f96692-854f-4358-b246-d455bc403e16';\n\nvirtualbox.snapshotDelete(vm, uuid, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/snapshot-list.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vm = 'node-virtualbox-test-machine';\n\nvirtualbox.snapshotList(vm, function (\n  error,\n  snapshotList,\n  currentSnapshotUUID\n) {\n  if (error) {\n    throw error;\n  }\n\n  if (snapshotList) {\n    virtualbox._logging.log(\n      JSON.stringify(snapshotList),\n      JSON.stringify(currentSnapshotUUID)\n    );\n  }\n});\n"
  },
  {
    "path": "test/integration/snapshot-restore.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vm = 'node-virtualbox-test-machine',\n  uuid = '44f96692-854f-4358-b246-d455bc403e16';\n\nvirtualbox.snapshotRestore(vm, uuid, function (error) {\n  if (error) {\n    throw error;\n  }\n\n  virtualbox._logging.log('Virtual machine has been restored');\n});\n"
  },
  {
    "path": "test/integration/snapshot-take.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vmname = 'node-virtualbox-test-machine',\n  exportName = 'test-export';\n\nvirtualbox.snapshotTake(vmname, exportName, function (error, uuid) {\n  if (error) {\n    throw error;\n  }\n  if (uuid) {\n    virtualbox._logging.log('UUID: ' + uuid);\n  }\n});\n"
  },
  {
    "path": "test/integration/start.js",
    "content": "'use strict';\n\nconst virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.start(vmName, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  },
  {
    "path": "test/integration/stop.js",
    "content": "'use strict';\n\nvar virtualbox = require('../../lib/virtualbox'),\n  vmName = 'node-virtualbox-test-machine';\n\nvirtualbox.stop(vmName, function (error) {\n  if (error) {\n    throw error;\n  }\n});\n"
  }
]