[
  {
    "path": ".github/workflows/alpine.yml",
    "content": "name: test-alpine\n\non:\n  push:\n    branches: '*'\n  pull_request:\n    branches: '*'\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    name: Test alpine\n    steps:\n      - uses: actions/checkout@v2\n      - run: |\n          docker build . -t pidusage \n          docker run -v $(pwd):/var/pidusage pidusage:latest npm install\n          docker run -v $(pwd):/var/pidusage pidusage:latest npm test\n"
  },
  {
    "path": ".github/workflows/lint.yml",
    "content": "name: lint\n\non:\n  push:\n    branches: '*'\n  pull_request:\n    branches: '*'\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    name: Lint\n    steps:\n      - name: Setup repo\n        uses: actions/checkout@v2\n      - name: Setup node\n        uses: actions/setup-node@v1\n      - name: Install dev dependencies\n        run: |\n          npm install --only=dev\n      - name: Run lint\n        run: npm run lint\n"
  },
  {
    "path": ".github/workflows/macos.yml",
    "content": "name: test-macos\n\non:\n  push:\n    branches: '*'\n  pull_request:\n    branches: '*'\n\njobs:\n  test:\n    runs-on: macos-latest\n    name: Test MacOS\n    steps:\n      - uses: actions/checkout@v2\n      - name: Setup node\n        uses: actions/setup-node@v2\n      - run: npm install\n      - run: npm test\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: linux\n\non:\n  push:\n    branches: '*'\n  pull_request:\n    branches: '*'\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node: [ '18', '20', '22', '23' ]\n    name: Test Node ${{ matrix.node }}\n    steps:\n      - uses: actions/checkout@v2\n      - name: Setup node\n        uses: actions/setup-node@v2\n        with:\n          node-version: ${{ matrix.node }}\n      - run: npm install\n      - run: npm test\n  coverage:\n    runs-on: ubuntu-latest\n    name: Test coverage\n    steps:\n      - uses: actions/checkout@v2\n      - name: Setup node\n        uses: actions/setup-node@v2\n      - run: npm install\n      - run: npm run coverage\n      - uses: codecov/codecov-action@v5\n"
  },
  {
    "path": ".github/workflows/windows.yml",
    "content": "name: test-windows\n\non:\n  push:\n    branches: '*'\n  pull_request:\n    branches: '*'\n\njobs:\n  test:\n    runs-on: windows-latest\n    name: Test Windows\n    steps:\n      - uses: actions/checkout@v2\n      - name: Setup node\n        uses: actions/setup-node@v2\n      - run: npm install\n      - run: npm test\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.nyc_output\ncoverage\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "### 4.0.1\n\n- fix spawned wmic processes not exiting after wmic/gwmi detection in packaged apps, leading to infinite build up of \"WMI Commandline Utility\" processes and system instability\n\n### 4.0.0\n\n- fix wmic removed on Windows 11 and add gwmi support\n- node >= 17 \n\n### 3.0.1\n\n- removed dynamic requires to allow for bundling #154\n- add ibm platform (os400) #158\n\n### 3.0\n\n- removes node 8 support\n- add z/OS (os390) support\n- environment variables to configure pidusage (`PIDUSAGE_USE_PS`, `PIDUSAGE_MAXAGE`, `PIDUSAGE_SILENT`)\n- use a default Date when `uptime` returns `undefined`\n\n### 2.0.17\n\n- allow to manually clear the event loop when needed it'll clear itself after a given timeout (default to `60000ms` but you can specify it with the `maxage` option, [see this file](https://github.com/soyuka/pidusage/blob/master/test/fixtures/eventloop.js#L3)) [1740a4f](https://github.com/soyuka/pidusage/commit/2779e520d3414a8318c86279cf14bebae3264604)\n- fix elapsed and timestamp calculations on linux [#80](https://github.com/soyuka/pidusage/issues/80) [e5e2b01](https://github.com/soyuka/pidusage/commit/081984a04bc97ad8abd82315f936861cce1df0d6)\n\n### 2.0.16\n\n- fix ps on darwin, centisenconds multiplier was wrong and was giving bad cpu usage values [bcda538](https://github.com/soyuka/pidusage/commit/bcda538b76498c6d4bcaa36520238990554929c5)\n\n### 2.0.15\n\n- Fix Buffer.alloc for node < 4.5\n\n### 2.0.14\n\n- Version unpublished because of a publish mistake from my part due to a npm error message that confused me. Explanation [in isse #71](https://github.com/soyuka/pidusage/issues/72#issuecomment-407572581)\n\n### 2.0.12\n\n- fix #69 with `ps` use elapsed instead of etime to avoid negative cpu values [0994268](https://github.com/soyuka/pidusage/commit/0994268c297e23efa3d9052f24cbacf2cbe31629)\n- fix typo in aix `ps` command #68 [7d55518](https://github.com/soyuka/pidusage/commit/7d55518b7d5d5aae964e64ddd7b13ecec75463a1)\n\n### 2.0.10\n\n- aix is using ps (was changed by mistake), still no aix CI though\n- add alpine to the test suite and make it use procfile\n- Improve procfile performances by keeping the procfile open [da1c5fb](https://github.com/soyuka/pidusage/commit/da1c5fb2480bdf8f871476d79161dac7733b89f3)\n\n### 2.0.8\n\n- After further discussion cpu formula got reverted to the initial one [f990f72](https://github.com/soyuka/pidusage/commit/f990f72fd185e4ba0a87048e6e6c59f814a016cc)\n\n\n### 2.0.7\n\n- Cpu formula changed a bit because of multi thread issues see [issue #58](https://github.com/soyuka/pidusage/issues/58) [88972d8](https://github.com/soyuka/pidusage/commit/88972d8cd38d4137b70261a830af22283b69c57c)\n\n### 2.0.6\n\n- procfiles are back because of performance issues [85e20fa](https://github.com/soyuka/pidusage/commit/85e20fa30aa9ff01d87d3ba9be7fec7f805fc5fb)\n\n### 2.0\n\n- allow multiple pids\n- remove `advanced` option\n- don't use `/proc` (procfiles) anymore but use `ps` instead\n- more tests\n- API change no more `stat` method, module exports a single function\n- no more `unmonitor` method, this is handed internally\n- the default call now returns more data:\n\n```\n{\n  cpu: 10.0,            // percentage (it may happen to be greater than 100%)\n  memory: 357306368,    // bytes\n  ppid: 312,            // PPID\n  pid: 727,             // PID\n  ctime: 867000,        // ms user + system time\n  elapsed: 6650000,     // ms since the start of the process\n  timestamp: 864000000  // ms since epoch\n}\n```\n\n### 1.2.0\n\nIntroduce `advanced` option to get time, and start\n\n### 1.1.0\n\nWindows: (wmic) goes back to the first version of wmic, naming `wmic process {pid} get workingsetsize,usermodetime,kernelmodetime`. CPU usage % is computed on the flight, per pid.\n\n### 1.0.5\n\nWindows: (wmic) Use raw data instead of formatted this should speed up wmic\n\n### 0.1.0\nAPI changes:\n```\nrequire('pidusage').stat(pid, fn)\n```\ninstead of:\n```\nrequire('pidusage')(pid, fn)\n```\nAdds a `unmonitor` method to clear process history\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM node:alpine\n\nRUN mkdir -p /var/pidusage\n\nWORKDIR /var/pidusage\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 soyuka\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."
  },
  {
    "path": "README.md",
    "content": "# pidusage\n\n[![Lint](https://github.com/soyuka/pidusage/workflows/lint/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:lint+branch:main)\n[![MacOS](https://github.com/soyuka/pidusage/workflows/test-macos/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:test-macos+branch:main)\n[![Ubuntu](https://github.com/soyuka/pidusage/workflows/linux/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:linux+branch:main)\n[![Windows](https://github.com/soyuka/pidusage/workflows/test-windows/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:test-windows+branch:main)\n[![Alpine](https://github.com/soyuka/pidusage/workflows/test-alpine/badge.svg?branch=main)](https://github.com/soyuka/pidusage/actions?query=workflow:test-alpine+branch:main)\n[![Code coverage](https://img.shields.io/codecov/c/github/soyuka/pidusage/master.svg)](https://codecov.io/gh/soyuka/pidusage)\n[![npm version](https://img.shields.io/npm/v/pidusage.svg)](https://www.npmjs.com/package/pidusage)\n[![license](https://img.shields.io/github/license/soyuka/pidusage.svg)](https://github.com/soyuka/pidusage/tree/master/license)\n\nCross-platform process cpu % and memory usage of a PID.\n\n## Synopsis\n\nIdeas from https://github.com/arunoda/node-usage but with no C-bindings.\n\nPlease note that if you need to check a Node.JS script process cpu and memory usage, you can use [`process.cpuUsage`][node:cpuUsage] and [`process.memoryUsage`][node:memUsage] since node v6.1.0. This script remain useful when you have no control over the remote script, or if the process is not a Node.JS process.\n\n\n## Usage\n\n```js\nvar pidusage = require('pidusage')\n\npidusage(process.pid, function (err, stats) {\n  console.log(stats)\n  // => {\n  //   cpu: 10.0,            // percentage (from 0 to 100*vcore)\n  //   memory: 357306368,    // bytes\n  //   ppid: 312,            // PPID\n  //   pid: 727,             // PID\n  //   ctime: 867000,        // ms user + system time\n  //   elapsed: 6650000,     // ms since the start of the process\n  //   timestamp: 864000000  // ms since epoch\n  // }\n  cb()\n})\n\n// It supports also multiple pids\npidusage([727, 1234], function (err, stats) {\n  console.log(stats)\n  // => {\n  //   727: {\n  //     cpu: 10.0,            // percentage (from 0 to 100*vcore)\n  //     memory: 357306368,    // bytes\n  //     ppid: 312,            // PPID\n  //     pid: 727,             // PID\n  //     ctime: 867000,        // ms user + system time\n  //     elapsed: 6650000,     // ms since the start of the process\n  //     timestamp: 864000000  // ms since epoch\n  //   },\n  //   1234: {\n  //     cpu: 0.1,             // percentage (from 0 to 100*vcore)\n  //     memory: 3846144,      // bytes\n  //     ppid: 727,            // PPID\n  //     pid: 1234,            // PID\n  //     ctime: 0,             // ms user + system time\n  //     elapsed: 20000,       // ms since the start of the process\n  //     timestamp: 864000000  // ms since epoch\n  //   }\n  // }\n})\n\n// If no callback is given it returns a promise instead\nconst stats = await pidusage(process.pid)\nconsole.log(stats)\n// => {\n//   cpu: 10.0,            // percentage (from 0 to 100*vcore)\n//   memory: 357306368,    // bytes\n//   ppid: 312,            // PPID\n//   pid: 727,             // PID\n//   ctime: 867000,        // ms user + system time\n//   elapsed: 6650000,     // ms since the start of the process\n//   timestamp: 864000000  // ms since epoch\n// }\n\n// Avoid using setInterval as they could overlap with asynchronous processing\nfunction compute(cb) {\n  pidusage(process.pid, function (err, stats) {\n    console.log(stats)\n    // => {\n    //   cpu: 10.0,            // percentage (from 0 to 100*vcore)\n    //   memory: 357306368,    // bytes\n    //   ppid: 312,            // PPID\n    //   pid: 727,             // PID\n    //   ctime: 867000,        // ms user + system time\n    //   elapsed: 6650000,     // ms since the start of the process\n    //   timestamp: 864000000  // ms since epoch\n    // }\n    cb()\n  })\n}\n\nfunction interval(time) {\n  setTimeout(function() {\n    compute(function() {\n      interval(time)\n    })\n  }, time)\n}\n\n// Compute statistics every second:\ninterval(1000)\n\n// Above example using async/await\nconst compute = async () => {\n  const stats = await pidusage(process.pid)\n  // do something\n}\n\n// Compute statistics every second:\nconst interval = async (time) => {\n  setTimeout(async () => {\n    await compute()\n    interval(time)\n  }, time)\n}\n\ninterval(1000)\n```\n\n## Compatibility\n\n| Property | Linux | FreeBSD | NetBSD | SunOS | macOS | Win | AIX | Alpine\n| ---         | --- | --- | --- | --- | --- | --- | --- | --- |\n| `cpu`       | ✅ | ❓ | ❓ | ❓ | ✅ | ℹ️ | ❓ | ✅ |\n| `memory`    | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |\n| `pid`       | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |\n| `ctime`     | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |\n| `elapsed`   | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |\n| `timestamp` | ✅ | ❓ | ❓ | ❓ | ✅ | ✅ | ❓ | ✅ |\n\n✅ = Working\nℹ️ = Not Accurate\n❓ = Should Work\n❌ = Not Working\n\nPlease if your platform is not supported or if you have reported wrong readings\n[file an issue][new issue].\n\nBy default, pidusage will use `procfile` parsing on most unix systems. If you want to use `ps` instead use the `usePs` option:\n\n```\npidusage(pid, {usePs: true})\n```\n\n## API\n\n<a name=\"pidusage\"></a>\n\n### pidusage(pids, [options = {}], [callback]) ⇒ <code>[Promise.&lt;Object&gt;]</code>\nGet pid informations.\n\n**Kind**: global function\n**Returns**: <code>Promise.&lt;Object&gt;</code> - Only when the callback is not provided.\n**Access**: public\n\n| Param | Type | Description |\n| --- | --- | --- |\n| pids | <code>Number</code> \\| <code>Array.&lt;Number&gt;</code> \\| <code>String</code> \\| <code>Array.&lt;String&gt;</code> | A pid or a list of pids. |\n| [options] | <code>object</code> | Options object. See the table below. |\n| [callback] | <code>function</code> | Called when the statistics are ready. If not provided a promise is returned instead. |\n\n### options\n\nSetting the options programatically will override environment variables\n\n| Param | Type | Environment variable | Default | Description |\n| --- | --- | --- | --- | --- |\n| [usePs] | <code>boolean</code> | `PIDUSAGE_USE_PS`| `false` | When true uses `ps` instead of proc files to fetch process information |\n| [maxage] | <code>number</code> | `PIDUSAGE_MAXAGE`| `60000` | Max age of a process on history. |\n\n`PIDUSAGE_SILENT=1` can be used to remove every console message triggered by pidusage.\n\n### pidusage.clear()\n\nIf needed this function can be used to delete all in-memory metrics and clear the event loop. This is not necessary before exiting as the interval we're registring does not hold up the event loop.\n\n## Related\n- [pidusage-tree][gh:pidusage-tree] -\nCompute a pidusage tree\n\n## Authors\n- **Antoine Bluchet** - [soyuka][github:soyuka]\n- **Simone Primarosa** - [simonepri][github:simonepri]\n\nSee also the list of [contributors][contributors] who participated in this project.\n\n## License\nThis project is licensed under the MIT License - see the [LICENSE][license] file for details.\n\n<!-- Links -->\n[new issue]: https://github.com/soyuka/pidusage/issues/new\n[license]: https://github.com/soyuka/pidusage/tree/master/LICENSE\n[contributors]: https://github.com/soyuka/pidusage/contributors\n\n[github:soyuka]: https://github.com/soyuka\n[github:simonepri]: https://github.com/simonepri\n\n[gh:pidusage-tree]: https://github.com/soyuka/pidusage-tree\n\n[node:cpuUsage]: https://nodejs.org/api/process.html#process_process_cpuusage_previousvalue\n[node:memUsage]: https://nodejs.org/api/process.html#process_process_memoryusage\n"
  },
  {
    "path": "examples/README.md",
    "content": "# Example section\n\n## server.js\n\nUsed to be tested with an HTTP benchmark tool like this one: https://github.com/wg/wrk.\n\nStart the server, run the tests on `localhost:8020`\n\n## stresstest.js\n\nJust start node stresstest.js (but be carefull though...)\n"
  },
  {
    "path": "examples/server.js",
    "content": "const http = require('http')\nconst pidusage = require('../')\n\nhttp.createServer(function (req, res) {\n  res.writeHead(200)\n  res.end('hello world\\n')\n}).listen(8020)\n\nconst interval = setInterval(function () {\n  pidusage(process.pid, function (err, stat) {\n    if (err) {\n      throw err\n    }\n\n    console.log(stat)\n  })\n}, 100)\n\nprocess.on('exit', function () {\n  clearInterval(interval)\n})\n"
  },
  {
    "path": "examples/stresstest.js",
    "content": "const pusage = require('../')\n\n// stress test to compare with top or another tool\nconsole.log('This is my PID: %s', process.pid)\n\n// classic \"drop somewhere\"... yeah I'm a lazy guy\nconst formatBytes = function (bytes, precision) {\n  const kilobyte = 1024\n  const megabyte = kilobyte * 1024\n  const gigabyte = megabyte * 1024\n  const terabyte = gigabyte * 1024\n\n  if ((bytes >= 0) && (bytes < kilobyte)) {\n    return bytes + ' B   '\n  } else if ((bytes >= kilobyte) && (bytes < megabyte)) {\n    return (bytes / kilobyte).toFixed(precision) + ' KB  '\n  } else if ((bytes >= megabyte) && (bytes < gigabyte)) {\n    return (bytes / megabyte).toFixed(precision) + ' MB  '\n  } else if ((bytes >= gigabyte) && (bytes < terabyte)) {\n    return (bytes / gigabyte).toFixed(precision) + ' GB  '\n  } else if (bytes >= terabyte) {\n    return (bytes / terabyte).toFixed(precision) + ' TB  '\n  } else {\n    return bytes + ' B   '\n  }\n}\n\nlet i = 0\nconst bigMemoryLeak = []\n\nconst stress = function (cb) {\n  let j = 500\n  const arr = []\n\n  while (j--) {\n    arr[j] = []\n\n    for (let k = 0; k < 1000; k++) {\n      arr[j][k] = { lorem: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non odio venenatis, pretium ligula nec, fringilla ipsum. Sed a erat et sem blandit dignissim. Pellentesque sollicitudin felis eu mattis porta. Nullam nec nibh nisl. Phasellus convallis vulputate massa vitae fringilla. Etiam facilisis lectus in odio lacinia rutrum. Praesent facilisis vitae urna a suscipit. Aenean lacinia blandit lorem, et ullamcorper metus sagittis faucibus. Nam porta eros nisi, at adipiscing quam varius eu. Vivamus sed sem quis lorem varius posuere ut quis elit.' }\n    }\n  }\n\n  bigMemoryLeak.push(arr)\n\n  pusage(process.pid, function (err, stat) {\n    if (err) {\n      throw err\n    }\n\n    console.log('Pcpu: %s', stat.cpu)\n    console.log('Mem: %s', formatBytes(stat.memory))\n\n    if (i === 100) {\n      return cb(null, true)\n    } else if (stat.memory > 3e8) {\n      console.log(\"That's enough right?\")\n      cb(null, true)\n    }\n\n    i++\n    return cb(null, false)\n  })\n}\n\nconst interval = function () {\n  return setTimeout(function () {\n    stress(function (err, stop) {\n      if (err) {\n        throw err\n      }\n\n      if (stop) {\n        process.exit()\n      } else {\n        return interval()\n      }\n    })\n  }, 400)\n}\n\nsetTimeout(function () {\n  interval()\n}, 2000)\n"
  },
  {
    "path": "index.js",
    "content": "'use strict'\n\nconst stats = require('./lib/stats')\n\n/**\n * Get pid informations.\n * @public\n * @param  {Number|Number[]|String|String[]} pids A pid or a list of pids.\n * @param  {Object} [options={}] Options object\n * @param  {Function} [callback=undefined] Called when the statistics are ready.\n * If not provided a promise is returned instead.\n * @returns  {Promise.<Object>} Only when the callback is not provided.\n */\nfunction pidusage (pids, options, callback) {\n  if (typeof options === 'function') {\n    callback = options\n    options = {}\n  }\n\n  if (options === undefined) {\n    options = {}\n  }\n\n  options = Object.assign({\n    usePs: /^true$/i.test(process.env.PIDUSAGE_USE_PS),\n    maxage: process.env.PIDUSAGE_MAXAGE\n  }, options)\n\n  if (typeof callback === 'function') {\n    stats(pids, options, callback)\n    return\n  }\n\n  return new Promise(function (resolve, reject) {\n    stats(pids, options, function (err, data) {\n      if (err) return reject(err)\n      resolve(data)\n    })\n  })\n}\n\nmodule.exports = pidusage\nmodule.exports.clear = require('./lib/history').clear\n"
  },
  {
    "path": "lib/bin.js",
    "content": "'use strict'\n\nconst spawn = require('child_process').spawn\n\n/**\n  * Spawn a binary and read its stdout.\n  * @param  {String} cmd\n  * @param  {String[]} args\n  * @param  {Function} done(err, stdout)\n  */\nfunction run (cmd, args, options, done) {\n  if (typeof options === 'function') {\n    done = options\n    options = undefined\n  }\n\n  let executed = false\n  const ch = spawn(cmd, args, options)\n  let stdout = ''\n  let stderr = ''\n\n  ch.stdout.on('data', function (d) {\n    stdout += d.toString()\n  })\n\n  ch.stderr.on('data', function (d) {\n    stderr += d.toString()\n  })\n\n  ch.on('error', function (err) {\n    if (executed) return\n    executed = true\n    done(new Error(err))\n  })\n\n  ch.on('close', function (code, signal) {\n    if (executed) return\n    executed = true\n\n    if (stderr) {\n      return done(new Error(stderr))\n    }\n\n    done(null, stdout, code)\n  })\n}\n\nmodule.exports = run\n"
  },
  {
    "path": "lib/gwmi.js",
    "content": "'use strict'\n\nconst os = require('os')\nconst bin = require('./bin')\nconst history = require('./history')\n\nfunction parseDate (datestr) {\n  const year = datestr.substring(0, 4)\n  const month = datestr.substring(4, 6)\n  const day = datestr.substring(6, 8)\n  const hour = datestr.substring(8, 10)\n  const minutes = datestr.substring(10, 12)\n  const seconds = datestr.substring(12, 14)\n  const useconds = datestr.substring(15, 21)\n  const sign = datestr.substring(21, 22)\n  const tmz = parseInt(datestr.substring(22, 25), 10)\n  const tmzh = Math.floor(tmz / 60)\n  const tmzm = tmz % 60\n\n  return new Date(\n    year + '-' + month + '-' + day + 'T' + hour +\n    ':' + minutes + ':' + seconds +\n    '.' + useconds +\n    sign + (tmzh > 9 ? tmzh : '0' + tmzh) + '' + (tmzm > 9 ? tmzm : '0' + tmzm)\n  )\n}\n\nfunction gwmi (pids, options, done) {\n  let whereClause = 'ProcessId=' + pids[0]\n  for (let i = 1; i < pids.length; i++) {\n    whereClause += ' or ' + 'ProcessId=' + pids[i]\n  }\n\n  const property = 'CreationDate,KernelModeTime,ParentProcessId,ProcessId,UserModeTime,WorkingSetSize'\n  const args = ['win32_process', '-Filter', '\\'' + whereClause + '\\'', '| select ' + property, '| format-table']\n\n  bin('gwmi', args, { windowsHide: true, windowsVerbatimArguments: true, shell: 'powershell.exe' }, function (err, stdout, code) {\n    if (err) {\n      if (err.message.indexOf('No Instance(s) Available.') !== -1) {\n        const error = new Error('No matching pid found')\n        error.code = 'ENOENT'\n        return done(error)\n      }\n      return done(err)\n    }\n    if (code !== 0) {\n      return done(new Error('pidusage gwmi command exited with code ' + code))\n    }\n    const date = Date.now()\n\n    // Note: On Windows the returned value includes fractions of a second.\n    // Use Math.floor() to get whole seconds.\n    // Fallback on current date when uptime is not allowed (see https://github.com/soyuka/pidusage/pull/130)\n    const uptime = Math.floor(os.uptime() || (date / 1000))\n\n    // Example of stdout on Windows 10\n    // CreationDate: is in the format yyyymmddHHMMSS.mmmmmmsUUU\n    // KernelModeTime: is in units of 100 ns\n    // UserModeTime: is in units of 100 ns\n    // WorkingSetSize: is in bytes\n    //\n    // Refs: https://superuser.com/a/937401/470946\n    // Refs: https://msdn.microsoft.com/en-us/library/aa394372(v=vs.85).aspx\n    // NB: The columns are returned in lexicographical order\n    //\n    // Stdout Format\n    //\n    // Active code page: 936\n    //\n    // CreationDate              KernelModeTime ParentProcessId ProcessId UserModeTime WorkingSetSize\n    // ------------              -------------- --------------- --------- ------------ --------------\n    // 20220220185531.619182+480      981406250           18940      2804    572656250       61841408\n\n    stdout = stdout.split(os.EOL).slice(1)\n    const index = stdout.findIndex(v => !!v)\n    stdout = stdout.slice(index + 2)\n\n    if (!stdout.length) {\n      const error = new Error('No matching pid found')\n      error.code = 'ENOENT'\n      return done(error)\n    }\n\n    let again = false\n    const statistics = {}\n    for (let i = 0; i < stdout.length; i++) {\n      const line = stdout[i].trim().split(/\\s+/)\n\n      if (!line || line.length === 1) {\n        continue\n      }\n\n      const creation = parseDate(line[0])\n      const ppid = parseInt(line[2], 10)\n      const pid = parseInt(line[3], 10)\n      const kerneltime = Math.round(parseInt(line[1], 10) / 10000)\n      const usertime = Math.round(parseInt(line[4], 10) / 10000)\n      const memory = parseInt(line[5], 10)\n\n      let hst = history.get(pid, options.maxage)\n      if (hst === undefined) {\n        again = true\n        hst = { ctime: kerneltime + usertime, uptime: uptime }\n      }\n\n      // process usage since last call\n      const total = (kerneltime + usertime - hst.ctime) / 1000\n      // time elapsed between calls in seconds\n      const seconds = uptime - hst.uptime\n      const cpu = seconds > 0 ? (total / seconds) * 100 : 0\n\n      history.set(pid, { ctime: usertime + kerneltime, uptime: uptime }, options.maxage)\n\n      statistics[pid] = {\n        cpu: cpu,\n        memory: memory,\n        ppid: ppid,\n        pid: pid,\n        ctime: usertime + kerneltime,\n        elapsed: date - creation.getTime(),\n        timestamp: date\n      }\n    }\n\n    if (again) {\n      return gwmi(pids, options, function (err, stats) {\n        if (err) return done(err)\n        done(null, Object.assign(statistics, stats))\n      })\n    }\n    done(null, statistics)\n  })\n}\n\nmodule.exports = gwmi\n"
  },
  {
    "path": "lib/helpers/cpu.js",
    "content": "const os = require('os')\nconst fs = require('fs')\nconst exec = require('child_process').exec\nconst parallel = require('./parallel')\n\n/**\n * Gathers Clock, PageSize and system uptime through /proc/uptime\n * This method is mocked in procfile tests\n */\nfunction updateCpu (cpu, next) {\n  if (cpu !== null) {\n    getRealUptime(function (err, uptime) {\n      if (err) return next(err)\n      cpu.uptime = uptime\n      next(null, cpu)\n    })\n    return\n  }\n\n  parallel([\n    getClockAndPageSize,\n    getRealUptime\n  ], function (err, data) {\n    if (err) return next(err)\n\n    cpu = {\n      clockTick: data[0].clockTick,\n      pageSize: data[0].pageSize,\n      uptime: data[1]\n    }\n\n    next(null, cpu)\n  })\n}\n\nmodule.exports = updateCpu\n\n/**\n * Fallback on os.uptime(), though /proc/uptime is more precise\n */\nfunction getRealUptime (next) {\n  fs.readFile('/proc/uptime', 'utf8', function (err, uptime) {\n    if (err || uptime === undefined) {\n      if (!process.env.PIDUSAGE_SILENT) {\n        console.warn(\"[pidusage] We couldn't find uptime from /proc/uptime, using os.uptime() value\")\n      }\n      return next(null, os.uptime() || (new Date() / 1000))\n    }\n\n    return next(null, parseFloat(uptime.split(' ')[0]))\n  })\n}\n\nfunction getClockAndPageSize (next) {\n  parallel([\n    function getClockTick (cb) {\n      getconf('CLK_TCK', { default: 100 }, cb)\n    },\n    function getPageSize (cb) {\n      getconf('PAGESIZE', { default: 4096 }, cb)\n    }\n  ], function (err, data) {\n    if (err) return next(err)\n\n    next(null, { clockTick: data[0], pageSize: data[1] })\n  })\n}\n\nfunction getconf (keyword, options, next) {\n  if (typeof options === 'function') {\n    next = options\n    options = { default: '' }\n  }\n\n  exec('getconf ' + keyword, function (error, stdout, stderr) {\n    if (error !== null) {\n      if (!process.env.PIDUSAGE_SILENT) {\n        console.error('Error while calling \"getconf ' + keyword + '\"', error)\n      }\n      return next(null, options.default)\n    }\n\n    stdout = parseInt(stdout)\n\n    if (!isNaN(stdout)) {\n      return next(null, stdout)\n    }\n\n    return next(null, options.default)\n  })\n}\n"
  },
  {
    "path": "lib/helpers/parallel.js",
    "content": "// execute an array of asynchronous functions in parallel\n// @param {Array} fns - an array of functions\n// @param {Function} done - callback(err, results)\nfunction parallel (fns, options, done) {\n  if (typeof options === 'function') {\n    done = options\n    options = {}\n  }\n\n  let keys\n  if (!Array.isArray(fns)) { keys = Object.keys(fns) }\n  const length = keys ? keys.length : fns.length\n  let pending = length\n  const results = keys ? {} : []\n\n  function each (i, err, result) {\n    results[i] = result\n\n    if (--pending === 0 || (err && !options.graceful)) {\n      if (options.graceful && err && length > 1) {\n        err = null\n      }\n\n      done && done(err, results)\n      done = null\n    }\n  }\n\n  if (keys) {\n    keys.forEach(function (key) {\n      fns[key](function (err, res) {\n        each(key, err, res)\n      })\n    })\n  } else {\n    fns.forEach(function (fn, i) {\n      fn(function (err, res) {\n        each(i, err, res)\n      })\n    })\n  }\n}\n\nmodule.exports = parallel\n"
  },
  {
    "path": "lib/history.js",
    "content": "'use strict'\nconst DEFAULT_MAXAGE = 60000\n\nconst expiration = {}\nconst history = {}\nconst expireListeners = {}\n\nlet size = 0\nlet interval = null\n\nfunction get (pid, maxage) {\n  if (maxage <= 0) {\n    return\n  }\n\n  if (history[pid] !== undefined) {\n    expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE)\n  }\n\n  return history[pid]\n}\n\nfunction set (pid, object, maxage, onExpire) {\n  if (object === undefined || maxage <= 0) return\n\n  expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE)\n  if (history[pid] === undefined) {\n    size++\n    sheduleInvalidator(maxage)\n  }\n\n  history[pid] = object\n  if (onExpire) {\n    expireListeners[pid] = onExpire\n  }\n}\n\nfunction sheduleInvalidator (maxage) {\n  if (size > 0) {\n    if (interval === null) {\n      interval = setInterval(runInvalidator, (maxage || DEFAULT_MAXAGE) / 2)\n      if (typeof interval.unref === 'function') {\n        interval.unref()\n      }\n    }\n\n    return\n  }\n\n  if (interval !== null) {\n    clearInterval(interval)\n    interval = null\n  }\n}\n\nfunction runInvalidator () {\n  const now = Date.now()\n  const pids = Object.keys(expiration)\n  for (let i = 0; i < pids.length; i++) {\n    const pid = pids[i]\n    if (expiration[pid] < now) {\n      size--\n      if (expireListeners[pid]) {\n        expireListeners[pid](history[pid])\n      }\n\n      delete history[pid]\n      delete expiration[pid]\n      delete expireListeners[pid]\n    }\n  }\n  sheduleInvalidator()\n}\n\nfunction deleteLoop (obj) { for (const i in obj) { delete obj[i] } }\n\nfunction clear () {\n  if (interval !== null) {\n    clearInterval(interval)\n    interval = null\n  }\n\n  deleteLoop(history)\n  deleteLoop(expiration)\n  deleteLoop(expireListeners)\n}\n\nmodule.exports = {\n  get: get,\n  set: set,\n  clear: clear\n}\n"
  },
  {
    "path": "lib/procfile.js",
    "content": "const fs = require('fs')\nconst path = require('path')\nconst updateCpu = require('./helpers/cpu')\nconst parallel = require('./helpers/parallel')\nconst history = require('./history')\nlet cpuInfo = null\nconst Buffer = require('safe-buffer').Buffer\nconst SIZE = 1024 // if the stat file is bigger then this I'll buy you a drink\n\nfunction noop () {}\n\nfunction open (path, history, cb) {\n  if (history.fd) { return cb(null, history.fd) }\n  fs.open(path, 'r', cb)\n}\n\nfunction close (history) {\n  if (history.fd) {\n    fs.close(history.fd, noop)\n  }\n}\n\nfunction readUntilEnd (fd, buf, cb) {\n  let firstRead = false\n  if (typeof buf === 'function') {\n    cb = buf\n    buf = Buffer.alloc(SIZE)\n    firstRead = true\n  }\n\n  fs.read(fd, buf, 0, SIZE, 0, function (err, bytesRead, buffer) {\n    if (err) {\n      cb(err)\n      return\n    }\n\n    const data = Buffer.concat([buf, buffer], firstRead ? bytesRead : buf.length + bytesRead)\n    if (bytesRead === SIZE) {\n      readUntilEnd(fd, data, cb)\n      return\n    }\n\n    cb(null, buf)\n  })\n}\n\nfunction readProcFile (pid, options, done) {\n  let hst = history.get(pid, options.maxage)\n  let again = false\n  if (hst === undefined) {\n    again = true\n    hst = {}\n  }\n\n  // Arguments to path.join must be strings\n  open(path.join('/proc', '' + pid, 'stat'), hst, function (err, fd) {\n    if (err) {\n      if (err.code === 'ENOENT') {\n        err.message = 'No matching pid found'\n      }\n      return done(err, null)\n    }\n\n    if (err) {\n      return done(err)\n    }\n\n    readUntilEnd(fd, function (err, buffer) {\n      if (err) {\n        return done(err)\n      }\n\n      let infos = buffer.toString('utf8')\n      const date = Date.now()\n\n      // https://github.com/arunoda/node-usage/commit/a6ca74ecb8dd452c3c00ed2bde93294d7bb75aa8\n      // preventing process space in name by removing values before last ) (pid (name) ...)\n      const index = infos.lastIndexOf(')')\n      infos = infos.substr(index + 2).split(' ')\n\n      // according to http://man7.org/linux/man-pages/man5/proc.5.html (index 0 based - 2)\n      // In kernels before Linux 2.6, start was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks\n      const stat = {\n        ppid: parseInt(infos[1]),\n        utime: parseFloat(infos[11]) * 1000 / cpuInfo.clockTick,\n        stime: parseFloat(infos[12]) * 1000 / cpuInfo.clockTick,\n        cutime: parseFloat(infos[13]) * 1000 / cpuInfo.clockTick,\n        cstime: parseFloat(infos[14]) * 1000 / cpuInfo.clockTick,\n        start: parseFloat(infos[19]) * 1000 / cpuInfo.clockTick,\n        rss: parseFloat(infos[21]),\n        uptime: cpuInfo.uptime * 1000,\n        fd: fd\n      }\n\n      const memory = stat.rss * cpuInfo.pageSize\n\n      // https://stackoverflow.com/a/16736599/3921589\n      const childrens = options.childrens ? stat.cutime + stat.cstime : 0\n      // process usage since last call in seconds\n      const total = (stat.stime - (hst.stime || 0) + stat.utime - (hst.utime || 0) + childrens)\n      // time elapsed between calls in seconds\n      const seconds = Math.abs(hst.uptime !== undefined ? stat.uptime - hst.uptime : stat.start - stat.uptime)\n      const cpu = seconds > 0 ? (total / seconds) * 100 : 0\n\n      history.set(pid, stat, options.maxage, close)\n\n      if (again) {\n        return readProcFile(pid, options, done)\n      }\n\n      return done(null, {\n        cpu: cpu,\n        memory: memory,\n        ctime: stat.utime + stat.stime,\n        elapsed: stat.uptime - stat.start,\n        timestamp: date,\n        pid: pid,\n        ppid: stat.ppid\n      })\n    })\n  })\n}\n\nfunction procfile (pids, options, done) {\n  updateCpu(cpuInfo, function (err, result) {\n    if (err) return done(err)\n\n    cpuInfo = result\n    const fns = {}\n\n    pids.forEach(function (pid, i) {\n      fns[pid] = function (cb) {\n        readProcFile(pid, options, cb)\n      }\n    })\n\n    parallel(fns, { graceful: true }, done)\n  })\n}\n\nmodule.exports = procfile\n"
  },
  {
    "path": "lib/ps.js",
    "content": "'use strict'\n\nconst os = require('os')\nconst bin = require('./bin')\nconst history = require('./history')\n\nconst PLATFORM = os.platform()\n\nfunction parseTime (timestr, centisec) {\n  let time = 0\n  const tpart = timestr.split(/-|:|\\./)\n  let i = tpart.length - 1\n  if (i >= 0 && centisec && PLATFORM === 'darwin') {\n    time += parseInt(tpart[i--], 10) * 10\n  }\n  if (i >= 0) { // Seconds\n    time += parseInt(tpart[i--], 10) * 1000\n  }\n  if (i >= 0) { // Minutes\n    time += parseInt(tpart[i--], 10) * 60000\n  }\n  if (i >= 0) { // Hours\n    time += parseInt(tpart[i--], 10) * 3600000\n  }\n  if (i >= 0) { // Days\n    time += parseInt(tpart[i--], 10) * 86400000\n  }\n  return time\n}\n\n/**\n  * Get pid informations through ps command.\n  * @param  {Number[]} pids\n  * @param  {Object} options\n  * @param  {Function} done(err, stat)\n  */\nfunction ps (pids, options, done) {\n  const pArg = pids.join(',')\n  let args = ['-o', 'etime,pid,ppid,pcpu,rss,time', '-p', pArg]\n\n  if (PLATFORM === 'aix' || PLATFORM === 'os400') {\n    args = ['-o', 'etime,pid,ppid,pcpu,rssize,time', '-p', pArg]\n  }\n\n  bin('ps', args, function (err, stdout, code) {\n    if (err) {\n      if (PLATFORM === 'os390' && /no matching processes found/.test(err)) {\n        err = new Error('No matching pid found')\n        err.code = 'ENOENT'\n      }\n\n      return done(err)\n    }\n    if (code === 1) {\n      const error = new Error('No matching pid found')\n      error.code = 'ENOENT'\n      return done(error)\n    }\n    if (code !== 0) {\n      return done(new Error('pidusage ps command exited with code ' + code))\n    }\n    const date = Date.now()\n\n    // Example of stdout on *nix.\n    // ELAPSED: format is [[dd-]hh:]mm:ss\n    // RSS: is counted as blocks of 1024 bytes\n    // TIME: format is [[dd-]hh:]mm:ss\n    // %CPU: goes from 0 to vcore * 100\n    //\n    // Refs: http://www.manpages.info/linux/ps.1.html\n    // NB: The columns are returned in the order given inside the -o option\n    //\n    //    ELAPSED   PID  PPID  %CPU     RSS        TIME\n    // 2-40:50:53   430     1   3.0    5145  1-02:03:04\n    //   40:50:53   432   430   0.0    2364  1-01:02:03\n    //   01:50:50   727     1  10.0  348932       14:27\n    //      00:20  7166     1   0.1    3756        0:00\n\n    // Example of stdout on Darwin\n    // ELAPSED: format is [[dd-]hh:]mm:ss\n    // RSS: is counted as blocks of 1024 bytes\n    // TIME: format is [[dd-]hh:]mm:ss.cc (cc are centiseconds)\n    // %CPU: goes from 0 to vcore * 100\n    //\n    // Refs: https://ss64.com/osx/ps.html\n    // NB: The columns are returned in the order given inside the -o option\n    //\n    //    ELAPSED   PID  PPID  %CPU     RSS           TIME\n    // 2-40:50:53   430     1   3.0    5145  1-02:03:04.07\n    //   40:50:53   432   430   0.0    2364  1-01:02:03.10\n    //   01:50:50   727     1  10.0  348932       14:27.26\n    //      00:20  7166     1   0.1    3756        0:00.02\n\n    stdout = stdout.split(os.EOL)\n\n    const statistics = {}\n    for (let i = 1; i < stdout.length; i++) {\n      const line = stdout[i].trim().split(/\\s+/)\n\n      if (!line || line.length !== 6) {\n        continue\n      }\n\n      const pid = parseInt(line[1], 10)\n      let hst = history.get(pid, options.maxage)\n      if (hst === undefined) hst = {}\n\n      const ppid = parseInt(line[2], 10)\n      const memory = parseInt(line[4], 10) * 1024\n      const etime = parseTime(line[0])\n      const ctime = parseTime(line[5], true)\n\n      const total = (ctime - (hst.ctime || 0))\n      // time elapsed between calls in seconds\n      const seconds = Math.abs(hst.elapsed !== undefined ? etime - hst.elapsed : etime)\n      const cpu = seconds > 0 ? (total / seconds) * 100 : 0\n\n      statistics[pid] = {\n        cpu: cpu,\n        memory: memory,\n        ppid: ppid,\n        pid: pid,\n        ctime: ctime,\n        elapsed: etime,\n        timestamp: date\n      }\n\n      history.set(pid, statistics[pid], options.maxage)\n    }\n\n    done(null, statistics)\n  })\n}\n\nmodule.exports = ps\n"
  },
  {
    "path": "lib/stats.js",
    "content": "'use strict'\n\nconst fs = require('fs')\nconst os = require('os')\nconst spawn = require('child_process').spawn\n\nconst requireMap = {\n  ps: () => require('./ps'),\n  procfile: () => require('./procfile'),\n  wmic: () => require('./wmic'),\n  gwmi: () => require('./gwmi')\n}\n\nconst platformToMethod = {\n  aix: 'ps',\n  os400: 'ps',\n  android: 'procfile',\n  alpine: 'procfile',\n  darwin: 'ps',\n  freebsd: 'ps',\n  os390: 'ps',\n  linux: 'procfile',\n  netbsd: 'procfile',\n  openbsd: 'ps',\n  sunos: 'ps',\n  win: 'wmic'\n}\n\nlet platform = os.platform()\n\nif (fs.existsSync('/etc/alpine-release')) {\n  platform = 'alpine'\n}\n\nif (platform.match(/^win/)) {\n  platform = 'win'\n}\n\nlet stat\ntry {\n  stat = requireMap[platformToMethod[platform]]()\n} catch (err) {}\n\n/**\n * @callback pidCallback\n * @param {Error} err A possible error.\n * @param {Object} statistics The object containing the statistics.\n */\n\n/**\n * Get pid informations.\n * @public\n * @param  {Number|Number[]|String|String[]} pids A pid or a list of pids.\n * @param  {Object} [options={}] Options object\n * @param  {pidCallback} callback Called when the statistics are ready.\n */\nfunction get (pids, options, callback) {\n  let fn = stat\n  if (platform !== 'win' && options.usePs === true) {\n    fn = requireMap.ps()\n  }\n  if (platform === 'win') {\n    // TODO: use https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/where to avoid try/catch\n    let child;\n    try {\n      child = spawn('wmic', function (err) {\n        if (err) throw new Error(err)\n      })\n    } catch (err) {\n      fn = requireMap.gwmi()\n    } finally {\n      if (child) {\n        child.kill()\n      }\n    }\n  }\n\n  if (fn === undefined) {\n    return callback(new Error(os.platform() + ' is not supported yet, please open an issue (https://github.com/soyuka/pidusage)'))\n  }\n\n  let single = false\n  if (!Array.isArray(pids)) {\n    single = true\n    pids = [pids]\n  }\n\n  if (pids.length === 0) {\n    return callback(new TypeError('You must provide at least one pid'))\n  }\n\n  for (let i = 0; i < pids.length; i++) {\n    pids[i] = parseInt(pids[i], 10)\n    if (isNaN(pids[i]) || pids[i] < 0) {\n      return callback(new TypeError('One of the pids provided is invalid'))\n    }\n  }\n\n  fn(pids, options, function (err, stats) {\n    if (err) {\n      return callback(err)\n    }\n\n    if (single) {\n      callback(null, stats[pids[0]])\n    } else {\n      callback(null, stats)\n    }\n  })\n}\n\nmodule.exports = get\n"
  },
  {
    "path": "lib/wmic.js",
    "content": "'use strict'\n\nconst os = require('os')\nconst bin = require('./bin')\nconst history = require('./history')\n\nfunction parseDate (datestr) {\n  const year = datestr.substring(0, 4)\n  const month = datestr.substring(4, 6)\n  const day = datestr.substring(6, 8)\n  const hour = datestr.substring(8, 10)\n  const minutes = datestr.substring(10, 12)\n  const seconds = datestr.substring(12, 14)\n  const useconds = datestr.substring(15, 21)\n  const sign = datestr.substring(21, 22)\n  const tmz = parseInt(datestr.substring(22, 25), 10)\n  const tmzh = Math.floor(tmz / 60)\n  const tmzm = tmz % 60\n\n  return new Date(\n    year + '-' + month + '-' + day + 'T' + hour +\n    ':' + minutes + ':' + seconds +\n    '.' + useconds +\n    sign + (tmzh > 9 ? tmzh : '0' + tmzh) + '' + (tmzm > 9 ? tmzm : '0' + tmzm)\n  )\n}\n\n/**\n  * Get pid informations through wmic command.\n  * @param  {Number[]} pids\n  * @param  {Object} options\n  * @param  {Function} done(err, stat)\n  */\nfunction wmic (pids, options, done) {\n  let whereClause = 'ProcessId=' + pids[0]\n  for (let i = 1; i < pids.length; i++) {\n    whereClause += ' or ' + 'ProcessId=' + pids[i]\n  }\n\n  const args = [\n    'PROCESS',\n    'where',\n    '\"' + whereClause + '\"',\n    'get',\n    'CreationDate,KernelModeTime,ParentProcessId,ProcessId,UserModeTime,WorkingSetSize'\n  ]\n\n  bin('wmic', args, { windowsHide: true, windowsVerbatimArguments: true }, function (err, stdout, code) {\n    if (err) {\n      if (err.message.indexOf('No Instance(s) Available.') !== -1) {\n        const error = new Error('No matching pid found')\n        error.code = 'ENOENT'\n        return done(error)\n      }\n      return done(err)\n    }\n    if (code !== 0) {\n      return done(new Error('pidusage wmic command exited with code ' + code))\n    }\n    const date = Date.now()\n\n    // Note: On Windows the returned value includes fractions of a second.\n    // Use Math.floor() to get whole seconds.\n    // Fallback on current date when uptime is not allowed (see https://github.com/soyuka/pidusage/pull/130)\n    const uptime = Math.floor(os.uptime() || (date / 1000))\n\n    // Example of stdout on Windows 10\n    // CreationDate: is in the format yyyymmddHHMMSS.mmmmmmsUUU\n    // KernelModeTime: is in units of 100 ns\n    // UserModeTime: is in units of 100 ns\n    // WorkingSetSize: is in bytes\n    //\n    // Refs: https://superuser.com/a/937401/470946\n    // Refs: https://msdn.microsoft.com/en-us/library/aa394372(v=vs.85).aspx\n    // NB: The columns are returned in lexicographical order\n    //\n    // CreationDate               KernelModeTime  ParentProcessId  ProcessId  UserModeTime  WorkingSetSize\n    // 20150329221650.080654+060  153750000       0                777        8556250000    110821376\n\n    stdout = stdout.split(os.EOL)\n\n    let again = false\n    const statistics = {}\n    for (let i = 1; i < stdout.length; i++) {\n      const line = stdout[i].trim().split(/\\s+/)\n\n      if (!line || line.length !== 6) {\n        continue\n      }\n\n      const creation = parseDate(line[0])\n      const ppid = parseInt(line[2], 10)\n      const pid = parseInt(line[3], 10)\n      const kerneltime = Math.round(parseInt(line[1], 10) / 10000)\n      const usertime = Math.round(parseInt(line[4], 10) / 10000)\n      const memory = parseInt(line[5], 10)\n\n      let hst = history.get(pid, options.maxage)\n      if (hst === undefined) {\n        again = true\n        hst = { ctime: kerneltime + usertime, uptime: uptime }\n      }\n\n      // process usage since last call\n      const total = (kerneltime + usertime - hst.ctime) / 1000\n      // time elapsed between calls in seconds\n      const seconds = uptime - hst.uptime\n      const cpu = seconds > 0 ? (total / seconds) * 100 : 0\n\n      history.set(pid, { ctime: usertime + kerneltime, uptime: uptime }, options.maxage)\n\n      statistics[pid] = {\n        cpu: cpu,\n        memory: memory,\n        ppid: ppid,\n        pid: pid,\n        ctime: usertime + kerneltime,\n        elapsed: date - creation.getTime(),\n        timestamp: date\n      }\n    }\n\n    if (again) {\n      return wmic(pids, options, function (err, stats) {\n        if (err) return done(err)\n        done(null, Object.assign(statistics, stats))\n      })\n    }\n    done(null, statistics)\n  })\n}\n\nmodule.exports = wmic\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"pidusage\",\n  \"version\": \"3.0.1\",\n  \"description\": \"Cross-platform process cpu % and memory usage of a PID\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/soyuka/pidusage\",\n  \"repository\": \"github:soyuka/pidusage\",\n  \"bugs\": {\n    \"url\": \"https://github.com/soyuka/pidusage/issues\"\n  },\n  \"author\": \"soyuka\",\n  \"contributors\": [\n    \"Simone Primarosa <simonepri@outlook.com> (https://simoneprimarosa.com)\"\n  ],\n  \"main\": \"index.js\",\n  \"files\": [\n    \"lib\",\n    \"index.js\"\n  ],\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"scripts\": {\n    \"lint\": \"standard\",\n    \"test\": \"nyc ava -m \\\"!*benchmark*\\\"\",\n    \"coverage\": \"c8 ava\",\n    \"bench\": \"ava -m \\\"*benchmark*\\\"\"\n  },\n  \"dependencies\": {\n    \"safe-buffer\": \"^5.2.1\"\n  },\n  \"devDependencies\": {\n    \"balanced-match\": \"^3.0.1\",\n    \"c8\": \"^10.1.3\",\n    \"ava\": \"^6.2.0\",\n    \"mockdate\": \"^2.0.5\",\n    \"mockery\": \"^2.1.0\",\n    \"nyc\": \"^15.1.0\",\n    \"pify\": \"^3.0.0\",\n    \"standard\": \"^16.0.4\",\n    \"string-to-stream\": \"^1.1.1\",\n    \"through\": \"^2.3.8\",\n    \"time-span\": \"^2.0.0\"\n  },\n  \"keywords\": [\n    \"pid\",\n    \"usage\",\n    \"ps\",\n    \"cpu\",\n    \"memory\",\n    \"proc\"\n  ],\n  \"ava\": {\n    \"verbose\": true,\n    \"failWithoutAssertions\": false\n  },\n  \"nyc\": {\n    \"reporter\": [\n      \"lcovonly\",\n      \"text\"\n    ]\n  }\n}\n"
  },
  {
    "path": "test/bench.js",
    "content": "const { spawn } = require('child_process')\nconst test = require('ava')\nconst tspan = require('time-span')\n\nconst m = require('..')\n\nasync function create (pidno) {\n  const code = `\n    console.log(process.pid);\n    setInterval(function(){}, 1000); // Does nothing, but prevents exit\n  `\n  let count = 0\n  const childs = []\n\n  return new Promise((resolve, reject) => {\n    for (let i = 0; i < pidno; i++) {\n      const child = spawn('node', ['-e', code], { windowsHide: true })\n      childs.push(child)\n\n      child.stdout.on('data', function (childs) {\n        if (++count === pidno) resolve(childs)\n      }.bind(this, childs))\n      child.stderr.on('data', function (data) {\n        reject(data.toString())\n      })\n      child.on('error', reject)\n    }\n  })\n}\n\nasync function destroy (childs) {\n  childs.forEach(child => child.kill())\n}\n\nasync function execute (childs, pidno, times, options = {}) {\n  const pids = childs.map(child => child.pid).slice(0, pidno)\n\n  const end = tspan()\n  try {\n    for (let i = 0; i < times; i++) {\n      await m(pids, options)\n    }\n    const time = end()\n    return Promise.resolve(time)\n  } catch (err) {\n    end()\n    return Promise.reject(err)\n  }\n}\n\ntest.serial('should execute the benchmark', async t => {\n  const childs = await create(100)\n\n  let time = await execute(childs, 1, 100, { usePs: true })\n  t.log(`1 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 1, 100)\n  t.log(`(procfile) 1 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 2, 100, { usePs: true })\n  t.log(`2 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 2, 100)\n  t.log(`(procfile) 2 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 5, 100, { usePs: true })\n  t.log(`5 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 5, 100)\n  t.log(`(procfile) 5 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 10, 100, { usePs: true })\n  t.log(`10 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 10, 100)\n  t.log(`(procfile) 10 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 25, 100, { usePs: true })\n  t.log(`25 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 25, 100)\n  t.log(`(procfile) 25 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 50, 100, { usePs: true })\n  t.log(`50 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 50, 100)\n  t.log(`(procfile) 50 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 100, 100, { usePs: true })\n  t.log(`100 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  time = await execute(childs, 100, 100)\n  t.log(`(procfile) 100 pid 100 times done in ${time.toFixed(3)} ms (${(1000 * 100 / time).toFixed(3)} op/s)`)\n\n  await destroy(childs)\n\n  t.pass()\n})\n"
  },
  {
    "path": "test/fixtures/_eventloop.js",
    "content": "const pidusage = require('../../')\n\npidusage(process.pid, { maxage: 1500 }, function (err, stat) {\n  if (err) {\n    throw err\n  }\n\n  console.log('Got stats', stat)\n  // clean the event loop right away\n  if (process.clear_pidusage === '1' || process.argv[2] === '1') {\n    pidusage.clear()\n  }\n})\n\nconsole.log('My pid is ' + process.pid)\n"
  },
  {
    "path": "test/gwmi.js",
    "content": "const mockery = require('mockery')\nconst test = require('ava')\nconst os = require('os')\nconst mockdate = require('mockdate')\nconst pify = require('pify')\n\nconst mocks = require('./helpers/_mocks')\n\nconst timeout = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))\n\ntest.before(() => {\n  mockery.enable({\n    warnOnReplace: false,\n    warnOnUnregistered: false,\n    useCleanCache: true\n  })\n  mockdate.set(new Date(1427749200000))\n})\n\ntest.beforeEach(() => {\n  mockery.resetCache()\n})\n\ntest.after(() => {\n  mockery.disable()\n  mockdate.reset()\n})\n\ntest('should parse gwmi output on Windows', async t => {\n  const stdout = '' +\n    'Active code page: 936' + os.EOL +\n    '' + os.EOL +\n    '' + os.EOL +\n    'CreationDate               KernelModeTime  ParentProcessId  ProcessId  UserModeTime  WorkingSetSize' + os.EOL +\n    '------------               -----------     -----------     ------------   --------  --------' + os.EOL +\n    '20150329221650.080654+060  153750000       0                777        8556250000    110821376'\n\n  let calls = 0\n\n  mockery.registerMock('child_process', {\n    spawn: () => {\n      calls++\n      return mocks.spawn(stdout, '', null, 0, null)\n    }\n  })\n\n  const gwmi = require('../lib/gwmi')\n\n  let result = await pify(gwmi)([6456], { maxage: 1000 })\n  t.deepEqual(result, {\n    777: {\n      cpu: 0,\n      memory: 110821376,\n      ppid: 0,\n      pid: 777,\n      ctime: (855625 + 15375),\n      elapsed: 1427749200000 - new Date('2015-03-29T22:16:50.080654+0100').getTime(),\n      timestamp: 1427749200000\n    }\n  })\n\n  result = await pify(gwmi)([6456], { maxage: 1000 })\n\n  t.is(calls, 3, '2 first calls to put in history + 1')\n\n  mockdate.set(new Date(1427749202000))\n\n  // wait 1 second, it should do 2 calls again\n  await timeout(1000)\n\n  calls = 0\n  result = await pify(gwmi)([6456], { maxage: 1000 })\n\n  t.is(calls, 2, '2 first calls')\n\n  mockery.deregisterMock('child_process')\n})\n"
  },
  {
    "path": "test/helpers/_mocks.js",
    "content": "const EventEmitter = require('events')\nconst streamify = require('string-to-stream')\nconst through = require('through')\n\nmodule.exports = {\n  spawn: (stdout, stderr, error, code, signal) => {\n    const ee = new EventEmitter()\n\n    ee.stdout = through(function (d) { this.queue(d) })\n    ee.stderr = through(function (d) { this.queue(d) })\n\n    streamify(stderr).pipe(ee.stderr)\n    streamify(stdout).pipe(ee.stdout)\n\n    if (error) {\n      ee.emit('error', error)\n    } else if (!stderr) {\n      ee.stdout.on('end', () => ee.emit('close', code, signal))\n    } else {\n      ee.stderr.on('end', () => ee.emit('close', code, signal))\n    }\n    return ee\n  }\n}\n"
  },
  {
    "path": "test/integration.js",
    "content": "const { spawn } = require('child_process')\nconst test = require('ava')\nconst os = require('os')\nconst path = require('path')\n\nconst m = require('..')\n\ntest('should work with a single pid', async t => {\n  const pid = process.pid\n\n  const result = await m(pid)\n\n  t.log(result)\n\n  t.is(typeof result, 'object')\n\n  t.is(typeof result, 'object', 'result')\n  t.is(typeof result.cpu, 'number', 'cpu')\n  t.false(isNaN(result.cpu), 'cpu')\n  t.is(typeof result.memory, 'number', 'memory')\n  // z/OS does not report memory\n  if (process.platform !== 'os390') {\n    t.false(isNaN(result.memory), 'memory')\n  }\n  t.is(typeof result.ppid, 'number', 'ppid')\n  t.false(isNaN(result.ppid), 'ppid')\n  t.is(typeof result.pid, 'number', 'pid')\n  t.false(isNaN(result.pid), 'pid')\n  t.is(typeof result.elapsed, 'number', 'elapsed')\n  t.false(isNaN(result.elapsed), 'elapsed')\n  t.is(typeof result.timestamp, 'number', 'timestamp')\n  t.false(isNaN(result.timestamp), 'timestamp')\n})\n\ntest('should work with an array of pids', async t => {\n  const child = spawn(\n    'node',\n    ['-e', 'console.log(`123`); setInterval(() => {}, 1000)'],\n    { windowsHide: true }\n  )\n  const ppid = process.pid\n  const pid = child.pid\n\n  await t.notThrowsAsync(\n    new Promise((resolve, reject) => {\n      child.stdout.on('data', d => resolve(d.toString()))\n      child.stderr.on('data', d => reject(d.toString()))\n      child.on('error', reject)\n      child.on('exit', code => reject(new Error('script exited with code ' + code)))\n    }),\n    'script not executed'\n  )\n\n  const pids = [ppid, pid]\n  let result\n  try {\n    result = await m(pids)\n    child.kill()\n  } catch (err) {\n    child.kill()\n    t.notThrows(() => { throw err })\n  }\n\n  t.log(result)\n\n  t.is(typeof result, 'object')\n  t.deepEqual(Object.keys(result).sort(), pids.map(pid => pid.toString()).sort())\n\n  pids.forEach(pid => {\n    t.is(typeof result[pid], 'object', 'result')\n    t.is(typeof result[pid].cpu, 'number', 'cpu')\n    t.false(isNaN(result[pid].cpu), 'cpu')\n    t.is(typeof result[pid].memory, 'number', 'memory')\n    // z/OS does not report memory\n    if (process.platform !== 'os390') {\n      t.false(isNaN(result[pid].memory), 'memory')\n    }\n\n    t.is(typeof result[pid].ppid, 'number', 'ppid')\n    t.false(isNaN(result[pid].ppid), 'ppid')\n    t.is(typeof result[pid].pid, 'number', 'pid')\n    t.false(isNaN(result[pid].pid), 'pid')\n    t.is(typeof result[pid].elapsed, 'number', 'elapsed')\n    t.false(isNaN(result[pid].elapsed), 'elapsed')\n    t.is(typeof result[pid].timestamp, 'number', 'timestamp')\n    t.false(isNaN(result[pid].timestamp), 'timestamp')\n  })\n\n  m.clear()\n})\n\ntest('should throw an error if no pid is provided', async t => {\n  const err = await t.throwsAsync(() => m([]))\n  t.is(err.message, 'You must provide at least one pid')\n})\n\ntest('should throw an error if one of the pid is invalid', async t => {\n  let err = await t.throwsAsync(() => m(null))\n  t.is(err.message, 'One of the pids provided is invalid')\n  err = await t.throwsAsync(() => m([null]))\n  t.is(err.message, 'One of the pids provided is invalid')\n  err = await t.throwsAsync(() => m(['invalid']))\n  t.is(err.message, 'One of the pids provided is invalid')\n  err = await t.throwsAsync(() => m(-1))\n  t.is(err.message, 'One of the pids provided is invalid')\n  err = await t.throwsAsync(() => m([-1]))\n  t.is(err.message, 'One of the pids provided is invalid')\n})\n\ntest('should not throw an error if one of the pids does not exists', async t => {\n  await t.notThrows(() => m([process.pid, 65535]))\n  await t.notThrows(() => m([65535, process.pid]))\n})\n\ntest('should throw an error if the pid does not exists', async t => {\n  const err = await t.throwsAsync(() => m([65535]))\n  t.is(err.message, 'No matching pid found')\n  t.is(err.code, 'ENOENT')\n})\n\ntest('should throw an error if the pid is too large', async t => {\n  await t.throwsAsync(async () => m(99999999))\n})\n\ntest('should exit right away because we cleaned up the event loop', t => {\n  if (os.platform().match(/^win/)) return t.pass()\n\n  process.clear_pidusage = '1'\n  require(path.join(__dirname, '/fixtures/_eventloop'))\n  process.nextTick(() => {\n    t.pass()\n  })\n})\n\ntest('should exit right away because the event loop ignores history', t => {\n  if (os.platform().match(/^win/)) return t.pass()\n\n  process.clear_pidusage = '0'\n  require(path.join(__dirname, '/fixtures/_eventloop'))\n  process.nextTick(() => {\n    t.pass()\n  })\n})\n\ntest(\"should use the callback if it's provided\", t => {\n  m(process.pid, () => t.pass())\n})\n\nprocess.on('unhandledException', (e) => {\n  console.error(e)\n  process.exit(1)\n})\n"
  },
  {
    "path": "test/procfile.js",
    "content": "const mockery = require('mockery')\nconst test = require('ava')\nconst os = require('os')\n\nconst IS_WIN = os.platform().match(/^win/)\n\ntest.before(() => {\n  mockery.enable({\n    warnOnReplace: false,\n    warnOnUnregistered: false,\n    useCleanCache: true\n  })\n})\n\ntest.beforeEach(() => {\n  mockery.resetCache()\n})\n\ntest.after(() => {\n  mockery.disable()\n})\n\ntest('procfile stat', async t => {\n  if (IS_WIN) {\n    t.pass()\n    return\n  }\n\n  const fs = require('fs')\n  let openCalled = 0\n\n  fs.open = function (path, mode, cb) {\n    openCalled++\n    cb(null, 10)\n  }\n\n  fs.readFile = function (path, encoding, callback) {\n    if (path === '/proc/uptime') {\n      callback(null, '100 0')\n    }\n  }\n\n  fs.read = function (fd, buffer, offset, length, position, callback) {\n    // proc/<pid>/stat\n    let infos = '0 (test)'\n    for (let i = 0; i < 22; i++) {\n      if (i === 12) {\n        infos += ' ' + 10000 // currentStime 10000 * clockTick\n      } else {\n        infos += ' 0'\n      }\n    }\n\n    buffer.write(infos)\n    callback(null, infos.length, buffer)\n  }\n\n  fs.existsSync = function (path) {\n    if (path === '/etc/alpine-release') { return true }\n    return false\n  }\n\n  const os = require('os')\n  os.platform = function () { return 'linux' }\n\n  mockery.registerMock('os', os)\n  mockery.registerMock('fs', fs)\n  mockery.registerMock('./cpu.js', function (cpu, next) {\n    next({\n      clockTick: 100,\n      uptime: 100,\n      pagesize: 4096\n    })\n  })\n\n  const m = require('..')\n  let stat = await m(10)\n  t.is(stat.cpu, 0)\n  t.is(stat.memory, 0)\n  t.is(stat.ppid, 0)\n  t.is(stat.pid, 10)\n  t.is(typeof stat.elapsed, 'number', 'elapsed')\n  t.false(isNaN(stat.elapsed), 'elapsed')\n  t.is(typeof stat.timestamp, 'number', 'timestamp')\n  t.false(isNaN(stat.timestamp), 'timestamp')\n\n  stat = await m(10)\n  t.is(openCalled, 1)\n})\n"
  },
  {
    "path": "test/ps.js",
    "content": "const mockery = require('mockery')\nconst test = require('ava')\nconst os = require('os')\nconst mockdate = require('mockdate')\nconst pify = require('pify')\n\nconst mocks = require('./helpers/_mocks')\n\ntest.before(() => {\n  mockery.enable({\n    warnOnReplace: false,\n    warnOnUnregistered: false,\n    useCleanCache: true\n  })\n  mockdate.set(new Date(864000000))\n})\n\ntest.beforeEach(() => {\n  mockery.resetCache()\n})\n\ntest.after(() => {\n  mockery.disable()\n  mockdate.reset()\n})\n\ntest('should parse ps output on Darwin', async t => {\n  const stdout = '' +\n    '   ELAPSED   PID  PPID  %CPU     RSS           TIME' + os.EOL +\n    '2-40:50:53   430     1   3.0    5145  1-02:03:04.07' + os.EOL +\n    '  40:50:53   432   430   0.0    2364  1-01:02:03.10' + os.EOL +\n    '  01:50:50   727     1  10.0  348932       14:27.26' + os.EOL +\n    '     00:20  7166     1   0.1    3756        0:00.02'\n\n  mockery.registerMock('child_process', {\n    spawn: () => mocks.spawn(stdout, '', null, 0, null)\n  })\n\n  mockery.registerMock('os', {\n    EOL: os.EOL,\n    platform: () => 'darwin',\n    type: () => 'type',\n    release: () => 'release'\n  })\n\n  const ps = require('../lib/ps')\n\n  const result = await pify(ps)([348932], {})\n  t.deepEqual(result, {\n    430: {\n      cpu: (93784070 / 319853000) * 100,\n      memory: 5145 * 1024,\n      ppid: 1,\n      pid: 430,\n      ctime: (1 * 86400 + 2 * 3600 + 3 * 60 + 4 * 1) * 1000 + (10 * 7),\n      elapsed: (2 * 86400 + 40 * 3600 + 50 * 60 + 53 * 1) * 1000,\n      timestamp: 864000000\n    },\n    432: {\n      cpu: (90123100 / 147053000) * 100,\n      memory: 2364 * 1024,\n      ppid: 430,\n      pid: 432,\n      ctime: (1 * 86400 + 1 * 3600 + 2 * 60 + 3 * 1) * 1000 + (10 * 10),\n      elapsed: (40 * 3600 + 50 * 60 + 53 * 1) * 1000,\n      timestamp: 864000000\n    },\n    727: {\n      cpu: (867260 / 6650000) * 100,\n      memory: 348932 * 1024,\n      ppid: 1,\n      pid: 727,\n      ctime: (14 * 60 + 27 * 1) * 1000 + (10 * 26),\n      elapsed: (1 * 3600 + 50 * 60 + 50 * 1) * 1000,\n      timestamp: 864000000\n    },\n    7166: {\n      cpu: (20 / 20000) * 100,\n      memory: 3756 * 1024,\n      ppid: 1,\n      pid: 7166,\n      ctime: (10 * 2),\n      elapsed: (20 * 1) * 1000,\n      timestamp: 864000000\n    }\n  })\n\n  mockery.deregisterMock('child_process')\n  mockery.deregisterMock('os')\n})\n\ntest('should parse ps output on *nix', async t => {\n  t.pass()\n  // const stdout = '' +\n  //   '   ELAPSED   PID  PPID  %CPU     RSS        TIME' + os.EOL +\n  //   '2-40:50:53   430     1   3.0    5145  1-02:03:04' + os.EOL +\n  //   '  40:50:53   432   430   0.0    2364  1-01:02:03' + os.EOL +\n  //   '  01:50:50   727     1  10.0  348932       14:27' + os.EOL +\n  //   '     00:20  7166     1   0.1    3756        0:00'\n  //\n  // mockery.registerMock('child_process', {\n  //   spawn: () => mocks.spawn(stdout, '', null, 0, null)\n  // })\n  // mockery.registerMock('os', {\n  //   EOL: os.EOL,\n  //   platform: () => 'linux',\n  //   type: () => 'type',\n  //   release: () => 'release'\n  // })\n  //\n  // const ps = require('../lib/ps')\n  //\n  // const result = await pify(ps)([11678], {})\n  // t.deepEqual(result, {\n  //   430: {\n  //     cpu: 3.0,\n  //     memory: 5145 * 1024,\n  //     ppid: 1,\n  //     pid: 430,\n  //     ctime: (1 * 86400 + 2 * 3600 + 3 * 60 + 4 * 1) * 1000,\n  //     elapsed: (2 * 86400 + 40 * 3600 + 50 * 60 + 53 * 1) * 1000,\n  //     timestamp: 864000000\n  //   },\n  //   432: {\n  //     cpu: 0.0,\n  //     memory: 2364 * 1024,\n  //     ppid: 430,\n  //     pid: 432,\n  //     ctime: (1 * 86400 + 1 * 3600 + 2 * 60 + 3 * 1) * 1000,\n  //     elapsed: (40 * 3600 + 50 * 60 + 53 * 1) * 1000,\n  //     timestamp: 864000000\n  //   },\n  //   727: {\n  //     cpu: 10.0,\n  //     memory: 348932 * 1024,\n  //     ppid: 1,\n  //     pid: 727,\n  //     ctime: (14 * 60 + 27 * 1) * 1000,\n  //     elapsed: (1 * 3600 + 50 * 60 + 50 * 1) * 1000,\n  //     timestamp: 864000000\n  //   },\n  //   7166: {\n  //     cpu: 0.1,\n  //     memory: 3756 * 1024,\n  //     ppid: 1,\n  //     pid: 7166,\n  //     ctime: 0,\n  //     elapsed: (20 * 1) * 1000,\n  //     timestamp: 864000000\n  //   }\n  // })\n  //\n  // mockery.deregisterMock('child_process')\n  // mockery.deregisterMock('os')\n})\n\ntest('should be able to set usePs from env var', async t => {\n  let usePsFromStats\n\n  mockery.registerMock('./lib/stats', (_, options) => {\n    usePsFromStats = options.usePs\n  })\n\n  const beforeValue = process.env.PIDUSAGE_USE_PS\n  process.env.PIDUSAGE_USE_PS = 'true'\n\n  const pidusage = require('../')\n  pidusage(1, () => {})\n\n  t.is(usePsFromStats, true)\n\n  process.env.PIDUSAGE_USE_PS = beforeValue\n  mockery.deregisterMock('./lib/stats')\n})\n"
  },
  {
    "path": "test/wmic.js",
    "content": "const mockery = require('mockery')\nconst test = require('ava')\nconst os = require('os')\nconst mockdate = require('mockdate')\nconst pify = require('pify')\n\nconst mocks = require('./helpers/_mocks')\n\nconst timeout = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))\n\ntest.before(() => {\n  mockery.enable({\n    warnOnReplace: false,\n    warnOnUnregistered: false,\n    useCleanCache: true\n  })\n  mockdate.set(new Date(1427749200000))\n})\n\ntest.beforeEach(() => {\n  mockery.resetCache()\n})\n\ntest.after(() => {\n  mockery.disable()\n  mockdate.reset()\n})\n\ntest('should parse wmic output on Windows', async t => {\n  const stdout = '' +\n    'CreationDate               KernelModeTime  ParentProcessId  ProcessId  UserModeTime  WorkingSetSize' + os.EOL +\n    '20150329221650.080654+060  153750000       0                777        8556250000    110821376'\n\n  let calls = 0\n\n  mockery.registerMock('child_process', {\n    spawn: () => {\n      calls++\n      return mocks.spawn(stdout, '', null, 0, null)\n    }\n  })\n\n  const wmic = require('../lib/wmic')\n\n  let result = await pify(wmic)([6456], { maxage: 1000 })\n  t.deepEqual(result, {\n    777: {\n      cpu: 0,\n      memory: 110821376,\n      ppid: 0,\n      pid: 777,\n      ctime: (855625 + 15375),\n      elapsed: 1427749200000 - new Date('2015-03-29T22:16:50.080654+0100').getTime(),\n      timestamp: 1427749200000\n    }\n  })\n\n  result = await pify(wmic)([6456], { maxage: 1000 })\n\n  t.is(calls, 3, '2 first calls to put in history + 1')\n\n  mockdate.set(new Date(1427749202000))\n\n  // wait 1 second, it should do 2 calls again\n  await timeout(1000)\n\n  calls = 0\n  result = await pify(wmic)([6456], { maxage: 1000 })\n\n  t.is(calls, 2, '2 first calls')\n\n  mockery.deregisterMock('child_process')\n})\n"
  }
]