From b78a29eb882e7579d49ee78d76eb9b42fdd9fdcf Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Sat, 30 May 2020 22:59:06 -0700 Subject: [PATCH] 1. Updated metadata for linux ipcSocket 2, Added linux-acpi, and attached events to power-monitor for linux --- microscript/ILibDuktape_Polyfills.c | 5 +++ microscript/ILibDuktape_net.c | 19 +++++++- modules/linux-acpi.js | 47 ++++++++++++++++++++ modules/power-monitor.js | 68 +++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 modules/linux-acpi.js diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index 2d3a89a..d496dcc 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -2157,12 +2157,17 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx) free(_servicehost); + // power-monitor, refer to modules/power-monitor.js for details + duk_peval_string_noresult(ctx, "addModule('power-monitor', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE4LTIwMjAgSW50ZWwgQ29ycG9yYXRpb24NCg0KTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7DQp5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuDQpZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQNCg0KICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMA0KDQpVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlDQpkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLA0KV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuDQpTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kDQpsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4NCiovDQoNCmZ1bmN0aW9uIHBvd2VyTW9uaXRvcigpDQp7DQogICAgdGhpcy5fT2JqZWN0SUQgPSAncG93ZXItbW9uaXRvcic7DQogICAgcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyLmNhbGwodGhpcywgdHJ1ZSkNCiAgICAgICAgLmNyZWF0ZUV2ZW50KCdjaGFuZ2VkJykNCiAgICAgICAgLmNyZWF0ZUV2ZW50KCdzeCcpDQogICAgICAgIC5jcmVhdGVFdmVudCgnYmF0dGVyeUxldmVsJykNCiAgICAgICAgLmNyZWF0ZUV2ZW50KCdhY2RjJykNCiAgICAgICAgLmNyZWF0ZUV2ZW50KCdkaXNwbGF5Jyk7DQoNCiAgICB0aGlzLl9BQ1N0YXRlID0gMTsNCiAgICB0aGlzLl9CYXR0ZXJ5TGV2ZWwgPSAtMTsNCg0KICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpDQogICAgew0KICAgICAgICAvLyBUaGVzZSBtdXN0IGJlIHJlZ2lzdGVyZWQgQkVGT1JFIG5ld0xpc3RlbmVyIGlzIGhvb2tlZCB1cA0KICAgICAgICB0aGlzLm9uKCdiYXR0ZXJ5TGV2ZWwnLCBmdW5jdGlvbiAobGV2ZWwpIHsgdGhpcy5fQmF0dGVyeUxldmVsID0gbGV2ZWw7IH0pOw0KICAgICAgICB0aGlzLm9uKCdhY2RjJywgZnVuY3Rpb24gKG0pIHsgdGhpcy5fQUNTdGF0ZSA9IChtID09ICdBQycgPyAxIDogMCk7IH0pOw0KICAgIH0NCg0KICAgIHRoaXMub24oJ25ld0xpc3RlbmVyJywgZnVuY3Rpb24gKG5hbWUsIGNhbGxiYWNrKQ0KICAgIHsNCiAgICAgICAgaWYgKG5hbWUgPT0gJ2FjZGMnKSB7IGNhbGxiYWNrLmNhbGwodGhpcywgdGhpcy5fQUNTdGF0ZSA9PSAxID8gJ0FDJyA6ICdCQVRURVJZJyk7IH0NCiAgICAgICAgaWYgKG5hbWUgPT0gJ2JhdHRlcnlMZXZlbCcpIHsgY2FsbGJhY2suY2FsbCh0aGlzLCB0aGlzLl9CYXR0ZXJ5TGV2ZWwpOyB9DQogICAgfSk7DQoNCiAgICB0aGlzLl9pID0gc2V0SW1tZWRpYXRlKGZ1bmN0aW9uIChzZWxmKQ0KICAgIHsNCiAgICAgICAgcmVxdWlyZSgndXNlci1zZXNzaW9ucycpOyAvLyBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIHRoaXMgaXMgd2hlcmUgdGhlIFdpbmRvd3MgTWVzc2FnZXMgYXJlIHByb2Nlc3NlZCBmb3IgdGhlc2UgZXZlbnRzDQogICAgICAgIGRlbGV0ZSBzZWxmLl9pOw0KICAgIH0sIHRoaXMpOw0KDQogICAgaWYocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnbGludXgnKQ0KICAgIHsNCiAgICAgICAgdGhpcy5fQUNQYXRoID0gbnVsbDsNCiAgICAgICAgdGhpcy5fQmF0dGVyeVBhdGggPSBbXTsNCg0KICAgICAgICB2YXIgZGV2aWNlcyA9IHJlcXVpcmUoJ2ZzJykucmVhZGRpclN5bmMoJy9zeXMvY2xhc3MvcG93ZXJfc3VwcGx5Jyk7CiAgICAgICAgZm9yICh2YXIgaSBpbiBkZXZpY2VzKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHJlcXVpcmUoJ2ZzJykucmVhZEZpbGVTeW5jKCcvc3lzL2NsYXNzL3Bvd2VyX3N1cHBseS8nICsgZGV2aWNlc1tpXSArICcvdHlwZScpLnRvU3RyaW5nKCkudHJpbSgpID09ICdNYWlucycpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMuX0FDUGF0aCA9ICcvc3lzL2NsYXNzL3Bvd2VyX3N1cHBseS8nICsgZGV2aWNlc1tpXSArICcvJzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQ0KICAgICAgICBmb3IgKHZhciBpIGluIGRldmljZXMpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChyZXF1aXJlKCdmcycpLnJlYWRGaWxlU3luYygnL3N5cy9jbGFzcy9wb3dlcl9zdXBwbHkvJyArIGRldmljZXNbaV0gKyAnL3R5cGUnKS50b1N0cmluZygpLnRyaW0oKSA9PSAnQmF0dGVyeScpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhpcy5fQmF0dGVyeVBhdGgucHVzaCgnL3N5cy9jbGFzcy9wb3dlcl9zdXBwbHkvJyArIGRldmljZXNbaV0gKyAnLycpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmKHRoaXMuX0FDUGF0aCAhPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICB0aGlzLl9BQ1N0YXRlID0gcGFyc2VJbnQocmVxdWlyZSgnZnMnKS5yZWFkRmlsZVN5bmModGhpcy5fQUNQYXRoICsgJ29ubGluZScpLnRvU3RyaW5nKCkudHJpbSgpKTsNCiAgICAgICAgfQ0KICAgICAgICBpZih0aGlzLl9CYXR0ZXJ5UGF0aC5sZW5ndGg+MCkNCiAgICAgICAgew0KICAgICAgICAgICAgdGhpcy5fZ2V0QmF0dGVyeUxldmVsID0gZnVuY3Rpb24gX2dldEJhdHRlcnlMZXZlbCgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIHN1bSA9IDA7DQogICAgICAgICAgICAgICAgdmFyIGk7DQogICAgICAgICAgICAgICAgZm9yIChpIGluIHRoaXMuX0JhdHRlcnlQYXRoKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgc3VtICs9IHBhcnNlSW50KHJlcXVpcmUoJ2ZzJykucmVhZEZpbGVTeW5jKHRoaXMuX0JhdHRlcnlQYXRoW2ldICsgJ2NhcGFjaXR5JykudG9TdHJpbmcoKS50cmltKCkpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBzdW0gPSBNYXRoLmZsb29yKHN1bSAvIHRoaXMuX0JhdHRlcnlQYXRoLmxlbmd0aCk7DQogICAgICAgICAgICAgICAgcmV0dXJuIChzdW0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgdGhpcy5fQmF0dGVyeUxldmVsID0gdGhpcy5fZ2V0QmF0dGVyeUxldmVsKCk7DQogICAgICAgIH0NCiAgICAgICAgdGhpcy5fYWNwaVNpbmsgPSBmdW5jdGlvbiBfYWNwaVNpbmsoYWNwaUV2ZW50KQ0KICAgICAgICB7DQogICAgICAgICAgICBpZihhY3BpRXZlbnQubmFtZSA9PSAnYWNfYWRhcHRlcicpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgX2FjcGlTaW5rLnNlbGYuX0FDU3RhdGUgPSBhY3BpRXZlbnQudmFsdWU7DQogICAgICAgICAgICAgICAgX2FjcGlTaW5rLnNlbGYuZW1pdCgnYWNkYycsIGFjcGlFdmVudC52YWx1ZSA9PSAxID8gJ0FDJyA6ICdCQVRURVJZJyk7DQogICAgICAgICAgICB9DQogICAgICAgIH07DQogICAgICAgIHRoaXMuX2FjcGlTaW5rLnNlbGYgPSB0aGlzOw0KICAgICAgICByZXF1aXJlKCdsaW51eC1hY3BpJykub24oJ2FjcGknLCB0aGlzLl9hY3BpU2luayk7DQogICAgfQ0KfQ0KDQptb2R1bGUuZXhwb3J0cyA9IG5ldyBwb3dlck1vbml0b3IoKTs=', 'base64').toString());"); + + // service-manager, which on linux has a dependency on user-sessions and process-manager. Refer to /modules folder for human readable versions. duk_peval_string_noresult(ctx, "addModule('process-manager', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE4IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQoNCnZhciBHTSA9IHJlcXVpcmUoJ19HZW5lcmljTWFyc2hhbCcpOw0KdmFyIFRIMzJDU19TTkFQUFJPQ0VTUyA9IDB4MDI7DQp2YXIgVEgzMkNTX1NOQVBNT0RVTEUzMiA9IDB4MTA7DQp2YXIgVEgzMkNTX1NOQVBNT0RVTEUgPSAweDA4Ow0KdmFyIFBST0NFU1NfUVVFUllfTElNSVRFRF9JTkZPUk1BVElPTiA9IDB4MTAwMDsNCg0KDQovLyBVc2VkIG9uIFdpbmRvd3MgYW5kIExpbnV4IHRvIGdldCBpbmZvcm1hdGlvbiBhYm91dCBydW5uaW5nIHByb2Nlc3Nlcw0KZnVuY3Rpb24gcHJvY2Vzc01hbmFnZXIoKSB7DQogICAgdGhpcy5fT2JqZWN0SUQgPSAncHJvY2Vzcy1tYW5hZ2VyJzsgLy8gVXNlZCBmb3IgZGVidWdnaW5nLCBhbGxvd3MgeW91IHRvIGdldCB0aGUgb2JqZWN0IHR5cGUgYXQgcnVudGltZS4NCiAgICANCiAgICAvLyBTZXR1cCB0aGUgcGxhdGZvcm0gc3BlY2lmaWMgY2FsbHMuDQogICAgc3dpdGNoIChwcm9jZXNzLnBsYXRmb3JtKQ0KICAgIHsNCiAgICAgICAgY2FzZSAnd2luMzInOg0KICAgICAgICAgICAgdGhpcy5fa2VybmVsMzIgPSBHTS5DcmVhdGVOYXRpdmVQcm94eSgna2VybmVsMzIuZGxsJyk7DQogICAgICAgICAgICB0aGlzLl9rZXJuZWwzMi5DcmVhdGVNZXRob2QoJ0Nsb3NlSGFuZGxlJyk7DQogICAgICAgICAgICB0aGlzLl9rZXJuZWwzMi5DcmVhdGVNZXRob2QoJ0dldExhc3RFcnJvcicpOw0KICAgICAgICAgICAgdGhpcy5fa2VybmVsMzIuQ3JlYXRlTWV0aG9kKCdDcmVhdGVUb29saGVscDMyU25hcHNob3QnKTsNCiAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNyZWF0ZU1ldGhvZCgnTW9kdWxlMzJGaXJzdFcnKTsNCiAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNyZWF0ZU1ldGhvZCgnTW9kdWxlMzJOZXh0VycpOw0KICAgICAgICAgICAgdGhpcy5fa2VybmVsMzIuQ3JlYXRlTWV0aG9kKCdPcGVuUHJvY2VzcycpOw0KICAgICAgICAgICAgdGhpcy5fa2VybmVsMzIuQ3JlYXRlTWV0aG9kKCdQcm9jZXNzMzJGaXJzdFcnKTsNCiAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNyZWF0ZU1ldGhvZCgnUHJvY2VzczMyTmV4dFcnKTsNCiAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNyZWF0ZU1ldGhvZCgnUXVlcnlGdWxsUHJvY2Vzc0ltYWdlTmFtZVcnKTsNCiAgICAgICAgICAgIGJyZWFrOw0KCWNhc2UgJ2ZyZWVic2QnOg0KICAgICAgICBjYXNlICdsaW51eCc6DQogICAgICAgIGNhc2UgJ2Rhcndpbic6DQogICAgICAgICAgICB0aGlzLl9jaGlsZFByb2Nlc3MgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJyk7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgZGVmYXVsdDoNCiAgICAgICAgICAgIHRocm93IChwcm9jZXNzLnBsYXRmb3JtICsgJyBub3Qgc3VwcG9ydGVkJyk7DQogICAgICAgICAgICBicmVhazsNCiAgICB9DQogICAgdGhpcy5lbnVtZXJhdGVQcm9jZXNzZXMgPSBmdW5jdGlvbiBlbnVtZXJhdGVQcm9jZXNzZXMoKQ0KICAgIHsNCiAgICAgICAgdmFyIHByb21pc2UgPSByZXF1aXJlKCdwcm9taXNlJyk7DQogICAgICAgIHZhciByZXQgPSBuZXcgcHJvbWlzZShmdW5jdGlvbiAocmVzLCByZWopIHsgdGhpcy5fcmVzID0gcmVzOyB0aGlzLl9yZWogPSByZWo7IH0pOw0KICAgICAgICByZXQuY2FsbGJhY2sgPSBmdW5jdGlvbiBjYWxsYmFjayhwcykNCiAgICAgICAgew0KICAgICAgICAgICAgY2FsbGJhY2sucHJvbS5fcmVzKHBzKTsNCiAgICAgICAgfQ0KICAgICAgICByZXQuY2FsbGJhY2sucHJvbSA9IHJldDsNCiAgICAgICAgdGhpcy5nZXRQcm9jZXNzZXMocmV0LmNhbGxiYWNrKTsNCiAgICAgICAgcmV0dXJuIChyZXQpOw0KICAgIH0NCiAgICAvLyBSZXR1cm4gYSBvYmplY3Qgb2Y6IHBpZCAtPiBwcm9jZXNzIGluZm9ybWF0aW9uLg0KICAgIHRoaXMuZ2V0UHJvY2Vzc2VzID0gZnVuY3Rpb24gZ2V0UHJvY2Vzc2VzKGNhbGxiYWNrKQ0KICAgIHsNCiAgICAgICAgc3dpdGNoKHByb2Nlc3MucGxhdGZvcm0pDQogICAgICAgIHsNCiAgICAgICAgICAgIGRlZmF1bHQ6DQogICAgICAgICAgICAgICAgdGhyb3cgKCdFbnVtZXJhdGluZyBwcm9jZXNzZXMgb24gJyArIHByb2Nlc3MucGxhdGZvcm0gKyAnIG5vdCBzdXBwb3J0ZWQnKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGNhc2UgJ3dpbjMyJzogLy8gV2luZG93cyBwcm9jZXNzZXMNCiAgICAgICAgICAgICAgICB2YXIgcGlkOw0KICAgICAgICAgICAgICAgIHZhciByZXRWYWwgPSB7fTsNCiAgICAgICAgICAgICAgICB2YXIgaCA9IHRoaXMuX2tlcm5lbDMyLkNyZWF0ZVRvb2xoZWxwMzJTbmFwc2hvdChUSDMyQ1NfU05BUFBST0NFU1MsIDApOw0KICAgICAgICAgICAgICAgIHZhciBpbmZvID0gR00uQ3JlYXRlVmFyaWFibGUoR00uUG9pbnRlclNpemUgPT0gOCA/IDU2OCA6IDU1Nik7DQogICAgICAgICAgICAgICAgdmFyIGZ1bGxwYXRoID0gR00uQ3JlYXRlVmFyaWFibGUoMjA0OCk7DQogICAgICAgICAgICAgICAgdmFyIHBhdGhTaXplID0gR00uQ3JlYXRlVmFyaWFibGUoNCk7DQogICAgICAgICAgICAgICAgdmFyIHBoOw0KDQogICAgICAgICAgICAgICAgaW5mby50b0J1ZmZlcigpLndyaXRlVUludDMyTEUoaW5mby5fc2l6ZSwgMCk7DQogICAgICAgICAgICAgICAgdmFyIG5leHRQcm9jZXNzID0gdGhpcy5fa2VybmVsMzIuUHJvY2VzczMyRmlyc3RXKGgsIGluZm8pOw0KICAgICAgICAgICAgICAgIHdoaWxlIChuZXh0UHJvY2Vzcy5WYWwpIA0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgcGlkID0gaW5mby5EZXJlZig4LCA0KS50b0J1ZmZlcigpLnJlYWRVSW50MzJMRSgwKTsNCiAgICAgICAgICAgICAgICAgICAgcmV0VmFsW3BpZF0gPSB7IHBpZDogcGlkLCBjbWQ6IGluZm8uRGVyZWYoR00uUG9pbnRlclNpemUgPT0gNCA/IDM2IDogNDQsIDI2MCkuV2lkZTJVVEY4IH07DQoNCiAgICAgICAgICAgICAgICAgICAgaWYgKChwaCA9IHRoaXMuX2tlcm5lbDMyLk9wZW5Qcm9jZXNzKFBST0NFU1NfUVVFUllfTElNSVRFRF9JTkZPUk1BVElPTiwgMCwgcGlkKSkuVmFsICE9IC0xKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICBwYXRoU2l6ZS50b0J1ZmZlcigpLndyaXRlVUludDMyTEUoZnVsbHBhdGguX3NpemUpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2tlcm5lbDMyLlF1ZXJ5RnVsbFByb2Nlc3NJbWFnZU5hbWVXKHBoLCAwLCBmdWxscGF0aCwgcGF0aFNpemUpLlZhbCAhPSAwKQ0KICAgICAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldFZhbFtwaWRdLnBhdGggPSBmdWxscGF0aC5XaWRlMlVURjg7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXJuZWwzMi5DbG9zZUhhbmRsZShwaCk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICByZXRWYWxbcGlkXS51c2VyID0gcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmdldFByb2Nlc3NPd25lck5hbWUocGlkKS5uYW1lOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGNhdGNoKGVlKQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIG5leHRQcm9jZXNzID0gdGhpcy5fa2VybmVsMzIuUHJvY2VzczMyTmV4dFcoaCwgaW5mbyk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHRoaXMuX2tlcm5lbDMyLkNsb3NlSGFuZGxlKGgpOw0KICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykgeyBjYWxsYmFjay5hcHBseSh0aGlzLCBbcmV0VmFsXSk7IH0NCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGNhc2UgJ2xpbnV4JzogLy8gTGludXggcHJvY2Vzc2VzDQogICAgICAgICAgICAgICAgdmFyIHAgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICAgICAgICAgIHAuc3Rkb3V0LnN0ciA9ICcnOyBwLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICAgICAgcC5zdGRlcnIuc3RyID0gJyc7IHAuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBwLnN0ZGluLndyaXRlKCdwcyAtYXggLW8gcGlkIC1vIHVzZXI6OTkgLW8gY29tbWFuZCB8IHRyICcgKyAiJ1xcbicgJ1xcdCcgfCBhd2sgLUYiICsgJyJcXHQiIFwneyBwcmludGYgInsiOyBmb3IoaT0yO2k8TkY7KytpKSB7IHNwbGl0KCRpLHRvaywiICIpOyBwaWQ9dG9rWzFdOyB1c2VyPXRva1syXTsgY21kPXN1YnN0cigkaSxsZW5ndGgodG9rWzFdKSsxMDIpOyBnc3ViKC9cXFxcLywiXFxcXFxcXFwmIixjbWQpOyBnc3ViKC8iLywiXFxcXFxcXFwmIixjbWQpOyBnc3ViKC9eWyBdKy8sIiIsY21kKTsgcHJpbnRmICIlc1xcIiVzXFwiOntcXCJwaWRcXCI6XFwiJXNcXCIsXFwidXNlclxcIjpcXCIlc1xcIixcXCJjbWRcXCI6XFwiJXNcXCJ9IiwoaSE9Mj8iLCI6IiIpLHBpZCxwaWQsdXNlcixjbWQ7IH0gcHJpbnRmICJ9IjsgfVwnXG5leGl0XG4nKTsNCiAgICAgICAgICAgICAgICBwLndhaXRFeGl0KCk7DQoNCiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2spDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBwLmFyZ3MgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyArK2kpIHsgcC5hcmdzLnB1c2goYXJndW1lbnRzW2ldKTsgfQ0KDQogICAgICAgICAgICAgICAgICAgIHAuYXJncy51bnNoaWZ0KEpTT04ucGFyc2UocC5zdGRvdXQuc3RyKSk7DQogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KHRoaXMsIHAuYXJncyk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlICdkYXJ3aW4nOg0KICAgICAgICAgICAgY2FzZSAnZnJlZWJzZCc6DQogICAgICAgICAgICAgICAgdmFyIHAgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICAgICAgICAgIHAuc3Rkb3V0LnN0ciA9ICcnOyBwLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICAgICAgcC5zdGRlcnIuc3RyID0gJyc7IHAuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBwLnN0ZGluLndyaXRlKCdwcyAtYXhvIHBpZCAtbyB1c2VyIC1vIGNvbW1hbmQgfCB0ciAnICsgIidcXG4nICdcXHQnIHwgYXdrIC1GIiArICciXFx0IiBcJ3sgcHJpbnRmICJ7IjsgZm9yKGk9MjtpPE5GOysraSkgeyBnc3ViKC9eWyBdKy8sIiIsJGkpOyBzcGxpdCgkaSx0b2ssIiAiKTsgcGlkPXRva1sxXTsgdXNlcj10b2tbMl07IGNtZD1zdWJzdHIoJGksbGVuZ3RoKHRva1sxXSkrbGVuZ3RoKHRva1syXSkrMik7IGdzdWIoL1xcXFwvLCJcXFxcXFxcXCYiLGNtZCk7IGdzdWIoLyIvLCJcXFxcXFxcXCYiLGNtZCk7IGdzdWIoL15bIF0rLywiIixjbWQpOyBwcmludGYgIiVzXFwiJXNcXCI6e1xcInBpZFxcIjpcXCIlc1xcIixcXCJ1c2VyXFwiOlxcIiVzXFwiLFxcImNtZFxcIjpcXCIlc1xcIn0iLChpIT0yPyIsIjoiIikscGlkLHBpZCx1c2VyLGNtZDsgfSBwcmludGYgIn0iOyB9XCdcbmV4aXRcbicpOw0KICAgICAgICAgICAgICAgIHAud2FpdEV4aXQoKTsNCg0KICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHAuYXJncyA9IFtdOw0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7ICsraSkgeyBwLmFyZ3MucHVzaChhcmd1bWVudHNbaV0pOyB9DQoNCiAgICAgICAgICAgICAgICAgICAgcC5hcmdzLnVuc2hpZnQoSlNPTi5wYXJzZShwLnN0ZG91dC5zdHIpKTsNCiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgcC5hcmdzKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgIH07DQoNCiAgICAvLyBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBzcGVjaWZpYyBwcm9jZXNzIG9uIExpbnV4DQogICAgdGhpcy5nZXRQcm9jZXNzSW5mbyA9IGZ1bmN0aW9uIGdldFByb2Nlc3NJbmZvKHBpZCkNCiAgICB7DQogICAgICAgIHN3aXRjaChwcm9jZXNzLnBsYXRmb3JtKQ0KICAgICAgICB7DQogICAgICAgICAgICBkZWZhdWx0Og0KICAgICAgICAgICAgICAgIHRocm93ICgnZ2V0UHJvY2Vzc0luZm8oKSBub3Qgc3VwcG9ydGVkIGZvciAnICsgcHJvY2Vzcy5wbGF0Zm9ybSk7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlICdsaW51eCc6DQogICAgICAgICAgICAgICAgdmFyIHN0YXR1cyA9IHJlcXVpcmUoJ2ZzJykucmVhZEZpbGVTeW5jKCcvcHJvYy8nICsgcGlkICsgJy9zdGF0dXMnKTsNCiAgICAgICAgICAgICAgICB2YXIgaW5mbyA9IHt9Ow0KICAgICAgICAgICAgICAgIHZhciBsaW5lcyA9IHN0YXR1cy50b1N0cmluZygpLnNwbGl0KCdcbicpOw0KICAgICAgICAgICAgICAgIGZvcih2YXIgaT0wO2k8bGluZXMubGVuZ3RoOysraSkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHZhciB0b2tlbnMgPSBsaW5lc1tpXS5zcGxpdCgnOicpOw0KICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW5zLmxlbmd0aCA+IDEpIHsgdG9rZW5zWzFdID0gdG9rZW5zWzFdLnRyaW0oKTsgfQ0KICAgICAgICAgICAgICAgICAgICBpbmZvW3Rva2Vuc1swXV0gPSB0b2tlbnNbMV07DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHJldHVybiAoaW5mbyk7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICB9Ow0KDQogICAgaWYocHJvY2Vzcy5wbGF0Zm9ybSAhPSAnd2luMzInKQ0KICAgIHsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdfcGdyZXAnLCB7DQogICAgICAgICAgICB2YWx1ZTogKGZ1bmN0aW9uICgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7DQogICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7IHRoaXMuc3RyICs9IGNodW5rLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCJ3aGVyZWlzIHBncmVwIHwgYXdrICd7IHByaW50ICQyIH0nXG5leGl0XG4iKTsNCiAgICAgICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICAgICAgICAgIHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpOw0KICAgICAgICAgICAgfSkoKQ0KICAgICAgICB9KTsNCg0KICAgICAgICBpZiAodGhpcy5fcGdyZXAgIT0gJycpDQogICAgICAgIHsNCiAgICAgICAgICAgIHRoaXMuZ2V0UHJvY2VzcyA9IGZ1bmN0aW9uIGdldFByb2Nlc3MoY21kKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGVyci5zdHIgPSAnJzsgY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgicGdyZXAgZ25vbWUtc2Vzc2lvbiB8IHRyICdcXG4nICdcXHQnIHwiICsgJyBhd2sgLUYiXFx0IiBcJ3sgcHJpbnRmICJbIjsgZm9yKGk9MTtpPE5GOysraSkgeyBpZihpPjEpIHsgcHJpbnRmICIsIjsgfSBwcmludGYgIiVkIiwgJGk7IH0gcHJpbnRmICJdIjsgfVwnJyk7DQogICAgICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ1xuZXhpdFxuJyk7DQogICAgICAgICAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICAgICAgICAgICAgICBpZiAoY2hpbGQuc3RkZXJyLnN0ciAhPSAnJykgeyB0aHJvdyAoY2hpbGQuc3RkZXJyLnN0ci50cmltKCkpOyB9DQogICAgICAgICAgICAgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpID09ICcnKSB7IHRocm93IChjbWQgKyAnIG5vdCBmb3VuZCcpOyB9DQoNCiAgICAgICAgICAgICAgICByZXR1cm4gKEpTT04ucGFyc2UoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpKTsNCiAgICAgICAgICAgIH07DQogICAgICAgIH0NCg0KICAgICAgICB0aGlzLmdldFByb2Nlc3NFeCA9IGZ1bmN0aW9uIGdldFByb2Nlc3NFeChjbWQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgncHMgLWF4IC1vIHBpZCAtbyBjb21tYW5kIHwgZ3JlcCAnICsgY21kICsgIiB8IHRyICdcXG4nICdcXHQnIHwgYXdrIC1GIiArICciXFx0IiBcJ3sgcHJpbnRmICJbIjsgZm9yKGk9MTtpPE5GOysraSkgeyBzcGxpdCgkaSxyLCIgIik7IGlmKHJbMl0hPSJncmVwIikgeyBpZihpPjEpIHsgcHJpbnRmICIsIjsgfSBwcmludGYgIiVzIiwgclsxXTsgfSB9IHByaW50ZiAiXSI7IH1cJycpOw0KICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoJ1xuZXhpdFxuJyk7DQogICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KDQogICAgICAgICAgICBpZiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkgPT0gJycpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhyb3cgKGNtZCArICcgbm90IGZvdW5kJyk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgcmV0dXJuIChKU09OLnBhcnNlKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpKSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQp9DQoNCm1vZHVsZS5leHBvcnRzID0gbmV3IHByb2Nlc3NNYW5hZ2VyKCk7DQo=', 'base64').toString());"); #if defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD) duk_peval_string_noresult(ctx, "addModule('linux-dbus', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE4IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQp0cnkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoQXJyYXkucHJvdG90eXBlLCAicGVlayIsIHsgdmFsdWU6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh0aGlzLmxlbmd0aCA+IDAgPyB0aGlzW3RoaXMubGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQpOyB9IH0pOyB9IGNhdGNoIChlKSB7IH0NCg0KDQoNCmZ1bmN0aW9uIGRidXMoYWRkcmVzcywgdWlkLCBlbnYpDQp7DQogICAgLy9jb25zb2xlLmxvZyhhZGRyZXNzLCB1aWQsIGVudik7DQogICAgdmFyIG9wdGlvbnMgPSB7IGVudjogZW52LCB1aWQ6IHVpZCA9PSBudWxsID8gLTEgOiB1aWQgfTsNCiAgICBpZiAodWlkID09IG51bGwgJiYgZW52ID09IG51bGwpIHsgb3B0aW9ucyA9IHt9OyB9DQoNCiAgICB0aGlzLl9PYmplY3RJRCA9ICdsaW51eC1kYnVzJzsNCiAgICByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXIuY2FsbCh0aGlzLCB0cnVlKQ0KICAgICAgICAuY3JlYXRlRXZlbnQoJ3NpZ25hbCcpOw0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAidWlkIiwgeyB2YWx1ZTogdWlkIH0pOw0KICAgIHRoaXMuX2NoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCIvYmluL3NoIiwgWyJzaCJdLCBvcHRpb25zKTsNCiAgICB0aGlzLl9jaGlsZC5kZXNjcmlwdG9yTWV0YWRhdGEgPSAnbGludXgtZGJ1cyB7dWlkOiAnICsgdWlkICsgJywgYWRkcmVzczogJyArIGFkZHJlc3MgKyAnfSc7DQoNCiAgICBpZiAodWlkICE9IG51bGwpDQogICAgew0KICAgICAgICB0aGlzLl9jaGlsZC5zdGRpbi53cml0ZSgnZGJ1cy1tb25pdG9yIC0tc2Vzc2lvbiAidHlwZT1cJ3NpZ25hbFwnLCBpbnRlcmZhY2U9XCcnICsgYWRkcmVzcyArICdcJyIgfCAoIHdoaWxlIHJlYWQgWDsgZG8gZWNobyAiJFgiOyBkb25lIClcbicpOw0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgICB0aGlzLl9jaGlsZC5zdGRpbi53cml0ZSgnZGJ1cy1tb25pdG9yIC0tc3lzdGVtICJ0eXBlPVwnc2lnbmFsXCcnICsgKGFkZHJlc3MhPW51bGw/KCcsIGludGVyZmFjZT1cJycgKyBhZGRyZXNzICsgJ1wnJyk6KCcnKSkgKyAnIiB8ICggd2hpbGUgcmVhZCBYOyBkbyBlY2hvICIkWCI7IGRvbmUgKVxuJyk7DQogICAgfQ0KICAgIHRoaXMuX2NoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7ICB9KTsNCiAgICB0aGlzLl9jaGlsZC5zdGRvdXQuZGJ1cyA9IHRoaXM7DQogICAgdGhpcy5fY2hpbGQuc3Rkb3V0Ll9zdHIgPSAnJzsNCiAgICB0aGlzLl9jaGlsZC5zdGRvdXQuX3BlbmRpbmcgPSBbXTsNCiAgICB0aGlzLl9jaGlsZC5vbignZXhpdCcsIGZ1bmN0aW9uICgpIHsgfSk7DQogICAgdGhpcy5fY2hpbGQuc3Rkb3V0Ll9wcm9jZXNzUGVuZGluZyA9IGZ1bmN0aW9uIF9wcm9jZXNzUGVuZGluZygpDQogICAgew0KICAgICAgICAvL2NvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHRoaXMuX3BlbmRpbmcsIG51bGwsIDEpKTsNCg0KICAgICAgICB0aGlzLl9wZW5kaW5nVGltZW91dCA9IG51bGw7DQogICAgICAgIHZhciBzaWcgPSB7fTsNCiAgICAgICAgdmFyIHRtcCwgdG1wMjsNCg0KICAgICAgICB2YXIgaW5mbyA9IHRoaXMuX3BlbmRpbmdbMF0uc3BsaXQoJzsnKTsNCiAgICAgICAgZm9yIChpID0gMTsgaSA8IGluZm8ubGVuZ3RoOyArK2kpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBpbmZvMiA9IGluZm9baV0uc3BsaXQoJz0nKTsNCiAgICAgICAgICAgIGlmIChpbmZvMlswXSAmJiBpbmZvMlsxXSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaWdbaW5mbzJbMF0udHJpbSgpXSA9IGluZm8yWzFdLnRyaW0oKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBmb3IgKGkgPSAxOyBpIDwgdGhpcy5fcGVuZGluZy5sZW5ndGg7ICsraSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKHRoaXMuX3BlbmRpbmdbaV0uc3RhcnRzV2l0aCgnc3RyaW5nICcpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHNpZ1sndmFsdWUnXSA9IHRoaXMuX3BlbmRpbmdbaV0uc3BsaXQoJyInKVsxXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3BlbmRpbmdbaV0uc3RhcnRzV2l0aCgnYm9vbGVhbiAnKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaWdbJ3ZhbHVlJ10gPSBKU09OLnBhcnNlKHRoaXMuX3BlbmRpbmdbaV0uc3BsaXQoJyAnKVsxXSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAodGhpcy5fcGVuZGluZ1tpXS5zdGFydHNXaXRoKCdhcnJheSAnKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzaWdbJ2RhdGEnXSA9IFtdOw0KICAgICAgICAgICAgICAgIGZvciAoaSA9IGkgKyAxOyBpIDwgdGhpcy5fcGVuZGluZy5sZW5ndGg7ICsraSkNCiAgICAgICAgICAgICAgICB7DQoJCSAgICAgICAgICAgIGlmKHRoaXMuX3BlbmRpbmdbaV0uc3RhcnRzV2l0aCgnZGljdCBlbnRyeScpKQ0KCQkgICAgICAgICAgICB7DQoJCQkgICAgICAgICAgICB2YXIgZGljdEVudHJ5ID0ge307DQoJCQkgICAgICAgICAgICB2YXIgajsNCgkJCSAgICAgICAgICAgIGZvcihqPWk7dGhpcy5fcGVuZGluZ1tqXS5pbmRleE9mKCcpJyk8MDsrK2opIHt9DQoJCQkgICAgICAgICAgICB2YXIgdG1wU3RyaW5nID0gdGhpcy5fcGVuZGluZy5zbGljZShpLGopLmpvaW4oJyAnKTsNCgkJCSAgICAgICAgICAgIHZhciB0bXBLZXkgPSB0bXBTdHJpbmcuc3BsaXQoJyInKVsxXTsNCgkJCSAgICAgICAgICAgIHZhciB0bXBWYWw7DQoJCQkgICAgICAgICAgICB0cnkNCgkJCSAgICAgICAgICAgIHsJCQkNCgkJCQkgICAgICAgICAgICB0bXBWYWwgID0gdG1wU3RyaW5nLnNwbGl0KCd2YXJpYW50JylbMV0udHJpbSgpOw0KCQkJICAgICAgICAgICAgfQ0KCQkJICAgICAgICAgICAgY2F0Y2goZSkNCgkJCSAgICAgICAgICAgIHsNCgkJCQkgICAgICAgICAgICBjb25zb2xlLmxvZygnT09QUzogJyArIHRtcFN0cmluZyk7DQoJCQkJICAgICAgICAgICAgY29uc29sZS5sb2coJ1xuJyk7DQoJCQkgICAgICAgICAgICB9DQoJCQkgICAgICAgICAgICBpZih0bXBWYWwuc3RhcnRzV2l0aCgnc3RyaW5nICcpKQ0KCQkJICAgICAgICAgICAgew0KCQkJICAgICAgICAgICAgICAgdG1wVmFsID0gdG1wVmFsLnNwbGl0KCciJylbMV07DQoJCQkgICAgICAgICAgICB9DQoJCQkgICAgICAgICAgICBpZih0bXBWYWwuc3RhcnRzV2l0aCgndWludCcpIHx8IHRtcFZhbC5zdGFydHNXaXRoKCdpbnQnKSkNCgkJCSAgICAgICAgICAgIHsNCgkJCSAgICAgICAgICAgICAgIHRtcFZhbCA9IHRtcFZhbC5zcGxpdCgnICcpWzFdOw0KCQkJICAgICAgICAgICAgfQ0KCQkJICAgICAgICAgICAgZGljdEVudHJ5W3RtcFN0cmluZy5zcGxpdCgnIicpWzFdXSA9IHRtcFZhbDsNCgkJCSAgICAgICAgICAgIHNpZ1snZGF0YSddLnB1c2goZGljdEVudHJ5KTsNCgkJCSAgICAgICAgICAgIGkgPSBqIC0gMTsNCgkJICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9wZW5kaW5nW2ldLnN0YXJ0c1dpdGgoJ3N0cmluZyAnKSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5fcGVuZGluZ1tpXS5zcGxpdCgnIicpWzFdLnNwbGl0KCc9Jyk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZih0bXBbMV0pDQogICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wMiA9IHt9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcDJbdG1wWzBdLnRyaW0oKV0gPSB0bXBbMV0udHJpbSgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ1snZGF0YSddLnB1c2godG1wMik7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgdGhpcy5fcGVuZGluZyA9IFtdOw0KDQogICAgICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbiAoZSwgcykNCiAgICAgICAgew0KICAgICAgICAgICAgZS5kYnVzLmVtaXQoJ3NpZ25hbCcsIHMpOw0KICAgICAgICB9LCB0aGlzLCBzaWcpOw0KICAgIH07DQogICAgdGhpcy5fY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKQ0KICAgIHsNCiAgICAgICAgLy8gUGFyc2UgREJVUyBEYXRhDQogICAgICAgIGlmICh0aGlzLl9wZW5kaW5nVGltZW91dCkgeyBjbGVhclRpbWVvdXQodGhpcy5fcGVuZGluZ1RpbWVvdXQpOyB0aGlzLl9wZW5kaW5nVGltZW91dCA9IG51bGw7IH0NCiAgICAgICAgLy9jb25zb2xlLmxvZygnPT4nICsgY2h1bmsudG9TdHJpbmcoKSArICc8PScpOw0KDQogICAgICAgIHZhciBpOw0KICAgICAgICB2YXIgdG9rZW5zID0gY2h1bmsudG9TdHJpbmcoKS5zcGxpdCgnXG4nKTsNCiAgICAgICAgZm9yIChpIGluIHRva2VucykNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKHRva2Vuc1tpXS5zdGFydHNXaXRoKCdzaWduYWwgJykpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYgKHRoaXMuX3BlbmRpbmcubGVuZ3RoID4gMCkgeyB0aGlzLl9wcm9jZXNzUGVuZGluZygpOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB0aGlzLl9wZW5kaW5nLnB1c2godG9rZW5zW2ldKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmICh0aGlzLl9wZW5kaW5nLmxlbmd0aCA+IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmdUaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoc2VsZikgeyBzZWxmLl9wcm9jZXNzUGVuZGluZygpOyB9LCA1MDAsIHRoaXMpOw0KICAgICAgICB9DQogICAgfSk7DQp9DQoNCm1vZHVsZS5leHBvcnRzID0gZGJ1czsNCm1vZHVsZS5leHBvcnRzLmhhc1NlcnZpY2UgPSBmdW5jdGlvbiBoYXNTZXJ2aWNlKG5hbWUpDQp7DQogICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdjYXQgL3Vzci9zaGFyZS9kYnVzLTEvc2VydmljZXMvKi5zZXJ2aWNlIHwgZ3JlcCAiJyArIG5hbWUgKyAnIiB8IGF3ayAtRj0gXCd7IGlmKCAkMj09IicgKyBuYW1lICsgJyIgKSB7IHByaW50ICQyOyB9IH1cJ1xuZXhpdFxuJyk7DQogICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICByZXR1cm4gKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpICE9ICcnKTsNCn07DQptb2R1bGUuZXhwb3J0cy5nZXRTZXJ2aWNlcyA9IGZ1bmN0aW9uIGdldFNlcnZpY2VzKCkNCnsNCiAgICB2YXIgZ3JlcCA9IG51bGw7DQogICAgdmFyIG9wdGlvbnMgPSBudWxsOw0KICAgIGZvciAodmFyIGF4IGluIGFyZ3VtZW50cykNCiAgICB7DQogICAgICAgIGlmKHR5cGVvZihhcmd1bWVudHNbYXhdKT09J3N0cmluZycpDQogICAgICAgIHsNCiAgICAgICAgICAgIGdyZXAgPSBhcmd1bWVudHNbYXhdOw0KICAgICAgICB9DQogICAgICAgIGlmKHR5cGVvZihhcmd1bWVudHNbYXhdKT09J29iamVjdCcpDQogICAgICAgIHsNCiAgICAgICAgICAgIG9wdGlvbnMgPSBhcmd1bWVudHNbYXhdOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgaWYgKGdyZXApIHsgZ3JlcCA9ICcgfCBncmVwICInICsgZ3JlcCArICciJzsgfSBlbHNlIHsgZ3JlcCA9ICcnOyB9DQogICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddLCBvcHRpb25zKTsNCiAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQogICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOyBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdkYnVzLXNlbmQgLS1zZXNzaW9uIC0tZGVzdD1vcmcuZnJlZWRlc2t0b3AuREJ1cyAtLXR5cGU9bWV0aG9kX2NhbGwgLS1wcmludC1yZXBseSAvb3JnL2ZyZWVkZXNrdG9wL0RCdXMgb3JnLmZyZWVkZXNrdG9wLkRCdXMuTGlzdE5hbWVzJyArIGdyZXAgKyAnXG5leGl0XG4nKTsNCiAgICBjaGlsZC53YWl0RXhpdCgpOw0KDQogICAgdmFyIHJldCA9IFtdOw0KICAgIHZhciBpLCB0bXA7DQogICAgdmFyIHRva2VucyA9IGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpLnNwbGl0KCdcbicpOw0KICAgIGZvciAoaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyArK2kpDQogICAgew0KICAgICAgICBpZiAoKHRtcCA9IHRva2Vuc1tpXS50cmltKCkpLnN0YXJ0c1dpdGgoJ2FycmF5ICcpKQ0KICAgICAgICB7DQogICAgICAgICAgICBmb3IgKGkgPSBpICsgMTsgaSA8IHRva2Vucy5sZW5ndGg7ICsraSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB0bXAgPSB0b2tlbnNbaV0udHJpbSgpOw0KICAgICAgICAgICAgICAgIGlmICh0bXAuc3RhcnRzV2l0aCgnc3RyaW5nICcpKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0LnB1c2goSlNPTi5wYXJzZSh0bXAuc3BsaXQoJyAnKVsxXSkpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmKHRtcC5zdGFydHNXaXRoKCdzdHJpbmcgJykpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldC5wdXNoKEpTT04ucGFyc2UodG1wLnNwbGl0KCcgJylbMV0pKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gKHJldCk7DQp9DQo=', 'base64').toString());"); duk_peval_string_noresult(ctx, "addModule('linux-gnome-helpers', Buffer.from('DQoNCmZ1bmN0aW9uIGdub21lX2dldFByb3h5U2V0dGluZ3ModWlkKQ0Kew0KICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSwgeyBlbnY6IHsgSE9NRTogcmVxdWlyZSgndXNlci1zZXNzaW9ucycpLmdldEhvbWVGb2xkZXIodWlkKSB9fSk7DQogICAgY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB9KTsNCiAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7IGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IHRoaXMuc3RyICs9IGMudG9TdHJpbmcoKTsgfSk7DQoNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIGxpc3QtcmVjdXJzaXZlbHkgb3JnLmdub21lLnN5c3RlbS5wcm94eSB8IHRyICJcXG4iICJcXHwiIHwgdHIgIlxcXCciICJcXGAiIHwgYXdrIFwneyBjb3VudD1zcGxpdCgkMCwgcmVzLCAifCIpOycpDQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2V4Yz0iW10iOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdmb3IoYT0wO2E8Y291bnQ7KythKScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCd7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3NwbGl0KHJlc1thXSwgbW9kZWNoZWNrLCAiICIpOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdpZihtb2RlY2hlY2tbMl0gPT0gIm1vZGUiKScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCd7Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ3NwbGl0KG1vZGVjaGVja1szXSwgcHJ4LCAiYCIpOyBtb2RlID0gcHJ4WzJdOycpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCd9Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2lmKG1vZGVjaGVja1sxXT09Im9yZy5nbm9tZS5zeXN0ZW0ucHJveHkuaHR0cCIgJiYgbW9kZWNoZWNrWzJdPT0iaG9zdCIpIHsgc3BsaXQobW9kZWNoZWNrWzNdLCBoc3QsICJgIik7IGhvc3QgPSBoc3RbMl07IH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnaWYobW9kZWNoZWNrWzFdPT0ib3JnLmdub21lLnN5c3RlbS5wcm94eS5odHRwIiAmJiBtb2RlY2hlY2tbMl09PSJwb3J0IikgeyBwb3J0ID0gbW9kZWNoZWNrWzNdOyB9Jyk7DQogICAgY2hpbGQuc3RkaW4ud3JpdGUoJ2lmKG1vZGVjaGVja1sxXT09Im9yZy5nbm9tZS5zeXN0ZW0ucHJveHkiICYmIG1vZGVjaGVja1syXT09Imlnbm9yZS1ob3N0cyIpIHsgZXhjID0gc3Vic3RyKHJlc1thXSwgMzYpOyBnc3ViKCJgIiwgIlxcIiIsIGV4Yyk7IH0nKTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnfScpOw0KICAgIGNoaWxkLnN0ZGluLndyaXRlKCdwcmludGYgIntcXCJtb2RlXFwiOiBcXCIlc1xcIiwgXFwiaG9zdFxcIjogXFwiJXNcXCIsIFxcInBvcnRcXCI6ICVzLCBcXCJleGNlcHRpb25zXFwiOiAlc30iLCBtb2RlLCBob3N0LCBwb3J0LCBleGM7IH1cJ1xuZXhpdFxuJyk7DQogICAgY2hpbGQud2FpdEV4aXQoKTsNCiAgICB0cnkNCiAgICB7DQogICAgICAgIHJldHVybiAoSlNPTi5wYXJzZShjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSkpOw0KICAgIH0NCiAgICBjYXRjaChlKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuICh7fSk7DQogICAgfQ0KfQ0KDQpmdW5jdGlvbiBnbm9tZV9nZXREZXNrdG9wV2FsbHBhcGVyKHVpZCkNCnsNCiAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10sIHsgZW52OiB7IEhPTUU6IHJlcXVpcmUoJ3VzZXItc2Vzc2lvbnMnKS5nZXRIb21lRm9sZGVyKHVpZCkgfSB9KTsNCiAgICBjaGlsZC5zdGRlcnIuc3RyID0gJyc7IGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IH0pOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIGdldCBvcmcuZ25vbWUuZGVza3RvcC5iYWNrZ3JvdW5kIHBpY3R1cmUtdXJpXG5leGl0XG4nKTsNCiAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSBjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKS5zcGxpdCgnZmlsZTovLycpLnBvcCgpOw0KICAgIGlmIChjaGlsZC5zdGRvdXQuc3RyLmVuZHNXaXRoKCciJykgfHwgY2hpbGQuc3Rkb3V0LnN0ci5lbmRzV2l0aCgiJyIpKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnN1YnN0cmluZygwLCBjaGlsZC5zdGRvdXQuc3RyLmxlbmd0aCAtIDEpKTsNCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyKTsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIGdub21lX3NldERlc2t0b3BXYWxscGFwZXIodWlkLCBmaWxlUGF0aCkNCnsNCiAgICBpZiAoIWZpbGVQYXRoKSB7IGZpbGVQYXRoID0gJy9kZXYvbnVsbCc7IH0NCg0KICAgIHZhciB2ID0geyBIT01FOiByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0SG9tZUZvbGRlcih1aWQpIH07DQogICAgdmFyIHBpZHMgPSByZXF1aXJlKCdwcm9jZXNzLW1hbmFnZXInKS5nZXRQcm9jZXNzKCdnbm9tZS1zZXNzaW9uJyk7DQogICAgZm9yICh2YXIgaSBpbiBwaWRzKQ0KICAgIHsNCiAgICAgICAgdmFyIGUgPSByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0RW52RnJvbVBpZChwaWRzW2ldKTsNCiAgICAgICAgaWYgKGUuVVNFUiAmJiByZXF1aXJlKCd1c2VyLXNlc3Npb25zJykuZ2V0VWlkKGUuVVNFUikhPXVpZCkNCiAgICAgICAgew0KICAgICAgICAgICAgY29udGludWU7DQogICAgICAgIH0NCiAgICAgICAgdi5EQlVTX1NFU1NJT05fQlVTX0FERFJFU1MgPSBlLkRCVVNfU0VTU0lPTl9CVVNfQUREUkVTUzsNCiAgICAgICAgaWYgKHYuREJVU19TRVNTSU9OX0JVU19BRERSRVNTKSB7IGJyZWFrOyB9DQogICAgfQ0KDQogICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddLCB7IHVpZDogdWlkLCBlbnY6IHYgfSk7DQogICAgY2hpbGQuc3RkZXJyLnN0ciA9ICcnOyBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCBmdW5jdGlvbiAoYykgeyB0aGlzLnN0ciArPSBjLnRvU3RyaW5nKCk7IH0pOw0KICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICBjaGlsZC5zdGRpbi53cml0ZSgnZ3NldHRpbmdzIHNldCBvcmcuZ25vbWUuZGVza3RvcC5iYWNrZ3JvdW5kIHBpY3R1cmUtdXJpIGZpbGU6Ly8nICsgZmlsZVBhdGggKyAnXG5leGl0XG4nKTsNCiAgICBjaGlsZC53YWl0RXhpdCgpOw0KfQ0KDQpzd2l0Y2gocHJvY2Vzcy5wbGF0Zm9ybSkNCnsNCiAgICBjYXNlICdsaW51eCc6DQogICAgICAgIG1vZHVsZS5leHBvcnRzID0NCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBnZXRQcm94eVNldHRpbmdzOiBnbm9tZV9nZXRQcm94eVNldHRpbmdzLA0KICAgICAgICAgICAgICAgIGdldERlc2t0b3BXYWxscGFwZXI6IGdub21lX2dldERlc2t0b3BXYWxscGFwZXIsDQogICAgICAgICAgICAgICAgc2V0RGVza3RvcFdhbGxwYXBlcjogZ25vbWVfc2V0RGVza3RvcFdhbGxwYXBlcg0KICAgICAgICAgICAgfTsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnX2xvY2F0aW9uJywgew0KICAgICAgICAgICAgdmFsdWU6IChmdW5jdGlvbiAoKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOw0KICAgICAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB0aGlzLnN0ciArPSBjaHVuay50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgid2hlcmVpcyBnc2V0dGluZ3MgfCBhd2sgJ3sgcHJpbnQgJDIgfSdcbmV4aXRcbiIpOw0KICAgICAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7DQogICAgICAgICAgICB9KSgpDQogICAgICAgIH0pOw0KICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLmV4cG9ydHMsICdhdmFpbGFibGUnLCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMuX2xvY2F0aW9uICE9ICcnID8gdHJ1ZSA6IGZhbHNlKTsgfSB9KTsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnc2NyaXB0VmVyc2lvbicsDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdmFsdWU6IChmdW5jdGlvbigpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB2YXIgcmV0ID0geyBtYWpvcjogMCwgbWlub3I6IDAgfTsNCiAgICAgICAgICAgICAgICAgICAgaWYocmVxdWlyZSgnZnMnKS5leGlzdHNTeW5jKCcvdXNyL2Jpbi9zY3JpcHQnKSkNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uICgpIHsgfSk7DQogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgnc2NyaXB0IC1WIHwgYXdrIFwneyBzcGxpdCgkTkYsIFQsICIuIik7IHByaW50ZiAie1xcIm1ham9yXFwiOiVzLCBcXCJtaW5vclxcIjolc30iLFRbMV0sVFsyXTsgfVwnXG5leGl0XG4nKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICB0cnkNCiAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBKU09OLnBhcnNlKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoICh4KQ0KICAgICAgICAgICAgICAgICAgICAgICAgeyB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChyZXQpOw0KICAgICAgICAgICAgICAgIH0pKCkNCiAgICAgICAgICAgIH0pOw0KICAgICAgICBicmVhazsNCn0=', 'base64').toString());"); duk_peval_string_noresult(ctx, "addModule('linux-cpuflags', Buffer.from('LyoKQ29weXJpZ2h0IDIwMTkgSW50ZWwgQ29ycG9yYXRpb24KCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwp5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQpkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLApXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZApsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKi8NCg0KdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCmNoaWxkLnN0ZG91dC5zdHIgPSAnJzsgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGMpIHsgdGhpcy5zdHIgKz0gYy50b1N0cmluZygpOyB9KTsNCmNoaWxkLnN0ZGluLndyaXRlKCJjYXQgL3Byb2MvY3B1aW5mbyB8IGdyZXAgZmxhZ3MgfCB0ciAnXFxuJyAnficgfCBhd2sgLUZ+ICd7IHByaW50ZiAiICsgJyJbIjsgZm9yKGk9MTtpPD1ORi0xOysraSkgeyBzcGxpdCgkaSwgbGluZSwgIjoiKTsgeD1zcGxpdChsaW5lWzJdLCB2YWxzLCAiICIpOyBwcmludGYgIiVzeyIsIChpIT0xPyIsIjoiIik7IGZvcihqPTE7ajw9eDsrK2opIHsgcHJpbnRmICIlc1xcIiVzXFwiOiAxIiwgKGohPTE/IiwiOiIiKSwgdmFsc1tqXTsgIH0gcHJpbnRmICJ9IjsgIH0gcHJpbnRmICJdIjsgfVwnXG5leGl0XG4nKTsNCmNoaWxkLnN0ZGVyci5vbignZGF0YScsIGZ1bmN0aW9uIChjKSB7IH0pOw0KY2hpbGQud2FpdEV4aXQoKTsNCg0KaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ2xpbnV4JykNCnsNCiAgICB0cnkNCiAgICB7DQogICAgICAgIG1vZHVsZS5leHBvcnRzID0gSlNPTi5wYXJzZShjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7DQogICAgfQ0KICAgIGNhdGNoICh4KQ0KICAgIHsNCiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBudWxsOw0KICAgIH0NCn0NCmVsc2UNCnsNCiAgICBtb2R1bGUuZXhwb3J0cyA9IG51bGw7DQp9DQoNCv==', 'base64').toString());"); + duk_peval_string_noresult(ctx, "addModule('linux-acpi', Buffer.from('LyoNCkNvcHlyaWdodCAyMDIwIEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQoNCmZ1bmN0aW9uIGxpbnV4X2FjcGkoKQ0Kew0KICAgIHRoaXMuX09iamVjdElEID0gJ2xpbnV4LWFjcGknOw0KICAgIHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMsIHRydWUpDQogICAgICAgIC5jcmVhdGVFdmVudCgnYWNwaScpOw0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAic3VwcG9ydGVkIiwgeyB2YWx1ZTogcmVxdWlyZSgnZnMnKS5leGlzdHNTeW5jKCcvdmFyL3J1bi9hY3BpZC5zb2NrZXQnKSB9KTsNCiAgICBpZih0aGlzLnN1cHBvcnRlZCkNCiAgICB7DQogICAgICAgIHRoaXMuX2NsaWVudCA9IHJlcXVpcmUoJ25ldCcpLmNyZWF0ZUNvbm5lY3Rpb24oeyBwYXRoOiAnL3Zhci9ydW4vYWNwaWQuc29ja2V0JywgbWV0YWRhdGE6ICdsaW51eC1hY3BpJyB9LCBmdW5jdGlvbiAoKQ0KICAgICAgICB7DQogICAgICAgICAgICB0aGlzLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBibG9ja3M7DQogICAgICAgICAgICAgICAgdmFyIHVidWZmZXIgPSBudWxsOw0KICAgICAgICAgICAgICAgIHZhciB0b2tlbnMgPSBjaHVuay50b1N0cmluZygpLnNwbGl0KCdcbicpOw0KICAgICAgICAgICAgICAgIGlmICh0b2tlbnMubGVuZ3RoID09IDEpIHsgdGhpcy51bnNoaWZ0KGNodW5rKTsgfQ0KICAgICAgICAgICAgICAgIGlmICh0b2tlbnMucGVlaygpICE9ICcnKSB7IHVidWZmZXIgPSBCdWZmZXIuZnJvbSh0b2tlbnMucG9wKCkpOyB9DQogICAgICAgICAgICAgICAgZWxzZSB7IHRva2Vucy5wb3AoKTsgfQ0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gdG9rZW5zKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgYmxvY2tzID0gdG9rZW5zW2ldLnNwbGl0KCcgJyk7DQogICAgICAgICAgICAgICAgICAgIHRoaXMucmV0LmVtaXQoJ2FjcGknLCB7IG5hbWU6IGJsb2Nrc1swXSwgdHlwZTogQnVmZmVyLmZyb20oYmxvY2tzWzJdLCAnaGV4JykucmVhZFVJbnQzMkJFKCksIHZhbHVlOiBCdWZmZXIuZnJvbShibG9ja3NbM10sICdoZXgnKS5yZWFkVUludDMyQkUoKSB9KTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSk7DQogICAgICAgIHRoaXMuX2NsaWVudC5yZXQgPSB0aGlzOw0KICAgIH0NCn0NCg0KbW9kdWxlLmV4cG9ydHMgPSBuZXcgbGludXhfYWNwaSgpOw==', 'base64').toString());"); #endif char *_servicemanager = ILibMemory_Allocate(305481, 0, NULL, NULL); memcpy_s(_servicemanager + 0, 174560, "LyoNCkNvcHlyaWdodCAyMDE4IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KdmFyIHByb21pc2UgPSByZXF1aXJlKCdwcm9taXNlJyk7DQoNCmZ1bmN0aW9uIGZhaWx1cmVBY3Rpb25Ub0ludGVnZXIoYWN0aW9uKQ0Kew0KICAgIHZhciByZXQ7DQogICAgc3dpdGNoKGFjdGlvbikNCiAgICB7DQogICAgICAgIGRlZmF1bHQ6DQogICAgICAgIGNhc2UgJ05PTkUnOg0KICAgICAgICAgICAgcmV0PTA7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAnU0VSVklDRV9SRVNUQVJUJzoNCiAgICAgICAgICAgIHJldD0xOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgJ1JFQk9PVCc6DQogICAgICAgICAgICByZXQ9MjsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgIH0NCiAgICByZXR1cm4ocmV0KTsNCn0NCg0KZnVuY3Rpb24gZXh0cmFjdEZpbGVOYW1lKGZpbGVQYXRoKQ0Kew0KICAgIGlmICh0eXBlb2YgKGZpbGVQYXRoKSA9PSAnc3RyaW5nJykNCiAgICB7DQogICAgICAgIHZhciB0b2tlbnMgPSBmaWxlUGF0aC5zcGxpdCgnXFwnKS5qb2luKCcvJykuc3BsaXQoJy8nKTsNCiAgICAgICAgdmFyIG5hbWU7DQoNCiAgICAgICAgd2hpbGUgKChuYW1lID0gdG9rZW5zLnBvcCgpKSA9PSAnJyk7DQogICAgICAgIHJldHVybiAobmFtZSk7DQogICAgfQ0KICAgIGVsc2UNCiAgICB7DQogICAgICAgIHJldHVybihmaWxlUGF0aC5uZXdOYW1lKQ0KICAgIH0NCn0NCmZ1bmN0aW9uIGV4dHJhY3RGaWxlU291cmNlKGZpbGVQYXRoKQ0Kew0KICAgIHJldHVybiAodHlwZW9mIChmaWxlUGF0aCkgPT0gJ3N0cmluZycgPyBmaWxlUGF0aCA6IGZpbGVQYXRoLnNvdXJjZSk7DQp9DQoNCmZ1bmN0aW9uIHBlcnBhcmVGb2xkZXJzKGZvbGRlclBhdGgpDQp7DQogICAgdmFyIGRsbXRyID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gJ1xcJyA6ICcvJzsNCg0KICAgIHZhciB0b2tlbnMgPSBmb2xkZXJQYXRoLnNwbGl0KGRsbXRyKTsNCiAgICB2YXIgcGF0aCA9IG51bGw7DQoNCiAgICB3aGlsZSAodG9rZW5zLmxlbmd0aD4wKQ0KICAgIHsNCiAgICAgICAgcGF0aCA9IChwYXRoID09IG51bGwgPyB0b2tlbnMuc2hpZnQoKSA6IChwYXRoICsgZGxtdHIgKyB0b2tlbnMuc2hpZnQoKSkpOw0KICAgICAgICBpZiAocGF0aC5pbmRleE9mKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/ICdcXCcgOiAnLycpIDwgMCkgeyBjb250aW51ZTsgfQ0KICAgICAgICBpZiAoIXJlcXVpcmUoJ2ZzJykuZXhpc3RzU3luYyhwYXRoKSkgeyByZXF1aXJlKCdmcycpLm1rZGlyU3luYyhwYXRoKTsgfQ0KICAgIH0NCn0NCg0KZnVuY3Rpb24gcGFyc2VTZXJ2aWNlU3RhdHVzKHRva2VuKQ0Kew0KICAgIHZhciBqID0ge307DQogICAgdmFyIHNlcnZpY2VUeXBlID0gdG9rZW4uRGVyZWYoMCwgNCkuSW50VmFsOw0KICAgIGouaXNGaWxlU3lzdGVtRHJpdmVyID0gKChzZXJ2aWNlVHlwZSAmIDB4MDAwMDAwMDIpID09IDB4MDAwMDAwMDIpOw0KICAgIGouaXNLZXJuZWxEcml2ZXIgPSAoKHNlcnZpY2VUeXBlICYgMHgwMDAwMDAwMSkgPT0gMHgwMDAwMDAwMSk7DQogICAgai5pc1NoYXJlZFByb2Nlc3MgPSAoKHNlcnZpY2VUeXBlICYgMHgwMDAwMDAyMCkgPT0gMHgwMDAwMDAyMCk7DQogICAgai5pc093blByb2Nlc3MgPSAoKHNlcnZpY2VUeXBlICYgMHgwMDAwMDAxMCkgPT0gMHgwMDAwMDAxMCk7DQogICAgai5pc0ludGVyYWN0aXZlID0gKChzZXJ2aWNlVHlwZSAmIDB4MDAwMDAxMDApID09IDB4MDAwMDAxMDApOw0KICAgIGoud2FpdEhpbnQgPSB0b2tlbi5EZXJlZigoNiAqIDQpLCA0KS50b0J1ZmZlcigpLnJlYWRVSW50MzJMRSgpOw0KICAgIHN3aXRjaCAodG9rZW4uRGVyZWYoKDEgKiA0KSwgNCkudG9CdWZmZXIoKS5yZWFkVUludDMyTEUoKSkNCiAgICB7DQogICAgICAgIGNhc2UgMHgwMDAwMDAwNToNCiAgICAgICAgICAgIGouc3RhdGUgPSAnQ09OVElOVUVfUEVORElORyc7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAweDAwMDAwMDA2Og0KICAgICAgICAgICAgai5zdGF0ZSA9ICdQQVVTRV9QRU5ESU5HJzsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlIDB4MDAwMDAwMDc6DQogICAgICAgICAgICBqLnN0YXRlID0gJ1BBVVNFRCc7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAweDAwMDAwMDA0Og0KICAgICAgICAgICAgai5zdGF0ZSA9ICdSVU5OSU5HJzsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlIDB4MDAwMDAwMDI6DQogICAgICAgICAgICBqLnN0YXRlID0gJ1NUQVJUX1BFTkRJTkcnOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgMHgwMDAwMDAwMzoNCiAgICAgICAgICAgIGouc3RhdGUgPSAnU1RPUF9QRU5ESU5HJzsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlIDB4MDAwMDAwMDE6DQogICAgICAgICAgICBqLnN0YXRlID0gJ1NUT1BQRUQnOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgfQ0KICAgIHZhciBjb250cm9sc0FjY2VwdGVkID0gdG9rZW4uRGVyZWYoKDIgKiA0KSwgNCkudG9CdWZmZXIoKS5yZWFkVUludDMyTEUoKTsNCiAgICBqLmNvbnRyb2xzQWNjZXB0ZWQgPSBbXTsNCiAgICBpZiAoKGNvbnRyb2xzQWNjZXB0ZWQgJiAweDAwMDAwMDEwKSA9PSAweDAwMDAwMDEwKQ0KICAgIHsNCiAgICAgICAgai5jb250cm9sc0FjY2VwdGVkLnB1c2goJ1NFUlZJQ0VfQ09OVFJPTF9ORVRCSU5EQUREJyk7DQogICAgICAgIGouY29udHJvbHNBY2NlcHRlZC5wdXNoKCdTRVJWSUNFX0NPTlRST0xfTkVUQklORFJFTU9WRScpOw0KICAgICAgICBqLmNvbnRyb2xzQWNjZXB0ZWQucHVzaCgnU0VSVklDRV9DT05UUk9MX05FVEJJTkRFTkFCTEUnKTsNCiAgICAgICAgai5jb250cm9sc0FjY2VwdGVkLnB1c2goJ1NFUlZJQ0VfQ09OVFJPTF9ORVRCSU5ERElTQUJMRScpOw0KICAgIH0NCiAgICBpZiAoKGNvbnRyb2xzQWNjZXB0ZWQgJiAweDAwMDAwMDA4KSA9PSAweDAwMDAwMDA4KSB7IGouY29udHJvbHNBY2NlcHRlZC5wdXNoKCdTRVJWSUNFX0NPTlRST0xfUEFSQU1DSEFOR0UnKTsgfQ0KICAgIGlmICgoY29udHJvbHNBY2NlcHRlZCAmIDB4MDAwMDAwMDIpID09IDB4MDAwMDAwMDIpIHsgai5jb250cm9sc0FjY2VwdGVkLnB1c2goJ1NFUlZJQ0VfQ09OVFJPTF9QQVVTRScpOyBqLmNvbnRyb2xzQWNjZXB0ZWQucHVzaCgnU0VSVklDRV9DT05UUk9MX0NPTlRJTlVFJyk7IH0NCiAgICBpZiAoKGNvbnRyb2xzQWNjZXB0ZWQgJiAweDAwMDAwMTAwKSA9PSAweDAwMDAwMTAwKSB7IGouY29udHJvbHNBY2NlcHRlZC5wdXNoKCdTRVJWSUNFX0NPTlRST0xfUFJFU0hVVERPV04nKTsgfQ0KICAgIGlmICgoY29udHJvbHNBY2NlcHRlZCAmIDB4MDAwMDAwMDQpID09IDB4MDAwMDAwMDQpIHsgai5jb250cm9sc0FjY2VwdGVkLnB1c2goJ1NFUlZJQ0VfQ09OVFJPTF9TSFVURE9XTicpOyB9DQogICAgaWYgKChjb250cm9sc0FjY2VwdGVkICYgMHgwMDAwMDAwMSkgPT0gMHgwMDAwMDAwMSkgeyBqLmNvbnRyb2xzQWNjZXB0ZWQucHVzaCgnU0VSVklDRV9DT05UUk9MX1NUT1AnKTsgfQ0KICAgIGlmICgoY29udHJvbHNBY2NlcHRlZCAmIDB4MDAwMDAwMjApID09IDB4MDAwMDAwMjApIHsgai5jb250cm9sc0FjY2VwdGVkLnB1c2goJ1NFUlZJQ0VfQ09OVFJPTF9IQVJEV0FSRVBST0ZJTEVDSEFOR0UnKTsgfQ0KICAgIGlmICgoY29udHJvbHNBY2NlcHRlZCAmIDB4MDAwMDAwNDApID09IDB4MDAwMDAwNDApIHsgai5jb250cm9sc0FjY2VwdGVkLnB1c2goJ1NFUlZJQ0VfQ09OVFJPTF9QT1dFUkVWRU5UJyk7IH0NCiAgICBpZiAoKGNvbnRyb2xzQWNjZXB0ZWQgJiAweDAwMDAwMDgwKSA9PSAweDAwMDAwMDgwKSB7IGouY29udHJvbHNBY2NlcHRlZC5wdXNoKCdTRVJWSUNFX0NPTlRST0xfU0VTU0lPTkNIQU5HRScpOyB9DQogICAgai5waWQgPSB0b2tlbi5EZXJlZigoNyAqIDQpLCA0KS50b0J1ZmZlcigpLnJlYWRVSW50MzJMRSgpOw0KICAgIHJldHVybiAoaik7DQp9DQoNCmlmIChwcm9jZXNzLnBsYXRmb3JtID09ICdkYXJ3aW4nKQ0Kew0KICAgIGZ1bmN0aW9uIGdldE9TVmVyc2lvbigpDQogICAgew0KICAgICAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7DQogICAgICAgIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB0aGlzLnN0ciArPSBjaHVuay50b1N0cmluZygpOyB9KTsNCiAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoInN3X3ZlcnMgfCBncmVwIFByb2R1Y3RWZXJzaW9uIHwgYXdrICd7IHByaW50ICQyIH0nXG5leGl0XG4iKTsNCiAgICAgICAgY2hpbGQud2FpdEV4aXQoKTsNCg0KICAgICAgICAvL2NoaWxkLnN0ZG91dC5zdHIgPSAnMTAuOSc7DQoNCiAgICAgICAgdmFyIHJldCA9IHsgcmF3OiBjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKS5zcGxpdCgnLicpLCB0b1N0cmluZzogZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMucmF3LmpvaW4oJy4nKSk7IH0gfTsNCiAgICAgICAgcmV0LmNvbXBhcmVUbyA9IGZ1bmN0aW9uIGNvbXBhcmVUbyh2YWwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciByYXcgPSAodHlwZW9mICh2YWwpID09ICdzdHJpbmcnKSA/IHZhbC5zcGxpdCgnLicpIDogdmFsLnJhdzsgaWYgKCFyYXcpIHsgdGhyb3cgKCdJbnZhbGlkIHBhcmFtZXRlcicpOyB9DQogICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXMucmF3LmpvaW4oJy4nKS5zcGxpdCgnLicpOw0KDQogICAgICAgICAgICB2YXIgciA9IG51bGwsIHMgPSBudWxsOw0KICAgICAgICAgICAgd2hpbGUgKHNlbGYubGVuZ3RoID4gMCAmJiByYXcubGVuZ3RoID4gMCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBzID0gcGFyc2VJbnQoc2VsZi5zaGlmdCgpKTsgciA9IHBhcnNlSW50KHJhdy5zaGlmdCgpKTsNCiAgICAgICAgICAgICAgICBpZiAocyA8IHIpIHsgcmV0dXJuICgtMSk7IH0NCiAgICAgICAgICAgICAgICBpZiAocyA+IHIpIHsgcmV0dXJuICgxKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKHNlbGYubGVuZ3RoID09IHJhdy5sZW5ndGgpIHsgcmV0dXJuICgwKTsgfQ0KICAgICAgICAgICAgaWYgKHNlbGYubGVuZ3RoIDwgcmF3Lmxlbmd0aCkgeyByZXR1cm4gKC0xKTsgfSBlbHNlIHsgcmV0dXJuICgxKTsgfSAgICANCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gKHJldCk7DQogICAgfTsNCg0KDQogICAgZnVuY3Rpb24gZmV0Y2hQbGlzdChmb2xkZXIsIG5hbWUsIHVzZXJpZCkNCiAgICB7DQogICAgICAgIGlmIChmb2xkZXIuZW5kc1dpdGgoJy8nKSkgeyBmb2xkZXIgPSBmb2xkZXIuc3Vic3RyaW5nKDAsIGZvbGRlci5sZW5ndGggLSAxKTsgfQ0KICAgICAgICB2YXIgcmV0ID0geyBuYW1lOiBuYW1lLCBjbG9zZTogZnVuY3Rpb24gKCkgeyB9LCBfdWlkOiB1c2VyaWQgfTsNCiAgICAgICAgaWYgKCFyZXF1aXJlKCdmcycpLmV4aXN0c1N5bmMoZm9sZGVyICsgJy8nICsgbmFtZSArICcucGxpc3QnKSkNCiAgICAgICAgew0KICAgICAgICAgICAgLy8gQmVmb3JlIHdlIHRocm93IGluIHRoZSB0b3dlbCwgbGV0J3MgZW51bWVyYXRlIGFsbCB0aGUgcGxpc3QgZmlsZXMsIGFuZCBzZWUgaWYgb25lIGhhcyBhIG1hdGNoaW5nIGxhYmVsDQogICAgICAgICAgICB2YXIgZmlsZXMgPSByZXF1aXJlKCdmcycpLnJlYWRkaXJTeW5jKGZvbGRlcik7DQogICAgICAgICAgICBmb3IgKHZhciBmaWxlIGluIGZpbGVzKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGlmICghZmlsZXNbZmlsZV0uZW5kc1dpdGgoJy5wbGlzdCcpKSB7IGNvbnRpbnVlOyB9DQogICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7DQogICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7IHRoaXMuc3RyICs9IGNodW5rLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCJjYXQgIiArIGZvbGRlciArICcvJyArIGZpbGVzW2ZpbGVdICsgIiB8IHRyICdcbicgJ1wuJyB8IGF3ayAneyBzcGxpdCgkMCwgYSwgXCI8a2V5PkxhYmVsPC9rZXk+XCIpOyBzcGxpdChhWzJdLCBiLCBcIjwvc3RyaW5nPlwiKTsgc3BsaXQoYlsxXSwgYywgXCI8c3RyaW5nPlwiKTsgcHJpbnQgY1syXTsgfSdcbmV4aXRcbiIpOw0KICAgICAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICAgICAgaWYgKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpID09IG5hbWUpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICByZXQubmFtZSA9IGZpbGVzW2ZpbGVdLmVuZHNXaXRoKCcucGxpc3QnKSA/IGZpbGVzW2ZpbGVdLnN1YnN0cmluZygwLCBmaWxlc1tmaWxlXS5sZW5ndGggLSA2KSA6IGZpbGVzW2ZpbGVdOw0KICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmV0LCAnYWxpYXMnLCB7IHZhbHVlOiBuYW1lIH0pOw0KICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmV0LCAncGxpc3QnLCB7IHZhbHVlOiBmb2xkZXIgKyAnLycgKyBmaWxlc1tmaWxlXSB9KTsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKHJldC5uYW1lID09IG5hbWUpIHsgdGhyb3cgKCcgJyArIChmb2xkZXIuc3BsaXQoJ0xhdW5jaERhZW1vbicpLmxlbmd0aD4xID8gJ0xhdW5jaERhZW1vbicgOiAnTGF1bmNoQWdlbnQnKSArICcgKCcgKyBuYW1lICsgJykgTk9UIEZPVU5EJyk7IH0NCiAgICAgICAgfQ0KICAgICAgICBlbHNlDQogICAgICAgIHsNCiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXQsICdwbGlzdCcsIHsgdmFsdWU6IGZvbGRlciArICcvJyArIG5hbWUgKyAnLnBsaXN0JyB9KTsNCiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXQsICdhbGlhcycsDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpDQogICAgICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7IHRoaXMuc3RyICs9IGNodW5rLnRvU3RyaW5nKCk7IH0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCJjYXQgIiArIHJldC5wbGlzdCArICIgfCB0ciAnXG4nICdcLicgfCBhd2sgJ3sgc3BsaXQoJDAsIGEsIFwiPGtleT5MYWJlbDwva2V5PlwiKTsgc3BsaXQoYVsyXSwgYiwgXCI8L3N0cmluZz5cIik7IHNwbGl0KGJbMV0sIGMsIFwiPHN0cmluZz5cIik7IHByaW50IGNbMl07IH0nXG5leGl0XG4iKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci50cmltKCkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0pOw0KICAgICAgICB9DQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXQsICdkYWVtb24nLCB7IHZhbHVlOiByZXQucGxpc3Quc3BsaXQoJy9MYXVuY2hEYWVtb25zLycpLmxlbmd0aCA+IDEgPyB0cnVlIDogZmFsc2UgfSk7DQoNCiAgICAgICAgcmV0LmFwcFdvcmtpbmdEaXJlY3RvcnkgPSBmdW5jdGlvbiBhcHBXb3JraW5nRGlyZWN0b3J5KCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5zdHIgPSAnJzsNCiAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB0aGlzLnN0ciArPSBjaHVuay50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCJjYXQgIiArIHRoaXMucGxpc3QgKyAiIHwgdHIgJ1xuJyAnXC4nIHwgYXdrICd7IHNwbGl0KCQwLCBhLCBcIjxrZXk+V29ya2luZ0RpcmVjdG9yeTwva2V5PlwiKTsgc3BsaXQoYVsyXSwgYiwgXCI8L3N0cmluZz5cIik7IHNwbGl0KGJbMV0sIGMsIFwiPHN0cmluZz5cIik7IHByaW50IGNbMl07IH0nXG5leGl0XG4iKTsNCiAgICAgICAgICAgIGNoaWxkLndhaXRFeGl0KCk7DQogICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gY2hpbGQuc3Rkb3V0LnN0ci50cmltKCk7DQoNCiAgICAgICAgICAgIHJldHVybiAoY2hpbGQuc3Rkb3V0LnN0ci5lbmRzV2l0aCgnLycpID8gY2hpbGQuc3Rkb3V0LnN0ci5zdWJzdHJpbmcoMCwgY2hpbGQuc3Rkb3V0LnN0ci5sZW5ndGggLSAxKSA6IGNoaWxkLnN0ZG91dC5zdHIpOw0KICAgICAgICB9Ow0KICAgICAgICByZXQuYXBwTG9jYXRpb24gPSBmdW5jdGlvbiBhcHBMb2NhdGlvbigpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjRmlsZSgnL2Jpbi9zaCcsIFsnc2gnXSk7DQogICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7DQogICAgICAgICAgICBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHsgdGhpcy5zdHIgKz0gY2h1bmsudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICBjaGlsZC5zdGRpbi53cml0ZSgiY2F0ICIgKyB0aGlzLnBsaXN0ICsgIiB8IHRyICdcbicgJ1wuJyB8IGF3ayAneyBzcGxpdCgkMCwgYSwgXCI8a2V5PlByb2dyYW1Bcmd1bWVudHM8L2tleT5cIik7IHNwbGl0KGFbMl0sIGIsIFwiPC9zdHJpbmc+XCIpOyBzcGxpdChiWzFdLCBjLCBcIjxzdHJpbmc+XCIpOyBwcmludCBjWzJdOyB9J1xuZXhpdFxuIik7DQogICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICAgICAgcmV0dXJuIChjaGlsZC5zdGRvdXQuc3RyLnRyaW0oKSk7DQogICAgICAgIH07DQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXQsICdfcnVuQXRMb2FkJywNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAvLyBXZSBuZWVkIHRvIHNlZSBpZiB0aGlzIGlzIGFuIEF1dG8tU3RhcnRpbmcgc2VydmljZSwgaW4gb3JkZXIgdG8gZmlndXJlIG91dCBob3cgdG8gaW1wbGVtZW50ICdzdGFydCcNCiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWNGaWxlKCcvYmluL3NoJywgWydzaCddKTsNCiAgICAgICAgICAgICAgICAgICAgY2hpbGQuc3Rkb3V0LnN0ciA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHsgdGhpcy5zdHIgKz0gY2h1bmsudG9TdHJpbmcoKTsgfSk7DQogICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCJjYXQgIiArIHJldC5wbGlzdCArICIgfCB0ciAnXG4nICdcLicgfCBhd2sgJ3sgc3BsaXQoJDAsIGEsIFwiPGtleT5SdW5BdExvYWQ8L2tleT5cIik7IHNwbGl0KGFbMl0sIGIsIFwiLz5cIik7IHNwbGl0KGJbMV0sIGMsIFwiPFwiKTsgcHJpbnQgY1syXTsgfSdcbmV4aXRcbiIpOw0KICAgICAgICAgICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpLnRvVXBwZXJDYXNlKCkgPT0gIlRSVUUiKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJldCwgJ3N0YXJ0VHlwZScsDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmRhZW1vbikNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0aGlzLl9ydW5BdExvYWQgPyAnQVVUT19TVEFSVCcgOiAnREVNQU5EX1NUQVJUJyk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCdBVVRPX1NUQVJUJyk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJldCwgIl9rZWVwQWxpdmUiLA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY0ZpbGUoJy9iaW4vc2gnLCBbJ3NoJ10pOw0KICAgICAgICAgICAgICAgICAgICBjaGlsZC5zdGRvdXQuc3RyID0gJyc7DQogICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykgeyB0aGlzLnN0ciArPSBjaHVuay50b1N0cmluZygpOyB9KTsNCiAgICAgICAgICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoImNhdCAiICsgcmV0LnBsaXN0ICsgIiB8IHRyICdcbicgJ1wuJyB8IGF3ayAne3NwbGl0KCQwLCBhLCBcIjxrZXk+S2VlcEFsaXZlPC9rZXk+XCIpOyBzcGxpdChhWzJdLCBiLCBcIjxcIik7IHNwbGl0KGJbMl0sIGMsIFwiPlwiKTsgIik7DQogICAgICAgICAgICAgICAgICAgIGNoaWxkLnN0ZGluLndyaXRlKCIgaWYoY1sxXT09XCJkaWN0XCIpeyBzcGxpdChhWzJdLCBkLCBcIjwvZGljdD5cIik7IGlmKHNwbGl0KGRbMV0sIHRydXZhbCwgXCI8dHJ1ZS8+XCIpPjEpIHsgc3BsaXQodHJ1dmFsWzFdLCBrbjEsIFwiPGtleT5cIik7IHNwbGl0KGtuMVsyXSwga24yLCBcIjwva2V5PlwiKTsgcHJpbnQga24yWzFdOyB9IH0iKTsNCiAgICAgICAgICAgICAgICAgICAgY2hpbGQuc3RkaW4ud3JpdGUoIiBlbHNlIHsgc3BsaXQoY1sxXSwga2EsIFwiL1wiKTsgaWYoa2FbMV09PVwidHJ1ZVwiKSB7cHJpbnQgXCJBTFdBWVNcIjt9IH0gfSdcbmV4aXRcbiIpOw0KICAgICAgICAgICAgICAgICAgICBjaGlsZC53YWl0RXhpdCgpOw0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGNoaWxkLnN0ZG91dC5zdHIudHJpbSgpKTsN", 16000); diff --git a/microscript/ILibDuktape_net.c b/microscript/ILibDuktape_net.c index ebd26fa..168cb04 100644 --- a/microscript/ILibDuktape_net.c +++ b/microscript/ILibDuktape_net.c @@ -484,11 +484,27 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx) duk_push_true(ptrs->ctx); // [socket][connecting] duk_put_prop_string(ptrs->ctx, -2, "connecting"); // [socket] duk_pop(ptrs->ctx); // ... + + if (duk_is_object(ptrs->ctx, 0)) + { + if (duk_has_prop_string(ptrs->ctx, 0, "metadata")) + { + duk_size_t len; + char *tmp = (char*)duk_push_sprintf(ptrs->ctx, "net.ipcSocket, %s", (char*)Duktape_GetStringPropertyValueEx(ptrs->ctx, 0, "metadata", "", &len)); + char *tmp2 = (char*)ILibMemory_SmartAllocate(len + 16); + memcpy_s(tmp2, ILibMemory_Size(tmp2), tmp, ILibMemory_Size(tmp2) - 1); + ILibChain_Link_SetMetadata(ptrs->socketModule, tmp2); + } + else + { + ILibChain_Link_SetMetadata(ptrs->socketModule, "net.ipcSocket"); + } + } + return(0); #endif } - if (duk_is_number(ctx, 0)) { // This is a PORT number @@ -807,7 +823,6 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe { ILibDuktape_net_server *ptr = (ILibDuktape_net_server*)((void**)ILibMemory_GetExtraMemory(AsyncServerSocketModule, ILibMemory_ASYNCSERVERSOCKET_CONTAINERSIZE))[0]; ILibDuktape_net_server_session *session; - int isIPC = 0; #ifndef MICROSTACK_NOTLS int isTLS = ILibAsyncSocket_IsUsingTls(ConnectionToken); #else diff --git a/modules/linux-acpi.js b/modules/linux-acpi.js new file mode 100644 index 0000000..28020cb --- /dev/null +++ b/modules/linux-acpi.js @@ -0,0 +1,47 @@ +/* +Copyright 2020 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +function linux_acpi() +{ + this._ObjectID = 'linux-acpi'; + require('events').EventEmitter.call(this, true) + .createEvent('acpi'); + Object.defineProperty(this, "supported", { value: require('fs').existsSync('/var/run/acpid.socket') }); + if(this.supported) + { + this._client = require('net').createConnection({ path: '/var/run/acpid.socket', metadata: 'linux-acpi' }, function () + { + this.on('data', function (chunk) + { + var blocks; + var ubuffer = null; + var tokens = chunk.toString().split('\n'); + if (tokens.length == 1) { this.unshift(chunk); } + if (tokens.peek() != '') { ubuffer = Buffer.from(tokens.pop()); } + else { tokens.pop(); } + for (var i in tokens) + { + blocks = tokens[i].split(' '); + this.ret.emit('acpi', { name: blocks[0], type: Buffer.from(blocks[2], 'hex').readUInt32BE(), value: Buffer.from(blocks[3], 'hex').readUInt32BE() }); + } + }); + }); + this._client.ret = this; + } +} + +module.exports = new linux_acpi(); \ No newline at end of file diff --git a/modules/power-monitor.js b/modules/power-monitor.js index ab70bbb..65a89d5 100644 --- a/modules/power-monitor.js +++ b/modules/power-monitor.js @@ -24,11 +24,79 @@ function powerMonitor() .createEvent('acdc') .createEvent('display'); + this._ACState = 1; + this._BatteryLevel = -1; + + if (process.platform == 'win32') + { + // These must be registered BEFORE newListener is hooked up + this.on('batteryLevel', function (level) { this._BatteryLevel = level; }); + this.on('acdc', function (m) { this._ACState = (m == 'AC' ? 1 : 0); }); + } + + this.on('newListener', function (name, callback) + { + if (name == 'acdc') { callback.call(this, this._ACState == 1 ? 'AC' : 'BATTERY'); } + if (name == 'batteryLevel') { callback.call(this, this._BatteryLevel); } + }); + this._i = setImmediate(function (self) { require('user-sessions'); // This is needed because this is where the Windows Messages are processed for these events delete self._i; }, this); + + if(process.platform == 'linux') + { + this._ACPath = null; + this._BatteryPath = []; + + var devices = require('fs').readdirSync('/sys/class/power_supply'); + for (var i in devices) + { + if (require('fs').readFileSync('/sys/class/power_supply/' + devices[i] + '/type').toString().trim() == 'Mains') + { + this._ACPath = '/sys/class/power_supply/' + devices[i] + '/'; + break; + } + } + for (var i in devices) + { + if (require('fs').readFileSync('/sys/class/power_supply/' + devices[i] + '/type').toString().trim() == 'Battery') + { + this._BatteryPath.push('/sys/class/power_supply/' + devices[i] + '/'); + } + } + if(this._ACPath != null) + { + this._ACState = parseInt(require('fs').readFileSync(this._ACPath + 'online').toString().trim()); + } + if(this._BatteryPath.length>0) + { + this._getBatteryLevel = function _getBatteryLevel() + { + var sum = 0; + var i; + for (i in this._BatteryPath) + { + sum += parseInt(require('fs').readFileSync(this._BatteryPath[i] + 'capacity').toString().trim()); + } + sum = Math.floor(sum / this._BatteryPath.length); + return (sum); + } + this._BatteryLevel = this._getBatteryLevel(); + } + this._acpiSink = function _acpiSink(acpiEvent) + { + if(acpiEvent.name == 'ac_adapter') + { + _acpiSink.self._ACState = acpiEvent.value; + _acpiSink.self.emit('acdc', acpiEvent.value == 1 ? 'AC' : 'BATTERY'); + } + }; + this._acpiSink.self = this; + require('linux-acpi').on('acpi', this._acpiSink); + } } module.exports = new powerMonitor(); \ No newline at end of file