nodejs: add 0.12 version of node
authorJohn Crispin <redacted>
Sun, 2 Aug 2015 06:26:39 +0000 (08:26 +0200)
committerJohn Crispin <redacted>
Mon, 19 Oct 2015 10:20:11 +0000 (12:20 +0200)
add node-js 0.12 and a few gyp bindings

Signed-off-by: John Crispin <redacted>
12 files changed:
lang/node-arduino-firmata/Makefile [new file with mode: 0644]
lang/node-arduino-firmata/files/usr/lib/node/arduino-firmata/lib/arduino-firmata.js [new file with mode: 0644]
lang/node-arduino-firmata/patches/000-new-serialport.patch [new file with mode: 0644]
lang/node-cylon/Makefile [new file with mode: 0644]
lang/node-hid/Makefile [new file with mode: 0644]
lang/node-hid/patches/000-compile.patch [new file with mode: 0644]
lang/node-serialport/Makefile [new file with mode: 0644]
lang/node-serialport/patches/package.json.patch [new file with mode: 0644]
lang/node/Makefile [new file with mode: 0644]
lang/node/patches/001-mips-no-fpu.patch [new file with mode: 0644]
lang/node/patches/002-addr_info.patch [new file with mode: 0644]
lang/node/patches/003-path.patch [new file with mode: 0644]

diff --git a/lang/node-arduino-firmata/Makefile b/lang/node-arduino-firmata/Makefile
new file mode 100644 (file)
index 0000000..a34c2ce
--- /dev/null
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2014 Arduino LLC
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NPM_NAME:=arduino-firmata
+PKG_NAME:=node-$(PKG_NPM_NAME)
+PKG_VERSION:=0.3.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=v$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/shokai/node-arduino-firmata/archive/
+
+PKG_BUILD_DEPENDS:=node
+PKG_NODE_VERSION:=0.12.7
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node-arduino-firmata
+  DEPENDS:=+node
+  SUBMENU:=Node.js
+  SECTION:=lang
+  CATEGORY:=Languages
+  DEPENDS:=+node +node-serialport
+  TITLE:=Node.js package to access serial ports for reading and writing
+  URL:=https://www.npmjs.org/package/serialport
+endef
+
+define Package/node-arduino-firmata/description
+ Node.js package to access serial ports for reading and writing OR Welcome your robotic JavaScript overlords. Better yet, program them!
+endef
+
+define Build/Prepare
+       /bin/tar xzf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip-components 1
+       $(Build/Patch)
+endef
+
+EXTRA_LDFLAGS="-L$(TOOLCHAIN_DIR)/lib/ -Wl,-rpath-link $(TOOLCHAIN_DIR)/lib/" \
+
+define Build/Compile
+       $(MAKE_FLAGS) \
+       npm_config_arch=$(CONFIG_ARCH) \
+       npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \
+       PREFIX="$(PKG_INSTALL_DIR)/usr/" \
+       $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR)
+endef
+
+define Package/node-arduino-firmata/install
+       mkdir -p $(1)/usr/lib/node
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/* $(1)/usr/lib/node
+       rm -rf $(1)/usr/lib/node/arduino-firmata/node_modules/serialport/ 
+       $(CP) -r ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,node-arduino-firmata))
+
diff --git a/lang/node-arduino-firmata/files/usr/lib/node/arduino-firmata/lib/arduino-firmata.js b/lang/node-arduino-firmata/files/usr/lib/node/arduino-firmata/lib/arduino-firmata.js
new file mode 100644 (file)
index 0000000..578bd40
--- /dev/null
@@ -0,0 +1,306 @@
+(function() {
+  'use strict';
+  var ArduinoFirmata, SerialPort, debug, events, exports, serialport,
+    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+    hasProp = {}.hasOwnProperty;
+
+  events = require('eventemitter2');
+
+  SerialPort = (serialport = require('serialport')).SerialPort;
+
+  debug = require('debug')('arduino-firmata');
+
+  exports = module.exports = ArduinoFirmata = (function(superClass) {
+    extend(ArduinoFirmata, superClass);
+
+    ArduinoFirmata.Status = {
+      CLOSE: 0,
+      OPEN: 1
+    };
+
+    ArduinoFirmata.INPUT = 0;
+
+    ArduinoFirmata.OUTPUT = 1;
+
+    ArduinoFirmata.ANALOG = 2;
+
+    ArduinoFirmata.PWM = 3;
+
+    ArduinoFirmata.SERVO = 4;
+
+    ArduinoFirmata.SHIFT = 5;
+
+    ArduinoFirmata.I2C = 6;
+
+    ArduinoFirmata.LOW = 0;
+
+    ArduinoFirmata.HIGH = 1;
+
+    ArduinoFirmata.MAX_DATA_BYTES = 32;
+
+    ArduinoFirmata.DIGITAL_MESSAGE = 0x90;
+
+    ArduinoFirmata.ANALOG_MESSAGE = 0xE0;
+
+    ArduinoFirmata.REPORT_ANALOG = 0xC0;
+
+    ArduinoFirmata.REPORT_DIGITAL = 0xD0;
+
+    ArduinoFirmata.SET_PIN_MODE = 0xF4;
+
+    ArduinoFirmata.REPORT_VERSION = 0xF9;
+
+    ArduinoFirmata.SYSTEM_RESET = 0xFF;
+
+    ArduinoFirmata.START_SYSEX = 0xF0;
+
+    ArduinoFirmata.END_SYSEX = 0xF7;
+
+    ArduinoFirmata.list = function(callback) {
+      return serialport.list(function(err, ports) {
+        var devices, j, len, port;
+        if (err) {
+          return callback(err);
+        }
+        devices = [];
+        for (j = 0, len = ports.length; j < len; j++) {
+          port = ports[j];
+          if (/usb|acm|com\d+/i.test(port.comName)) {
+            devices.push(port.comName);
+          }
+        }
+        return callback(null, devices);
+      });
+    };
+
+    function ArduinoFirmata() {
+      this.status = ArduinoFirmata.Status.CLOSE;
+      this.wait_for_data = 0;
+      this.execute_multi_byte_command = 0;
+      this.multi_byte_channel = 0;
+      this.stored_input_data = [];
+      this.parsing_sysex = false;
+      this.sysex_bytes_read = 0;
+      this.digital_output_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+      this.digital_input_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+      this.analog_input_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+      this.boardVersion = null;
+    }
+
+    ArduinoFirmata.prototype.isOldArduinoDevice = function() {
+      return /usbserial|USB/.test(this.serialport_name);
+    };
+
+    ArduinoFirmata.prototype.connect = function(serialport_name, opts) {
+      this.serialport_name = serialport_name;
+      if (opts == null) {
+        opts = {
+          baudrate: 57600
+        };
+      }
+      opts.parser = serialport.parsers.raw;
+      if (!this.serialport_name) {
+        ArduinoFirmata.list((function(_this) {
+          return function(err, devices) {
+            return _this.connect(devices[0], opts);
+          };
+        })(this));
+        return this;
+      }
+      this.once('boardReady', function() {
+        var io_init_wait;
+        debug('boardReady');
+        io_init_wait = this.isOldArduinoDevice() ? (debug("old arduino device found " + this.serialport_name), 3000) : (debug("new arduino device found " + this.serialport_name), 100);
+        debug("wait " + io_init_wait + "(msec)");
+        return setTimeout((function(_this) {
+          return function() {
+            var i, j, k;
+            for (i = j = 0; j < 6; i = ++j) {
+              _this.write([ArduinoFirmata.REPORT_ANALOG | i, 1]);
+            }
+            for (i = k = 0; k < 2; i = ++k) {
+              _this.write([ArduinoFirmata.REPORT_DIGITAL | i, 1]);
+            }
+            debug('init IO ports');
+            return _this.emit('connect');
+          };
+        })(this), io_init_wait);
+      });
+      this.serialport = new SerialPort(this.serialport_name, opts);
+      this.serialport.once('open', (function(_this) {
+        return function() {
+          var cid;
+          cid = setInterval(function() {
+            debug('request REPORT_VERSION');
+            return _this.write([ArduinoFirmata.REPORT_VERSION]);
+          }, 500);
+          _this.once('boardVersion', function(version) {
+            clearInterval(cid);
+            _this.status = ArduinoFirmata.Status.OPEN;
+            return _this.emit('boardReady');
+          });
+          return _this.serialport.on('data', function(data) {
+            var byte, j, len, results;
+            results = [];
+            for (j = 0, len = data.length; j < len; j++) {
+              byte = data[j];
+              results.push(_this.process_input(byte));
+            }
+            return results;
+          });
+        };
+      })(this));
+      return this;
+    };
+
+    ArduinoFirmata.prototype.isOpen = function() {
+      return this.status === ArduinoFirmata.Status.OPEN;
+    };
+
+    ArduinoFirmata.prototype.close = function(callback) {
+      this.status = ArduinoFirmata.Status.CLOSE;
+      return this.serialport.close(callback);
+    };
+
+    ArduinoFirmata.prototype.reset = function(callback) {
+      return this.write([ArduinoFirmata.SYSTEM_RESET], callback);
+    };
+
+    ArduinoFirmata.prototype.write = function(bytes, callback) {
+      return this.serialport.write(bytes, callback);
+    };
+
+    ArduinoFirmata.prototype.sysex = function(command, data, callback) {
+      var write_data;
+      if (data == null) {
+        data = [];
+      }
+      data = data.map(function(i) {
+        return i & 0x7f;
+      });
+      write_data = [ArduinoFirmata.START_SYSEX, command].concat(data, [ArduinoFirmata.END_SYSEX]);
+      return this.write(write_data, callback);
+    };
+
+    ArduinoFirmata.prototype.pinMode = function(pin, mode, callback) {
+      switch (mode) {
+        case true:
+          mode = ArduinoFirmata.OUTPUT;
+          break;
+        case false:
+          mode = ArduinoFirmata.INPUT;
+      }
+      return this.write([ArduinoFirmata.SET_PIN_MODE, pin, mode], callback);
+    };
+
+    ArduinoFirmata.prototype.digitalWrite = function(pin, value, callback) {
+      var port_num;
+      this.pinMode(pin, ArduinoFirmata.OUTPUT);
+      port_num = (pin >>> 3) & 0x0F;
+      if (value === 0 || value === false) {
+        this.digital_output_data[port_num] &= ~(1 << (pin & 0x07));
+      } else {
+        this.digital_output_data[port_num] |= 1 << (pin & 0x07);
+      }
+      return this.write([ArduinoFirmata.DIGITAL_MESSAGE | port_num, this.digital_output_data[port_num] & 0x7F, this.digital_output_data[port_num] >>> 7], callback);
+    };
+
+    ArduinoFirmata.prototype.analogWrite = function(pin, value, callback) {
+      value = Math.floor(value);
+      this.pinMode(pin, ArduinoFirmata.PWM);
+      return this.write([ArduinoFirmata.ANALOG_MESSAGE | (pin & 0x0F), value & 0x7F, value >>> 7], callback);
+    };
+
+    ArduinoFirmata.prototype.servoWrite = function(pin, angle, callback) {
+      this.pinMode(pin, ArduinoFirmata.SERVO);
+      return this.write([ArduinoFirmata.ANALOG_MESSAGE | (pin & 0x0F), angle & 0x7F, angle >>> 7], callback);
+    };
+
+    ArduinoFirmata.prototype.digitalRead = function(pin) {
+      return ((this.digital_input_data[pin >>> 3] >>> (pin & 0x07)) & 0x01) > 0;
+    };
+
+    ArduinoFirmata.prototype.analogRead = function(pin) {
+      return this.analog_input_data[pin];
+    };
+
+    ArduinoFirmata.prototype.process_input = function(input_data) {
+      var analog_value, command, diff, i, j, old_analog_value, results, stat, sysex_command, sysex_data;
+      if (this.parsing_sysex) {
+        if (input_data === ArduinoFirmata.END_SYSEX) {
+          this.parsing_sysex = false;
+          sysex_command = this.stored_input_data[0];
+          sysex_data = this.stored_input_data.slice(1, this.sysex_bytes_read);
+          return this.emit('sysex', {
+            command: sysex_command,
+            data: sysex_data
+          });
+        } else {
+          this.stored_input_data[this.sysex_bytes_read] = input_data;
+          return this.sysex_bytes_read += 1;
+        }
+      } else if (this.wait_for_data > 0 && input_data < 128) {
+        this.wait_for_data -= 1;
+        this.stored_input_data[this.wait_for_data] = input_data;
+        if (this.execute_multi_byte_command !== 0 && this.wait_for_data === 0) {
+          switch (this.execute_multi_byte_command) {
+            case ArduinoFirmata.DIGITAL_MESSAGE:
+              input_data = (this.stored_input_data[0] << 7) + this.stored_input_data[1];
+              diff = this.digital_input_data[this.multi_byte_channel] ^ input_data;
+              this.digital_input_data[this.multi_byte_channel] = input_data;
+              if (this.listeners('digitalChange').length > 0) {
+                results = [];
+                for (i = j = 0; j <= 13; i = ++j) {
+                  if (((0x01 << i) & diff) > 0) {
+                    stat = (input_data & diff) > 0;
+                    results.push(this.emit('digitalChange', {
+                      pin: i + this.multi_byte_channel * 8,
+                      value: stat,
+                      old_value: !stat
+                    }));
+                  } else {
+                    results.push(void 0);
+                  }
+                }
+                return results;
+              }
+              break;
+            case ArduinoFirmata.ANALOG_MESSAGE:
+              analog_value = (this.stored_input_data[0] << 7) + this.stored_input_data[1];
+              old_analog_value = this.analogRead(this.multi_byte_channel);
+              this.analog_input_data[this.multi_byte_channel] = analog_value;
+              if (old_analog_value !== analog_value) {
+                return this.emit('analogChange', {
+                  pin: this.multi_byte_channel,
+                  value: analog_value,
+                  old_value: old_analog_value
+                });
+              }
+              break;
+            case ArduinoFirmata.REPORT_VERSION:
+              this.boardVersion = this.stored_input_data[1] + "." + this.stored_input_data[0];
+              return this.emit('boardVersion', this.boardVersion);
+          }
+        }
+      } else {
+        if (input_data < 0xF0) {
+          command = input_data & 0xF0;
+          this.multi_byte_channel = input_data & 0x0F;
+        } else {
+          command = input_data;
+        }
+        if (command === ArduinoFirmata.START_SYSEX) {
+          this.parsing_sysex = true;
+          return this.sysex_bytes_read = 0;
+        } else if (command === ArduinoFirmata.DIGITAL_MESSAGE || command === ArduinoFirmata.ANALOG_MESSAGE || command === ArduinoFirmata.REPORT_VERSION) {
+          this.wait_for_data = 2;
+          return this.execute_multi_byte_command = command;
+        }
+      }
+    };
+
+    return ArduinoFirmata;
+
+  })(events.EventEmitter2);
+
+}).call(this);
diff --git a/lang/node-arduino-firmata/patches/000-new-serialport.patch b/lang/node-arduino-firmata/patches/000-new-serialport.patch
new file mode 100644 (file)
index 0000000..10eab64
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/package.json
++++ b/package.json
+@@ -30,7 +30,6 @@
+   "author": "Sho Hashimoto <hashimoto@shokai.org>",
+   "license": "MIT",
+   "dependencies": {
+-    "serialport": "*",
+     "eventemitter2": "*",
+     "debug": "*"
+   },
diff --git a/lang/node-cylon/Makefile b/lang/node-cylon/Makefile
new file mode 100644 (file)
index 0000000..3f77dcd
--- /dev/null
@@ -0,0 +1,94 @@
+#
+# Copyright (C) 2014 Arduino LLC
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NPM_NAME:=cylon
+PKG_NAME:=node-$(PKG_NPM_NAME)
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=v0.22.0.tar.gz
+PKG_SOURCE_URL:=https://github.com/hybridgroup/cylon-firmata/archive/
+
+PKG_BUILD_DEPENDS:=node
+PKG_NODE_VERSION:=0.12.7
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=Apache-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node-cylon/default
+  DEPENDS:=+node $(2)
+  SUBMENU:=Node.js
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=CylonJS - $(1)
+  URL:=https://www.npmjs.org/package/cylon
+endef
+
+define Package/node-cylon
+  $(call Package/node-cylon/default,Core)
+endef
+
+define Package/node-cylon-i2c
+  $(call Package/node-cylon/default,I2C,+node-cylon)
+endef
+
+define Package/node-cylon-gpio
+  $(call Package/node-cylon/default,GPIO,+node-cylon)
+endef
+
+define Package/node-cylon-firmata
+  $(call Package/node-cylon/default,Firmata,+node-cylon-gpio +node-cylon-i2c +node-arduino-firmata)
+endef
+
+define Package/node-cylon/description
+       JavaScript Robotics, By Your Command Next generation robotics framework with support for 36 different platforms Get Started
+endef
+
+define Build/Prepare
+       /bin/tar xzf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip-components 1
+       $(Build/Patch)
+endef
+
+EXTRA_LDFLAGS="-L$(TOOLCHAIN_DIR)/lib/ -Wl,-rpath-link $(TOOLCHAIN_DIR)/lib/" \
+
+define Build/Compile
+       $(MAKE_FLAGS) \
+       npm_config_arch=$(CONFIG_ARCH) \
+       npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \
+       PREFIX="$(PKG_INSTALL_DIR)/usr/" \
+       $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR)
+endef
+
+define Package/node-cylon/install
+       mkdir -p $(1)/usr/lib/node/cylon
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/cylon-firmata/node_modules/cylon/* $(1)/usr/lib/node/cylon/
+endef
+
+define Package/node-cylon-i2c/install
+       mkdir -p $(1)/usr/lib/node/cylon-i2c
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/cylon-firmata/node_modules/cylon-i2c/* $(1)/usr/lib/node/cylon-i2c/
+endef
+
+define Package/node-cylon-gpio/install
+       mkdir -p $(1)/usr/lib/node/cylon-gpio
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/cylon-firmata/node_modules/cylon-gpio/* $(1)/usr/lib/node/cylon-gpio/
+endef
+
+define Package/node-cylon-firmata/install
+       mkdir -p $(1)/usr/lib/node/cylon-firmata
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/cylon-firmata/{index.js,lib,LICENSE,package.json,README.md,RELEASES.md,spec} $(1)/usr/lib/node/cylon-firmata/
+endef
+
+$(eval $(call BuildPackage,node-cylon))
+$(eval $(call BuildPackage,node-cylon-i2c))
+$(eval $(call BuildPackage,node-cylon-gpio))
+$(eval $(call BuildPackage,node-cylon-firmata))
+
diff --git a/lang/node-hid/Makefile b/lang/node-hid/Makefile
new file mode 100644 (file)
index 0000000..4485355
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NPM_NAME:=hid
+PKG_NAME:=node-$(PKG_NPM_NAME)
+PKG_VERSION:=0.4.0
+
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/node-hid/node-hid.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=c56c8aa5d113c6f2574d1f7e64d41745702965bb
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+PKG_BUILD_DEPENDS:=node
+PKG_NODE_VERSION:=0.12.7
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=MIT
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node-hid
+  DEPENDS:=+node
+  SUBMENU:=Node.js
+  SECTION:=lang
+  CATEGORY:=Languages
+  DEPENDS:=+libusb-1.0 +hidapi +libstdcpp
+  TITLE:=Node.js package to access HID devices
+  URL:=https://github.com/node-hid/node-hid
+endef
+
+define Package/node-hid/description
+ Node.js package to access HID devices
+endef
+
+EXTRA_LDFLAGS+="-lhidapi-libusb"
+EXTRA_CFLAGS+="-I$(STAGING_DIR)/usr/include/hidapi/"
+
+define Build/Compile
+       $(MAKE_VARS) \
+       $(MAKE_FLAGS) \
+       npm_config_arch=$(CONFIG_ARCH) \
+       npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \
+       PREFIX="$(PKG_INSTALL_DIR)/usr/" \
+       $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR)
+endef
+
+define Package/node-hid/install
+       mkdir -p $(1)/usr/lib/node/node-hid/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/node-hid/{index.js,package.json,build,node_modules} $(1)/usr/lib/node/node-hid/
+endef
+
+$(eval $(call BuildPackage,node-hid))
+
diff --git a/lang/node-hid/patches/000-compile.patch b/lang/node-hid/patches/000-compile.patch
new file mode 100644 (file)
index 0000000..d44e9b3
--- /dev/null
@@ -0,0 +1,2457 @@
+--- a/package.json
++++ b/package.json
+@@ -14,9 +14,6 @@
+     "type": "git",
+     "url": "git://github.com/hanshuebner/node-hid.git"
+   },
+-  "scripts": {
+-    "prepublish": "git submodule update --init"
+-  },
+   "main": "./index.js",
+   "engines": {
+     "node": ">=0.8.0"
+--- a/src/wscript
++++ b/src/wscript
+@@ -3,10 +3,8 @@
+ import sys;
+ import os;
+-hidapi_home='../hidapi'
+ cflags=["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall", "-fPIC" ]
+-includes=[ hidapi_home + "/hidapi" ]
+ def set_options(opt):
+   opt.tool_options("compiler_cxx")
+@@ -16,24 +14,10 @@
+   conf.check_tool("compiler_cxx")
+   conf.check_tool("node_addon")
+   conf.check_tool("compiler_cc")
+-  if sys.platform == 'darwin':
+-    conf.env.append_value('LINKFLAGS', ['Release/libhidapi.a', '-framework', 'IOKit', '-framework', 'CoreFoundation'])
+-  else:
+-    conf.env.append_value('LINKFLAGS', ['Release/libhidapi.a', '-ludev' ])
+-  
+-def build(bld):
+-    bld.add_group("hidapi")
+-    hidapi = bld.new_task_gen("cc", "staticlib")
+-    hidapi.includes = includes
+-    hidapi.cflags = cflags
+-    if sys.platform == 'darwin':
+-      hidapi.source = "../hidapi/mac/hid.c"
+-    else:
+-      hidapi.source = "../hidapi/linux/hid.c"
+-    hidapi.target = "hidapi"
++def build(bld):
+     bld.add_group("adapter")
+-    adapter = bld.new_task_gen("cxx", "shlib", "node_addon", use = ['hidapi'])
++    adapter = bld.new_task_gen("cxx", "shlib", "node_addon")
+     adapter.includes = includes
+     adapter.cxxflags = cflags
+     adapter.target = "HID"
+--- a/binding.gyp
++++ b/binding.gyp
+@@ -4,61 +4,8 @@
+   },\r
+   'targets': [\r
+     {\r
+-      'target_name': 'hidapi',\r
+-      'type': 'static_library',\r
+-      'conditions': [\r
+-        [ 'OS=="mac"', {\r
+-          'sources': [ 'hidapi/mac/hid.c' ],\r
+-          'include_dirs+': [\r
+-            '/usr/include/libusb-1.0/'\r
+-          ]\r
+-        }],\r
+-        [ 'OS=="linux"', {\r
+-          'conditions': [\r
+-            [ 'driver=="libusb"', {\r
+-              'sources': [ 'hidapi/libusb/hid.c' ],\r
+-              'include_dirs+': [\r
+-                '/usr/include/libusb-1.0/'\r
+-              ]\r
+-            }],\r
+-            [ 'driver=="hidraw"', {\r
+-              'sources': [ 'hidapi/linux/hid.c' ]\r
+-            }]\r
+-          ]\r
+-        }],\r
+-        [ 'OS=="win"', {\r
+-          'sources': [ 'hidapi/windows/hid.c' ],\r
+-          'msvs_settings': {\r
+-            'VCLinkerTool': {\r
+-              'AdditionalDependencies': [\r
+-                'setupapi.lib',\r
+-              ]\r
+-            }\r
+-          }\r
+-        }]\r
+-      ],\r
+-      'direct_dependent_settings': {\r
+-        'include_dirs': [\r
+-          'hidapi/hidapi',\r
+-          "<!(node -e \"require('nan')\")"\r
+-        ]\r
+-      },\r
+-      'include_dirs': [\r
+-        'hidapi/hidapi'\r
+-      ],\r
+-      'defines': [\r
+-        '_LARGEFILE_SOURCE',\r
+-        '_FILE_OFFSET_BITS=64',\r
+-      ],\r
+-      'cflags': ['-g'],\r
+-      'cflags!': [\r
+-        '-ansi'\r
+-      ]\r
+-    },\r
+-    {\r
+       'target_name': 'HID',\r
+       'sources': [ 'src/HID.cc' ],\r
+-      'dependencies': ['hidapi'],\r
+       'defines': [\r
+         '_LARGEFILE_SOURCE',\r
+         '_FILE_OFFSET_BITS=64',\r
+@@ -108,4 +55,4 @@
+       'cflags_cc': ['-g', '-exceptions']\r
+     }\r
+   ]\r
+-}
+\ No newline at end of file
++}\r
+--- /dev/null
++++ b/src/nan.h
+@@ -0,0 +1,2331 @@
++/**********************************************************************************
++ * NAN - Native Abstractions for Node.js
++ *
++ * Copyright (c) 2014 NAN contributors:
++ *   - Rod Vagg <https://github.com/rvagg>
++ *   - Benjamin Byholm <https://github.com/kkoopa>
++ *   - Trevor Norris <https://github.com/trevnorris>
++ *   - Nathan Rajlich <https://github.com/TooTallNate>
++ *   - Brett Lawson <https://github.com/brett19>
++ *   - Ben Noordhuis <https://github.com/bnoordhuis>
++ *
++ * MIT +no-false-attribs License <https://github.com/rvagg/nan/blob/master/LICENSE>
++ *
++ * Version 1.3.0: current Node unstable: 0.11.13, Node stable: 0.10.30
++ *
++ * See https://github.com/rvagg/nan for the latest update to this file
++ **********************************************************************************/
++
++#ifndef NAN_H_
++#define NAN_H_
++
++#include <uv.h>
++#include <node.h>
++#include <node_buffer.h>
++#include <node_version.h>
++#include <node_object_wrap.h>
++#include <string.h>
++#include <limits.h>
++#include <string>
++
++#if defined(__GNUC__) && !defined(DEBUG)
++# define NAN_INLINE inline __attribute__((always_inline))
++#elif defined(_MSC_VER) && !defined(DEBUG)
++# define NAN_INLINE __forceinline
++#else
++# define NAN_INLINE inline
++#endif
++
++#if defined(__GNUC__) && !V8_DISABLE_DEPRECATIONS
++# define NAN_DEPRECATED __attribute__((deprecated))
++#elif defined(_MSC_VER) && !V8_DISABLE_DEPRECATIONS
++# define NAN_DEPRECATED __declspec(deprecated)
++#else
++# define NAN_DEPRECATED
++#endif
++
++// some generic helpers
++
++template<typename T> NAN_INLINE bool NanSetPointerSafe(
++    T *var
++  , T val
++) {
++  if (var) {
++    *var = val;
++    return true;
++  } else {
++    return false;
++  }
++}
++
++template<typename T> NAN_INLINE T NanGetPointerSafe(
++    T *var
++  , T fallback = reinterpret_cast<T>(0)
++) {
++  if (var) {
++    return *var;
++  } else {
++    return fallback;
++  }
++}
++
++NAN_INLINE bool NanBooleanOptionValue(
++    v8::Local<v8::Object> optionsObj
++  , v8::Handle<v8::String> opt, bool def
++) {
++  if (def) {
++    return optionsObj.IsEmpty()
++      || !optionsObj->Has(opt)
++      || optionsObj->Get(opt)->BooleanValue();
++  } else {
++    return !optionsObj.IsEmpty()
++      && optionsObj->Has(opt)
++      && optionsObj->Get(opt)->BooleanValue();
++  }
++}
++
++NAN_INLINE bool NanBooleanOptionValue(
++    v8::Local<v8::Object> optionsObj
++  , v8::Handle<v8::String> opt
++) {
++  return NanBooleanOptionValue(optionsObj, opt, false);
++}
++
++NAN_INLINE uint32_t NanUInt32OptionValue(
++    v8::Local<v8::Object> optionsObj
++  , v8::Handle<v8::String> opt
++  , uint32_t def
++) {
++  return !optionsObj.IsEmpty()
++    && optionsObj->Has(opt)
++    && optionsObj->Get(opt)->IsNumber()
++      ? optionsObj->Get(opt)->Uint32Value()
++      : def;
++}
++
++#if (NODE_MODULE_VERSION > 0x000B)
++// Node 0.11+ (0.11.3 and below won't compile with these)
++
++# define _NAN_METHOD_ARGS_TYPE const v8::FunctionCallbackInfo<v8::Value>&
++# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args
++# define _NAN_METHOD_RETURN_TYPE void
++
++# define _NAN_GETTER_ARGS_TYPE const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args
++# define _NAN_GETTER_RETURN_TYPE void
++
++# define _NAN_SETTER_ARGS_TYPE const v8::PropertyCallbackInfo<void>&
++# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args
++# define _NAN_SETTER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_GETTER_ARGS_TYPE                                        \
++    const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args
++# define _NAN_PROPERTY_GETTER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_SETTER_ARGS_TYPE                                        \
++    const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args
++# define _NAN_PROPERTY_SETTER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE                                    \
++    const v8::PropertyCallbackInfo<v8::Array>&
++# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args
++# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE void
++
++# define _NAN_PROPERTY_DELETER_ARGS_TYPE                                       \
++    const v8::PropertyCallbackInfo<v8::Boolean>&
++# define _NAN_PROPERTY_DELETER_ARGS                                            \
++    _NAN_PROPERTY_DELETER_ARGS_TYPE args
++# define _NAN_PROPERTY_DELETER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_QUERY_ARGS_TYPE                                         \
++    const v8::PropertyCallbackInfo<v8::Integer>&
++# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args
++# define _NAN_PROPERTY_QUERY_RETURN_TYPE void
++
++# define _NAN_INDEX_GETTER_ARGS_TYPE                                           \
++    const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args
++# define _NAN_INDEX_GETTER_RETURN_TYPE void
++
++# define _NAN_INDEX_SETTER_ARGS_TYPE                                           \
++    const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args
++# define _NAN_INDEX_SETTER_RETURN_TYPE void
++
++# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE                                       \
++    const v8::PropertyCallbackInfo<v8::Array>&
++# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args
++# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE void
++
++# define _NAN_INDEX_DELETER_ARGS_TYPE                                          \
++    const v8::PropertyCallbackInfo<v8::Boolean>&
++# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args
++# define _NAN_INDEX_DELETER_RETURN_TYPE void
++
++# define _NAN_INDEX_QUERY_ARGS_TYPE                                            \
++    const v8::PropertyCallbackInfo<v8::Integer>&
++# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args
++# define _NAN_INDEX_QUERY_RETURN_TYPE void
++
++  typedef v8::FunctionCallback NanFunctionCallback;
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew() {
++    return T::New(v8::Isolate::GetCurrent());
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(P arg1) {
++    return T::New(v8::Isolate::GetCurrent(), arg1);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::Signature> NanNew(
++      v8::Handle<v8::FunctionTemplate> receiver
++    , int argc
++    , v8::Handle<v8::FunctionTemplate> argv[] = 0) {
++    return v8::Signature::New(v8::Isolate::GetCurrent(), receiver, argc, argv);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::FunctionTemplate> NanNew(
++      NanFunctionCallback callback
++    , v8::Handle<v8::Value> data = v8::Handle<v8::Value>()
++    , v8::Handle<v8::Signature> signature = v8::Handle<v8::Signature>()) {
++    return T::New(v8::Isolate::GetCurrent(), callback, data, signature);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew(v8::Handle<T> arg1) {
++    return v8::Local<T>::New(v8::Isolate::GetCurrent(), arg1);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew(const v8::Persistent<T> &arg1) {
++    return v8::Local<T>::New(v8::Isolate::GetCurrent(), arg1);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(P arg1, int arg2) {
++    return T::New(v8::Isolate::GetCurrent(), arg1, arg2);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>() {
++    return v8::Array::New(v8::Isolate::GetCurrent());
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>(int length) {
++    return v8::Array::New(v8::Isolate::GetCurrent(), length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(double time) {
++    return v8::Date::New(v8::Isolate::GetCurrent(), time).As<v8::Date>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(int time) {
++    return v8::Date::New(v8::Isolate::GetCurrent(), time).As<v8::Date>();
++  }
++
++  typedef v8::UnboundScript NanUnboundScript;
++  typedef v8::Script NanBoundScript;
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(
++      P s
++    , const v8::ScriptOrigin& origin
++  ) {
++    v8::ScriptCompiler::Source source(s, origin);
++    return v8::ScriptCompiler::CompileUnbound(
++        v8::Isolate::GetCurrent(), &source);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<NanUnboundScript> NanNew<NanUnboundScript>(
++      v8::Local<v8::String> s
++  ) {
++    v8::ScriptCompiler::Source source(s);
++    return v8::ScriptCompiler::CompileUnbound(
++        v8::Isolate::GetCurrent(), &source);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::BooleanObject> NanNew(bool value) {
++    return v8::BooleanObject::New(value).As<v8::BooleanObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::StringObject>
++  NanNew<v8::StringObject, v8::Local<v8::String> >(
++      v8::Local<v8::String> value) {
++    return v8::StringObject::New(value).As<v8::StringObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::StringObject>
++  NanNew<v8::StringObject, v8::Handle<v8::String> >(
++      v8::Handle<v8::String> value) {
++    return v8::StringObject::New(value).As<v8::StringObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::NumberObject> NanNew<v8::NumberObject>(double val) {
++    return v8::NumberObject::New(
++        v8::Isolate::GetCurrent(), val).As<v8::NumberObject>();
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Local<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Local<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, int32_t>(int32_t val) {
++    return v8::Uint32::NewFromUnsigned(
++        v8::Isolate::GetCurrent(), val)->ToUint32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, uint32_t>(uint32_t val) {
++    return v8::Uint32::NewFromUnsigned(
++        v8::Isolate::GetCurrent(), val)->ToUint32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, int32_t>(int32_t val) {
++    return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, uint32_t>(uint32_t val) {
++    return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, char *>(
++      char *arg
++    , int length) {
++    return v8::String::NewFromUtf8(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const char *>(
++      const char *arg
++    , int length) {
++    return v8::String::NewFromUtf8(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, char *>(char *arg) {
++    return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const char *>(
++      const char *arg) {
++    return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(
++      uint8_t *arg
++    , int length) {
++    return v8::String::NewFromOneByte(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
++      const uint8_t *arg
++    , int length) {
++    return v8::String::NewFromOneByte(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(uint8_t *arg) {
++    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
++      const uint8_t *arg) {
++    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint16_t *>(
++      uint16_t *arg
++    , int length) {
++    return v8::String::NewFromTwoByte(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint16_t *>(
++      const uint16_t *arg
++    , int length) {
++    return v8::String::NewFromTwoByte(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint16_t *>(
++      uint16_t *arg) {
++    return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint16_t *>(
++      const uint16_t *arg) {
++    return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, std::string>(
++      std::string arg) {
++    return NanNew<v8::String>(arg.c_str(), arg.size());
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String>() {
++    return v8::String::Empty(v8::Isolate::GetCurrent());
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(const char* arg, int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const uint8_t* arg
++    , int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const uint16_t* arg
++    , int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const std::string& arg) {
++    return NanNew<v8::String>(arg.c_str(), arg.size());
++  }
++
++  NAN_INLINE v8::Local<v8::Number> NanNew(double val) {
++    return NanNew<v8::Number>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Integer> NanNew(int val) {
++    return NanNew<v8::Integer>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Uint32> NanNew(unsigned int val) {
++    return NanNew<v8::Uint32>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanNew(bool val) {
++    return NanNew<v8::Boolean>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      v8::String::ExternalStringResource *resource) {
++    return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      v8::String::ExternalAsciiStringResource *resource) {
++    return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource);
++  }
++
++# define NanScope() v8::HandleScope scope(v8::Isolate::GetCurrent())
++# define NanEscapableScope()                                                   \
++  v8::EscapableHandleScope scope(v8::Isolate::GetCurrent())
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Handle<T> val) {
++    return NanNew(val);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
++    return val;
++  }
++
++# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
++# define NanLocker() v8::Locker locker(v8::Isolate::GetCurrent())
++# define NanUnlocker() v8::Unlocker unlocker(v8::Isolate::GetCurrent())
++# define NanReturnValue(value) return args.GetReturnValue().Set(value)
++# define NanReturnUndefined() return
++# define NanReturnNull() return args.GetReturnValue().SetNull()
++# define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString()
++
++# define NanObjectWrapHandle(obj) obj->handle()
++
++  NAN_INLINE v8::Local<v8::Primitive> NanUndefined() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent())));
++  }
++
++  NAN_INLINE v8::Local<v8::Primitive> NanNull() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent())));
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanTrue() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent())));
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanFalse() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent())));
++  }
++
++  NAN_INLINE int NanAdjustExternalMemory(int bc) {
++    return static_cast<int>(
++        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
++  }
++
++  NAN_INLINE void NanSetTemplate(
++      v8::Handle<v8::Template> templ
++    , const char *name
++    , v8::Handle<v8::Data> value) {
++    templ->Set(v8::Isolate::GetCurrent(), name, value);
++  }
++
++  NAN_INLINE void NanSetTemplate(
++      v8::Handle<v8::Template> templ
++    , v8::Handle<v8::String> name
++    , v8::Handle<v8::Data> value
++    , v8::PropertyAttribute attributes) {
++    templ->Set(name, value, attributes);
++  }
++
++  NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {
++    return v8::Isolate::GetCurrent()->GetCurrentContext();
++  }
++
++  NAN_INLINE void* NanGetInternalFieldPointer(
++      v8::Handle<v8::Object> object
++    , int index) {
++    return object->GetAlignedPointerFromInternalField(index);
++  }
++
++  NAN_INLINE void NanSetInternalFieldPointer(
++      v8::Handle<v8::Object> object
++    , int index
++    , void* value) {
++    object->SetAlignedPointerInInternalField(index, value);
++  }
++
++  NAN_INLINE void NanAddGCEpilogueCallback(
++      v8::Isolate::GCEpilogueCallback callback
++    , v8::GCType gc_type_filter = v8::kGCTypeAll) {
++    v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);
++  }
++
++  NAN_INLINE void NanRemoveGCEpilogueCallback(
++      v8::Isolate::GCEpilogueCallback callback) {
++    v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);
++  }
++
++  NAN_INLINE void NanAddGCPrologueCallback(
++      v8::Isolate::GCPrologueCallback callback
++    , v8::GCType gc_type_filter = v8::kGCTypeAll) {
++    v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);
++  }
++
++  NAN_INLINE void NanRemoveGCPrologueCallback(
++      v8::Isolate::GCPrologueCallback callback) {
++    v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);
++  }
++
++  NAN_INLINE void NanGetHeapStatistics(
++      v8::HeapStatistics *heap_statistics) {
++    v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);
++  }
++
++  NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol(
++      const char* data, int length = -1) {
++    return NanNew<v8::String>(data, length);
++  }
++
++  template<typename T>
++  NAN_INLINE void NanAssignPersistent(
++      v8::Persistent<T>& handle
++    , v8::Handle<T> obj) {
++      handle.Reset(v8::Isolate::GetCurrent(), obj);
++  }
++
++  template<typename T>
++  NAN_INLINE void NanAssignPersistent(
++      v8::Persistent<T>& handle
++    , const v8::Persistent<T>& obj) {
++      handle.Reset(v8::Isolate::GetCurrent(), obj);
++  }
++
++  template<typename T, typename P>
++  class _NanWeakCallbackData;
++
++  template<typename T, typename P>
++  struct _NanWeakCallbackInfo {
++    typedef void (*Callback)(const _NanWeakCallbackData<T, P>& data);
++    NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb)
++      : parameter(param), callback(cb) {
++       NanAssignPersistent(persistent, handle);
++    }
++
++    NAN_INLINE ~_NanWeakCallbackInfo() {
++      persistent.Reset();
++    }
++
++    P* const parameter;
++    Callback const callback;
++    v8::Persistent<T> persistent;
++  };
++
++  template<typename T, typename P>
++  class _NanWeakCallbackData {
++   public:
++    NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info)
++      : info_(info) { }
++
++    NAN_INLINE v8::Local<T> GetValue() const {
++      return NanNew(info_->persistent);
++    }
++
++    NAN_INLINE P* GetParameter() const { return info_->parameter; }
++
++    NAN_INLINE bool IsNearDeath() const {
++      return info_->persistent.IsNearDeath();
++    }
++
++    NAN_INLINE void Revive() const;
++
++    NAN_INLINE _NanWeakCallbackInfo<T, P>* GetCallbackInfo() const {
++      return info_;
++    }
++
++    NAN_DEPRECATED NAN_INLINE void Dispose() const {
++    }
++
++   private:
++    _NanWeakCallbackInfo<T, P>* info_;
++  };
++
++  template<typename T, typename P>
++  static void _NanWeakCallbackDispatcher(
++    const v8::WeakCallbackData<T, _NanWeakCallbackInfo<T, P> > &data) {
++      _NanWeakCallbackInfo<T, P> *info = data.GetParameter();
++      _NanWeakCallbackData<T, P> wcbd(info);
++      info->callback(wcbd);
++      if (wcbd.IsNearDeath()) {
++        delete wcbd.GetCallbackInfo();
++      }
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const {
++      info_->persistent.SetWeak(info_, &_NanWeakCallbackDispatcher<T, P>);
++  }
++
++template<typename T, typename P>
++NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
++    v8::Handle<T> handle
++  , P* parameter
++  , typename _NanWeakCallbackInfo<T, P>::Callback callback) {
++    _NanWeakCallbackInfo<T, P> *cbinfo =
++     new _NanWeakCallbackInfo<T, P>(handle, parameter, callback);
++    cbinfo->persistent.SetWeak(cbinfo, &_NanWeakCallbackDispatcher<T, P>);
++    return cbinfo;
++}
++
++# define NAN_WEAK_CALLBACK(name)                                               \
++    template<typename T, typename P>                                           \
++    static void name(const _NanWeakCallbackData<T, P> &data)
++
++# define _NAN_ERROR(fun, errmsg) fun(NanNew<v8::String>(errmsg))
++
++# define _NAN_THROW_ERROR(fun, errmsg)                                         \
++    do {                                                                       \
++      NanScope();                                                              \
++      v8::Isolate::GetCurrent()->ThrowException(_NAN_ERROR(fun, errmsg));      \
++    } while (0);
++
++  NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) {
++    return  _NAN_ERROR(v8::Exception::Error, errmsg);
++  }
++
++  NAN_INLINE void NanThrowError(const char* errmsg) {
++    _NAN_THROW_ERROR(v8::Exception::Error, errmsg);
++  }
++
++  NAN_INLINE void NanThrowError(v8::Handle<v8::Value> error) {
++    NanScope();
++    v8::Isolate::GetCurrent()->ThrowException(error);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanError(
++      const char *msg
++    , const int errorNumber
++  ) {
++    v8::Local<v8::Value> err = v8::Exception::Error(NanNew<v8::String>(msg));
++    v8::Local<v8::Object> obj = err.As<v8::Object>();
++    obj->Set(NanNew<v8::String>("code"), NanNew<v8::Integer>(errorNumber));
++    return err;
++  }
++
++  NAN_INLINE void NanThrowError(
++      const char *msg
++    , const int errorNumber
++  ) {
++    NanThrowError(NanError(msg, errorNumber));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) {
++    return _NAN_ERROR(v8::Exception::TypeError, errmsg);
++  }
++
++  NAN_INLINE void NanThrowTypeError(const char* errmsg) {
++    _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRangeError(const char* errmsg) {
++    return _NAN_ERROR(v8::Exception::RangeError, errmsg);
++  }
++
++  NAN_INLINE void NanThrowRangeError(const char* errmsg) {
++    _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);
++  }
++
++  template<typename T> NAN_INLINE void NanDisposePersistent(
++      v8::Persistent<T> &handle
++  ) {
++    handle.Reset();
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
++      char *data
++    , size_t length
++    , node::smalloc::FreeCallback callback
++    , void *hint
++  ) {
++    return node::Buffer::New(
++        v8::Isolate::GetCurrent(), data, length, callback, hint);
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
++      const char *data
++    , uint32_t size
++  ) {
++    return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {
++    return node::Buffer::New(v8::Isolate::GetCurrent(), size);
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanBufferUse(
++      char* data
++    , uint32_t size
++  ) {
++    return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
++  }
++
++  NAN_INLINE bool NanHasInstance(
++      v8::Persistent<v8::FunctionTemplate>& function_template
++    , v8::Handle<v8::Value> value
++  ) {
++    return NanNew(function_template)->HasInstance(value);
++  }
++
++  NAN_INLINE v8::Local<v8::Context> NanNewContextHandle(
++      v8::ExtensionConfiguration* extensions = NULL
++    , v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>()
++    , v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()
++  ) {
++    v8::Isolate* isolate = v8::Isolate::GetCurrent();
++    return v8::Local<v8::Context>::New(
++        isolate
++      , v8::Context::New(isolate, extensions, tmpl, obj)
++    );
++  }
++
++  NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
++      v8::Local<v8::String> s
++    , const v8::ScriptOrigin& origin
++  ) {
++    v8::ScriptCompiler::Source source(s, origin);
++    return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
++  }
++
++  NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
++      v8::Local<v8::String> s
++  ) {
++    v8::ScriptCompiler::Source source(s);
++    return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRunScript(
++      v8::Handle<NanUnboundScript> script
++  ) {
++    return script->BindToCurrentContext()->Run();
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRunScript(
++      v8::Handle<NanBoundScript> script
++  ) {
++    return script->Run();
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , v8::Handle<v8::Function> func
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++    return NanNew(node::MakeCallback(
++        v8::Isolate::GetCurrent(), target, func, argc, argv));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , v8::Handle<v8::String> symbol
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++    return NanNew(node::MakeCallback(
++        v8::Isolate::GetCurrent(), target, symbol, argc, argv));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , const char* method
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++    return NanNew(node::MakeCallback(
++        v8::Isolate::GetCurrent(), target, method, argc, argv));
++  }
++
++  template<typename T>
++  NAN_INLINE void NanSetIsolateData(
++      v8::Isolate *isolate
++    , T *data
++  ) {
++      isolate->SetData(0, data);
++  }
++
++  template<typename T>
++  NAN_INLINE T *NanGetIsolateData(
++      v8::Isolate *isolate
++  ) {
++      return static_cast<T*>(isolate->GetData(0));
++  }
++
++  class NanAsciiString {
++   public:
++    NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Length() + 1;
++      buf = new char[buf_size];
++      size = toStr->WriteOneByte(
++          reinterpret_cast<unsigned char*>(buf), 0, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE char* operator*() { return buf; }
++
++    NAN_INLINE ~NanAsciiString() {
++      delete[] buf;
++    }
++
++   private:
++    char *buf;
++    int size;
++  };
++
++  class NanUtf8String {
++   public:
++    NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Utf8Length() + 1;
++      buf = new char[buf_size];
++      size = toStr->WriteUtf8(buf, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE char* operator*() { return buf; }
++
++    NAN_INLINE ~NanUtf8String() {
++      delete[] buf;
++    }
++
++   private:
++    char *buf;
++    int size;
++  };
++
++  class NanUcs2String {
++   public:
++    NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Length() + 1;
++      buf = new uint16_t[buf_size];
++      size = toStr->Write(buf, 0, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE uint16_t* operator*() { return buf; }
++
++    NAN_INLINE ~NanUcs2String() {
++      delete[] buf;
++    }
++
++   private:
++    uint16_t *buf;
++    int size;
++  };
++
++#else
++// Node 0.8 and 0.10
++
++# define _NAN_METHOD_ARGS_TYPE const v8::Arguments&
++# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args
++# define _NAN_METHOD_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_GETTER_ARGS_TYPE const v8::AccessorInfo &
++# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args
++# define _NAN_GETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_SETTER_ARGS_TYPE const v8::AccessorInfo &
++# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args
++# define _NAN_SETTER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_GETTER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args
++# define _NAN_PROPERTY_GETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_PROPERTY_SETTER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args
++# define _NAN_PROPERTY_SETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args
++# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE v8::Handle<v8::Array>
++
++# define _NAN_PROPERTY_DELETER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_DELETER_ARGS _NAN_PROPERTY_DELETER_ARGS_TYPE args
++# define _NAN_PROPERTY_DELETER_RETURN_TYPE v8::Handle<v8::Boolean>
++
++# define _NAN_PROPERTY_QUERY_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args
++# define _NAN_PROPERTY_QUERY_RETURN_TYPE v8::Handle<v8::Integer>
++
++# define _NAN_INDEX_GETTER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args
++# define _NAN_INDEX_GETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_INDEX_SETTER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args
++# define _NAN_INDEX_SETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args
++# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE v8::Handle<v8::Array>
++
++# define _NAN_INDEX_DELETER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args
++# define _NAN_INDEX_DELETER_RETURN_TYPE v8::Handle<v8::Boolean>
++
++# define _NAN_INDEX_QUERY_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args
++# define _NAN_INDEX_QUERY_RETURN_TYPE v8::Handle<v8::Integer>
++
++  typedef v8::InvocationCallback NanFunctionCallback;
++
++  NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol(
++      const char* data, int length = -1) {
++    return v8::String::NewSymbol(data, length);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew() {
++    return v8::Local<T>::New(T::New());
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew(v8::Handle<T> arg) {
++    return v8::Local<T>::New(arg);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::Signature> NanNew(
++      v8::Handle<v8::FunctionTemplate> receiver
++    , int argc
++    , v8::Handle<v8::FunctionTemplate> argv[] = 0) {
++    return v8::Signature::New(receiver, argc, argv);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::FunctionTemplate> NanNew(
++      NanFunctionCallback callback
++    , v8::Handle<v8::Value> data = v8::Handle<v8::Value>()
++    , v8::Handle<v8::Signature> signature = v8::Handle<v8::Signature>()) {
++    return T::New(callback, data, signature);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew(const v8::Persistent<T> &arg) {
++    return v8::Local<T>::New(arg);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(P arg) {
++    return v8::Local<T>::New(T::New(arg));
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(P arg, int length) {
++    return v8::Local<T>::New(T::New(arg, length));
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Local<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Local<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>() {
++    return v8::Array::New();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>(int length) {
++    return v8::Array::New(length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(double time) {
++    return v8::Date::New(time).As<v8::Date>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(int time) {
++    return v8::Date::New(time).As<v8::Date>();
++  }
++
++  typedef v8::Script NanUnboundScript;
++  typedef v8::Script NanBoundScript;
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(
++      P s
++    , const v8::ScriptOrigin& origin
++  ) {
++    return v8::Script::New(s, const_cast<v8::ScriptOrigin *>(&origin));
++  }
++
++  template<>
++  NAN_INLINE v8::Local<NanUnboundScript> NanNew<NanUnboundScript>(
++      v8::Local<v8::String> s
++  ) {
++    return v8::Script::New(s);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::BooleanObject> NanNew(bool value) {
++    return v8::BooleanObject::New(value).As<v8::BooleanObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::StringObject>
++  NanNew<v8::StringObject, v8::Local<v8::String> >(
++      v8::Local<v8::String> value) {
++    return v8::StringObject::New(value).As<v8::StringObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::StringObject>
++  NanNew<v8::StringObject, v8::Handle<v8::String> >(
++      v8::Handle<v8::String> value) {
++    return v8::StringObject::New(value).As<v8::StringObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::NumberObject> NanNew<v8::NumberObject>(double val) {
++    return v8::NumberObject::New(val).As<v8::NumberObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, int32_t>(int32_t val) {
++    return v8::Uint32::NewFromUnsigned(val)->ToUint32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, uint32_t>(uint32_t val) {
++    return v8::Uint32::NewFromUnsigned(val)->ToUint32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, int32_t>(int32_t val) {
++    return v8::Int32::New(val)->ToInt32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, uint32_t>(uint32_t val) {
++    return v8::Int32::New(val)->ToInt32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(
++      uint8_t *arg
++    , int length) {
++    int len = length;
++    if (len < 0) {
++      size_t temp = strlen(reinterpret_cast<const char *>(arg));
++      assert(temp <= INT_MAX && "too long string");
++      len = static_cast<int>(temp);
++    }
++    uint16_t *warg = new uint16_t[len];
++    for (int i = 0; i < len; i++) {
++      warg[i] = arg[i];
++    }
++    v8::Local<v8::String> retval = v8::String::New(warg, len);
++    delete[] warg;
++    return retval;
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
++      const uint8_t *arg
++    , int length) {
++    int len = length;
++    if (len < 0) {
++      size_t temp = strlen(reinterpret_cast<const char *>(arg));
++      assert(temp <= INT_MAX && "too long string");
++      len = static_cast<int>(temp);
++    }
++    uint16_t *warg = new uint16_t[len];
++    for (int i = 0; i < len; i++) {
++      warg[i] = arg[i];
++    }
++    v8::Local<v8::String> retval = v8::String::New(warg, len);
++    delete[] warg;
++    return retval;
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(uint8_t *arg) {
++    size_t temp = strlen(reinterpret_cast<char *>(arg));
++    assert(temp <= INT_MAX && "too long string");
++    int length = static_cast<int>(temp);
++    uint16_t *warg = new uint16_t[length];
++    for (int i = 0; i < length; i++) {
++      warg[i] = arg[i];
++    }
++
++    v8::Local<v8::String> retval = v8::String::New(warg, length);
++    delete[] warg;
++    return retval;
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
++      const uint8_t *arg) {
++    size_t temp = strlen(reinterpret_cast<const char *>(arg));
++    assert(temp <= INT_MAX && "too long string");
++    int length = static_cast<int>(temp);
++    uint16_t *warg = new uint16_t[length];
++    for (int i = 0; i < length; i++) {
++      warg[i] = arg[i];
++    }
++    v8::Local<v8::String> retval = v8::String::New(warg, length);
++    delete[] warg;
++    return retval;
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, std::string>(
++      std::string arg) {
++    return NanNew<v8::String>(arg.c_str(), arg.size());
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String>() {
++    return v8::String::Empty();
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(const char* arg, int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const uint8_t* arg
++    , int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const uint16_t* arg
++    , int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      std::string& arg) {
++    return NanNew<v8::String>(arg.c_str(), arg.size());
++  }
++
++  NAN_INLINE v8::Local<v8::Number> NanNew(double val) {
++    return NanNew<v8::Number>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Integer> NanNew(int val) {
++    return NanNew<v8::Integer>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Uint32> NanNew(unsigned int val) {
++    return NanNew<v8::Uint32>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanNew(bool val) {
++    return NanNew<v8::Boolean>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      v8::String::ExternalStringResource *resource) {
++    return v8::String::NewExternal(resource);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      v8::String::ExternalAsciiStringResource *resource) {
++    return v8::String::NewExternal(resource);
++  }
++
++# define NanScope() v8::HandleScope scope
++# define NanEscapableScope() v8::HandleScope scope
++# define NanEscapeScope(val) scope.Close(val)
++# define NanLocker() v8::Locker locker
++# define NanUnlocker() v8::Unlocker unlocker
++# define NanReturnValue(value) return scope.Close(value)
++# define NanReturnUndefined() return v8::Undefined()
++# define NanReturnNull() return v8::Null()
++# define NanReturnEmptyString() return v8::String::Empty()
++# define NanObjectWrapHandle(obj) v8::Local<v8::Object>::New(obj->handle_)
++
++  NAN_INLINE v8::Local<v8::Primitive> NanUndefined() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::Undefined()));
++  }
++
++  NAN_INLINE v8::Local<v8::Primitive> NanNull() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::Null()));
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanTrue() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::True()));
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanFalse() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::False()));
++  }
++
++  NAN_INLINE int NanAdjustExternalMemory(int bc) {
++    return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
++  }
++
++  NAN_INLINE void NanSetTemplate(
++      v8::Handle<v8::Template> templ
++    , const char *name
++    , v8::Handle<v8::Data> value) {
++    templ->Set(name, value);
++  }
++
++  NAN_INLINE void NanSetTemplate(
++      v8::Handle<v8::Template> templ
++    , v8::Handle<v8::String> name
++    , v8::Handle<v8::Data> value
++    , v8::PropertyAttribute attributes) {
++    templ->Set(name, value, attributes);
++  }
++
++  NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {
++    return v8::Context::GetCurrent();
++  }
++
++  NAN_INLINE void* NanGetInternalFieldPointer(
++      v8::Handle<v8::Object> object
++    , int index) {
++    return object->GetPointerFromInternalField(index);
++  }
++
++  NAN_INLINE void NanSetInternalFieldPointer(
++      v8::Handle<v8::Object> object
++    , int index
++    , void* value) {
++    object->SetPointerInInternalField(index, value);
++  }
++
++  NAN_INLINE void NanAddGCEpilogueCallback(
++    v8::GCEpilogueCallback callback
++  , v8::GCType gc_type_filter = v8::kGCTypeAll) {
++    v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);
++  }
++  NAN_INLINE void NanRemoveGCEpilogueCallback(
++    v8::GCEpilogueCallback callback) {
++    v8::V8::RemoveGCEpilogueCallback(callback);
++  }
++  NAN_INLINE void NanAddGCPrologueCallback(
++    v8::GCPrologueCallback callback
++  , v8::GCType gc_type_filter = v8::kGCTypeAll) {
++    v8::V8::AddGCPrologueCallback(callback, gc_type_filter);
++  }
++  NAN_INLINE void NanRemoveGCPrologueCallback(
++    v8::GCPrologueCallback callback) {
++    v8::V8::RemoveGCPrologueCallback(callback);
++  }
++  NAN_INLINE void NanGetHeapStatistics(
++    v8::HeapStatistics *heap_statistics) {
++    v8::V8::GetHeapStatistics(heap_statistics);
++  }
++
++  template<typename T>
++  NAN_INLINE void NanAssignPersistent(
++      v8::Persistent<T>& handle
++    , v8::Handle<T> obj) {
++      handle.Dispose();
++      handle = v8::Persistent<T>::New(obj);
++  }
++
++  template<typename T, typename P>
++  class _NanWeakCallbackData;
++
++  template<typename T, typename P>
++  struct _NanWeakCallbackInfo {
++    typedef void (*Callback)(const _NanWeakCallbackData<T, P> &data);
++    NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb)
++      : parameter(param)
++      , callback(cb)
++      , persistent(v8::Persistent<T>::New(handle)) { }
++
++    NAN_INLINE ~_NanWeakCallbackInfo() {
++      persistent.Dispose();
++      persistent.Clear();
++    }
++
++    P* const parameter;
++    Callback const callback;
++    v8::Persistent<T> persistent;
++  };
++
++  template<typename T, typename P>
++  class _NanWeakCallbackData {
++   public:
++    NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info)
++      : info_(info) { }
++
++    NAN_INLINE v8::Local<T> GetValue() const {
++      return NanNew(info_->persistent);
++    }
++
++    NAN_INLINE P* GetParameter() const { return info_->parameter; }
++
++    NAN_INLINE bool IsNearDeath() const {
++      return info_->persistent.IsNearDeath();
++    }
++
++    NAN_INLINE void Revive() const;
++
++    NAN_INLINE _NanWeakCallbackInfo<T, P>* GetCallbackInfo() const {
++      return info_;
++    }
++
++    NAN_DEPRECATED NAN_INLINE void Dispose() const {
++    }
++
++   private:
++    _NanWeakCallbackInfo<T, P>* info_;
++  };
++
++  template<typename T, typename P>
++  static void _NanWeakPersistentDispatcher(
++      v8::Persistent<v8::Value> object, void *data) {
++    _NanWeakCallbackInfo<T, P>* info =
++        static_cast<_NanWeakCallbackInfo<T, P>*>(data);
++    _NanWeakCallbackData<T, P> wcbd(info);
++    info->callback(wcbd);
++    if (wcbd.IsNearDeath()) {
++      delete wcbd.GetCallbackInfo();
++    }
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const {
++      info_->persistent.MakeWeak(
++          info_
++        , &_NanWeakPersistentDispatcher<T, P>);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
++    v8::Handle<T> handle
++  , P* parameter
++  , typename _NanWeakCallbackInfo<T, P>::Callback callback) {
++      _NanWeakCallbackInfo<T, P> *cbinfo =
++        new _NanWeakCallbackInfo<T, P>(handle, parameter, callback);
++      cbinfo->persistent.MakeWeak(
++          cbinfo
++        , &_NanWeakPersistentDispatcher<T, P>);
++      return cbinfo;
++  }
++
++# define NAN_WEAK_CALLBACK(name)                                               \
++    template<typename T, typename P>                                           \
++    static void name(const _NanWeakCallbackData<T, P> &data)
++
++# define _NAN_ERROR(fun, errmsg)                                               \
++    fun(v8::String::New(errmsg))
++
++# define _NAN_THROW_ERROR(fun, errmsg)                                         \
++    do {                                                                       \
++      NanScope();                                                              \
++      return v8::Local<v8::Value>::New(                                        \
++        v8::ThrowException(_NAN_ERROR(fun, errmsg)));                          \
++    } while (0);
++
++  NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) {
++    return _NAN_ERROR(v8::Exception::Error, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowError(const char* errmsg) {
++    _NAN_THROW_ERROR(v8::Exception::Error, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowError(
++      v8::Handle<v8::Value> error
++  ) {
++    NanScope();
++    return v8::Local<v8::Value>::New(v8::ThrowException(error));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanError(
++      const char *msg
++    , const int errorNumber
++  ) {
++    v8::Local<v8::Value> err = v8::Exception::Error(v8::String::New(msg));
++    v8::Local<v8::Object> obj = err.As<v8::Object>();
++    obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber));
++    return err;
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowError(
++      const char *msg
++    , const int errorNumber
++  ) {
++    return NanThrowError(NanError(msg, errorNumber));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) {
++    return _NAN_ERROR(v8::Exception::TypeError, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowTypeError(
++      const char* errmsg
++  ) {
++    _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRangeError(
++      const char* errmsg
++  ) {
++    return _NAN_ERROR(v8::Exception::RangeError, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowRangeError(
++      const char* errmsg
++  ) {
++    _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);
++  }
++
++  template<typename T>
++  NAN_INLINE void NanDisposePersistent(
++      v8::Persistent<T> &handle) {  // NOLINT(runtime/references)
++    handle.Dispose();
++    handle.Clear();
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
++      char *data
++    , size_t length
++    , node::Buffer::free_callback callback
++    , void *hint
++  ) {
++    return NanNew(
++        node::Buffer::New(data, length, callback, hint)->handle_);
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
++      const char *data
++    , uint32_t size
++  ) {
++#if NODE_MODULE_VERSION >= 0x000B
++    return NanNew(node::Buffer::New(data, size)->handle_);
++#else
++    return NanNew(
++      node::Buffer::New(const_cast<char*>(data), size)->handle_);
++#endif
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {
++    return NanNew(node::Buffer::New(size)->handle_);
++  }
++
++  NAN_INLINE void FreeData(char *data, void *hint) {
++    delete[] data;
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanBufferUse(
++      char* data
++    , uint32_t size
++  ) {
++    return NanNew(
++        node::Buffer::New(data, size, FreeData, NULL)->handle_);
++  }
++
++  NAN_INLINE bool NanHasInstance(
++      v8::Persistent<v8::FunctionTemplate>& function_template
++    , v8::Handle<v8::Value> value
++  ) {
++    return function_template->HasInstance(value);
++  }
++
++  NAN_INLINE v8::Local<v8::Context> NanNewContextHandle(
++      v8::ExtensionConfiguration* extensions = NULL
++    , v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>()
++    , v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()
++  ) {
++    v8::Persistent<v8::Context> ctx = v8::Context::New(extensions, tmpl, obj);
++    v8::Local<v8::Context> lctx = NanNew(ctx);
++    ctx.Dispose();
++    return lctx;
++  }
++
++  NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
++      v8::Local<v8::String> s
++    , const v8::ScriptOrigin& origin
++  ) {
++    return v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin));
++  }
++
++  NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
++    v8::Local<v8::String> s
++  ) {
++    return v8::Script::Compile(s);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRunScript(v8::Handle<v8::Script> script) {
++    return script->Run();
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , v8::Handle<v8::Function> func
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++# if NODE_VERSION_AT_LEAST(0, 8, 0)
++    return NanNew(node::MakeCallback(target, func, argc, argv));
++# else
++    v8::TryCatch try_catch;
++    v8::Local<v8::Value> result = NanNew(func->Call(target, argc, argv));
++    if (try_catch.HasCaught()) {
++        node::FatalException(try_catch);
++    }
++    return result;
++# endif
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , v8::Handle<v8::String> symbol
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++# if NODE_VERSION_AT_LEAST(0, 8, 0)
++    return NanNew(node::MakeCallback(target, symbol, argc, argv));
++# else
++    v8::Local<v8::Function> callback = target->Get(symbol).As<v8::Function>();
++    return NanMakeCallback(target, callback, argc, argv);
++# endif
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , const char* method
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++# if NODE_VERSION_AT_LEAST(0, 8, 0)
++    return NanNew(node::MakeCallback(target, method, argc, argv));
++# else
++    return NanMakeCallback(target, NanNew(method), argc, argv);
++# endif
++  }
++
++  template<typename T>
++  NAN_INLINE void NanSetIsolateData(
++      v8::Isolate *isolate
++    , T *data
++  ) {
++      isolate->SetData(data);
++  }
++
++  template<typename T>
++  NAN_INLINE T *NanGetIsolateData(
++      v8::Isolate *isolate
++  ) {
++      return static_cast<T*>(isolate->GetData());
++  }
++
++  class NanAsciiString {
++   public:
++    NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Length() + 1;
++      buf = new char[buf_size];
++      size = toStr->WriteAscii(buf, 0, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE char* operator*() { return buf; }
++
++    NAN_INLINE ~NanAsciiString() {
++      delete[] buf;
++    }
++
++   private:
++    char *buf;
++    int size;
++  };
++
++  class NanUtf8String {
++   public:
++    NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Utf8Length() + 1;
++      buf = new char[buf_size];
++      size = toStr->WriteUtf8(buf, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE char* operator*() { return buf; }
++
++    NAN_INLINE ~NanUtf8String() {
++      delete[] buf;
++    }
++
++   private:
++    char *buf;
++    int size;
++  };
++
++  class NanUcs2String {
++   public:
++    NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Length() + 1;
++      buf = new uint16_t[buf_size];
++      size = toStr->Write(buf, 0, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE uint16_t* operator*() { return buf; }
++
++    NAN_INLINE ~NanUcs2String() {
++      delete[] buf;
++    }
++
++   private:
++    uint16_t *buf;
++    int size;
++  };
++
++#endif  // NODE_MODULE_VERSION
++
++typedef void (*NanFreeCallback)(char *data, void *hint);
++
++#define NAN_METHOD(name) _NAN_METHOD_RETURN_TYPE name(_NAN_METHOD_ARGS)
++#define NAN_GETTER(name)                                                       \
++    _NAN_GETTER_RETURN_TYPE name(                                              \
++        v8::Local<v8::String> property                                         \
++      , _NAN_GETTER_ARGS)
++#define NAN_SETTER(name)                                                       \
++    _NAN_SETTER_RETURN_TYPE name(                                              \
++        v8::Local<v8::String> property                                         \
++      , v8::Local<v8::Value> value                                             \
++      , _NAN_SETTER_ARGS)
++#define NAN_PROPERTY_GETTER(name)                                              \
++    _NAN_PROPERTY_GETTER_RETURN_TYPE name(                                     \
++        v8::Local<v8::String> property                                         \
++      , _NAN_PROPERTY_GETTER_ARGS)
++#define NAN_PROPERTY_SETTER(name)                                              \
++    _NAN_PROPERTY_SETTER_RETURN_TYPE name(                                     \
++        v8::Local<v8::String> property                                         \
++      , v8::Local<v8::Value> value                                             \
++      , _NAN_PROPERTY_SETTER_ARGS)
++#define NAN_PROPERTY_ENUMERATOR(name)                                          \
++    _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(_NAN_PROPERTY_ENUMERATOR_ARGS)
++#define NAN_PROPERTY_DELETER(name)                                             \
++    _NAN_PROPERTY_DELETER_RETURN_TYPE name(                                    \
++        v8::Local<v8::String> property                                         \
++      , _NAN_PROPERTY_DELETER_ARGS)
++#define NAN_PROPERTY_QUERY(name)                                               \
++    _NAN_PROPERTY_QUERY_RETURN_TYPE name(                                      \
++        v8::Local<v8::String> property                                         \
++      , _NAN_PROPERTY_QUERY_ARGS)
++# define NAN_INDEX_GETTER(name)                                                \
++    _NAN_INDEX_GETTER_RETURN_TYPE name(uint32_t index, _NAN_INDEX_GETTER_ARGS)
++#define NAN_INDEX_SETTER(name)                                                 \
++    _NAN_INDEX_SETTER_RETURN_TYPE name(                                        \
++        uint32_t index                                                         \
++      , v8::Local<v8::Value> value                                             \
++      , _NAN_INDEX_SETTER_ARGS)
++#define NAN_INDEX_ENUMERATOR(name)                                             \
++    _NAN_INDEX_ENUMERATOR_RETURN_TYPE name(_NAN_INDEX_ENUMERATOR_ARGS)
++#define NAN_INDEX_DELETER(name)                                                \
++    _NAN_INDEX_DELETER_RETURN_TYPE name(                                       \
++        uint32_t index                                                         \
++      , _NAN_INDEX_DELETER_ARGS)
++#define NAN_INDEX_QUERY(name)                                                  \
++    _NAN_INDEX_QUERY_RETURN_TYPE name(uint32_t index, _NAN_INDEX_QUERY_ARGS)
++
++class NanCallback {
++ public:
++  NanCallback() {
++    NanScope();
++    v8::Local<v8::Object> obj = NanNew<v8::Object>();
++    NanAssignPersistent(handle, obj);
++  }
++
++  explicit NanCallback(const v8::Handle<v8::Function> &fn) {
++    NanScope();
++    v8::Local<v8::Object> obj = NanNew<v8::Object>();
++    NanAssignPersistent(handle, obj);
++    SetFunction(fn);
++  }
++
++  ~NanCallback() {
++    if (handle.IsEmpty()) return;
++    NanDisposePersistent(handle);
++  }
++
++  NAN_INLINE void SetFunction(const v8::Handle<v8::Function> &fn) {
++    NanScope();
++    NanNew(handle)->Set(kCallbackIndex, fn);
++  }
++
++  NAN_INLINE v8::Local<v8::Function> GetFunction() const {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(handle)->Get(kCallbackIndex)
++        .As<v8::Function>());
++  }
++
++  NAN_INLINE bool IsEmpty() const {
++    NanScope();
++    return NanNew(handle)->Get(kCallbackIndex)->IsUndefined();
++  }
++
++  v8::Handle<v8::Value> Call(int argc, v8::Handle<v8::Value> argv[]) const {
++    NanEscapableScope();
++#if (NODE_MODULE_VERSION > 0x000B)  // 0.11.12+
++    v8::Isolate* isolate = v8::Isolate::GetCurrent();
++    v8::Local<v8::Function> callback = NanNew(handle)->
++        Get(kCallbackIndex).As<v8::Function>();
++    return NanEscapeScope(node::MakeCallback(
++        isolate
++      , isolate->GetCurrentContext()->Global()
++      , callback
++      , argc
++      , argv
++    ));
++#else
++#if NODE_VERSION_AT_LEAST(0, 8, 0)
++    v8::Local<v8::Function> callback = handle->
++        Get(kCallbackIndex).As<v8::Function>();
++    return NanEscapeScope(node::MakeCallback(
++        v8::Context::GetCurrent()->Global()
++      , callback
++      , argc
++      , argv
++    ));
++#else
++    v8::Local<v8::Function> callback = handle->
++        Get(kCallbackIndex).As<v8::Function>();
++    return NanEscapeScope(NanMakeCallback(
++        v8::Context::GetCurrent()->Global(), callback, argc, argv));
++#endif
++#endif
++  }
++
++ private:
++  v8::Persistent<v8::Object> handle;
++  static const uint32_t kCallbackIndex = 0;
++};
++
++/* abstract */ class NanAsyncWorker {
++ public:
++  explicit NanAsyncWorker(NanCallback *callback)
++      : callback(callback), errmsg_(NULL) {
++    request.data = this;
++
++    NanScope();
++    v8::Local<v8::Object> obj = NanNew<v8::Object>();
++    NanAssignPersistent(persistentHandle, obj);
++  }
++
++  virtual ~NanAsyncWorker() {
++    NanScope();
++
++    if (!persistentHandle.IsEmpty())
++      NanDisposePersistent(persistentHandle);
++    if (callback)
++      delete callback;
++    if (errmsg_)
++      delete[] errmsg_;
++  }
++
++  virtual void WorkComplete() {
++    NanScope();
++
++    if (errmsg_ == NULL)
++      HandleOKCallback();
++    else
++      HandleErrorCallback();
++    delete callback;
++    callback = NULL;
++  }
++
++  NAN_INLINE void SaveToPersistent(
++      const char *key, const v8::Local<v8::Object> &obj) {
++    v8::Local<v8::Object> handle = NanNew(persistentHandle);
++    handle->Set(NanNew<v8::String>(key), obj);
++  }
++
++  v8::Local<v8::Object> GetFromPersistent(const char *key) const {
++    NanEscapableScope();
++    v8::Local<v8::Object> handle = NanNew(persistentHandle);
++    return NanEscapeScope(handle->Get(NanNew(key)).As<v8::Object>());
++  }
++
++  virtual void Execute() = 0;
++
++  uv_work_t request;
++
++ protected:
++  v8::Persistent<v8::Object> persistentHandle;
++  NanCallback *callback;
++
++  virtual void HandleOKCallback() {
++    NanScope();
++
++    callback->Call(0, NULL);
++  }
++
++  virtual void HandleErrorCallback() {
++    NanScope();
++
++    v8::Local<v8::Value> argv[] = {
++        v8::Exception::Error(NanNew<v8::String>(ErrorMessage()))
++    };
++    callback->Call(1, argv);
++  }
++
++  void SetErrorMessage(const char *msg) {
++    if (errmsg_) {
++      delete[] errmsg_;
++    }
++
++    size_t size = strlen(msg) + 1;
++    errmsg_ = new char[size];
++    memcpy(errmsg_, msg, size);
++  }
++
++  const char* ErrorMessage() const {
++    return errmsg_;
++  }
++
++ private:
++  char *errmsg_;
++};
++
++NAN_INLINE void NanAsyncExecute (uv_work_t* req) {
++  NanAsyncWorker *worker = static_cast<NanAsyncWorker*>(req->data);
++  worker->Execute();
++}
++
++NAN_INLINE void NanAsyncExecuteComplete (uv_work_t* req) {
++  NanAsyncWorker* worker = static_cast<NanAsyncWorker*>(req->data);
++  worker->WorkComplete();
++  delete worker;
++}
++
++NAN_INLINE void NanAsyncQueueWorker (NanAsyncWorker* worker) {
++  uv_queue_work(
++      uv_default_loop()
++    , &worker->request
++    , NanAsyncExecute
++    , (uv_after_work_cb)NanAsyncExecuteComplete
++  );
++}
++
++//// Base 64 ////
++
++#define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4)
++
++// Doesn't check for padding at the end.  Can be 1-2 bytes over.
++NAN_INLINE size_t _nan_base64_decoded_size_fast(size_t size) {
++  size_t remainder = size % 4;
++
++  size = (size / 4) * 3;
++  if (remainder) {
++    if (size == 0 && remainder == 1) {
++      // special case: 1-byte input cannot be decoded
++      size = 0;
++    } else {
++      // non-padded input, add 1 or 2 extra bytes
++      size += 1 + (remainder == 3);
++    }
++  }
++
++  return size;
++}
++
++template<typename T>
++NAN_INLINE size_t _nan_base64_decoded_size(
++    const T* src
++  , size_t size
++) {
++  if (size == 0)
++    return 0;
++
++  if (src[size - 1] == '=')
++    size--;
++  if (size > 0 && src[size - 1] == '=')
++    size--;
++
++  return _nan_base64_decoded_size_fast(size);
++}
++
++// supports regular and URL-safe base64
++static const int _nan_unbase64_table[] = {
++    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63
++  , 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1
++  , -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14
++  , 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63
++  , -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40
++  , 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++};
++
++#define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)]
++
++template<typename T> static size_t _nan_base64_decode(
++    char* buf
++  , size_t len
++  , const T* src
++  , const size_t srcLen
++) {
++  char* dst = buf;
++  char* dstEnd = buf + len;
++  const T* srcEnd = src + srcLen;
++
++  while (src < srcEnd && dst < dstEnd) {
++    ptrdiff_t remaining = srcEnd - src;
++    char a, b, c, d;
++
++    while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
++    if (remaining == 0 || *src == '=') break;
++    a = _nan_unbase64(*src++);
++
++    while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
++    if (remaining <= 1 || *src == '=') break;
++    b = _nan_unbase64(*src++);
++
++    *dst++ = (a << 2) | ((b & 0x30) >> 4);
++    if (dst == dstEnd) break;
++
++    while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
++    if (remaining <= 2 || *src == '=') break;
++    c = _nan_unbase64(*src++);
++
++    *dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2);
++    if (dst == dstEnd) break;
++
++    while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
++    if (remaining <= 3 || *src == '=') break;
++    d = _nan_unbase64(*src++);
++
++    *dst++ = ((c & 0x03) << 6) | (d & 0x3F);
++  }
++
++  return dst - buf;
++}
++
++//// HEX ////
++
++template<typename T> unsigned _nan_hex2bin(T c) {
++  if (c >= '0' && c <= '9') return c - '0';
++  if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
++  if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
++  return static_cast<unsigned>(-1);
++}
++
++template<typename T> static size_t _nan_hex_decode(
++    char* buf
++  , size_t len
++  , const T* src
++  , const size_t srcLen
++) {
++  size_t i;
++  for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) {
++    unsigned a = _nan_hex2bin(src[i * 2 + 0]);
++    unsigned b = _nan_hex2bin(src[i * 2 + 1]);
++    if (!~a || !~b) return i;
++    buf[i] = a * 16 + b;
++  }
++
++  return i;
++}
++
++static bool _NanGetExternalParts(
++    v8::Handle<v8::Value> val
++  , const char** data
++  , size_t* len
++) {
++  if (node::Buffer::HasInstance(val)) {
++    *data = node::Buffer::Data(val.As<v8::Object>());
++    *len = node::Buffer::Length(val.As<v8::Object>());
++    return true;
++  }
++
++  assert(val->IsString());
++  v8::Local<v8::String> str = NanNew(val.As<v8::String>());
++
++  if (str->IsExternalAscii()) {
++    const v8::String::ExternalAsciiStringResource* ext;
++    ext = str->GetExternalAsciiStringResource();
++    *data = ext->data();
++    *len = ext->length();
++    return true;
++
++  } else if (str->IsExternal()) {
++    const v8::String::ExternalStringResource* ext;
++    ext = str->GetExternalStringResource();
++    *data = reinterpret_cast<const char*>(ext->data());
++    *len = ext->length();
++    return true;
++  }
++
++  return false;
++}
++
++namespace Nan {
++  enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
++}
++
++/* NAN_DEPRECATED */ NAN_INLINE void* _NanRawString(
++    v8::Handle<v8::Value> from
++  , enum Nan::Encoding encoding
++  , size_t *datalen
++  , void *buf
++  , size_t buflen
++  , int flags
++) {
++  NanScope();
++
++  size_t sz_;
++  size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION);
++  char *data = NULL;
++  size_t len;
++  bool is_extern = _NanGetExternalParts(
++      from
++    , const_cast<const char**>(&data)
++    , &len);
++
++  if (is_extern && !term_len) {
++    NanSetPointerSafe(datalen, len);
++    return data;
++  }
++
++  v8::Local<v8::String> toStr = from->ToString();
++
++  char *to = static_cast<char *>(buf);
++
++  switch (encoding) {
++    case Nan::ASCII:
++#if NODE_MODULE_VERSION < 0x000C
++      sz_ = toStr->Length();
++      if (to == NULL) {
++        to = new char[sz_ + term_len];
++      } else {
++        assert(buflen >= sz_ + term_len && "too small buffer");
++      }
++      NanSetPointerSafe<size_t>(
++          datalen
++        , toStr->WriteAscii(to, 0, static_cast<int>(sz_ + term_len), flags));
++      return to;
++#endif
++    case Nan::BINARY:
++    case Nan::BUFFER:
++      sz_ = toStr->Length();
++      if (to == NULL) {
++        to = new char[sz_ + term_len];
++      } else {
++        assert(buflen >= sz_ + term_len && "too small buffer");
++      }
++#if NODE_MODULE_VERSION < 0x000C
++      {
++        uint16_t* twobytebuf = new uint16_t[sz_ + term_len];
++
++        size_t len = toStr->Write(twobytebuf, 0,
++          static_cast<int>(sz_ + term_len), flags);
++
++        for (size_t i = 0; i < sz_ + term_len && i < len + term_len; i++) {
++          unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
++          to[i] = *b;
++        }
++
++        NanSetPointerSafe<size_t>(datalen, len);
++
++        delete[] twobytebuf;
++        return to;
++      }
++#else
++      NanSetPointerSafe<size_t>(
++        datalen,
++        toStr->WriteOneByte(
++            reinterpret_cast<uint8_t *>(to)
++          , 0
++          , static_cast<int>(sz_ + term_len)
++          , flags));
++      return to;
++#endif
++    case Nan::UTF8:
++      sz_ = toStr->Utf8Length();
++      if (to == NULL) {
++        to = new char[sz_ + term_len];
++      } else {
++        assert(buflen >= sz_ + term_len && "too small buffer");
++      }
++      NanSetPointerSafe<size_t>(
++          datalen
++        , toStr->WriteUtf8(to, static_cast<int>(sz_ + term_len)
++            , NULL, flags)
++          - term_len);
++      return to;
++    case Nan::BASE64:
++      {
++        v8::String::Value value(toStr);
++        sz_ = _nan_base64_decoded_size(*value, value.length());
++        if (to == NULL) {
++          to = new char[sz_ + term_len];
++        } else {
++          assert(buflen >= sz_ + term_len);
++        }
++        NanSetPointerSafe<size_t>(
++            datalen
++          , _nan_base64_decode(to, sz_, *value, value.length()));
++        if (term_len) {
++          to[sz_] = '\0';
++        }
++        return to;
++      }
++    case Nan::UCS2:
++      {
++        sz_ = toStr->Length();
++        if (to == NULL) {
++          to = new char[(sz_ + term_len) * 2];
++        } else {
++          assert(buflen >= (sz_ + term_len) * 2 && "too small buffer");
++        }
++
++        int bc = 2 * toStr->Write(
++            reinterpret_cast<uint16_t *>(to)
++          , 0
++          , static_cast<int>(sz_ + term_len)
++          , flags);
++        NanSetPointerSafe<size_t>(datalen, bc);
++        return to;
++      }
++    case Nan::HEX:
++      {
++        v8::String::Value value(toStr);
++        sz_ = value.length();
++        assert(!(sz_ & 1) && "bad hex data");
++        if (to == NULL) {
++          to = new char[sz_ / 2 + term_len];
++        } else {
++          assert(buflen >= sz_ / 2 + term_len && "too small buffer");
++        }
++        NanSetPointerSafe<size_t>(
++            datalen
++          , _nan_hex_decode(to, sz_ / 2, *value, value.length()));
++      }
++      if (term_len) {
++        to[sz_ / 2] = '\0';
++      }
++      return to;
++    default:
++      assert(0 && "unknown encoding");
++  }
++  return to;
++}
++
++NAN_DEPRECATED NAN_INLINE void* NanRawString(
++    v8::Handle<v8::Value> from
++  , enum Nan::Encoding encoding
++  , size_t *datalen
++  , void *buf
++  , size_t buflen
++  , int flags
++) {
++  return _NanRawString(from, encoding, datalen, buf, buflen, flags);
++}
++
++
++NAN_DEPRECATED NAN_INLINE char* NanCString(
++    v8::Handle<v8::Value> from
++  , size_t *datalen
++  , char *buf = NULL
++  , size_t buflen = 0
++  , int flags = v8::String::NO_OPTIONS
++) {
++    return static_cast<char *>(
++      _NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags)
++    );
++}
++
++NAN_INLINE void NanSetPrototypeTemplate(
++    v8::Local<v8::FunctionTemplate> templ
++  , const char *name
++  , v8::Handle<v8::Data> value
++) {
++  NanSetTemplate(templ->PrototypeTemplate(), name, value);
++}
++
++NAN_INLINE void NanSetPrototypeTemplate(
++    v8::Local<v8::FunctionTemplate> templ
++  , v8::Handle<v8::String> name
++  , v8::Handle<v8::Data> value
++  , v8::PropertyAttribute attributes
++) {
++  NanSetTemplate(templ->PrototypeTemplate(), name, value, attributes);
++}
++
++NAN_INLINE void NanSetInstanceTemplate(
++    v8::Local<v8::FunctionTemplate> templ
++  , const char *name
++  , v8::Handle<v8::Data> value
++) {
++  NanSetTemplate(templ->InstanceTemplate(), name, value);
++}
++
++NAN_INLINE void NanSetInstanceTemplate(
++    v8::Local<v8::FunctionTemplate> templ
++  , v8::Handle<v8::String> name
++  , v8::Handle<v8::Data> value
++  , v8::PropertyAttribute attributes
++) {
++  NanSetTemplate(templ->InstanceTemplate(), name, value, attributes);
++}
++
++#endif  // NAN_H_
diff --git a/lang/node-serialport/Makefile b/lang/node-serialport/Makefile
new file mode 100644 (file)
index 0000000..56d0697
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2014 Arduino LLC
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NPM_NAME:=serialport
+PKG_NAME:=node-$(PKG_NPM_NAME)
+PKG_VERSION:=1.4.6
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NPM_NAME)-$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=http://registry.npmjs.org/$(PKG_NPM_NAME)/-/
+PKG_MD5SUM:=1eb21082e0aa676b8350182a60230808
+
+PKG_BUILD_DEPENDS:=node
+PKG_NODE_VERSION:=0.12.7
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node-serialport
+  DEPENDS:=+node
+  SUBMENU:=Node.js
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Node.js package to access serial ports for reading and writing
+  URL:=https://www.npmjs.org/package/serialport
+endef
+
+define Package/node-serialport/description
+ Node.js package to access serial ports for reading and writing OR Welcome your robotic JavaScript overlords. Better yet, program them!
+endef
+
+define Build/Prepare
+       /bin/tar xzf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip-components 1
+       $(Build/Patch)
+endef
+
+EXTRA_LDFLAGS="-L$(TOOLCHAIN_DIR)/lib/ -Wl,-rpath-link $(TOOLCHAIN_DIR)/lib/" \
+
+define Build/Compile
+       $(MAKE_FLAGS) \
+       npm_config_arch=$(CONFIG_ARCH) \
+       npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \
+       PREFIX="$(PKG_INSTALL_DIR)/usr/" \
+       $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR)
+endef
+
+define Package/node-serialport/install
+       mkdir -p $(1)/usr/lib/node/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/* $(1)/usr/lib/node/
+endef
+
+$(eval $(call BuildPackage,node-serialport))
+
diff --git a/lang/node-serialport/patches/package.json.patch b/lang/node-serialport/patches/package.json.patch
new file mode 100644 (file)
index 0000000..a20c6a5
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/package.json     2014-05-02 12:02:02.940515727 +0200
++++ b/package.json     2014-05-02 12:03:08.488512762 +0200
+@@ -69,7 +71,7 @@
+     "serialportterm": "./bin/serialportTerminal.js"
+   },
+   "scripts": {
+-    "install": "node-pre-gyp install --fallback-to-build",
++    "install": "node-pre-gyp reinstall --build-from-source --target_arch=${npm_config_arch}",
+     "test": "grunt --verbose"
+   }
+ }
diff --git a/lang/node/Makefile b/lang/node/Makefile
new file mode 100644 (file)
index 0000000..98a76b8
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=node
+PKG_VERSION:=v0.12.7
+PKG_RELEASE:=1
+
+PKG_SOURCE:=node-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://nodejs.org/dist/${PKG_VERSION}
+
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node
+  SECTION:=lang
+  CATEGORY:=Languages
+  SUBMENU:=Node.js
+  TITLE:=Node.js is a platform built on Chrome's JavaScript runtime
+  URL:=http://nodejs.org/
+  DEPENDS:=+libpthread +librt +libstdcpp +libopenssl +libuv
+endef
+
+define Package/node/description
+  Node.jsĀ® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses
+  an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js'
+   package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
+endef
+
+CONFIGURE_ARGS= \
+       --dest-cpu=$(CONFIG_ARCH) \
+       --dest-os=linux \
+       --without-snapshot \
+       --shared-zlib \
+       --shared-openssl \
+       --prefix=/usr
+
+HOST_CONFIGURE_VARS:=
+HOST_CONFIGURE_ARGS:= \
+       --dest-os=linux \
+       --without-snapshot \
+       --prefix=$(STAGING_DIR_HOST)/
+
+HOST_CONFIGURE_CMD:=python ./configure
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+endef
+
+define Package/node/install
+       mkdir -p $(1)/usr/bin $(1)/usr/lib/node_modules/npm/{bin,lib,node_modules}
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/{node,npm} $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/{package.json,LICENSE,cli.js} $(1)/usr/lib/node_modules/npm
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/bin/npm-cli.js $(1)/usr/lib/node_modules/npm/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/lib/* $(1)/usr/lib/node_modules/npm/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/node_modules/* $(1)/usr/lib/node_modules/npm/node_modules/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,node))
diff --git a/lang/node/patches/001-mips-no-fpu.patch b/lang/node/patches/001-mips-no-fpu.patch
new file mode 100644 (file)
index 0000000..5bf8142
--- /dev/null
@@ -0,0 +1,15 @@
+--- a/deps/v8/build/toolchain.gypi
++++ b/deps/v8/build/toolchain.gypi
+@@ -50,10 +50,10 @@
+     'arm_test_noprobe%': 'off',
+     # Similar to vfp but on MIPS.
+-    'v8_can_use_fpu_instructions%': 'true',
++    'v8_can_use_fpu_instructions%': 'false',
+     # Similar to the ARM hard float ABI but on MIPS.
+-    'v8_use_mips_abi_hardfloat%': 'true',
++    'v8_use_mips_abi_hardfloat%': 'false',
+     # Default arch variant for MIPS.
+     'mips_arch_variant%': 'r2',
diff --git a/lang/node/patches/002-addr_info.patch b/lang/node/patches/002-addr_info.patch
new file mode 100644 (file)
index 0000000..78225db
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/deps/uv/src/unix/getaddrinfo.c
++++ b/deps/uv/src/unix/getaddrinfo.c
+@@ -99,6 +99,7 @@
+   int err;
+   req = container_of(w, uv_getaddrinfo_t, work_req);
++   req->hints->ai_flags &= ~AI_V4MAPPED;
+   err = getaddrinfo(req->hostname, req->service, req->hints, &req->addrinfo);
+   req->retcode = uv__getaddrinfo_translate_error(err);
+ }
diff --git a/lang/node/patches/003-path.patch b/lang/node/patches/003-path.patch
new file mode 100644 (file)
index 0000000..723fe9d
--- /dev/null
@@ -0,0 +1,12 @@
+--- a/lib/module.js
++++ b/lib/module.js
+@@ -512,7 +512,8 @@
+     var homeDir = process.env.HOME;
+   }
+-  var paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node')];
++  var paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node'),
++    path.resolve(process.execPath, '..', '..', 'lib', 'node_modules')];
+   if (homeDir) {
+     paths.unshift(path.resolve(homeDir, '.node_libraries'));
git clone https://git.99rst.org/PROJECT