diff --git a/.gitignore b/.gitignore new file mode 100755 index 00000000..be971a1a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +doc \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..085a35f0 --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +test +examples +.gitignore \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..bee947b5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +(The GPLv3 License) + + vast.js: a P2P library for spatial publish subscribe (SPS) + Copyright (C) 2014 Imonology Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + diff --git a/NN.bat b/NN.bat deleted file mode 100644 index ef1447ba..00000000 --- a/NN.bat +++ /dev/null @@ -1 +0,0 @@ -node test_von_peer 3770 127.0.0.1 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 807173bf..740c514a --- a/README.md +++ b/README.md @@ -1,4 +1,98 @@ -vast.js -======= +# VAST.js +P2P Spatial Publish and Subscribe built on the Voronoi Overlay Network (VON). +This documentation is not exhaustive and may not conform to current code 100%. + +- [VAST.js](#vastjs) +- [Introduction to VAST.js](#introduction-to-vastjs) + - [Basic Stricture](#basic-structure) + - [Matchers](#matchers) + - [Voronoi Overlay Network](#voronoi-overlay-network) + - [The Global Server](#the-global-server) +- [Dependancies](#dependancies) +- [Getting Started](#getting-started) -VAST.js is the javascript implementation of VAST: a scalable P2P network for spatial publish/subscribe (SPS) \ No newline at end of file +# Introduction to VAST.js +## Basic Structure +drawing + +## Matchers +Clients establish connections to [matchers](./docs/matcher.md) based on their position in the environment. Matchers act as "spatial message brokers", i.e. they are responsible for handling subscription requests from their own clients and for matching publications to subscriptions. +Each matcher keeps a list of all subscriptions of its own clients as well as copies of "ovelapping" subscriptions for clients connected to other matchers. + +Matchers are not "aware" of each other and do not have direct connections, instead each matcher has an underlying [VON Peer](./docs/VON.md), which can be used to send any matcher-to-matcher packets with the newly implemented spatial forwarding functions in the VON peer. + +

+ +## Voronoi Overlay Network +The Voronoi Overlay Network (VON) is a dynamic, self-organising peer-to-peer network that establishes mutual awareness and a TCP socket between each peer and its neighbours in the virtual environment. Each peer maintains a localised Voronoi partition of its enclosing, AoI and boundary neighbours, which is shared between peers to facilitate neighbour discovery as peers join, leave and move around the VE. The VON has been extended to send any message to a point or area in the environment, and each VON peer will only receive the message once. + +For more detail on the VON, see [VON Peer](./docs/VON.md) + +

+ +## The Global Server +The HTML visualiser requires the global server to function. Each matcher has a connection to the global server and sends updates on its position, its perceived neighbours, clients, etc. +The global server collects all of this localised data and constructs a global understanding of the environments, which is rendered on the html client. The global server does not have any functional purpose in VAST.js and is strictly for debugging and demonstration purposes. + +**NOTE: If you wish to use VAST.js without the global server, the "RequireGS" flag must be set to false in matcher.js.** +If "RequireGS" is set to true, the matcher will not initialise before establishing a connection to the Global Server. + + +When using the Global Server for visualisation, ensure that you start it before any matchers. You can manually start it from the terminal: +```sh +node ./lib/visualiser/global_server.js +``` + +

+ +### Limitations to the Visualiser Imposed by Multithreading +When inspecting the ./lib/visualiser/visualiser.html, you will notice a renderLocal flag. Back when the matcher and VON peer were instantiated in the same process, the matcher was able to send its underlying VON peers neighbour list to the GS, which allowed for the visualiser to display both the global and localised views of the VON. +When the VON peer was shifted to run in a worker thread, this functionality was lost as no mechanism has been written for the VON peer to exchange this data with its matcher. +This functionality can be reintroduced by expanding the VON_peer_worker to accept a "get_VON_data" message from its matcher or something similar. +For now, the renderLocal flag is forced to false in the render function in the visualiser. + +

+ +# Dependancies +## Worker Threads Module +The VON peer runs on a worker thread of the Matcher. Install in the VAST.js directory using: +```sh +npm install worker-threads +``` + +

+ +## Socket.io and Socket.io-client +Currently, the matcher uses socket.io to establish a WebSocket connection with clients. +The Global Server also uses Socket.io to establish a connection with each matcher. +Clients and matchers also require the socket.io-client module. +Install in the VAST.js directory using: +```sh +npm install socket.io +npm install socket.io-client +``` + +

+ +# Getting Started +## ./test +The ./test directory contains some basic .js files to start matchers and clients. + +## start_GW.js and start_matcher.js +These files start a Gate Way or ordinary matcher at the given coordinates with the given AoI. If these arguments are not specified, the matchers will be placed randomly. +**NOTE: The hostname for the machine running the gateway is currently specified directly in these files. By default, it listens on port 8000 for VON traffic and 20000 for client sockets** +Example: Start the Gate Way matcher at {x: 200, y: 600} with an AoI radius of 100: +```sh +node ./test/start_GW.js 200 600 100 +``` + +## new_client.js +This file creates a new client. Currently, this file starts clients, registers them for subscriptions, and makes them publish messages at set intervals. +This file was unfortunately written for tests performed by CFM specifically, and have not yet been changed for more generalised applications. Use this file as an example to write your own client starter app for your own debugging needs. + +## start_test.js +This file starts the global server and a number of matchers (including a GW) randomly around the environment, each with the same specified AoI. The amount of time to wait between adding each new matcher can also be specified. All matchers are instantiated in a new node process. +Example: To start 5 matchers (including the gateway), each with an aoi of 100, and a wait time between matchers of 2 seconds +```sh +node ./test/start_test.js 5 100 2000 +``` diff --git a/SFVoronoi.java b/SFVoronoi.java deleted file mode 100644 index 2eb77ea3..00000000 --- a/SFVoronoi.java +++ /dev/null @@ -1,1189 +0,0 @@ -/* - * The author of this software is Steven Fortune. - * Copyright (c) 1994 by AT&T Bell Laboratories. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - */ - -/* - * VAST, a scalable peer-to-peer network for virtual environments - * Copyright (C) 2004 Guan-Ming Liao (gm.liao@msa.hinet.net) adpated from C to C++ - * Copyright (C) 2006 Shun-Yun Hu (syhu@yahoo.com) adapted from C++ to Java - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -package vast; - -import java.awt.*; // Point (?) -import java.util.*; // Vector, TreeMap - -/* structure used both for sites and for vertices */ -// NOTE: all 'float' have been converted to 'double' from the original SFVoronoi - - -class Site //implements Comparable, Comparator -{ - public point2d coord = new point2d (); - public int num; // originally 'sitenbr', now either the site id or vertex num - public int ref_count = 0; // originally 'refcnt', reference count - - public Vector edge_idxlist = new Vector(); - - public Site (double x, double y) { - coord.x = x; - coord.y = y; - } - -/* - // required by Comparable interface, compares any two Sites in lexicographical order - public int compareTo (Object o) { - return coord.compareTo (((Site)o).coord); - } - - public int compare (Object o1, Object o2) { - point2d p1 = ((Site)o1).coord; - point2d p2 = ((Site)o2).coord; - if (p1.y < p2.y) - return (-1); - if (p1.y > p2.y) - return (1); - if (p1.x < p2.x) - return (-1); - if (p1.x > p2.x) - return (1); - return (0); - } - - public boolean equals (Object o) { - point2d p = ((Site)o).coord; - return (coord.x == p.x && coord.y == p.y); - } -*/ - public double dist (Site s) { - return coord.distance (s.coord); - } -}; - -class Edge -{ - public double a,b,c; - public Site[] ep = new Site[2]; - public Site[] reg = new Site[2]; - public int num; -}; - -class Halfedge -{ - public Halfedge ELleft, ELright; - public Edge ELedge; - public int ELref_count; - public int ELpm; - public Site vertex; - public double ystar; - public Halfedge PQnext; -}; - -public class SFVoronoi { - - public SFVoronoi () { - DELETED = new Edge (); - DELETED.a = DELETED.b = DELETED.c = (-2); - - le = 0; - re = 1; - } - - // - // Peter variables - // - private boolean invalidated = false; - - // NOTE: we use TreeMap for mSites as it is both sorted and also a map (hashtable functions) - private Hashtable sites = new Hashtable(); // internal persistent record - public TreeMap mSites = new TreeMap(); // vector _sites; // mHPPVector; - public Vector mEdges = new Vector(); // vector mLines; - public Vector mVertices = new Vector(); // vector mVertex; - - // insert a new site, the first inserted is myself - public void insert (int id, Point coord) { - - // avoid duplicate insert - if (sites.containsKey (new Integer(id)) == false) { - invalidated = true; - //System.err.println ("inserting [" + id + "] coord: " + coord); - sites.put (new Integer(id), new point2d ((double)coord.x, (double)coord.y)); - } - } - - // remove a site - public void remove (int id) { - - if (sites.remove (new Integer(id)) != null) - invalidated = true; - } - - // modify the coordinates of a site - public void update (int id, Point coord) { - - invalidated = true; - point2d pt = (point2d)sites.get (new Integer(id)); - if (pt == null) - insert (id, coord); - else { - pt.x = coord.x; - pt.y = coord.y; - } - } - - // get the point of a site - public Point get (int id) { - - point2d p = (point2d)sites.get(new Integer(id)); - return new Point((int)p.x, (int)p.y); - } - - // check if a point lies inside a particular region - public boolean contains (int id, Point coord) { - if (sites.containsKey (new Integer(id)) == false) - return false; - - recompute (); - - return insideRegion (id, new point2d (coord.x, coord.y)); - } - - // check if the node is a boundary neighbor - public boolean is_boundary (int id, Point center, int radius) { - - //if (sites.containsKey (new Integer(id)) == false) - // return false; - - point2d coord = (point2d)sites.get (new Integer(id)); - if (coord == null) - return false; - - recompute (); - - point2d c = new point2d (center.x, center.y); - int idx1, idx2, edge_idx; - Enumeration e = ((Site)mSites.get (coord)).edge_idxlist.elements(); - - while (e.hasMoreElements ()) { - - edge_idx = ((Integer)e.nextElement()).intValue(); - - idx1 = ((line2d)mEdges.elementAt(edge_idx)).vertexIndex[0]; - idx2 = ((line2d)mEdges.elementAt(edge_idx)).vertexIndex[1]; - - // TODO: we are checking redundent points, can be avoided - if ( idx1 == -1 || - idx2 == -1 || - c.distance ((point2d)mVertices.elementAt(idx1)) >= (double)radius || - c.distance ((point2d)mVertices.elementAt(idx2)) >= (double)radius ) { - return true; - } - } - - // all the ENs of the node to check are within the AOI-radius (so not a boundary neighbor) - return false; - } - - // check if the node 'id' is an enclosing neighbor of 'center_node_id' - public boolean is_enclosing (int id, int center_node_id) { - - Vector v = get_en (center_node_id); - return (v == null ? false : v.contains (new Integer(id))); - } - - // get a list of enclosing neighbors - public Vector get_en (int id) { - //if (sites.containsKey (new Integer(id)) == false) - // return null; - - point2d coord = (point2d)sites.get (new Integer(id)); - if (coord == null) - return null; - - recompute(); - Vector en_list = new Vector(); - - // void getNeighborSet (int index, set& nset) - - Enumeration e = ((Site)mSites.get (coord)).edge_idxlist.elements (); - - while (e.hasMoreElements ()) { - - int edge_idx = ((Integer)e.nextElement ()).intValue (); - line2d line = (line2d)mEdges.elementAt (edge_idx); - - // NOTE: bisecting has changed from storing node index to node id - int en_id = (line.bisectingID[0] == id ? line.bisectingID[1] : line.bisectingID[0]); - en_list.add (new Integer(en_id)); - } - - return en_list; - } - - // check if a circle overlaps with a particular node - public boolean overlaps (int id, Point center, int radius) { - //if (sites.containsKey (new Integer(id)) == false) - // return false; - point2d coord = (point2d)sites.get (new Integer(id)); - if (coord == null) - return false; - - - /* version 1 - recompute(); - sfv::point2d center (pt.x, pt.y); - return _voronoi.collides (idx, center, (int)(radius+5)); - */ - - // version 2: simply check if it's within AOI - point2d c = new point2d (center.x, center.y); - - return (coord.distance (c) <= (double)(radius) ? true : false); - } - - // - // non Voronoi-specific methods - // - - // returns the closest node to a point - public int closest_to (Point coord) { - - Object[] keys = sites.keySet ().toArray (); - Object[] points = sites.values ().toArray (); - point2d p = new point2d (coord.x, coord.y); - - // assume the first node is the closest - int closest = ((Integer)keys[0]).intValue (); - double min_dist = p.distance ((point2d)points[0]); - - point2d pt; - double d; - - for (int i=1; i edge.c); - b2 = (edge.a * p.x + edge.b * p.y > edge.c); - - if (Math.abs (edge.a * p.x + edge.b * p.y - edge.c) < 0.001) - b2 = b1; - if (b1 != b2) - return false; - } - - if (e.hasMoreElements () == false) - return true; - else - return false; - } - - // - // original SFVoronoi protected functions, but now turn them into private ones - // - - private Site nextone () { - - if (curr_site.hasNext() == false) - return null; - - Site s = (Site)curr_site.next (); - - //System.err.println ("nextone [" + s.num + "] (" + s.coord.x + ", " + s.coord.y + ")"); - - return s; - } - - private void readsites() { - - // find out the x & y ranges for all sites - nsites = sites.size (); - - Object[] points = sites.values ().toArray (); - Object[] keys = sites.keySet ().toArray (); - - - xmin = xmax = ((point2d)points[0]).x; - ymin = ymax = ((point2d)points[0]).y; - point2d pt; - Site s; - - // converting sites to mSites - // NOTE: this is an important step as mSites needs to be sorted for Voronoi construction - for (int i=0; i xmax) - xmax = pt.x; - if(pt.y < ymin) - ymin = pt.y; - else if(pt.y > ymax) - ymax = pt.y; - - //System.err.println ("storing num: [" + s.num + "] (" + pt.x + ", " + pt.y + ")"); - } - - //ymin = ((Site)((Map.Entry)entries[0]).getValue()).coord.y; - //ymax = ((Site)((Map.Entry)entries[nsites-1]).getValue()).coord.y; - - Iterator it = mSites.values ().iterator (); - while (it.hasNext ()) { - s = (Site)it.next (); - //System.err.println ("sorted num: [" + s.num + "] (" + s.coord.x + ", " + s.coord.y + ")"); - } - - //System.err.println ("xmax=" + xmax + " xmin=" + xmin + " ymax=" + ymax + " ymin=" + ymin); - - } - - ////////////////////////////////////////////////////////////////////////// - // defs.h - // - - // command-line flags - - private boolean triangulate, sorted, plot, debug; - private double xmin, xmax, ymin, ymax, deltax, deltay; - private int nsites; - private Iterator curr_site; - private int sqrt_nsites; - private int nvertices; - private Site bottomsite; // Site *bottomsite; - private int nedges; - private Halfedge[] PQhash; // Halfedge *PQhash; - private int PQhashsize; - private int PQcount; - private int PQmin; - private Halfedge ELleftend, ELrightend; // Halfedge *ELleftend, *ELrightend; - private int ELhashsize; - private Halfedge[] ELhash; // Halfedge **ELhash; - private Edge DELETED; // special marker - - private int le; - private int re; - - - ////////////////////////////////////////////////////////////////////////// - // geometry.c - // - private void geominit() { - - nvertices = 0; - nedges = 0; - double sn = nsites+4; - sqrt_nsites = (int)Math.sqrt(sn); - deltay = ymax - ymin; - deltax = xmax - xmin; - } - - // find the bisecting edge for two sites (creating a new edge) - private Edge bisect (Site s1, Site s2) { - - //System.out.println ("bisecting (" + s1.coord.x + ", " + s1.coord.y + ") (" + s2.coord.x + ", " + s2.coord.y + ")"); - double dx, dy, adx, ady; // deltas in coords and their absolute values - Edge newedge = new Edge (); - - newedge.reg[0] = s1; - newedge.reg[1] = s2; - ref (s1); - ref (s2); - - newedge.ep[0] = null; - newedge.ep[1] = null; - - dx = s2.coord.x - s1.coord.x; - dy = s2.coord.y - s1.coord.y; - adx = (dx > 0 ? dx : -dx); - ady = (dy > 0 ? dy : -dy); - - newedge.c = s1.coord.x * dx + s1.coord.y * dy + (dx*dx + dy*dy) * 0.5; - - if (adx > ady) { - newedge.a = 1.0; - newedge.b = dy/dx; - newedge.c /= dx; - } - else { - newedge.b = 1.0; - newedge.a = dx/dy; - newedge.c /= dy; - } - - newedge.num = nedges++; - out_bisector (newedge); - - return newedge; - } - - private Site intersect (Halfedge el1, Halfedge el2, point2d p) { - - Edge e1, e2, e; - Halfedge el; - - double d, xint, yint; - - e1 = el1.ELedge; - e2 = el2.ELedge; - - if (e1 == null || e2 == null || (e1.reg[1] == e2.reg[1])) - return null; - - d = e1.a * e2.b - e1.b * e2.a; - - if (-1.0e-10 < d && d < 1.0e-10) - return null; - - xint = (e1.c * e2.b - e2.c * e1.b) / d; - yint = (e2.c * e1.a - e1.c * e2.a) / d; - - if (e1.reg[1].coord.compareTo (e2.reg[1].coord) < 0) { - el = el1; - e = e1; - } - else { - el = el2; - e = e2; - } - - boolean right_of_site = xint >= e.reg[1].coord.x; - - if ((right_of_site && el.ELpm == le) || (!right_of_site && el.ELpm == re)) - return null; - - Site v = new Site (xint, yint); - v.ref_count = 0; // perhaps can remove? - - return v; - } - - private boolean right_of (Halfedge el, point2d p) { - - boolean right_of_site, above, fast; - double dxp, dyp, dxs, t1, t2, t3, yl; - - Edge e = el.ELedge; - Site topsite = e.reg[1]; - - right_of_site = p.x > topsite.coord.x; - - if (right_of_site && el.ELpm == le) - return true; - - if (!right_of_site && el.ELpm == re) - return false; - - if (e.a == 1.0) { - - dyp = p.y - topsite.coord.y; - dxp = p.x - topsite.coord.x; - fast = false; - - if ((!right_of_site & (e.b<0.0)) | (right_of_site & (e.b>=0.0))) - fast = above = (dyp >= e.b*dxp); - else { - above = p.x + p.y * e.b > e.c; - if (e.b < 0.0) - above = !above; - if (!above) - fast = true; - } - if (!fast) { - - dxs = topsite.coord.x - (e.reg[0]).coord.x; - - // joker: update, skip divide by zero 2005/05/27 - // TODO: need to further check what cases could cause divide by 0 - if (dxs != 0) - above = e.b * (dxp*dxp - dyp*dyp) < dxs*dyp*(1.0+2.0*dxp/dxs + e.b*e.b); - else - above = false; - - if (e.b < 0.0) - above = !above; - }; - } - // e.b==1.0 - else { - yl = e.c - e.a*p.x; - t1 = p.y - yl; - t2 = p.x - topsite.coord.x; - t3 = yl - topsite.coord.y; - above = t1*t1 > (t2*t2 + t3*t3); - } - - return (el.ELpm == le ? above : !above); - } - - private void endpoint (Edge e, int lr, Site s) { - - e.ep[lr] = s; - ref (s); - - if(e.ep[re-lr] == null) - return; - - out_ep (e); - deref (e.reg[le]); - deref (e.reg[re]); - //makefree(e, &efl); - } - - // return int change to void - private void makevertex (Site v) { - - v.num = nvertices++; - out_vertex (v); - } - - private void deref (Site v) { - v.ref_count--; - } - - private void ref (Site v) { - v.ref_count++; - } - - -/* - ////////////////////////////////////////////////////////////////////////// - // memory.c - // - private void freeinit( Freelist *fl , int size); - private char* getfree( Freelist *fl); - private void makefree( Freenode *curr, Freelist *fl ); - private char* myalloc(unsigned n); -*/ - - ////////////////////////////////////////////////////////////////////////// - // output.c - // - - private double pxmin, pxmax, pymin, pymax, cradius; - - private void out_bisector (Edge e) { - - //System.out.println ("out_bisector [" + (float)e.a + ", " + (float)e.b + ", " + (float)e.c + "]"); - - line2d line = new line2d(e.a, e.b, e.c); - - line.bisectingID[0] = e.reg[le].num; - line.bisectingID[1] = e.reg[re].num; - - point2d pt1 = (point2d)sites.get (new Integer(line.bisectingID[0])); - point2d pt2 = (point2d)sites.get (new Integer(line.bisectingID[1])); - - ((Site)mSites.get (pt1)).edge_idxlist.add (new Integer(e.num)); - ((Site)mSites.get (pt2)).edge_idxlist.add (new Integer(e.num)); - - mEdges.add (line); - } - - private void out_ep (Edge e) { - - ((line2d)mEdges.elementAt (e.num)).vertexIndex[0] = (e.ep[le] != null) ? (e.ep[le].num) : (-1); - ((line2d)mEdges.elementAt (e.num)).vertexIndex[1] = (e.ep[re] != null) ? (e.ep[re].num) : (-1); - - if (!triangulate & plot) - clip_line (e); - } - - private void out_vertex (Site v) { - - mVertices.add (new point2d(v.coord.x, v.coord.y)); - } - - - // store output of a site - //private void out_site (Site s) {} - //private void out_triple (Site s1, Site s2, Site s3) {} - - private void plotinit() { - double dy = ymax - ymin;; - double dx = xmax - xmin; - double d = (dx > dy ? dx : dy) * 1.1; - - pxmin = xmin - (d-dx)/2.0; - pxmax = xmax + (d-dx)/2.0; - pymin = ymin - (d-dy)/2.0; - pymax = ymax + (d-dy)/2.0; - - cradius = (pxmax - pxmin)/350.0; - } - - // cut edges so that they are displayable - private void clip_line (Edge e) { - - Site s1, s2; - double x1, x2, y1, y2; - - if(e.a == 1.0 && e.b >= 0.0) { - s1 = e.ep[1]; - s2 = e.ep[0]; - } - else { - s1 = e.ep[0]; - s2 = e.ep[1]; - } - - if(e.a == 1.0) { - - y1 = pymin; - if (s1 != null && s1.coord.y > pymin) - y1 = s1.coord.y; - - if (y1 > pymax) - return; - - x1 = e.c - e.b * y1; - y2 = pymax; - - if (s2 != null && s2.coord.y < pymax) - y2 = s2.coord.y; - - if (y2 < pymin) - return; - - x2 = e.c - e.b * y2; - - if (((x1> pxmax) & (x2>pxmax)) | ((x1 < pxmin) & (x2 pxmax) { - x1 = pxmax; - y1 = (e.c - x1)/e.b; - } - - if (x1 < pxmin) { - x1 = pxmin; - y1 = (e.c - x1)/e.b; - } - - if (x2 > pxmax) { - x2 = pxmax; - y2 = (e.c - x2)/e.b; - } - - if (x2 < pxmin) { - x2 = pxmin; - y2 = (e.c - x2)/e.b; - } - } - else { - - x1 = pxmin; - if (s1 != null && s1.coord.x > pxmin) - x1 = s1.coord.x; - - if (x1 > pxmax) - return; - - y1 = e.c - e.a * x1; - x2 = pxmax; - - if (s2 != null && s2.coord.x < pxmax) - x2 = s2.coord.x; - - if (x2 < pxmin) - return; - - y2 = e.c - e.a * x2; - - if (((y1> pymax) & (y2>pymax)) | ((y1 pymax) { - y1 = pymax; - x1 = (e.c - y1)/e.a; - } - - if (y1 < pymin) { - y1 = pymin; - x1 = (e.c - y1)/e.a; - } - - if (y2 > pymax) { - y2 = pymax; - x2 = (e.c - y2)/e.a; - } - - if (y2 next.ystar || (he.ystar == next.ystar && v.coord.x > next.vertex.coord.x))) - last = next; - - he.PQnext = last.PQnext; - last.PQnext = he; - PQcount++; - } - - private void PQdelete (Halfedge he) { - Halfedge last; - - if(he.vertex != null) { - last = PQhash[PQbucket (he)]; - while (last.PQnext != he) - last = last.PQnext; - - last.PQnext = he.PQnext; - - PQcount--; - deref (he.vertex); - he.vertex = null; - } - } - - private int PQbucket (Halfedge he) { - - int bucket = (int)((he.ystar - ymin)/deltay * PQhashsize); - if (bucket < 0) - bucket = 0; - if (bucket >= PQhashsize) - bucket = PQhashsize-1; - if (bucket < PQmin) - PQmin = bucket; - return bucket; - } - - private boolean PQempty () { - return (PQcount == 0); - } - - private point2d PQ_min () { - - point2d answer = new point2d (); - - while (PQhash[PQmin].PQnext == null) - PQmin++; - - answer.x = PQhash[PQmin].PQnext.vertex.coord.x; - answer.y = PQhash[PQmin].PQnext.ystar; - - return answer; - } - - private Halfedge PQextractmin () { - Halfedge curr; - - curr = PQhash[PQmin].PQnext; - PQhash[PQmin].PQnext = curr.PQnext; - PQcount--; - return curr; - } - - private void PQinitialize () { - - PQcount = 0; - PQmin = 0; - PQhashsize = 4 * sqrt_nsites; - PQhash = new Halfedge[PQhashsize]; - - for (int i=0; i < PQhashsize; i++) { - PQhash[i] = new Halfedge (); - PQhash[i].PQnext = null; - } - } - - ////////////////////////////////////////////////////////////////////////// - // edgelist.c - // - private int ntry, totalsearch; - - // initialize edgelist - private void ELinitialize() { - - //freeinit (&hfl, sizeof (Halfedge)); - ELhashsize = 2 * sqrt_nsites; - ELhash = new Halfedge[ELhashsize]; - - for(int i=0; i < ELhashsize; i++) - ELhash[i] = null; - - ELleftend = HEcreate (null, 0); - ELrightend = HEcreate (null, 0); - - ELleftend.ELleft = null; - ELleftend.ELright = ELrightend; - - ELrightend.ELleft = ELleftend; - ELrightend.ELright = null; - - ELhash[0] = ELleftend; - ELhash[ELhashsize-1] = ELrightend; - } - - private Halfedge HEcreate (Edge e, int pm) { - - Halfedge he = new Halfedge (); - - he.ELedge = e; - he.ELpm = pm; - he.PQnext = null; - he.vertex = null; - he.ELref_count = 0; - he.ystar = 0; - - return he; - } - - //change arg2 to newH - private void ELinsert (Halfedge lb, Halfedge newH) { - newH.ELleft = lb; - newH.ELright = lb.ELright; - lb.ELright.ELleft = newH; - lb.ELright = newH; - } - - private Halfedge ELgethash (int b) { - - Halfedge he; - - if (b<0 || b>=ELhashsize) - return null; - - he = ELhash[b]; - if (he == null || he.ELedge != DELETED) - return he; - - /* Hash table points to deleted half edge. Patch as necessary. */ - ELhash[b] = null; - - //if ((he . ELrefcnt -= 1) == 0) makefree(he, &hfl); - return null; - } - - private Halfedge ELleftbnd (point2d p) { - - //System.err.println ("ELleftbnd processing ("+ p.x + ", " + p.y + ")"); - int i, bucket; - Halfedge he; - - /* Use hash table to get close to desired halfedge */ - bucket = (int)((p.x - xmin)/deltax * ELhashsize); - if (bucket < 0) - bucket = 0; - if (bucket >= ELhashsize) - bucket = ELhashsize - 1; - he = ELgethash (bucket); - - if (he == null) { - //System.err.println ("ELleftbnd: first he is null"); - for (i=1; true; i++) { - if ((he=ELgethash(bucket-i)) != null) - break; - if ((he=ELgethash(bucket+i)) != null) - break; - } - //totalsearch += i; - } - //System.err.println ("ELleftbnd: bucket: " + bucket + " hsize: " + ELhashsize + " he - elpm: " + he.ELpm + " ref_count: " + he.ELref_count + " ystar: " + he.ystar); - //ntry++; - - /* Now search linear list of halfedges for the correct one */ - if (he == ELleftend || (he != ELrightend && right_of (he, p))) { - //System.err.println ("ELleftbnd: loop1"); - do { - he = he.ELright; - } - while (he != ELrightend && right_of (he,p)); - - he = he.ELleft; - } - else { - do { - he = he.ELleft; - } - while (he != ELleftend && !right_of(he,p)); - } - - // Update hash table and reference counts - if (bucket > 0 && bucket < ELhashsize-1) { - if (ELhash[bucket] != null) - ELhash[bucket].ELref_count--; - ELhash[bucket] = he; - ELhash[bucket].ELref_count++; - } -/* - public int ELref_count; - public int ELpm; - public Site vertex; - public double ystar; - public Halfedge PQnext; -*/ - //System.err.println ("ELleftbnd: elpm: " + he.ELpm + " ref_count: " + he.ELref_count + " ystar: " + he.ystar); - return he; - } - - private void ELdelete (Halfedge he) { - he.ELleft.ELright = he.ELright; - he.ELright.ELleft = he.ELleft; - he.ELedge = DELETED; - } - - private Halfedge ELright (Halfedge he) { - return (he.ELright); - } - - private Halfedge ELleft (Halfedge he) { - return (he.ELleft); - } - - private Site leftreg (Halfedge he) { - if (he.ELedge == null) - return bottomsite; - return (he.ELpm == le ? he.ELedge.reg[le] : he.ELedge.reg[re]); - } - - private Site rightreg (Halfedge he) { - if (he.ELedge == null) { - //System.err.println ("rightreg..returning bottomesite"); - return bottomsite; - } - //System.err.println ("rightreg..returning other"); - return (he.ELpm == le ? he.ELedge.reg[re] : he.ELedge.reg[le]); - } - - ////////////////////////////////////////////////////////////////////////// - // voronoi.c - // - private void voronoi (boolean triangulate) { - - Site newsite, bot, top, temp, p; - Site v; - - point2d newintstar = new point2d(); // perhaps no need to allocate? - int pm; - - Halfedge lbnd, rbnd, llbnd, rrbnd, bisector; - Edge e; - - PQinitialize (); - bottomsite = nextone (); - //out_site (bottomsite); - ELinitialize(); - - newsite = nextone (); - - while (true) { - - if(!PQempty ()) - newintstar = PQ_min(); - - if (newsite != null && - (PQempty() || newsite.coord.compareTo (newintstar) < 0)) { - - // new site is smallest - //out_site(newsite); - //System.err.println ("new site is smallest"); - - lbnd = ELleftbnd (newsite.coord); - rbnd = ELright (lbnd); - bot = rightreg (lbnd); - - e = bisect (bot, newsite); - bisector = HEcreate (e, le); - - ELinsert (lbnd, bisector); - - if ((p = intersect (lbnd, bisector, null)) != null) { - PQdelete (lbnd); - PQinsert (lbnd, p, p.dist (newsite)); - } - - lbnd = bisector; - bisector = HEcreate (e, re); - ELinsert (lbnd, bisector); - - if ((p = intersect (bisector, rbnd, null)) != null) - PQinsert (bisector, p, p.dist (newsite)); - - newsite = nextone(); - } - - // intersection is smallest - else if (!PQempty ()) { - - lbnd = PQextractmin(); - llbnd = ELleft (lbnd); - rbnd = ELright (lbnd); - rrbnd = ELright (rbnd); - bot = leftreg (lbnd); - top = rightreg (rbnd); - //out_triple (bot, top, rightreg (lbnd)); - v = lbnd.vertex; - - makevertex (v); - - endpoint (lbnd.ELedge, lbnd.ELpm, v); - endpoint (rbnd.ELedge, rbnd.ELpm, v); - - ELdelete (lbnd); - PQdelete (rbnd); - ELdelete (rbnd); - - pm = le; - - if (bot.coord.y > top.coord.y) { - temp = bot; - bot = top; - top = temp; - pm = re; - } - - e = bisect (bot, top); - bisector = HEcreate (e, pm); - ELinsert (llbnd, bisector); - endpoint (e, re-pm, v); - deref (v); - - if ((p = intersect (llbnd, bisector, null)) != null) { - PQdelete (llbnd); - PQinsert (llbnd, p, p.dist (bot)); - } - - if ((p = intersect(bisector, rrbnd, null)) != null) - PQinsert (bisector, p, p.dist (bot)); - } - else - break; - - } // end while (true) - - // print out the edges (here we store them in 'mEdges') - for (lbnd = ELright(ELleftend); lbnd != ELrightend; lbnd = ELright(lbnd)) { - e = lbnd.ELedge; - out_ep (e); - } - - } // end voronoi() - -} // end of SFVoronoi diff --git a/VAST.js b/VAST.js deleted file mode 100644 index 21d5fcd9..00000000 Binary files a/VAST.js and /dev/null differ diff --git a/VON_peer.js b/VON_peer.js deleted file mode 100644 index 060b22ef..00000000 --- a/VON_peer.js +++ /dev/null @@ -1,1355 +0,0 @@ - -/* - * VAST, a scalable peer-to-peer network for virtual environments - * Copyright (C) 2005-2011 Shun-Yun Hu (syhu@ieee.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/* - VON_peer.js - - The basic interface for a basic VON peer - supporting distributed neighbor discovery and management - - supported functions: - - // basic callback / structure - addr = {host, port}; - center = {x, y}; - aoi = {center, radius}; - endpt = {id, addr, last_accessed}; - node = {id, endpt, aoi, time}; - pack = {type, msg, group, priority, targets} // message package during delivery - vast_net (see definition in vast_net.js) - - // constructor - VON_peer(id, port, aoi_buffer, aoi_use_strict) - - // basic functions - join(addr, aoi, done_CB) join a VON network with a given gateway (entry) - leave() leave the VON network - move(aoi, send_time) move the AOI to a new position (or change radius) - list(); get a list of AOI neighbors - send(id, msg); send a message to a given node - - // accessors - isJoined(); check if we've joined the VON network - isNeighbor(id); check if a given ID is an existing neighbor - getVoronoi(); get a reference to the Voronoi object - getNeighbor(id); get a particular neighbor's info given its ID - getSelf(); get self info - getEdges(); get a list of edges known to the current node - - history: - 2012-07-07 initial version (from VAST.h) -*/ - -require('./common.js'); -var Voronoi = require('./vast_voro.js'); - -// config -var VON_DEFAULT_PORT = 37; // by default which port does the node listen -var AOI_DETECTION_BUFFER = 32; // detection buffer around AOI -var MAX_TIMELY_PERIOD = 10; // # of seconds considered to be still active -var MAX_DROP_SECONDS = 2; // # of seconds to disconnect a non-overlapped neighbor -var NONOVERLAP_MULTIPLIER = 1.25; // multiplier for aoi buffer for determining non-overlap -var TICK_INTERVAL = 100; // interval (in milliseconds) to perform tick tasks - -// flags -var OVERLAP_CHECK_ACCURATE = false; // whether VON overlap checks are accurate - -// enumation of VON message -// TODO: combine DISCONNECT & BYE? -var VON_Message = { - VON_DISCONNECT: 0, // VON's disconnect - VON_QUERY: 1, // VON's query, to find an acceptor that can take in a joining node - VON_NODE: 2, // VON's notification of new nodes - VON_HELLO: 3, // VON's hello, to let a newly learned node to be mutually aware - VON_HELLO_R: 4, // VON's hello response - VON_EN: 5, // VON's enclosing neighbor inquiry (to see if my knowledge of EN is complete) - VON_MOVE: 6, // VON's move, to notify AOI neighbors of new/current position - VON_MOVE_F: 7, // VON's move, full notification on AOI - VON_MOVE_B: 8, // VON's move for boundary neighbors - VON_MOVE_FB: 9, // VON's move for boundary neighbors with full notification on AOI - VON_BYE: 10 // VON's disconnecting a remote node -}; - -var VON_Message_String = [ - 'VON_DISCONNECT', - 'VON_QUERY', - 'VON_NODE', - 'VON_HELLO', - 'VON_HELLO_R', - 'VON_EN', - 'VON_MOVE', - 'VON_MOVE_F', - 'VON_MOVE_B', - 'VON_MOVE_FB', - 'VON_BYE' -]; - -var VON_Priority = { - HIGHEST: 0, - HIGH: 1, - NORMAL: 2, - LOW: 3, - LOWEST: 4 -}; - -var NodeState = { - ABSENT: 0, - QUERYING: 1, // finding / determing certain thing - JOINING: 2, // different stages of join - JOINING_2: 3, - JOINING_3: 4, - JOINED: 5, -}; - -// status on known nodes in the neighbor list, can be either just inserted / deleted / updated -var NeighborUpdateStatus = { - INSERTED: 1, - DELETED: 2, - UNCHANGED: 3, - UPDATED: 4 -}; - -// states for an enclosing neighbor -var NeighborState = { - NEIGHBOR_REGULAR: 0, - NEIGHBOR_OVERLAPPED: 1, - NEIGHBOR_ENCLOSED: 2 -}; - - -// definition of a VON peer -exports.peer = function (l_self_id, l_port, l_aoi_buffer, l_aoi_use_strict) { - - ///////////////////// - // public methods - // - - // callback to use once join is successful - var _join_done_CB = undefined; - - // interval id for removing periodic ticking - var _interval_id = undefined; - - // join a VON network with a given gateway (entry) - var _join = this.join = function (GW_addr, aoi, done_CB) { - - // check if already joined - if (_state === NodeState.JOINED) { - LOG.warn('VON_peer.join(): node already joined'); - if (done_CB !== undefined) - done_CB(_self.id); - return; - } - - // ensure function input conforms to internal data structure - var addr = new VAST.addr(); - addr.parse(GW_addr); - LOG.debug('VON_peer join() called, joining: ' + addr.toString()); - - // change internal state - _state = NodeState.JOINING; - - // keep reference to call future once join is completed - _join_done_CB = done_CB; - - // set self AOI - _self.aoi.update(aoi); - - // create self object - _net.getHost(function (local_IP) { - - LOG.debug('local IP: ' + local_IP); - - // update address info for self - _self.endpt = new VAST.endpt(local_IP, l_port); - - // return value is actual port binded - _net.listen(l_port, function (actual_port) { - // update port of self if different from the one attempting to bind - if (actual_port != l_port) - _self.endpt.addr.port = actual_port; - - // store self node to neighbor map - _insertNode(_self); - - // if I'm gateway, no further action required - // TODO: doesn't look clean, can gateway still send query request to itself? - // that'll be a more general process - // (however, will deal with how to determined 'already joined' for gateway) - if (_self.id === VAST_ID_GATEWAY) - return _setJoined(); - - // send out join request - // TODO: if id is not correct, remote host will send back correct one - _net.storeMapping(VAST_ID_GATEWAY, GW_addr); - _sendMessage(VAST_ID_GATEWAY, VON_Message.VON_QUERY, _self, VON_Priority.HIGHEST); - - }); - }); - } - - // leave the VON network - var _leave = this.leave = function () { - - LOG.debug('VON_peer leave() called, neighbor size: ' + Object.keys(_neighbors).length); - - // always notify neighbors - var notify_neighbors = true; - - // see if we need to explicityly notify neighbors of our leave - if (notify_neighbors) { - - var targets = []; - for (var id in _neighbors) { - if (_isSelf(id) === false) - targets.push(id); - } - - _sendBye(targets); - - // TODO: notify potential_neighbors - } - - // clean data structure - _initStates(); - - // remove ticking interval - // TODO: remove js-specific code or collect them - if (_interval_id !== undefined) { - clearInterval(_interval_id); - _interval_id = undefined; - } - } - - // move the AOI to a new position (or change radius) - var _move = this.move = function (aoi, sendtime) { - LOG.debug('VON_Peer moving to: ' + aoi.center.toString()); - - try { - if (typeof aoi.radius === 'string') - aoi.radius = parseInt(aoi.radius); - else if (typeof aoi.radius !== 'number') { - LOG.error('radius format incorrect, ignore move request'); - return _self.aoi; - } - } - catch (e) { - LOG.error('parsing radius error: ' + e); - return _self.aoi; - } - - _self.aoi.center = aoi.center; - - // check if AOI radius has changed (besides position) - var aoi_reshaped = (aoi.hasOwnProperty('radius') && _self.aoi.radius !== aoi.radius); - if (aoi_reshaped) - LOG.warn('AOI radius updated to: ' + aoi.radius); - - _self.aoi.update(aoi); - - // TODO: check if my new position overlaps a neighbor, if so then move slightly - // avoid moving to the same position as my neighbor - //_self.aoi.center = _isOverlapped (_self.aoi.center); - - // record send time of the movement - // this is to help receiver determine which position update should be used - // also to help calculate latency - // if external time is supplied (we respect the sender's time), then record it - _self.time = (sendtime != undefined ? sendtime : UTIL.getTimestamp()); - _updateNode(_self); - - // notify all connected neighbors, pack my own node info & AOI info - - // if AOI radius has changed, send full self info - // otherwise just send new center for AOI - // NOTE: we make a copy for this, so any modifications required won't affect original - var node_info = _getNode(_self.id); - - // remove info not needed by VON_MOVE - delete node_info['endpt']; - - if (aoi_reshaped === false) - delete node_info.aoi['radius']; - - // go over each neighbor and do a boundary neighbor check - var boundary_list = []; - var regular_list = []; - - for (var id in _neighbors) { - - if (_isSelf(id)) - continue; - // save boundary neighbors for later - if (_voro.is_boundary (id, _self.aoi.center, _self.aoi.radius)) - boundary_list.push(id); - else - regular_list.push(id); - } - - // create a delivery package to send - // NOTE: For now we send move reliably, but can experiment with unreliable delivery - var pack = new VAST.pack( - VON_Message.VON_MOVE, - node_info, - VON_Priority.HIGHEST); - - // send to regular neighbors - pack.targets = regular_list; - pack.type = (aoi_reshaped ? VON_Message.VON_MOVE_F : VON_Message.VON_MOVE); - _sendPack(pack, true); - - // send MOVE to boundary neighbors - pack.targets = boundary_list; - pack.type = (aoi_reshaped ? VON_Message.VON_MOVE_FB : VON_Message.VON_MOVE_B); - _sendPack(pack, true); - - return _self.aoi; - } - - // get a list of AOI neighbors - this.list = function () { - return _neighbors; - } - - // send a message to a given node - var _send = this.send = function (id, msg) { - - } - - ///////////////////// - // public accessors - // - - // check if we've joined the VON network - var _isJoined = this.isJoined = function () { - return (_state === NodeState.JOINED); - } - - // check if a given ID is an existing neighbor - var _isNeighbor = this.isNeighbor = function (id) { - // list all neighbors - //for (var key in _neighbors) - // LOG.debug('isNeighbor: ' + _neighbors[key].id); - - return _neighbors.hasOwnProperty(id); - } - - // get a reference to the Voronoi object - this.getVoronoi = function () { - return _voro; - } - - // get a particular neighbor's info given its ID - this.getNeighbor = function (id) { - return (_neighbors.hasOwnProperty(id) ? _neighbors[id] : undefined); - } - - // get self info - this.getSelf = function () { - return _self; - } - - // get a list of edges known to the current node - this.getEdges = function () { - return _voro.getedges(); - } - - ///////////////////// - // internal methods - // - - // - // check helpers - // - - var _isSelf = function (id) { - //LOG.debug(typeof _self.id + ' self.id: ' + _self.id + ' ' + typeof id + ' id: ' + id); - return (_self.id == id); - } - - // is a particular neighbor within AOI - // NOTE: right now we only consider circular AOI, not rectangular AOI.. - // NOTE: l_aoi_buffer is a paramter passed to VON_peer when creating instance - var _isAOINeighbor = function (id, neighbor) { - //LOG.debug('_isAOINeighbor called'); - return _voro.overlaps(id, neighbor.aoi.center, neighbor.aoi.radius + l_aoi_buffer, OVERLAP_CHECK_ACCURATE); - } - - // whether a neighbor is either 1) AOI neighbor or 2) an enclosing neighbor - // NOTE: enclosing neighbor is checked mutually, as it's possible - // for A to not consider B as enclosing neighbor, but B sees A as enclosing neighbor - var _isRelevantNeighbor = function (node1, node2) { - - return (_voro.is_enclosing(node1.id, node2.id) || - _isAOINeighbor(node1.id, node2) || - _isAOINeighbor(node2.id, node1)); - } - - // whether a neighbor has stayed alive with regular updates - // input period is in number of seconds - var _isTimelyNeighbor = function (id, period) { - return true; -/* - if (_isNeighbor (id) == false) - return false; - - var timeout = period * _net.getTimestampPerSecond (); - return ((_tick_count - _neighbors[id].endpt.lastAccessed) < timeout); -*/ - //return true; - } - - // - // node management - // - - var _insertNode = function (node) { - - //LOG.debug('insertNode [' + node.id + '] isNeighbor: ' + _isNeighbor(node.id)); - - // check for redundency - if (_isNeighbor(node.id)) - return false; - - // notify network layer about connection info, no need to actually connect for now - _net.storeMapping (node.id, node.endpt.addr); - - // update last access time - node.endpt.lastAccessed = UTIL.getTimestamp(); - //LOG.debug('last accessed: ' + node.endpt.lastAccessed); - - // store the new node to - _voro.insert (node.id, node.aoi.center); - - // store to neighbors - _neighbors[node.id] = node; - - // init mapping of neighbor's states - _neighbor_states[node.id] = {}; - - // TODO: still needed? - // record time to determine a neighbor is no longer active and can disconnect - _time_drop[node.id] = 0; - - // update node status - _updateStatus[node.id] = NeighborUpdateStatus.INSERTED; - - LOG.debug('insertNode neighbor (after insert) size: ' + Object.keys(_neighbors).length + ' voro: ' + _voro.size()); - - return true; - } - - var _deleteNode = function (id) { - - // NOTE: it's possible to remove self or EN, use carefully. - // we don't check for that to allow force-remove in - // the case of disconnection by remote node, or - // when leaving the overlay (removal of self) - if (_isNeighbor(id) === false) - return false; - - // remove from Voronoi & neighbor list - _voro.remove (id); - delete _neighbors[id]; - - // clean neighbor states - _neighbor_states[id] = undefined; - delete _neighbor_states[id]; - - delete _time_drop[id]; - _updateStatus[id] = NeighborUpdateStatus.DELETED; - - return true; - } - - var _updateNode = function (node) { - - if (_isNeighbor (node.id) === false) - return false; - - // only update the node if it's at a later time - if (node.time < _neighbors[node.id].time) - return false; - - _voro.update (node.id, node.aoi.center); - _neighbors[node.id].update (node); - - // NOTE: should not reset drop counter here, as it might make irrelevant neighbor - // difficult to get disconnected - //_time_drop[node.id] = 0; - - // update last access time of this node - node.endpt.lastAccessed = UTIL.getTimestamp (); - - // set flag so that updated nodes' states are also sent - // instead of sending only updates for newly inserted node - if (_updateStatus.hasOwnProperty(node.id) === false || _updateStatus[node.id] !== NeighborUpdateStatus.INSERTED) - _updateStatus[node.id] = NeighborUpdateStatus.UPDATED; - - return true; - } - - // get a clean node to send (no extra stuff in 'node.aoi.center') - // TODO: remove this? - // do not keep anything else besides the original attributes - var _getNode = function (id) { - var node = new VAST.node(); - node.parse(_neighbors[id]); - var center = new VAST.pos(); - center.parse(node.aoi.center); - node.aoi.center = center; - //delete node.aoi.center['id']; - //delete node.aoi.center['voronoiId']; - return node; - } - - - // - // regular processing (done periodically) - // - - // the master function for all things regular - var _tick = function () { - - //_sendKeepAlive(); - _contactNewNeighbors(); - _checkNeighborDiscovery(); - _removeNonOverlapped(); - } - - // set current node to be 'joined' - var _setJoined = function () { - - _state = NodeState.JOINED; - - // notify callback - if (_join_done_CB !== undefined) - _join_done_CB(_self.id); - - // start ticking - _interval_id = setInterval(_tick, TICK_INTERVAL); - } - - var _sendKeepAlive = function () { - - // simply move a little to indicate keepalive - if (_isJoined() && _isTimelyNeighbor (_self.id, MAX_TIMELY_PERIOD/2) == false) { - LOG.debug('[' + _self.id + '] sendKeepAlive ()', _self.id); - move (_self.aoi); - } - } - - var _contactNewNeighbors = function () { - - // check if any new neighbors to contact - if (Object.keys(_new_neighbors).length === 0) - return; - - // - // new neighbor notification check - // - var new_list = []; // list of new, unknown nodes - var target; - - LOG.debug('voro nodes before insertion: ' + _voro.size()); - - // loop through each notified neighbor and see if it's unknown - for (var target in _new_neighbors) { - - // NOTE: be careful that 'target' is now of type 'string', not 'number' - var new_node = _new_neighbors[target]; - - // ignore self - if (_isSelf(new_node.id)) - continue; - - // update existing info if the node is known, otherwise prepare to add - if (_isNeighbor(new_node.id)) - _updateNode(new_node); - else { - // insert to Voronoi first to see if this addition indeed is relevant to us - _voro.insert(new_node.id, new_node.aoi.center); - new_list.push(new_node.id); - } - } - - LOG.debug('voro nodes after insertion: ' + _voro.size()); - - // check through each newly inserted Voronoi for relevance - for (var i=0; i < new_list.length; ++i) { - - target = new_list[i]; - var node = _new_neighbors[target]; - - // if the neighbor is relevant and we insert it successfully - // NOTE that we're more tolerant for AOI buffer when accepting notification - if (_isRelevantNeighbor (node, _self)) { - - LOG.debug('[' + node.id + '] is relevant to self [' + _self.id + ']'); - - // store new node as a potential neighbor, pending confirmation from the new node - // this is to ensure that a newly discovered neighbor is indeed relevant - _potential_neighbors[target] = node; - - // notify mapping for sending Hello message - // TODO: a cleaner way (less notifymapping call?) - _net.storeMapping(node.id, node.endpt.addr); - - // send HELLO message to newly discovered nodes - // NOTE that we do not perform insert yet (until the remote node has confirmed via MOVE) - // this is to avoid outdated neighbor discovery notice from taking effect - //LOG.debug('before calling get_en, target: ' + target + ' node.id: ' + node.id); - //LOG.debug('voro nodes before get_en: ' + _voro.size()); - - // NOTE: even if en_list is empty, should still send out HELLO - // empty can occur if initially just two nodes with overlapped positions - _sendHello(target); - _sendEN(target); - } - } - - // clear up the temporarily inserted test node from Voronoi (if not becoming neighbor) - for (var i=0; i < new_list.length; ++i) - _voro.remove(new_list[i]); - - // NOTE: erase new neighbors seems to bring better consistency - // (rather than keep to next round, as in previous version) - _new_neighbors = {}; - - // TODO: _potential_neighbors should be cleared once in a while - - LOG.debug('total neighbors (after process neighbors): ' + Object.keys(_neighbors).length); - LOG.debug('total voro nodes: ' + _voro.size() + '\n'); - } - - var _checkNeighborDiscovery = function (check_requester_only, check_en_only) { - - var req_size = Object.keys(_req_nodes).length; - if (req_size === 0) - return; - - //LOG.debug(req_size + ' neighbors need neighbor discovery check'); - - // by default we check only those requested - if (check_requester_only === undefined) - check_requester_only = true; - - // by default all neighbors are potential candiates to notify - if (check_en_only === undefined) - check_en_only = false; - - var requesters = {}; - - // re-build request list if we need to check all neighbors (instead of those sending MOVE_B or MOVE_FB) - if (check_requester_only === true) - requesters = _req_nodes; - else - requesters = _neighbors; - - // build a list of nodes to be checked (can be either my enclosing neighbors, or all my neighbors) - var check_list; - if (check_en_only) - check_list = _voro.get_en(_self.id); - else { - check_list = []; - for (var id in _neighbors) - check_list.push(id); - } - - // list of new neighbors to notify a node requesting neighbor discovery - var notify_list; - - // go over each requesting node - for (var from_id in requesters) { - - // a node requesting for check might be disconnected by now, as requests are processed in batch - // TODO: is it correct? as this is event-driven now, maybe neighbor list can always be assumed to be correct - if (_isSelf(from_id) || _isNeighbor(from_id) === false) - continue; - - // TODO: determine whether clear or new is better / faster (?) - notify_list = []; - - /* - map *known_list = new map; // current neighbor states - map::iterator it; // iterator for neighbor states - - id_t id; - int state, known_state; - */ - var known_list = {}; // current neighbor's states - var state, known_state; - - for (var i=0; i < check_list.length; i++) { - - var id = check_list[i]; - - // avoid checking myself or the requester - if (_isSelf(id) || id === from_id) - continue; - - // TODO: - // do a simple test to see if this enclosing neighbor is - // on the right side of me if I face the moving node directly - // only notify the moving node for these 'right-hand-side' neighbors - - //if (right_of (id, from_id) == false) - // continue; - - // TODO: need to check whether values of states are correct - state = NeighborState.NEIGHBOR_REGULAR; - known_state = NeighborState.NEIGHBOR_REGULAR; - - if (_isAOINeighbor(id, _neighbors[from_id])) - state = state | NeighborState.NEIGHBOR_OVERLAPPED; - if (_voro.is_enclosing(id, from_id)) - state = state | NeighborState.NEIGHBOR_ENCLOSED; - - // notify case1: new overlap by moving node's AOI - // notify case2: new EN for the moving node - if (state != NeighborState.NEIGHBOR_REGULAR) { - - // TODO: check known_state correctness - if (_neighbor_states[from_id].hasOwnProperty(id)) - known_state = _neighbor_states[from_id][id]; - - // note: what we want to achieve is: - // 1. notify just once when new enclosing neighbor (EN) is found - // 2. notify about new overlap, even if the node is known to be an EN - - // check if the neighbors not overlapped previously is - // 1) currently overlapped, or... - // 2) previously wasn't enclosing, but now is - - if ((known_state & NeighborState.NEIGHBOR_OVERLAPPED) == 0 && - ((state & NeighborState.NEIGHBOR_OVERLAPPED) > 0 || - ((known_state & NeighborState.NEIGHBOR_ENCLOSED) == 0 && (state & NeighborState.NEIGHBOR_ENCLOSED) > 0))) - notify_list.push(id); - - // store the state of this particular neighbor - known_list[id] = state; - } - } - - // update known states about neighbors - delete _neighbor_states[from_id]; - _neighbor_states[from_id] = known_list; - - // notify only moving nodes of new neighbors - // NOTE: we still update neighbor states for all known neighbors - if (_req_nodes.hasOwnProperty(from_id) && notify_list.length > 0) - _sendNodes(from_id, notify_list); - } - - _req_nodes = {}; - } - - // check consistency of enclosing neighbors - var _checkConsistency = function (skip_id) { - - // NOTE: must make a copy of the enclosing neighbors, as sendEN will also call get_en () - // (still appliable in js?) - var en_list = _voro.get_en(_self.id); - - // notify my enclosing neighbors to check for discovery - for (var i=0; i < en_list.length; i++) { - var target = en_list[i]; - if (target != skip_id) - _sendEN (target); - } - } - - // remove neighbors no longer in view - var _removeNonOverlapped = function () { - - //vector delete_list; - var delete_list = []; - - var now = UTIL.getTimestamp (); - - // wait time in milliseconds - var grace_period = now + (MAX_DROP_SECONDS * 1000); - - // go over each neighbor and do an overlap check - //for (map::iterator it = _id2node.begin(); it != _id2node.end(); ++it) - for (var id in _neighbors) { - - // check if a neighbor is relevant (within AOI or enclosing) - // or if the neighbor still covers me - // NOTE: the AOI_BUFFER here should be slightly larger than that used for - // neighbor discovery, this is so that if a node is recently disconnect - // here, other neighbors can re-notify should it comes closer again - // TODO: possible to avoid checking every time, simply record some - // flag when messages come in, then check whether connection's still active? - // or.. simply use network timeout (if available)? - if (_isSelf(id) || - (_isRelevantNeighbor(_self, _neighbors[id], l_aoi_buffer * NONOVERLAP_MULTIPLIER)) && - _isTimelyNeighbor(id)) { - _time_drop[id] = grace_period; - continue; - } - - // if current time exceeds grace period, then prepare to delete - if (now >= _time_drop[id]) { - delete_list.push(id); - delete _time_drop[id]; - } - } - - // send BYE message to disconnected node - return _sendBye(delete_list); - } - - // - // send helpers - // - - // send a javascript object to a SINGLE target node (given message 'type' and 'priority') - var _sendMessage = function (target, msg_type, js_obj, priority, is_reliable) { - - // create a delivery package to send - var pack = new VAST.pack( - msg_type, - js_obj, - priority); - - pack.targets.push(target); - - // convert pack to JSON or binary string - return _sendPack(pack, is_reliable); - } - - // send a pack object to its destinated targets - // TODO: this previously exist at the network layer, should move it there? - var _sendPack = function (pack, is_reliable) { - - // serialize string - var encode_str = JSON.stringify(pack); - - // go through each target and send - // TODO: optimize so only one message is sent to each physical host target - for (var i=0; i < pack.targets.length; i++) - _net.send(pack.targets[i], encode_str, is_reliable); - } - - // send node infos (NODE message) to a particular target - // target: destination node id - // list: a list of neighbor id to be sent - // reliable: whether to deliver reliably - var _sendNodes = function (target, list, reliable) { - - LOG.debug('_sendNodes: [' + _self.id + '] sends to [' + target + '] ' + list.length + ' nodes'); - - // we warn but do not prevent send (this is needed when gateway joins itself as client) - if (list.length === 0) { - LOG.warn('sendNodes send out a list of 0 neighbors'); - } - - // grab the node info - var nodes = []; - for (var i=0; i < list.length; i++) - nodes.push(_getNode(list[i])); - - _sendMessage(target, VON_Message.VON_NODE, nodes, VON_Priority.NORMAL, reliable); - } - - // send a list of IDs to a particular node - // target: destination node id - // list: a list of id to be sent - var _sendHello = function (target) { - - LOG.debug('sendHello target: ' + target); - - // prepare HELLO message - // TODO: do not create new HELLO message every time? (local-side optimization) - _sendMessage(target, VON_Message.VON_HELLO, _getNode(_self.id), VON_Priority.HIGHEST, true); - } - - // send a particular node its perceived enclosing neighbors - var _sendEN = function (target) { - - var id_list = _voro.get_en(target); - if (id_list.length > 0) - _sendMessage(target, VON_Message.VON_EN, id_list, VON_Priority.HIGH, true); - } - - var _sendBye = function (targets) { - - var num_deleted = 0; - - if (targets.length > 0) { - - LOG.debug('sendBye target size: ' + targets.length); - - var pack = new VAST.pack(VON_Message.VON_BYE, {}, VON_Priority.HIGHEST); - pack.targets = targets; - _sendPack(pack, true); - - // perform node removal - for (var i=0; i < targets.length; i++) { - LOG.debug('removing node: ' + targets[i]); - if (_deleteNode(targets[i]) === true) - num_deleted++; - } - } - - return num_deleted; - } - - // - // handlers for incoming messages, connect/disconnect - // - - // handler for incoming messages - var _msgHandler = function (from_id, msg) { - - LOG.debug('[' + _self.id + '] handles msg from [' + from_id + '] msg: ' + msg); - - // prevent processing invalid msg - // NOTE: we allow for empty message (?) such as VON_DISCONNECT - if (msg == '' || msg === null || msg === undefined) { - LOG.error('[' + _self.id + '] msgHandler got invalid msg, skip processing'); - return; - } - - var pack; - try { - // convert msg back to js_obj - pack = JSON.parse(msg); - } - catch (e) { - LOG.error('convert to js_obj fail: ' + e + ' msg: ' + msg); - return; - } - - LOG.debug('[' + _self.id + '] ' + VON_Message_String[pack.type] + ' from [' + from_id + '], neighbor size: ' + Object.keys(_neighbors).length); - - // if join is not even initiated, do not process any message - if (_state == NodeState.ABSENT) { - LOG.error('node not yet join, should not process any messages'); - return; - } - - switch (pack.type) { - - // VON's query, to find an acceptor that can take in a joining node - case VON_Message.VON_QUERY: { - - // update the joiner's id (if it's a newly joined node) - if (pack.msg.id === VAST_ID_UNASSIGNED) - pack.msg.id = from_id; - - // extract message - var joiner = new VAST.node(); - joiner.parse(pack.msg); - LOG.debug('joiner: ' + joiner.toString()); - - // TODO: verify message in a systematic way - if (joiner.endpt.addr.isEmpty()) { - LOG.error('joiner has no valid IP/port address, ignore request'); - break; - } - - // find the node closest to the joiner - var closest = _voro.closest_to (joiner.aoi.center); - - // if this is gateway receiving its own request - if (closest === VAST_ID_UNASSIGNED && Object.keys(_neighbors).length === 1) { - LOG.warn('gateway getting its own VON_QUERY, return empty list'); - _sendNodes (from_id, [], true); - break; - } - - LOG.debug('closest node: ' + closest + ' (' + typeof closest + ')'); - - // forward the request if a more appropriate node exists - // TODO: contains() might recompute Voronoi, isRelevantNeighbor below - // also will recompute Voronoi. possible to combine into one calculation? - if (_voro.contains (_self.id, joiner.aoi.center) === false && - _isSelf (closest) === false && - closest != from_id) { - - LOG.warn('forward VON_QUERY request to: ' + closest); - - // re-assign target for the query request - pack.targets = []; - pack.targets.push(closest); - _sendPack(pack); - } - else { - - // insert first so we can properly find joiner's EN - _insertNode (joiner); - - // I am the acceptor, send back initial neighbor list - var list = []; - - // loop through all my known neighbors and check which are relevant to the joiner to know - var out_str = ''; - for (var id in _neighbors) { - - var neighbor = _neighbors[id]; - //LOG.debug('checking if neighbor [' + neighbor.id + '] should be notified'); - // store only if neighbor is both relevant and timely - // TODO: more efficient check (EN of joiner is calculated multiple times now) - - var is_relevant = _isRelevantNeighbor(neighbor, joiner); - //LOG.debug('is relevant: ' + is_relevant); - if (neighbor.id != joiner.id && - is_relevant && - _isTimelyNeighbor(neighbor.id)) { - list.push(neighbor.id); - out_str += neighbor.id + ' '; - } - } - - LOG.debug('notify ' + list.length + ' nodes to joiner: ' + out_str); - if (list.length <= 1) { - LOG.warn('too few neighbors are notified! check correctness\n'); - LOG.debug(_voro.to_string()); - } - - // send a list of nodes to a specific target node - _sendNodes (joiner.id, list, true); - } - } - break; - - // process notifications for new nodes - case VON_Message.VON_NODE: { - - // if VON_NODE is received, we're considered joined - // NOTE: do this first as we need to update our self ID for later VON_NODE process to work - if (_state === NodeState.JOINING) { - - // check if we're getting new ID - // TODO: is this clean? consider use VON_HELLO first when contacting new node/neighbor? - var selfID = _net.getID(); - LOG.debug('selfID, prev: ' + _self.id + ' new: ' + selfID); - - // update self - // NOTE: we don't use _updateNode as it requires the same node id - _deleteNode(_self.id); - _self.id = selfID; - _insertNode(_self); - - _setJoined(); - } - - var nodelist = pack.msg; - - for (var i=0; i < nodelist.length; i++) { - - // extract message - var new_node = new VAST.node(); - new_node.parse(nodelist[i]); - - LOG.debug('node ' + new_node.toString()); - - _stat[pack.type].total++; - - // check data validity - /* - if (new_node.endpt.addr.isEmpty()) { - LOG.error('new node has no valid IP/port address, ignore info'); - continue; - } - */ - - // store the new node and process later - // if there's existing notification, then replace only if newer - if (_new_neighbors.hasOwnProperty(new_node.id) === false || - _new_neighbors[new_node.id].time <= new_node.time) { - - LOG.debug('adding node id [' + new_node.id + '] type: ' + typeof new_node.id); - - _stat[pack.type].normal++; - _new_neighbors[new_node.id] = new_node; - } - } // end going through node list - - // process new neighbors - // NOTE: do this collectively during tick - //_contactNewNeighbors(); - - } - break; - - // VON's hello, to let a newly learned node to be mutually aware - case VON_Message.VON_HELLO: { - - var node = new VAST.node(); - node.parse(pack.msg); - LOG.debug('node: ' + node.toString()); - - // update existing or new neighbor status - if (_isNeighbor (from_id)) - _updateNode(node); - else - _insertNode(node); - - // send HELLO_R as response (my own position, reliably) - var pos = new VAST.pos(); - pos.parse(_self.aoi.center); - _sendMessage(from_id, VON_Message.VON_HELLO_R, pos, VON_Priority.HIGH, true); - - // check if enclosing neighbors need any update - _checkConsistency (from_id); - } - break; - - // VON's hello response - case VON_Message.VON_HELLO_R: { - - // check if it's a response from new neighbor - if (_potential_neighbors.hasOwnProperty(from_id) === true) { - - // insert the new node as a confirmed neighbor with updated position - //var pos = new VAST.pos(); - //pos.parse(pack.msg); - var neighbor = _potential_neighbors[from_id]; - neighbor.aoi.center.parse(pack.msg); - - LOG.debug('got latest pos: ' + neighbor.aoi.center.toString() + ' id: ' + from_id); - _insertNode (neighbor); - - delete _potential_neighbors[from_id]; - } - } - break; - - // VON's enclosing neighbor inquiry (to see if knowledge of EN is complete) - case VON_Message.VON_EN: { - - // - // check my enclosing neighbors to notify moving node any missing neighbors - // - - // check if the neighbor still exists - // (it's possible the neighbor will depart before VON_EN is processed) - // TODO: cleaner way to check? - if (_neighbors.hasOwnProperty(from_id) === false) { - LOG.debug('neighbor [' + from_id + '] is no longer connected, ignore VON_EN request'); - break; - } - - // extract list of EN id received & create searchable list of EN - var id_list = pack.msg; - LOG.debug('recv en_list size: ' + id_list.length); - - var list = {}; - for (var i=0; i < id_list.length; i++) { - var id = id_list[i]; - //LOG.debug('en: ' + id); - list[id] = NeighborState.NEIGHBOR_OVERLAPPED; - } - - // enclosing neighbors missing from remote node's knowledge - var missing = []; - - // my view of my current enclosing neighbors - var en_list = _voro.get_en(_self.id); - - // store as initial known list - // TODO: do we need to update the neighbor_states here? - // because during neighbor discovery checks, each node's knowledge will be calculated - delete _neighbor_states[from_id]; - _neighbor_states[from_id] = list; - - var id; - for (var i=0; i < en_list.length; ++i) - { - id = en_list[i]; - - // send only relevant missing neighbors, defined as - // 1) not the sender node - // 2) one of my enclosing neighbors but not in the EN list received - // 3) one of the sender node's relevant neighbors - // - if (id != from_id && - list.hasOwnProperty(id) === false && - _isRelevantNeighbor (_neighbors[id], _neighbors[from_id])) - missing.push(id); - } - - // notify the node sending me HELLO of neighbors it should know - if (missing.length > 0) - _sendNodes(from_id, missing); - } - break; - - // VON's move, to notify AOI neighbors of new/current position - // VON's move, full notification on AOI - // VON's move for boundary neighbors - // VON's move for boundary neighbors with full notification on AOI - case VON_Message.VON_MOVE: - case VON_Message.VON_MOVE_F: - case VON_Message.VON_MOVE_B: - case VON_Message.VON_MOVE_FB: { - - // we only take MOVE from known neighbors - if (_isNeighbor(from_id) === false) - break; - - // extract full node info or just position update - var node = new VAST.node(from_id); - node.parse(pack.msg); - - // if the remote node has just been disconnected, - // then no need to process MOVE message in queue - if (_updateNode(node) === false) - break; - - // records nodes requesting neighbor discovery check - if (pack.type == VON_Message.VON_MOVE_B || pack.type == VON_Message.VON_MOVE_FB) - _req_nodes[from_id] = true; - - // check for neighbor discovery - // NOTE: do this only periodically during tick - //_checkNeighborDiscovery(); - } - break; - - // VON's disconnecting a remote node - case VON_Message.VON_DISCONNECT: - case VON_Message.VON_BYE: { - - // TODO: check if from_id is certainly the sending node's ID - if (_neighbors.hasOwnProperty(from_id)) { - _checkConsistency (from_id); - _deleteNode (from_id); - } - - // TODO: physically disconnect the node? (or it will be done by the remote node?) - var result = _net.disconnect(from_id); - LOG.debug('disconnect succcess: ' + result); - LOG.debug('after removal, neighbor size: ' + Object.keys(_neighbors).length); - } - break; - - default: { - LOG.error('cannot recongize message type: ' + pack.type + ' msg: ' + msg); - } - break; - } - } - - var _connHandler = function (id) { - LOG.debug('VON_peer [' + id + '] connected'); - } - - var _disconnHandler = function (id) { - LOG.debug('VON_peer [' + id + '] disconnected'); - - // generate a VON_DISCONNECT message - var pack = new VAST.pack( - VON_Message.VON_DISCONNECT, - {}, - VON_Priority.HIGHEST); - - var encode_str = JSON.stringify(pack); - _msgHandler(id, encode_str); - } - - // clean up all internal states for a new fresh join - var _initStates = function () { - - LOG.debug('initStates called'); - - // node state definition - _state = NodeState.ABSENT; - - // list of AOI neighbors (map from node id to node) - _neighbors = {}; - - // list of new neighbors (learned via VON_NODE messages) - _new_neighbors = {}; - - // record on EN neighbors (& their states) for each of my neighbor (used in VON_EN) - _neighbor_states = {}; - - _updateStatus = {}; - _potential_neighbors = {}; - _req_nodes = {}; - _time_drop = {}; - - // create an object to calculate Voronoi diagram for neighbor mangement/discovery - _voro = new Voronoi(); - - // init stat collection for selected messsage types - _stat = {}; - _stat[VON_Message.VON_NODE] = new VAST.ratio(); - } - - ///////////////////// - // constructor - // - - // set default AOI buffer size - if (l_aoi_buffer === undefined) - l_aoi_buffer = AOI_DETECTION_BUFFER; - - // check whether AOI neighbor is defined as nodes whose regions - // are completely inside AOI, default to be 'true' - if (l_aoi_use_strict === undefined) - l_aoi_use_strict = true; - - if (l_port === undefined) - l_port = VON_DEFAULT_PORT; - - // create network layer & start listening - // NOTE: internal handlers must be defined before creating the VAST.net instance - var _net = new VAST.net(_msgHandler, _connHandler, _disconnHandler, l_self_id); - - // reference to self - // NOTE: other info of 'self' may be empty at this moment (e.g., endpt, aoi, etc.) - var _self = new VAST.node(l_self_id); - - // - // internal states - // - - // node state definition - var _state; - - // list of AOI neighbors (map from node id to node) - var _neighbors; - - // TODO: combine these structures into one? - var _new_neighbors; // nodes worth considering to connect (learned via VON_NODE messages) - var _neighbor_states; // neighbors' knowledge of my neighbors (for neighbor discovery check) - var _potential_neighbors; // neighbors to be discovered - var _req_nodes; // nodes requesting neighbor discovery check - - var _updateStatus; // status about whether a neighbor is: 1: inserted, 2: deleted, 3: updated - - var _time_drop; - - // create an object to calculate Voronoi diagram for neighbor mangement/discovery - var _voro; - - // init stat collection for selected messsage types - var _stat; - - // clean all states - _initStates(); - -} // end of peer diff --git a/VSO_peer.js b/VSO_peer.js deleted file mode 100644 index bcb8b2dc..00000000 --- a/VSO_peer.js +++ /dev/null @@ -1,354 +0,0 @@ - -/* - * VAST, a scalable peer-to-peer network for virtual environments - * Copyright (C) 2005-2011 Shun-Yun Hu (syhu@ieee.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/* - VSO_peer.js - - a logical node that performs Voronoi Self-organizing Overlay (VSO) functions - main functions are loading notification and dynamic load balancing for regions - - supported functions: - - void join (Area &aoi, Node *origin, bool is_static = false); - bool handleMessage (Message &in_msg); - void notifyLoading (float level); - void tick (); - - // shared object ownership management - - // add a particular shared object into object pool for ownership management - bool insertSharedObject (id_t obj_id, Area &aoi, bool is_owner = true, void *obj = NULL); - - // change position for a particular shared object - bool updateSharedObject (id_t obj_id, Area &aoi, bool *is_owner = NULL); - - // remove a shared object - bool deleteSharedObject (id_t obj_id); - - // obtain reference to a shared object, returns NULL for invalid object - VSOSharedObject *getSharedObject (id_t obj_id); - - // get the number of objects I own - int getOwnedObjectSize (); - - // check if I'm the owner of an object - bool isOwner (id_t obj_id); - - // request particular object from a neighbor node - // TODO: try to hide this from public? - void requestObjects (id_t target, vector &obj_list); - - // - // helper - // - - // find the closest enclosing neighbor to a given position (other than myself) - // returns 0 for no enclosing neighbors - id_t getClosestEnclosing (Position &pos); - - bool isJoining (); - - - history: - 2010/03/18 adopted from ArbitratorImpl.h in VASTATE - 2012/09/09 initial js version (from VSOPeer.h) -*/ - -require('./common.js'); -require('./VON_peer.js'); - - -#ifndef _VAST_VSOPeer_H -#define _VAST_VSOPeer_H - -#include "Config.h" -#include "VASTTypes.h" -#include "VONPeer.h" -#include "VSOPolicy.h" - -// load balancing settings -#define VSO_MOVEMENT_FRACTION (0.1f) // fraction of remaining distance to move for nodes -#define VSO_TIMEOUT_OVERLOAD_REQUEST (3) // seconds to re-send a overload help request -#define VSO_INSERTION_TRIGGER (5) // # of matcher movement requests before an insertion should be requested - -#define VSO_AOI_BUFFER_OVERLAP (10) // buffer size determining whether an AOI overlaps with a region - -#define VSO_PEER_AOI_BUFFER (5) // buffer for a VSOPeer's AOI (which needs to cover all AOI of the objects it manages) - - -// ownership transfer setting -#define VSO_TIMEOUT_TRANSFER (0.3) // # of seconds before transfering ownership to a neighbor -#define VSO_TIMEOUT_AUTO_REMOVE (2.0) // # of seconds to delete an un-owned object if it's not being updated - - -// WARNING: VON messages currently should not exceed VON_MAX_MSG defined in Config.h -// otherwise there may be ID collisons with other handlers that use VONpeer -// internally (e.g., VASTClient in VAST or Arbitrator in VASTATE) -typedef enum -{ - VSO_DISCONNECT = 0, // VSO's disconnect - VSO_CANDIDATE = 11, // notify gateway of a candidate node - VSO_PROMOTE, // promote a candidate to be functional - VSO_INSERT, // overload request for insertion - VSO_MOVE, // overload request for movement - VSO_JOINED, // a new node has joined successfully - VSO_TRANSFER, // transfer ownership of an object - VSO_TRANSFER_ACK, // acknowledgment of ownership transfer - VSO_REQUEST, // request for object - -} VSO_Message; - -// object ownership info maintained by a VSOPeer -class VSOSharedObject -{ -public: - - VSOSharedObject () - { - obj = NULL; - is_owner = false; - in_transit = 0; - last_update = 0; - closest = 0; - }; - - void * obj; // pointer to the object itself - Area aoi; // area of interest of the object (will determine how far the object should spread) - bool is_owner; // whether it is owned by the local host - timestamp_t in_transit; // countdown of object in ownership transfer to others - timestamp_t last_update; // time of object's last update (used for Object expiring) - id_t closest; // ID for closest managing node for this object -}; - -// message for ownership transfer -class VSOOwnerTransfer : public Serializable -{ -public: - VSOOwnerTransfer (id_t id, id_t new_o, id_t old_o) - { - obj_id = id; - new_owner = new_o; - old_owner = old_o; - }; - - VSOOwnerTransfer () - { - obj_id = 0; - new_owner = 0; - old_owner = 0; - }; - - // size of this class - inline size_t sizeOf () const - { - return sizeof (id_t)*3; - } - - size_t serialize (char *p) const - { - if (p != NULL) - { - memcpy (p, &obj_id, sizeof (id_t)); p += sizeof (id_t); - memcpy (p, &new_owner, sizeof (id_t)); p += sizeof (id_t); - memcpy (p, &old_owner, sizeof (id_t)); - } - return sizeOf (); - } - - size_t deserialize (const char *p, size_t size) - { - // perform size check - if (p != NULL && size >= sizeOf ()) - { - memcpy (&obj_id, p, sizeof (id_t)); p += sizeof (id_t); - memcpy (&new_owner, p, sizeof (id_t)); p += sizeof (id_t); - memcpy (&old_owner, p, sizeof (id_t)); - - return sizeOf (); - } - return 0; - } - - id_t obj_id; // object to be transferred - id_t new_owner; // nodeID for new owner - id_t old_owner; // nodeID for previous owner -}; - -// -// This class joins a node as "VONPeer", which allows the user client -// to execute VON commands: move, getNeighbors -// -class EXPORT VSOPeer : public VONPeer -{ - -public: - - VSOPeer (id_t id, VONNetwork *net, VSOPolicy *policy, length_t aoi_buffer = AOI_DETECTION_BUFFER); - ~VSOPeer (); - - // perform joining the overlay, indicate the joining position, AOI, contact origin, also whether dynamic adjustment is enabled - void join (Area &aoi, Node *origin, bool is_static = false); - - // returns whether the message was successfully handled - bool handleMessage (Message &in_msg); - - // current node overloaded, call for help - // note that this will be called continously until the situation improves - void notifyLoading (float level); - - // notify the gateway that I can be available to join - //bool notifyCandidacy (); - - // check if a particular point is within our region - //bool inRegion (Position &pos); - - // process incoming messages & other regular maintain stuff - void tick (); - - // - // shared object ownership management - // - - // add a particular shared object into object pool for ownership management - bool insertSharedObject (id_t obj_id, Area &aoi, bool is_owner = true, void *obj = NULL); - - // change position for a particular shared object - bool updateSharedObject (id_t obj_id, Area &aoi, bool *is_owner = NULL); - - // remove a shared object - bool deleteSharedObject (id_t obj_id); - - // obtain reference to a shared object, returns NULL for invalid object - VSOSharedObject *getSharedObject (id_t obj_id); - - // get the number of objects I own - int getOwnedObjectSize (); - - // check if I'm the owner of an object - bool isOwner (id_t obj_id); - - // request particular object from a neighbor node - // TODO: try to hide this from public? - void requestObjects (id_t target, vector &obj_list); - - // - // helper - // - - // find the closest enclosing neighbor to a given position (other than myself) - // returns 0 for no enclosing neighbors - id_t getClosestEnclosing (Position &pos); - - // check if I'm a joining peer (in progress) - bool isJoining (); - -private: - - // - // AOI management methods - // - - // change the center position in response to overload signals - void movePeerPosition (); - - // enlarge or reduce the AOI radius to cover all objects's interest scope - void adjustPeerRadius (); - - // - // object management methods - // - - // check if neighbors need to be notified of object updates - // returns the # of updates sent - int checkUpdateToNeighbors (); - - // remove obsolete objects (those unowned objects no longer being updated) - // and send keepalive for owned objects - void refreshObjects (); - - // - // ownership transfer methods - // - - // check to see if subscriptions have migrated - // returns the # of transfers - int checkOwnershipTransfer (); - - // process ownership transfer notification - void processTransfer (Message &in_msg); - - // accept and ownership transfer - void acceptTransfer (VSOOwnerTransfer &transfer); - - // make an object my own - void claimOwnership (id_t obj_id, VSOSharedObject &so); - - // - // helper methods - // - - // get a new node that can be inserted - //bool findCandidate (float level, Node &new_node); - - // get the center of all current objects I maintain - bool getLoadCenter (Position ¢er); - - // check whether a new node position is legal - bool isLegalPosition (const Position &pos, bool include_self); - - // get a list of neighbors whose regions are covered by the specified AOI - // optionally to include the closest neighbor - bool getOverlappedNeighbors (Area &aoi, vector &neighbors, id_t closest = 0); - - // helper function to identify if a node is gateway - inline bool isGateway (id_t id) - { - return (_policy->getGatewayID () == id); - } - - - VSOPolicy * _policy; // various load balancing policies - NodeState _vso_state; // state of the VSOpeer - Node _newpos; // new AOI & position to be updated due to load balancing - bool _is_static; // whether load balancing is turned off - - Node _origin; // the origin peer (1st contact node) for this VSO network - - // server data (Gateway node) - //vector _candidates; // list of potential nodes - map _promote_requests; // requesting nodes' timestamp of promotion and position, index is the promoted node - - // ownership related - map _objects; // list of objects I manage - map _transfer_timeout; // onset time to transfer ownership - map _reclaim_timeout; // onset time to reclaim ownership to unowned objects - - map _transfer; // pending ownership transfers - map _obj_requested; // objects request & the target being asked - - // counters & time record - int _overload_count; // counter for # of times a OVERLOAD_M request is sent - - timestamp_t _overload_timeout; // overload time - timestamp_t _underload_timeout; // underload time - - timestamp_t _next_periodic; // last timestamp executing periodic task -}; diff --git a/common.js b/common.js deleted file mode 100644 index 43ef4233..00000000 --- a/common.js +++ /dev/null @@ -1,23 +0,0 @@ - -/* - common definitions for VAST -*/ - -// -// utilities -// - -var logger = require('./common/logger'); -global.LOG = new logger(); -global.UTIL = require('./common/util'); - -// -// VAST & VON -// -global.VAST = require('./vast_types'); -global.VAST.net = require('./vast_net'); -global.VON = require('./VON_peer'); - -// ID definitions -global.VAST_ID_GATEWAY = 1; -global.VAST_ID_UNASSIGNED = 0; diff --git a/common/logger.js b/common/logger.js deleted file mode 100644 index 2ee01349..00000000 --- a/common/logger.js +++ /dev/null @@ -1,66 +0,0 @@ - - - -/* - - logger for vast.js -*/ - -// color control codes -var _green = '\033[32m'; -var _red = '\033[31m'; -var _white = '\033[m'; -var _yellow = '\033[33m'; - -var _ERR = _red + 'ERR -'; -var _ERREND = _white; - -var _WARN = _yellow + 'WARN -'; - -function logger() { - - // by default we display all - var _level = 3; - - // set log level: 1 (error only), 2 (warning), 3 (debug) - this.setLevel = function (level) { - if (level <= 0 || level > 3) { - this.error('log level setting incorrect'); - return; - } - _level = level; - this.debug('set error level to be: ' + level); - } - - this.debug = function (msg) { - if (_level >= 3) - console.log(msg); - } - - this.warn = function (msg) { - if (_level >= 2) - console.log(_WARN + msg + _ERREND); - } - - this.error = function (msg) { - if (_level >= 1) - console.log(_ERR + msg + _ERREND); - } -} - -if (typeof module !== 'undefined') - module.exports = logger; - -/* -exports.debug = function (msg) { - console.log(msg); -} - -exports.warn = function (msg) { - console.log(_WARN + msg + _ERREND); -} - -exports.error = function (msg) { - console.log(_ERR + msg + _ERREND); -} -*/ \ No newline at end of file diff --git a/common/util.js b/common/util.js deleted file mode 100644 index c5158fdc..00000000 --- a/common/util.js +++ /dev/null @@ -1,11 +0,0 @@ - -/* - common utilities for vast.js -*/ - -// returns number of milliseconds since 1970 -exports.getTimestamp = function () { - var now = new Date(); - return now.getTime(); -} - diff --git a/common_util.js b/common_util.js deleted file mode 100644 index 96f58642..00000000 --- a/common_util.js +++ /dev/null @@ -1,33 +0,0 @@ - -if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function (obj, fromIndex) { - if (fromIndex == null) { - fromIndex = 0; - } else if (fromIndex < 0) { - fromIndex = Math.max(0, this.length + fromIndex); - } - for (var i = fromIndex, j = this.length; i < j; i++) { - if (this[i] === obj) - return i; - } - return -1; - }; -} - -//var sleep = require('./node-sleep/index.js'); - -/* -// will print stack when called -function debug_pause() -{ - try { - i.dont.exist += 0; //doesn't exist- that's the point - } catch(e) { - console.log(e.stack); - } - //throw ("stop here"); - console.log('sleeping for 2 seconds...'); - sleep.sleep(2); -} -*/ - diff --git a/docs/VON.md b/docs/VON.md new file mode 100644 index 00000000..a18c3d4f --- /dev/null +++ b/docs/VON.md @@ -0,0 +1,60 @@ +# VON Peer +The underlying P2P network of VAST.js. +**Clients ARE NOT part of the VON, only matchers are.** + +- [VON Peer](#von-peer) +- [The Gateway Peer](#the-gateway-peer) +- [Types of Neighbours](#types-of-neighbours) +- [API](#api) + - [VON packet](#von-packet) + - [VON Messages](#von-messages) + +# The Gateway Peer +The Gateway peer is the first VON peer that joins the VON, and will always have an ID = 1. Each new peer that joins the VON first establishes a connection to the GW and is assigned an ID. Then (in _oversimplified terms_) the join request is greedy-forwarded to the accepting peer, who inserts the joining peer into its voronoi partition and gives the joining peer it's neighbour list. The joining peer contacts all of it's neighbours and they insert the new peer into their own voronoi partitions and _voila_. For a more thourough understanding, refer to "Scalable Peer-to-Peer Networked Virtual Environment, S.Y Hu, 2005" and "VON: A Scalable Peer-to-Peer Network for Virtual Environments, Shun-Yun Hu, Jui-Fa Chen, Tsu-Han Chen, 2006" + +drawing + +# Types of Neighbours +VON defines 3 different types of neighbours: _enclosing neighbours, AoI neighbours and boundary neighbours_. +An _enclosing neighbour_ is a neighbour who shares a boundary with a peer’s region in the Voronoi diagram. An _AoI neighbour_ is any neighbour whose site lies within the peer’s Area of Interest (AoI). A _boundary neighbour_ is an enclosing or AoI neighbour whose region intersects the boundary of a peer’s AoI. +drawing + + +# API +## VON Packet +The packets sent between VON peers are defined in ./lib/types.js as packs. + +| Property | Description | +| ----------- | ----------- | +| type | The type of [VON Message](von-messages) | +| msg | The message content | +| priority | The priotity of this packet (currently has no effect) | +| targets | Array of each VON peer ID this packet should be sent to| +| src | The VON peer who sent this packet | + +--- +

+ +## VON Messages +These are an enumeration that specify the type of message that one peer is sending to another (or itself). +This is declared in ./lib/common.js + +| Message | Description | +| ----------- | ----------- | +| VON_BYE | VON's disconnect | +| VON_PING | VON's PING to check if a neighbour is still alive (currently not used?) | +| VON_QUERY | VON's query to find an accepting peer for a given point | +| VON_JOIN | VON's Join to learn of initial neighbours | +| VON_NODE | VON's notification of new nodes | +| VON_HELLO | VON's greeting to newly learned node to be mutually aware | +| VON_HELLO_R | VON's response to VON_HELLO | +| VON_EN | VON's enclosing neighbour enquiry, to determine if my EN list is complete | +| VON_MOVE | VON's move to notify AoI neighbours of new/current position | +| VON_MOVE_F | VON's move, full notification of AoI | +| VON_MOVE_B | VON's move for boundary neighbours | +| VON_MOVE_FB | VON's move for boundary neighbours with full notification on AoI | +| MATCHER_POINT | Matcher Message to be sent to point over VON | +| MATCHER_AREA | Matcher Message to be sent to area over VON | + +--- +

\ No newline at end of file diff --git a/docs/client.md b/docs/client.md new file mode 100644 index 00000000..c8fcb259 --- /dev/null +++ b/docs/client.md @@ -0,0 +1,11 @@ +# Client +P2P Spatial Publish and Subscribe built on the Voronoi Overlay Network (VON). + +- [VAST.js](#vastjs) + - [Introduction to VAST.js](#introtovastjs) + - [Dependencies](#dependancies) + - [API](#api) + +# Intro to VAST.js +## Basic Structure +drawing \ No newline at end of file diff --git a/docs/images/VAST_Layers.png b/docs/images/VAST_Layers.png new file mode 100644 index 00000000..4a993873 Binary files /dev/null and b/docs/images/VAST_Layers.png differ diff --git a/docs/images/client_join.png b/docs/images/client_join.png new file mode 100644 index 00000000..268e98eb Binary files /dev/null and b/docs/images/client_join.png differ diff --git a/docs/images/neighbour_types.png b/docs/images/neighbour_types.png new file mode 100644 index 00000000..61a48b61 Binary files /dev/null and b/docs/images/neighbour_types.png differ diff --git a/docs/matcher.md b/docs/matcher.md new file mode 100644 index 00000000..55db109a --- /dev/null +++ b/docs/matcher.md @@ -0,0 +1,129 @@ +# Matcher +The spatial message broker for VAST.js. + +- [ Matcher](#vastjs) +- [Default Parameters](#default-parameters) +- [The Gateway Matcher](#the-gateway-matcher) +- [The VON Peer Worker](#the-von-peer-worker) +- [API](#api) + - [Subscription](#subscription) + - [Publication](#publication) + - [Point Packet](#point-packet) + - [Area Packet](#area-packet) + - [Matcher Messages](matcher-messages) + +# Default Parameters +```sh +VON Port: 8000 # automatically increments if 8000 is unavalable +Client Port: 20000 # automatically increments if 20000 is unavalable +Global Server Hostname: 'localhost' # assumes GS is running on local machine, change if necessary +Global Server Port: 7777 +RequireGS: false # set to true to enable GS and visualiser +``` + +# The Gateway Matcher +The Gateway matcher is the matcher that runs on top of the Gateway VON peer, and is the matcher that all new clients first connect to. When a new client connects, the GW assigns it an ID and sends a FIND_MATCHER message to the accepting matcher over VON (which could be the GW itself). When a FOUND_MATCHER message returns, the GW informs the new client of its real "owner" matcher and the client establishes a connection. + +drawing + +# The VON Peer Worker +The VON Peer Worker (./lib/VON_peer_worker.js) is the mechanism whereby the VON peer and matcher are seperated to run on two seperate threads. +In a single threaded implementation, the VON peer is instantiated within the matcher, and the VON peers functions and properties can be accessed directly. In the current worker-thread implementation, the matcher is only capable of sending and receiveing pointMessages and areaMessages through the VON using the VON_peer_worker. + +The matcher and the VON peer worker "communicate" using worker-threads messages. + +# API +## Subscription +The subscription is defined in ./lib/types.js + +| Property | Description | +| ----------- | ----------- | +| hostID | The ID of the matcher/(VON peer) that 'owns' this subscription | +| hostPos | The position of the host matcher. Used to forward matched overlapping/distant subscriptions back to the host | +| clientID | The ID of the client who requested this subscription | +| subID | A unique ID to identify this subscription | +| channel | The channel that this subscription is for. _Wildcards are_ **not** _supported_ | +| aoi | The Area of Interest that this subscription is for | +| recipients | A list containing _at least_ all of this peer's enclosing neighbours who also received this subscription | +--- +

+ +## Publication +The publication is defined in ./lib/types.js + +| Property | Description | +| ----------- | ----------- | +| payload | The application-specific payload of the publication. Any JSON object (serialisable by socket.io) | +| channel | The channel that this publication is for | +| aoi | The Area of Interest that this publication is for | +| recipients | A list containing _at least_ all of this peer's enclosing neighbours who also received this publication | +| | | +| **Properties to Remove^** | +| clientID | The ID of the client that sent this publication. Unnecessary field for matcher-layer. Specify in payload for application-specific requirements | +| matcherID | The ID of the matcher/(VON peer) responsible for the client that sent this publicationtion | +| chain | This is the list of VON IDs (in order) that specify how the publication was forwarded on the VON layer | + +**^A Note on Properties To Remove** +These fields are used for bug fixing and verification of SPS functions. They are not needed for VAST.js to function, and should be removed. + +--- +

+ +## Point Packet +The point packet is used to send [matcher messages](matcher-messages) to a point in the VE using pointMessage(...) in VON_peer. + +| Property | Description | +| ----------- | ----------- | +| type | The type of [Matcher Message](matcher-messages) | +| msg | The message content | +| sender | The ID of the matcher that sent the message | +| sourcePos | The position of the sender | +| targetPos | The target position | +| chain^ | This is the list of VON IDs (in order) that specify how the publication was forwarded on the VON layer | +| checklist^^ | Optional checklist used for filtering | + + +^: The chain field is only used for debugging. Remove it in the future +^^: The checklist field should rather be passed as an additional argument to the pointMessage(...) function in VON_peer.js. It was only added to pointPacket to simplify sendWorkerMessage(...) in matcher.js. + +--- +

+ +## Area Packet +The area packet is used to send [matcher messages](matcher-messages) to an area in the VE using areaMessage(...) and forwardOverlapping(...) in VON_peer.js. + +| Property | Description | +| ----------- | ----------- | +| type | The type of [Matcher Message](matcher-messages) | +| msg | The message content | +| sender | The ID of the matcher that sent the message | +| sourcePos | The position of the sender | +| targetAoI | The target Area of Interest | +| recipients | A list containing _at least_ all of this peer's enclosing neighbours who also received this message | +| chain^ | This is the list of VON IDs (in order) that specify how the publication was forwarded on the VON layer | + + +^: The chain field is only used for debugging. Remove it in the future + +--- +

+ +## Matcher Messages +These are an enumeration that specify the type of message that one matcher is sending to another (or itself). +This is declared in ./lib/common.js + +| Message | Description | +| ----------- | ----------- | +| FIND_MATCHER | Sent by GW to the position of a joining client to find the accepting matcher | +| FOUND_MATCHER | The response returned to the GW from the accepting matcher, containing its ID, address and port | +| PUB | Contains a client publication and is sent to the pub's AoI | +| PUB_MATCHED | Sent to the owner matcher for publications matched by overlapping / distant subscriptions. | +| SUB_NEW | Sent to matchers to indicate a new subscription that they must maintain | +| SUB_DELETE | Sent to matchers to notify them of a deleted subscription | +| **TO BE ADDED**| +| SUB_UPDATE | Send to the _old_ AoI of a sub to notify of _new_ sub details. Also need to inform new matchers if relevant | + +--- +

+ + diff --git a/generic_net.js b/generic_net.js deleted file mode 100644 index 39f03205..00000000 --- a/generic_net.js +++ /dev/null @@ -1,144 +0,0 @@ -// -// generic_net: A generic network layer that supports net basics -// connect/disconnect/send/recv/stat -// - -// parameters -var port = 1037; // local server listen port - - -// Include the event emitter class - the generic network is a specialized -// instance of the event emitter and will emit the events: -// -// - data / response -// - error / errorType (HTTP Status code) - -var EventEmitter = require( "events" ).EventEmitter; -var net = require( 'net' ); -var Hash = require( "./hash.js" ); - -// map from socket id to socket object -var sockets = new Hash(); - -// Create an instance of our event emitter. -var net_layer = new EventEmitter(); - -// connect to a particular host and obtain a socket ID -net_layer.connect = function(port, host){ - - var sock = net.createConnection( port, host ); - var sock_id = null; - - // handles callback - sock.addListener( 'connect', function() { - console.log( "generic_net: connection established to: " + host + ":" + port); - - // generate a sock_id - while( true ) { - sock_id = Math.floor( Math.random()*1000 ) - - // test for existence - if( sockets.has( sock_id ) == true ) - continue; - - // insert socket object - sockets.set( sock_id, sock ); - - break; - } - - // notify the socket's ID - net_layer.emit( "connected", sock_id ); - }); - - sock.addListener( 'close', function() { - console.log("generic_net: disconnected from " + host + ":" + port); - - net_layer.emit( "disconnected", sock_id ); - }); - - sock.addListener( 'error', function (e) { - console.log( "generic_net: error connecting to: " + host + ":" + port + "\nerror: " + e); - }); - - sock.addListener( 'data', function( data ){ - - try { - // forward the received data to event handler - console.log ( "incoming data from " + sock_id ); - net_layer.emit( "data", sock_id, data ); - } catch( e ){ - console.log("exception (" + e.name + "): " + e.message); - - // notify error - net_layer.emit( "error", "socket data receive error" ); - } - }); -}; - -// disconnect a socket -net_layer.disconnect = function( target ){ - if( sockets.has( target ) == false ) - return false; - - var socket = sockets.get( target ); - socket.end(); - - // remove from sockets mapping - sockets.remove( target ); - return true; -}; - -// send a message to a given socket -// returns whether write to kernel buffer is successful -net_layer.send = function( target, message ){ - - console.log( "sending to: " + target + " msg: " + message ); - - // check if socket connection exists - if( sockets.has( target ) == false ) - return false; - - var socket = sockets.get( target ); - - return socket.write( message ); -}; - -// create simple socket server -var server = net.createServer( function( socket ) { - console.log( "server gets connection, remote is: " + socket.remoteAddress ); - - //socket.write("Echo server\r\n"); - //socket.pipe(socket); - - //socket.addListener( "data", ... ); - - socket.addListener( "connection", function() { - console.log( "server incoming socket established, remote is: " + socket.remoteAddress ); - }); - - // generate socket id & store it -}); - -// try to bind listen port -var bind_success = false; - -while( bind_success != true) { - - try { - // adjust port - server.listen(port+1, "127.0.0.1"); - console.log( "server now listens at port: " + port); - } catch( e ) { - console.log("exception (" + e.name + "): " + e.message); - - // notify error - //net_layer.emit( "error", "socket bind error, adjusting bind port number" ); - port++; - continue; - } - break; -} - -// expose the generic network layer -module.exports = net_layer; \ No newline at end of file diff --git a/gw.bat b/gw.bat deleted file mode 100644 index e1162bbe..00000000 --- a/gw.bat +++ /dev/null @@ -1 +0,0 @@ -node test_von_peer diff --git a/hash.js b/hash.js deleted file mode 100644 index cf423e1f..00000000 --- a/hash.js +++ /dev/null @@ -1,93 +0,0 @@ - -// -// a generic Hash object: -// see: http://www.mojavelinux.com/articles/javascript_hashes.html -// -// property: -// - length: the length of the hash object -// - items: the actual objects stored - -function Hash() -{ - this.length = 0; - this.items = new Array(); - var idxmap = new Array(); - - for (var i = 0; i < arguments.length; i += 2) { - if (typeof(arguments[i + 1]) != 'undefined') { - this.items[arguments[i]] = arguments[i + 1]; - this.length++; - } - } - - this.remove = function(in_key) - { - var tmp_previous; - if (typeof(this.items[in_key]) != 'undefined') { - this.length--; - var tmp_previous = this.items[in_key]; - delete this.items[in_key]; - - // remove index to key mapping - var newmap = [] - for (var i=0; i < idxmap.length; i++) { - if (idxmap[i] != in_key) - newmap.push(idxmap[i]); - } - idxmap = newmap; - } - - return tmp_previous; - } - - this.get = function(in_key) { - if (typeof(this.items[in_key]) == 'undefined') - return null; - return this.items[in_key]; - } - - // doesn't work this way - this.getByIndex = function(index) { - if (index < 0 || index >= idxmap.length) - return null; - return this.items[idxmap[index]]; - } - - this.set = function(in_key, in_value) - { - var tmp_previous; - - if (typeof(in_value) != 'undefined') { - if (typeof(this.items[in_key]) == 'undefined') { - - // store map of index to key - idxmap[this.length] = in_key; - this.length++; - } - else { - tmp_previous = this.items[in_key]; - } - - this.items[in_key] = in_value; - } - - return tmp_previous; - } - - this.has = function(in_key) - { - return typeof(this.items[in_key]) != 'undefined'; - } - - this.clear = function() - { - for (var i in this.items) { - delete this.items[i]; - } - idxmap = []; - - this.length = 0; - } -} - -module.exports = Hash; \ No newline at end of file diff --git a/lib/VON_peer.js b/lib/VON_peer.js new file mode 100755 index 00000000..10280a5c --- /dev/null +++ b/lib/VON_peer.js @@ -0,0 +1,1963 @@ + +/* + * VAST, a scalable peer-to-peer network for virtual environments + * Copyright (C) 2005-2011 Shun-Yun Hu (syhu@ieee.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* + VON_peer.js + + The basic interface for a basic VON peer + supporting distributed neighbor discovery and management + + supported functions: + + // basic callback / structure + addr = {host, port}; + center = {x, y}; + aoi = {center, radius}; + endpt = {id, addr, last_accessed}; + node = {id, endpt, aoi, time}; + pack = {type, msg, group, priority, targets} // message package during delivery + vast_net (see definition in vast_net.js) + + // VON functions + join(addr, aoi, onDone) join a VON network at a gateway with a given aoi + leave() leave the VON network + move(aoi, send_time) move the AOI to a new position (or change radius) + list() get a list of AOI neighbors + send(id, msg) send a message to a given node + put(obj) store app-specific data to the node + + // basic external functions + init(id, port, onDone) init a VON peer with id, listen port + shut() shutdown a VON peer (will close down listen port) + query(center, onAcceptor) find app-specific data along with the node (will pass during node discovery) + get() retrieve app-specific data for this node + + // accessors + isJoined(); check if we've joined the VON network + isNeighbor(id); check if a given ID is an existing neighbor + getVoronoi(); get a reference to the Voronoi object + getNeighbor(id); get a particular neighbor's info given its ID + getSelf(); get self info + getEdges(); get a list of edges known to the current node + + history: + 2012-07-07 initial version (from VAST.h) +*/ + +require('./common.js'); + +// to be inherited by VON.peer +var msg_handler = msg_handler || require('./net/msg_handler.js'); + +const { area } = require('./types.js'); +// voronoi computation +var Voronoi = require('./voronoi/vast_voro.js'); + +// config +var VON_DEFAULT_PORT = 37; // by default which port does the node listen +var AOI_DETECTION_BUFFER = 32; // detection buffer around AOI +var MAX_TIMELY_PERIOD = 10; // # of seconds considered to be still active +var MAX_DROP_SECONDS = 2; // # of seconds to disconnect a non-overlapped neighbor +var NONOVERLAP_MULTIPLIER = 1.25; // multiplier for aoi buffer for determining non-overlap +var TICK_INTERVAL = 100; // interval (in milliseconds) to perform tick tasks +var MAX_TICK_INTERVAL = 15000; + +// flags +var OVERLAP_CHECK_ACCURATE = false; // whether VON overlap checks are accurate + +// status on known nodes in the neighbor list, can be either just inserted / deleted / updated +var NeighborUpdateStatus = { + INSERTED: 1, + DELETED: 2, + UNCHANGED: 3, + UPDATED: 4 +}; + +// states for an enclosing neighbor +var NeighborState = { + NEIGHBOR_REGULAR: 0, + NEIGHBOR_OVERLAPPED: 1, + NEIGHBOR_ENCLOSED: 2 +}; + +// +// NOTE: this class interface with msg_handler via the following: +// _connHandler, _disconnHandler, _packetHandler, _self_id +// it also uses the following provided by msg_handler +// sendMessage, sendPack, net +// + +// definition of a VON peer +function VONPeer(l_aoi_buffer, l_aoi_use_strict) { + + ///////////////////// + // public methods + // + + var _that = this; + + var log = LOG.newLayer('VON', 'VON', 'logs'); + + // function to create a new net layer + this.init = function (self_id, localIP, port, matcher, onDone) { + + self_id = self_id || VAST.ID_UNASSIGNED; + port = port || VON_DEFAULT_PORT; + _my_matcher = matcher; + + // create new layer + var handler = new msg_handler(self_id, localIP, port, function (local_addr) { + + // NOTE: this will cause initStates() be called + handler.addHandler(_that); + + // notify done + if (typeof onDone === 'function') + onDone(local_addr); + }); + } + + // shutdown a VON peer (will close down listen port) + this.shut = function () { + + if (_msg_handler !== undefined) { + // stop server, if currently listening + // NOTE: if VON peer is used with other nodes, stopping server here will impact other nodes as well + _msg_handler.close(); + _msg_handler = undefined; + } + _state = VAST.state.ABSENT; + } + + // find the acceptor for a given center point + var _query = this.query = function (contact_id, center, msg_type, msg_para) { + + //log.debug('VON_peer query() will contact node[' + contact_id + '] to find acceptor'); + + var msg = { + pos: center, + type: msg_type, + para: msg_para + } + + // send out query request + _sendMessage(contact_id, VON_Message.VON_QUERY, msg, VAST.priority.HIGHEST); + } + + // join a VON network with a given aoi + var _join = this.join = function (GW_addr, aoi, onDone) { + + // check if already joined + if (_state === VAST.state.JOINED) { + //log.warn('VON_peer.join(): node already joined'); + if (typeof onDone === 'function') + onDone(_self.id); + return; + } + + //log.debug('VON_peer join() called, self: ' + _self.id + ' getID: ' + _getID()); + + // store gateway address, ensure input conforms to internal data structure + // NOTE: need to do it here, as _storeMapping is not effective after addHandler calls initStates + var addr = new VAST.addr(); + addr.parse(GW_addr); + _storeMapping(VAST.ID_GATEWAY, addr); + //log.warn('gateway set to: ' + addr.toString()); + + // store initial aoi + _self.aoi.update(aoi); + + // change internal state + _state = VAST.state.JOINING; + + // keep reference to call future once join is completed + _join_onDone = onDone; + + // if id is empty, send PING to gateway to learn of my id first + // otherwise attempt to join by contacting gateway + if (_getID() === VAST.ID_UNASSIGNED) + _sendMessage(VAST.ID_GATEWAY, VON_Message.VON_PING, {request: true}, VAST.priority.HIGHEST); + else + _setInited(); + } + + // leave the VON network + var _leave = this.leave = function () { + + //log.debug('VON_peer leave() called, neighbor size: ' + Object.keys(_neighbours).length); + + // always notify neighbors + var notify_neighbors = true; + + // see if we need to explicityly notify neighbors of our leave + if (notify_neighbors) { + + var targets = []; + for (var id in _neighbours) { + if (_isSelf(id) === false) + targets.push(id); + } + + _sendBye(targets); + + // TODO: notify potential_neighbors + } + + // clean data structure + _initStates(); + } + + // move the AOI to a new position (or change radius) + var _move = this.move = function (aoi, sendtime) { + ////log.warn('VON_Peer moving to: ' + aoi.center.toString()); + + try { + if (typeof aoi.radius === 'string') + aoi.radius = parseInt(aoi.radius); + else if (typeof aoi.radius !== 'number') { + //log.error('radius format incorrect, ignore move request'); + return _self.aoi; + } + } + catch (e) { + //log.error('parsing radius error: ' + e); + return _self.aoi; + } + + _self.aoi.center = aoi.center; + + // check if AOI radius has changed (besides position) + var aoi_reshaped = (aoi.hasOwnProperty('radius') && _self.aoi.radius !== aoi.radius); + if (aoi_reshaped) + //log.warn('AOI radius updated to: ' + aoi.radius); + + _self.aoi.update(aoi); + + // TODO: check if my new position overlaps a neighbor, if so then move slightly + // avoid moving to the same position as my neighbor + //_self.aoi.center = _isOverlapped (_self.aoi.center); + + // record send time of the movement + // this is to help receiver determine which position update should be used + // also to help calculate latency + // if external time is supplied (we respect the sender's time), then record it + _self.time = (sendtime != undefined ? sendtime : UTIL.getTimestamp()); + _updateNode(_self); + + // notify all connected neighbors, pack my own node info & AOI info + + // if AOI radius has changed, send full self info + // otherwise just send new center for AOI + // NOTE: we make a copy for this, so any modifications required won't affect original + var node_info = _getNode(_self.id); + + // remove info not needed by VON_MOVE + delete node_info['endpt']; + + if (aoi_reshaped === false) + delete node_info.aoi['radius']; + + // go over each neighbor and do a boundary neighbor check + var boundary_list = []; + var regular_list = []; + + for (var id in _neighbours) { + + if (_isSelf(id)) + continue; + // save boundary neighbors for later + if (_voro.is_boundary (id, _self.aoi.center, _self.aoi.radius)) + boundary_list.push(id); + else + regular_list.push(id); + } + + // create a delivery package to send + // NOTE: For now we send move reliably, but can experiment with unreliable delivery + var pack = new VAST.pack( + VON_Message.VON_MOVE, + node_info, + VAST.priority.HIGHEST, _self.id); + + // send to regular neighbors + pack.targets = regular_list; + pack.type = (aoi_reshaped ? VON_Message.VON_MOVE_F : VON_Message.VON_MOVE); + _sendPack(pack, true); + + // send MOVE to boundary neighbors + pack.targets = boundary_list; + pack.type = (aoi_reshaped ? VON_Message.VON_MOVE_FB : VON_Message.VON_MOVE_B); + _sendPack(pack, true); + + return _self.aoi; + } + + // store a app-specific data along with the node (will pass during node discovery) + var _put = this.put = function (obj) { + _meta = obj; + //log.debug('after put() meta keys: ' + Object.keys(_meta).length); + + // update to self (so that it can be sent over) + _self.meta = _meta; + } + + // retrieve app-specific data for this node + var _get = this.get = function () { + //log.debug('get() meta keys: ' + Object.keys(_meta).length); + return _meta; + } + + //////////////////////////////////////////////// + // Public methods / accessors used by matcher + + // get a list of AOI neighbors + this.list = function () { + return _neighbours; + } + + // checks if id is an enclosing neighbour of center_node_id + this.is_enclosing_neighbour = function(id, center_node_id){ + return _voro.is_enclosing(id, center_node_id); + } + //--------------------------------------- + // BROKEN ALWAYS RETURNS FALSE + this.contains = function(pos){ + return _voro.contains(_self.id, pos); + } + + this.closest_to = function(pos){ + return _voro.closest_to(pos); + } + + // send message to a point via VON + var l_pointMessage = this.pointMessage = function(pointPacket){ + var checklist = pointPacket.checklist || []; + + // If a checklist is present, I must ensure that I am the closest node before forwarding + if (checklist.length > 0){ + var targetPos = new VAST.pos(); + targetPos.parse(pointPacket.targetPos); + + // distance of myself to the target + var myDist = targetPos.distance(_self.aoi.center); + var myID = _self.id; + + // neighbour + var key, neighbour; + var tempDist; + + // for each node in the checklist, check distance + for (var i = 0; i < checklist.length; i++){ + + // using key and getting properties from _neighbours is faster than getNode() + // (we dont need the functions and extra properties from getNode) + key = checklist[i]; + neighbour = _neighbours[key]; + + // I do not know this node + if (typeof(neighbour) === 'undefined'){ + continue; + } + // Distance of current node to target + tempDist = targetPos.distance(neighbour.aoi.center); + + // If I am not the nearest, I know that I should not foward and can exit immediately + // Also, if equal distance, the smaller ID is responsible for forwarding + if ((tempDist < myDist) || (tempDist === myDist && neighbour.id < myID)) { + return; + } + } + } + + // clear the checklist before forwarding + pointPacket.checklist = []; + + var VON_pack = new VAST.pack(VON_Message.MATCHER_POINT, pointPacket, VAST.priority.HIGHEST, _self.id); + _packetHandler(_self.id, VON_pack); + } + + this.areaMessage = function(areaPacket){ + + var VON_pack = new VAST.pack(VON_Message.MATCHER_AREA, areaPacket, VAST.priority.HIGHEST, _self.id); + _packetHandler(_self.id, VON_pack); + } + + // forward message to all overlapping neighbours + var _forwardOverlapping = function(areaPacket, callback){ + + // aoi that must be sent to + var aoi = new VAST.area(); + aoi.parse(areaPacket.targetAoI); + + // array of node IDs that have already received the message (not always complete) + var recipients = Object.values(areaPacket.recipients); + + // struct overlapping neighbours who don't have the message yet + // (need their positions and is faster than parsing nodes later on) + var newNeighbours = {}; + + var targets = []; + + var neighbour_i, id_i; + var neighbour_j, id_j; + + var checklist; // array of neighbours that we have in common with the neighbour_i + + var rootDist; // distance between j and the root + + var nearest; //Am I the nearest to the root? + + // For each of my neighbours + for (var key_i in _neighbours){ + neighbour_i = _neighbours[key_i]; + id_i = neighbour_i.id; + + // skip myself and any neighbours that have already recieved the message + if(_self.id === id_i || recipients.includes(id_i)){ + continue; + } + + // If the neighbour's region collides, they are a potential target + if(_voro.collidesID(id_i, aoi.center, aoi.radius)){ + newNeighbours[key_i] = neighbour_i; + } + } + + // position of the root of the message and my distance to it + var rootPos = new VAST.pos(); + rootPos.parse(areaPacket.targetAoI.center); + var myRootDistance = rootPos.distance(_self.aoi.center); + + // for each new neighbour + for (var key_i in newNeighbours){ + + neighbour_i = newNeighbours[key_i]; + id_i = neighbour_i.id; + + // if the common neighbour list is not valid, update it + if(_nghbrsNghbrsValid[key_i] != true){ + _nghbrsNghbrs[key_i] = _voro.get_neighbour(id_i, neighbour_i.aoi.radius); + _nghbrsNghbrsValid[key_i] = true; + } + + checklist = _nghbrsNghbrs[key_i]; + + nearest = true; + + // for each common neigbour of neighbour_i, see if they are closer to the root + for (var j = 0; j < checklist.length; j++){ + + neighbour_j = _neighbours[checklist[j]]; + id_j = neighbour_j.id; + + // skip self or any new neighbours + if (id_j === _self.id || Object.keys(newNeighbours).includes(checklist[j])){ + continue; + } + + rootDist = rootPos.distance(neighbour_j.aoi.center); + + // if the neighbour j is closer to the root than I am, + // I should not forward this message and can break the loop + if (rootDist < myRootDistance){ + nearest = false; + break; + } + if (rootDist == myRootDistance && id_j < _self.id){ + nearest = false; + break; + } + } + + // If i am the nearest to the root than all common received neigbours, I should forward to neighbour i + if (nearest === true){ + targets.push(id_i); + } + + // add the new neighbour to the list of recipients, even if we aren't forwarding it to them + recipients.push(neighbour_i.id); + } + + // pass updated packet to my matcher + areaPacket.recipients = recipients; + if (typeof callback == 'function'){ + callback(areaPacket); + } + + // send the packet to the targets + var VON_pack = new VAST.pack(VON_Message.MATCHER_AREA, areaPacket, VAST.priority.HIGHEST, _self.id) + VON_pack.targets = targets; + _sendPack(VON_pack, true); + } + + + // return true if my voronoi region overlaps / contains + this.isOverlapping = function (aoi){ + + var region = new VAST.region(); + region.update(_voro.getRegion(_self.id)); + region.convertingEdges(); + + if(region.intersects(aoi.center, aoi.radius)){ + return true; + } + else{ + return false; + } + } + + // return a list of neighbours that overlap with an AoI + var _getOverlappingNeighbours = function(aoi){ + var overlapping = []; + var temp; + + // Need to convert voronoi cell to VAST region for intersect checking + // TODO: combine required functionality into single region/cell type + var region = new VAST.region(); + + for (var key in _neighbours) { + temp = _neighbours[key].id; + // skip self + // TODO: accept list of nodes not to check? (Sub already forwarded to them, don't recheck and resend) + if (temp === _self.id) + continue + + region.update(_voro.getRegion(temp)); + region.convertingEdges(); + if(region.intersects(aoi.center, aoi.radius)){ + overlapping.push(temp); + } + } + return overlapping; + } + + ///////////////////// + // public accessors + // + + this.getHandler = function () { + ////log.debug("Get Handler", _self.id); + return _msg_handler; + } + + // check if we've joined the VON network + var _isJoined = this.isJoined = function () { + return (_state === VAST.state.JOINED); + } + + // check if a given ID is an existing neighbor + var _isNeighbor = this.isNeighbor = function (id) { + return _neighbours.hasOwnProperty(id); + } + + // get a reference to the Voronoi object + this.getVoronoi = function () { + return _voro; + } + + // get a particular neighbor's info given its ID + this.getNeighbor = function (id) { + return (_neighbours.hasOwnProperty(id) ? _neighbours[id] : undefined); + } + + // get self info + this.getSelf = function () { + return _self; + } + + // get a list of edges known to the current node + this.getEdges = function () { + return _voro.getedges(); + } + + ///////////////////// + // internal methods + // + + // + // check helpers + // + + var _isSelf = function (id) { + return (_self.id == id); + } + + // is a particular neighbor within AOI + // NOTE: right now we only consider circular AOI, not rectangular AOI.. + // NOTE: l_aoi_buffer is a paramter passed to VON_peer when creating instance + var _isAOINeighbor = function (id, neighbor) { + return _voro.overlaps(id, neighbor.aoi.center, neighbor.aoi.radius + l_aoi_buffer, OVERLAP_CHECK_ACCURATE); + } + + // whether a neighbor is either 1) AOI neighbor or 2) an enclosing neighbor + // NOTE: enclosing neighbor is checked mutually, as it's possible + // for A to not consider B as enclosing neighbor, but B sees A as enclosing neighbor + var _isRelevantNeighbor = function (node1, node2) { + + return (_voro.is_enclosing(node1.id, node2.id) || + _isAOINeighbor(node1.id, node2) || + _isAOINeighbor(node2.id, node1)); + } + + // whether a neighbor has stayed alive with regular updates + // input period is in number of seconds + var _isTimelyNeighbor = function (id, period) { + return true; +/* + if (_isNeighbor (id) == false) + return false; + + var timeout = period * _net.getTimestampPerSecond (); + return ((_tick_count - _neighbors[id].endpt.lastAccessed) < timeout); +*/ + } + + // + // node management + // + + var _insertNode = function (node) { + + //log.debug('insertNode [' + node.id + '] isNeighbor: ' + _isNeighbor(node.id)); + + // check for redundency + if (_isNeighbor(node.id)) + return false; + + // notify network layer about connection info, no need to actually connect for now + _storeMapping(node.id, node.endpt.addr); + + // update last access time + node.endpt.lastAccessed = UTIL.getTimestamp(); + ////log.debug('last accessed: ' + node.endpt.lastAccessed); + + // store the new node to + _voro.insert(node.id, node.aoi.center); + + // store to neighbors + _neighbours[node.id] = node; + + // init mapping of neighbor's states + _neighbor_states[node.id] = {}; + + // TODO: still needed? + // record time to determine a neighbor is no longer active and can disconnect + _time_drop[node.id] = 0; + + // update node status + _updateStatus[node.id] = NeighborUpdateStatus.INSERTED; + + var meta_keys = node.hasOwnProperty('meta') ? Object.keys(node.meta).length : 0; + + //log.debug('[' + _self.id + '] insertNode neighbor (after insert) size: ' + Object.keys(_neighbours).length + + // ' voro: ' + _voro.size() + + // ' meta: ' + meta_keys); + + return true; + } + + var _deleteNode = function (id) { + + // NOTE: it's possible to remove self or EN, use carefully. + // we don't check for that to allow force-remove in + // the case of disconnection by remote node, or + // when leaving the overlay (removal of self) + if (_isNeighbor(id) === false) + return false; + + // remove from Voronoi & neighbor list + _voro.remove (id); + delete _neighbours[id]; + + + // update common neighbour list validity for each perceived common neighbour + for (var key in _nghbrsNghbrs[id]){ + _nghbrsNghbrsValid[key] = false; + } + // delete the list of common neighbours for the removed node + delete _nghbrsNghbrs[id]; + delete _nghbrsNghbrsValid[id]; + + // clean neighbor states + _neighbor_states[id] = undefined; + delete _neighbor_states[id]; + + delete _time_drop[id]; + _updateStatus[id] = NeighborUpdateStatus.DELETED; + + return true; + } + + var _updateNode = function (node) { + + if (_isNeighbor(node.id) === false) + return false; + + // only update the node if it's the same or a later time + if (node.time < _neighbours[node.id].time) + return false; + + _voro.update(node.id, node.aoi.center); + _neighbours[node.id].update(node); + + // update meta, if available + if (node.hasOwnProperty('meta')) + _neighbours[node.id].meta = node.meta; + + // NOTE: should not reset drop counter here, as it might make irrelevant neighbor + // difficult to get disconnected + //_time_drop[node.id] = 0; + + // update last access time of this node + node.endpt.lastAccessed = UTIL.getTimestamp(); + + // the common neighbours may have shifted, reset validity + for (var key in _nghbrsNghbrs[node.id]){ + _nghbrsNghbrsValid[key] = false; + } + _nghbrsNghbrsValid[node.id] = false; + + // set flag so that updated nodes' states are also sent + // instead of sending only updates for newly inserted node + if (_updateStatus.hasOwnProperty(node.id) === false || _updateStatus[node.id] !== NeighborUpdateStatus.INSERTED) + _updateStatus[node.id] = NeighborUpdateStatus.UPDATED; + + return true; + + + } + + // get a clean node to send (no extra stuff in 'node.aoi.center', for example) + // TODO: remove this? (will need to make sure all nodes are clean) + // do not keep anything else besides the original attributes + var _getNode = function (id) { + // REMOVED BY CFM TO IMPROVE SPEED; + // don't want to waste time creating and parseing node if we don't need its functions + + //var node = new VAST.node(); + //node.parse(_neighbours[id]); + + var node = _neighbours[id]; + var center = new VAST.pos(); + center.parse(node.aoi.center); + node.aoi.center = center; + return node; + } + + // + // regular processing (done periodically) + // + + // the master function for all things regular + // TODO: Generally find a better way of doing all of this. + // _tick() was removed for js version because of asynchronicity, + // but we need to regularly check the relevant neighbours, etc. + var _tick = function () { + //_sendKeepAlive(); + + var now = UTIL.getTimestamp(); + var dt = now - _lastTick;; + + try { + _contactNewNeighbors(); + _checkNeighborDiscovery(); + _removeNonOverlapped(); + } + catch (e) { + //log.error('tick error:\n' + e.stack); + } + + //adjust tick interval + if(dt > MAX_TICK_INTERVAL){ + TICK_INTERVAL = MAX_TICK_INTERVAL; + //log.warn('VON: max tick reached'); + }else{ + TICK_INTERVAL = dt; + } + + _lastTick = now; + + // set timeout is not memory-efficient, but I have bigger fish to fry + setTimeout(_tick, TICK_INTERVAL); + } + + + // self creation once self ID is obtained + var _setInited = function () { + + // update id & address info for self (we need valid self address for acceptor to contact) + _self.id = _getID(); + var addr = _msg_handler.getAddress(); + _self.endpt = new VAST.endpt(addr.host, addr.port); + + //log.warn('init myself as ' + _self.toString()); + + // store self node to neighbor map + _insertNode(_self); + + // if I'm gateway, no further action required + // TODO: doesn't look clean, can gateway still send query request to itself? + // that'll be a more general process + // (however, will deal with how to determined 'already joined' for gateway) + if (_self.id === VAST.ID_GATEWAY) + _setJoined(); + else + // send out query request first to find acceptor + _query(VAST.ID_GATEWAY, _self.aoi.center, VON_Message.VON_JOIN, _self); + + } + + // set current node to be 'joined' + // NOTE: should not do other init stuff (such as insert self to neighbor list) here + // otherwise VON_NODE message may be incorrectly processed + var _setJoined = function () { + + _state = VAST.state.JOINED; + + // notify join is done + if (typeof _join_onDone === 'function') + _join_onDone(_self.id); + + _tick(); + } + + var _sendKeepAlive = function () { + + // simply move a little to indicate keepalive + if (_isJoined() && _isTimelyNeighbor (_self.id, MAX_TIMELY_PERIOD/2) == false) { + //log.debug('[' + _self.id + '] sendKeepAlive ()', _self.id); + move(_self.aoi); + } + } + + var _contactNewNeighbors = function () { + + // check if any new neighbors to contact + if (Object.keys(_new_neighbors).length === 0) + return; + + // + // new neighbor notification check + // + var new_list = []; // list of new, unknown nodes + var target; + + ////log.debug('voro nodes before insertion: ' + _voro.size()); + + // loop through each notified neighbor and see if it's unknown + for (var target in _new_neighbors) { + + // NOTE: be careful that 'target' is now of type 'string', not 'number' + var new_node = _new_neighbors[target]; + + // ignore self + if (_isSelf(new_node.id)) + continue; + + // update existing info if the node is known, otherwise prepare to add + if (_isNeighbor(new_node.id)) + _updateNode(new_node); + else { + // insert to Voronoi first to see if this addition indeed is relevant to us + _voro.insert(new_node.id, new_node.aoi.center); + new_list.push(new_node.id); + } + } + + ////log.debug('voro nodes after insertion: ' + _voro.size()); + + // record a list of relevant neighbors to be inserted + var relevant_neighbors = []; + + // check through each newly inserted Voronoi for relevance + for (var i=0; i < new_list.length; ++i) { + + target = new_list[i]; + var node = _new_neighbors[target]; + + // if the neighbor is relevant and we insert it successfully + // NOTE that we're more tolerant for AOI buffer when accepting notification + if (_isRelevantNeighbor(node, _self)) { + + //log.debug('[' + node.id + '] is relevant to self [' + _self.id + ']'); + + // add a new relevant neighbor + // NOTE: we record first without inserting because we need to remove + // the new neighbor positions from Voronoi first + relevant_neighbors.push(node); + + // notify mapping for sending Hello message + // TODO: a cleaner way (less notifymapping call?) + _storeMapping(node.id, node.endpt.addr); + + // send HELLO message to newly discovered nodes + // NOTE that we do not perform insert yet (until the remote node has confirmed via MOVE) + // this is to avoid outdated neighbor discovery notice from taking effect + ////log.debug('before calling get_en, target: ' + target + ' node.id: ' + node.id); + ////log.debug('voro nodes before get_en: ' + _voro.size()); + + // NOTE: even if en_list is empty, should still send out HELLO + // empty can occur if initially just two nodes with overlapped positions + //_sendHello(target); + //_sendEN(target); + } + } + + // clear up the temporarily inserted test node from Voronoi (if not becoming neighbor) + for (var i=0; i < new_list.length; ++i) + _voro.remove(new_list[i]); + + // insert new neighbors + for (var i=0; i < relevant_neighbors.length; i++) { + _insertNode(relevant_neighbors[i]); + + // NOTE: even if en_list is empty, should still send out HELLO + // empty can occur if initially just two nodes with overlapped positions + _sendHello(relevant_neighbors[i].id); + _sendEN(relevant_neighbors[i].id); + } + + // NOTE: erase new neighbors seems to bring better consistency + // (rather than keep to next round, as in previous version) + _new_neighbors = {}; + + //log.debug('total neighbors (after process neighbors): ' + Object.keys(_neighbours).length); + //log.debug('total voro nodes: ' + _voro.size() + '\n'); + + // remove neighbours that may no longer be relevant + //_removeNonOverlapped(); (called in tick function) + + return; + } + + var _checkNeighborDiscovery = function (check_requester_only, check_en_only) { + + var req_size = Object.keys(_req_nodes).length; + if (req_size === 0) + return true; // done? + + ////log.debug(req_size + ' neighbors need neighbor discovery check'); + + // by default we check only those requested + if (check_requester_only === undefined) + check_requester_only = true; + + // by default all neighbors are potential candiates to notify + if (check_en_only === undefined) + check_en_only = false; + + var requesters = {}; + + // re-build request list if we need to check all neighbors (instead of those sending MOVE_B or MOVE_FB) + if (check_requester_only === true) + requesters = _req_nodes; + else + requesters = _neighbours; + + // build a list of nodes to be checked (can be either my enclosing neighbors, or all my neighbors) + var check_list; + if (check_en_only) + check_list = _voro.get_en(_self.id); + else { + check_list = []; + for (var id in _neighbours) + check_list.push(id); + } + + // list of new neighbors to notify a node requesting neighbor discovery + var notify_list; + + // go over each requesting node + for (var from_id in requesters) { + + // a node requesting for check might be disconnected by now, as requests are processed in batch + // TODO: is it correct? as this is event-driven now, maybe neighbor list can always be assumed to be correct + if (_isSelf(from_id) || _isNeighbor(from_id) === false) + continue; + + // TODO: determine whether clear or new is better / faster (?) + notify_list = []; + + var known_list = {}; // current neighbor's states + var state, known_state; + + for (var i=0; i < check_list.length; i++) { + + var id = check_list[i]; + + // avoid checking myself or the requester + if (_isSelf(id) || id === from_id) + continue; + + // TODO: + // do a simple test to see if this enclosing neighbor is + // on the right side of me if I face the moving node directly + // only notify the moving node for these 'right-hand-side' neighbors + + //if (right_of (id, from_id) == false) + // continue; + + // TODO: need to check whether values of states are correct + state = NeighborState.NEIGHBOR_REGULAR; + known_state = NeighborState.NEIGHBOR_REGULAR; + + if (_isAOINeighbor(id, _neighbours[from_id])) + state = state | NeighborState.NEIGHBOR_OVERLAPPED; + if (_voro.is_enclosing(id, from_id)) + state = state | NeighborState.NEIGHBOR_ENCLOSED; + + // notify case1: new overlap by moving node's AOI + // notify case2: new EN for the moving node + if (state != NeighborState.NEIGHBOR_REGULAR) { + + // TODO: check known_state correctness + if (_neighbor_states[from_id].hasOwnProperty(id)) + known_state = _neighbor_states[from_id][id]; + + // note: what we want to achieve is: + // 1. notify just once when new enclosing neighbor (EN) is found + // 2. notify about new overlap, even if the node is known to be an EN + + // check if the neighbors not overlapped previously is + // 1) currently overlapped, or... + // 2) previously wasn't enclosing, but now is + + if ((known_state & NeighborState.NEIGHBOR_OVERLAPPED) == 0 && + ((state & NeighborState.NEIGHBOR_OVERLAPPED) > 0 || + ((known_state & NeighborState.NEIGHBOR_ENCLOSED) == 0 && (state & NeighborState.NEIGHBOR_ENCLOSED) > 0))) + notify_list.push(id); + + // store the state of this particular neighbor + known_list[id] = state; + } + } + + // update known states about neighbors + delete _neighbor_states[from_id]; + _neighbor_states[from_id] = known_list; + + // notify only moving nodes of new neighbors + // NOTE: we still update neighbor states for all known neighbors + if (_req_nodes.hasOwnProperty(from_id) && notify_list.length > 0) + _sendNodes(from_id, notify_list); + } + + _req_nodes = {}; + + return; + } + + // check consistency of enclosing neighbors + var _checkConsistency = function (skip_id) { + + // NOTE: must make a copy of the enclosing neighbors, as sendEN will also call get_en () + // (still appliable in js?) + var en_list = _voro.get_en(_self.id); + + // notify my enclosing neighbors to check for discovery + for (var i=0; i < en_list.length; i++) { + var target = en_list[i]; + if (target != skip_id) + _sendEN (target); + } + } + + // remove neighbors no longer in view + var _removeNonOverlapped = function () { + + var now = UTIL.getTimestamp (); + + // check if we should perform check (should check no more than once per second) + if ((now - _lastRemoveNonOverlapped) < 1000) + return true; // done? + + // update check time + _lastRemoveNonOverlapped = now; + + // prepare neighbor list to remove + var delete_list = []; + + // wait time in milliseconds + //var grace_period = now + (MAX_DROP_SECONDS * 1000); + + // go over each neighbor and do an overlap check + //for (map::iterator it = _id2node.begin(); it != _id2node.end(); ++it) + for (var id in _neighbours) { + + // check if a neighbor is relevant (within AOI or enclosing) + // or if the neighbor still covers me + // NOTE: the AOI_BUFFER here should be slightly larger than that used for + // neighbor discovery, this is so that if a node is recently disconnect + // here, other neighbors can re-notify should it comes closer again + // TODO: possible to avoid checking every time, simply record some + // flag when messages come in, then check whether connection's still active? + // or.. simply use network timeout (if available)? + + if (_isSelf(id) === false && + _isRelevantNeighbor(_self, _neighbours[id], l_aoi_buffer * NONOVERLAP_MULTIPLIER) === false){ + delete_list.push(id) + } + + + //CFM 2021: removed timedrop + /* + if (_isSelf(id) || + (_isRelevantNeighbor(_self, _neighbors[id], l_aoi_buffer * NONOVERLAP_MULTIPLIER)) + && _isTimelyNeighbor(id)) { + _time_drop[id] = grace_period; + continue; + } + + // if current time exceeds grace period, then prepare to delete + if (now >= _time_drop[id]) { + delete_list.push(id); + delete _time_drop[id]; + } + */ + } + + // send BYE message to disconnected node + _sendBye(delete_list); + + return; + } + + // + // send helpers + // + + // send node infos (NODE message) to a particular target + // target: destination node id + // list: a list of neighbor id to be sent + // reliable: whether to deliver reliably + var _sendNodes = function (target, list, reliable) { + + //log.debug('_sendNodes: [' + _self.id + '] sends to [' + target + '] ' + list.length + ' nodes'); + + // we warn but do not prevent send (this is needed when gateway joins itself as client) + if (list.length === 0) { + //log.warn('sendNodes send out a list of 0 neighbors'); + } + + // grab the node info + var nodes = []; + for (var i=0; i < list.length; i++) + nodes.push(_getNode(list[i])); + + _sendMessage(target, VON_Message.VON_NODE, nodes, VAST.priority.NORMAL, reliable); + } + + // send a list of IDs to a particular node + // target: destination node id + // list: a list of id to be sent + var _sendHello = function (target) { + + ////log.warn('[' + _self.id + '] sendHello to [' + target + ']'); + + var node = _getNode(_self.id); + + //log.debug('meta keys: ' + Object.keys(_meta).length); + + // add app-specific attributes, if exist + // TODO: find a cleaner way (for example, meta already exists in the node returned by getNode) + if (Object.keys(_meta).length > 0) { + //log.debug('storing meta keys ' + Object.keys(_meta).length + ' to node to be sent for VON_HELLO'); + node.meta = _meta; + } + + // prepare HELLO message + // TODO: do not create new HELLO message every time? (local-side optimization) + _sendMessage(target, VON_Message.VON_HELLO, node, VAST.priority.HIGHEST, true); + } + + // send a particular node its perceived enclosing neighbors + var _sendEN = function (target) { + + var id_list = _voro.get_en(target); + if (id_list.length > 0) + _sendMessage(target, VON_Message.VON_EN, id_list, VAST.priority.HIGH, true); + } + + var _sendBye = function (targets) { + + var num_deleted = 0; + + if (targets.length > 0) { + + //log.debug('sendBye target size: ' + targets.length); + + var pack = new VAST.pack(VON_Message.VON_BYE, {}, VAST.priority.HIGHEST, _self.id); + pack.targets = targets; + _sendPack(pack, true); + + // perform node removal + for (var i=0; i < targets.length; i++) { + //log.debug('removing node: ' + targets[i]); + if (_deleteNode(targets[i]) === true) + num_deleted++; + } + } + + return num_deleted; + } + + // + // handlers for incoming messages, connect/disconnect + // + + // new ID assignment + var _new_ID = undefined; + var _assignNewID = function () { + + // we use our own ID as first + // NOTE if we start with VAST.ID_UNASSIGNED (0) then first ID will be 1 + if (_new_ID === undefined) + _new_ID = _getID() + 1; + + //log.warn('new ID assigned: ' + _new_ID); + return _new_ID++; + } + + var _packetHandler = this.packetHandler = function (from_id, pack) { + + // if node is not joined, do not process any message, unless it's response for + // getting ID (VON_PING) or neighbor list (VON_NODE) or handshake (VON_HELLO) + // NOTE: it's possible for VON_HELLO to arrive earlier than VON_NODE + /* + if (_state < VAST.state.JOINED) { + + if (pack.type !== VON_Message.VON_PING && + pack.type !== VON_Message.VON_NODE && + pack.type !== VON_Message.VON_HELLO) { + //log.error('VON_peer: node not yet joined, should not process any messages'); + return false; + } + } + */ + + if (_self.id === VAST.ID_UNASSIGNED && pack.type !== VON_Message.VON_PING) { + //log.error('VON_peer: node not yet init (got unique ID), should not process any messages'); + return false; + } + + //log.debug('[' + _self.id + '] ' + VON_Message_String[pack.type] + ' from [' + from_id + '], neighbor size: ' + Object.keys(_neighbours).length); + + switch (pack.type) { + + // VON's ping, to check if a connected host is still alive + case VON_Message.VON_PING: { + + // check if it's a request, respond to it + if (typeof pack.msg.request !== 'undefined' && pack.msg.request == true) { + + // if remote id is not yet assigned, assign new one + var remote_id = _assignNewID(); + //log.warn('assign new ID [' + remote_id + '] to [' + from_id + ']'); + + // check if this is the first ever ID assigned by me + // if so, then I'm likely the gateway (my ID is also unassigned yet) + if (_self.id === VAST.ID_UNASSIGNED) { + //log.warn('first ID assigned, likely I am the gateway'); + _self.id = remote_id; + } + + ////log.warn('VON_PING receive request, simply respond'); + _sendMessage(from_id, VON_Message.VON_PING, {request: false, aid: remote_id}, VAST.priority.HIGH, true); + } + // otherwise we got a response from gateway, set my ID, can now send join request + else if (_self.id === VAST.ID_UNASSIGNED) { + var assigned_id = parseInt(pack.msg.aid); + //log.debug('assigned_id: ' + assigned_id); + _setID(assigned_id); + _setInited(); + } + } + break; + + // VON's query, to find an acceptor to a given point + case VON_Message.VON_QUERY: { + + // extract message + var pos = new VAST.pos(); + pos.parse(pack.msg.pos); + //log.debug('VON_QUERY checking pos: ' + pos.toString()); + + // find the node closest to the joiner + var closest = _voro.closest_to(pos); + //log.debug('closest node: ' + closest + ' (' + typeof closest + ')'); + + // forward the request if a more appropriate node exists + // TODO: contains() might recompute Voronoi, isRelevantNeighbor below + // also will recompute Voronoi. possible to combine into one calculation? + if (closest === null) { + //log.warn('closest node is null, something is not right.. please check', 'VON_QUERY'); + } + + if (closest !== null && + _voro.contains(_self.id, pos) === false && + _isSelf(closest) === false && + closest != from_id) { + + ////log.warn('forward VON_QUERY request to: ' + closest); + + // re-assign target for the query request + pack.targets = []; + pack.targets.push(closest); + _sendPack(pack, true); + } + else { + + //log.debug('accepting VON_QUERY from: ' + from_id); + + // I'm the acceptor, re-direct message content to self + pack.type = pack.msg.type; + pack.msg = pack.msg.para; + pack.targets = []; + pack.targets.push(_self.id); + + // add from_id as this is not found elsewhere + // TODO: not clean to add to pack? + //pack.from_id = from_id; + + //log.debug('redirect to self: ' + JSON.stringify(pack)); + + // NOTE: need to check if this works correctly, to send back to self + //_sendPack(pack); + + // NOTE: has danger to enter infinite loop + // TODO: make some kind of msgqueue for sending? + _packetHandler(from_id, pack); + } + } + break; + + // VON's join, to learn of initial neighbors + case VON_Message.VON_JOIN: { + + // extract message + var joiner = new VAST.node(); + joiner.parse(pack.msg); + //log.debug('joiner: ' + joiner.toString()); + + // TODO: verify message in a systematic way + if (joiner.endpt.addr.isEmpty()) { + //log.error('joiner has no valid IP/port address, ignore request'); + break; + } + + // insert first so we can properly find joiner's EN + _insertNode(joiner); + + // if this is gateway receiving its own request + // TODO: to check correctness + if (Object.keys(_neighbours).length === 1) { + //log.warn('gateway getting its own VON_QUERY, return empty list'); + _sendNodes(from_id, [], true); + break; + } + + // I am the acceptor, send back initial neighbor list + var list = []; + + // loop through all my known neighbors and check which are relevant to the joiner to know + var out_str = ''; + for (var id in _neighbours) { + + var neighbor = _neighbours[id]; + ////log.debug('checking if neighbor [' + neighbor.id + '] should be notified'); + // store only if neighbor is both relevant and timely + // TODO: more efficient check (EN of joiner is calculated multiple times now) + + var is_relevant = _isRelevantNeighbor(neighbor, joiner); + //log.debug('is relevant: ' + is_relevant); + if (neighbor.id != joiner.id && + is_relevant && + _isTimelyNeighbor(neighbor.id)) { + list.push(neighbor.id); + out_str += neighbor.id + ' '; + } + } + + //log.debug('notify ' + list.length + ' nodes to joiner: ' + out_str); + if (list.length <= 1) { + //log.warn('too few neighbors are notified! check correctness\n'); + //log.debug(_voro.to_string()); + } + + // send a list of nodes to a specific target node + _sendNodes(joiner.id, list, true); + } + break; + + // process notifications for new nodes + case VON_Message.VON_NODE: { + + var nodelist = pack.msg; + for (var i=0; i < nodelist.length; i++) { + + // extract message + var new_node = new VAST.node(); + new_node.parse(nodelist[i]); + + //log.debug('node ' + new_node.toString()); + + _stat[pack.type].total++; + + // check data validity + /* + if (new_node.endpt.addr.isEmpty()) { + //log.error('new node has no valid IP/port address, ignore info'); + continue; + } + */ + + // store the new node and process later + // if there's existing notification, then replace only if newer + if (_new_neighbors.hasOwnProperty(new_node.id) === false || + _new_neighbors[new_node.id].time <= new_node.time) { + + //log.debug('adding node id [' + new_node.id + '] type: ' + typeof new_node.id); + + _stat[pack.type].normal++; + _new_neighbors[new_node.id] = new_node; + } + + } // end going through node list + + // process new neighbors immediately after learning new nodes + _contactNewNeighbors(); + + // if VON_NODE is received for the first time, we're considered joined + if (_state === VAST.state.JOINING) { + + // process new neighbors if we just joined, + // otherwise, do this periodically & collectively during tick + //_contactNewNeighbors(); + + // NOTE: we don't notify join success until neighbor list is processe + // so that upon join success, the client already has a list of neighbors + _setJoined(); + } + } + break; + + // VON's hello, to let a newly learned node to be mutually aware + // NOTE: it's found a node may already knows a neighbor even if it receives + // VON_HELLO for the first time + // this occurs when the current node first receives VON_QUERY and had inserted + // the joining node before + case VON_Message.VON_HELLO: { + + var node = new VAST.node(); + node.parse(pack.msg); + //log.debug('node: ' + node.toString()); + + // store meta data, if any + if (pack.msg.hasOwnProperty('meta') && typeof pack.msg.meta === 'object') { + //log.debug('VON_HELLO storing to node meta keys: ' + Object.keys(pack.msg.meta).length); + node.meta = pack.msg.meta; + } + + // update existing or new neighbor status + if (_isNeighbor(from_id)) + _updateNode(node); + else + _insertNode(node); + + // send HELLO_R as response (my own position, reliably) + // NOTE: we need to create a new pos as self.aoi.center has other properties (put by Voronoi) + // TODO: this should be clean-up + var pos = new VAST.pos; + pos.parse(_self.aoi.center); + var res_obj = { + pos: pos + }; + + // add meta-data, if any + if (Object.keys(_meta).length > 0) + res_obj.meta = _meta; + + _sendMessage(from_id, VON_Message.VON_HELLO_R, res_obj, VAST.priority.HIGH, true); + + // check if enclosing neighbors need any update + _checkConsistency(from_id); + } + break; + + // VON's hello response + case VON_Message.VON_HELLO_R: { + + // check if it's a response from an existing neighbor + if (_neighbours.hasOwnProperty(from_id) === true) { + + // update the neighbor's position + // NOTE: that 'time' is not updated here + var neighbor = _neighbours[from_id]; + neighbor.aoi.center.parse(pack.msg.pos); + + // store meta data, if any + if (pack.msg.hasOwnProperty('meta') && typeof pack.msg.meta === 'object') { + //log.debug('meta keys received: ' + Object.keys(pack.msg.meta).length); + neighbor.meta = pack.msg.meta; + } + + //log.debug('got latest pos: ' + neighbor.aoi.center.toString() + ' id: ' + from_id); + try { + _updateNode(neighbor); + } + catch(e) { + //log.debug(e.stack); + } + } + else{ + //log.warn('[' + _self.id + '] got VON_HELLO_R from unknown neighbor [' + from_id + ']'); + } + } + break; + + // VON's enclosing neighbor inquiry (to see if knowledge of EN is complete) + case VON_Message.VON_EN: { + + // + // check my enclosing neighbors to notify moving node any missing neighbors + // + + // check if the neighbor still exists + // (it's possible the neighbor will depart before VON_EN is processed) + // TODO: cleaner way to check? + if (_neighbours.hasOwnProperty(from_id) === false) { + //log.debug('neighbor [' + from_id + '] is no longer connected, ignore VON_EN request'); + break; + } + + // extract list of EN id received & create searchable list of EN + var id_list = pack.msg; + //log.debug('recv en_list size: ' + id_list.length); + + var list = {}; + for (var i=0; i < id_list.length; i++) { + var id = id_list[i]; + ////log.debug('en: ' + id); + list[id] = NeighborState.NEIGHBOR_OVERLAPPED; + } + + // enclosing neighbors missing from remote node's knowledge + var missing = []; + + // my view of my current enclosing neighbors + var en_list = _voro.get_en(_self.id); + + // store as initial known list + // TODO: do we need to update the neighbor_states here? + // because during neighbor discovery checks, each node's knowledge will be calculated + delete _neighbor_states[from_id]; + _neighbor_states[from_id] = list; + + var id; + for (var i=0; i < en_list.length; ++i) + { + id = en_list[i]; + + // send only relevant missing neighbors, defined as + // 1) not the sender node + // 2) one of my enclosing neighbors but not in the EN list received + // 3) one of the sender node's relevant neighbors + // + if (id != from_id && + list.hasOwnProperty(id) === false && + _isRelevantNeighbor (_neighbours[id], _neighbours[from_id])) + missing.push(id); + } + + // notify the node sending me HELLO of neighbors it should know + if (missing.length > 0) + _sendNodes(from_id, missing); + } + break; + + // VON's move, to notify AOI neighbors of new/current position + // VON's move, full notification on AOI + // VON's move for boundary neighbors + // VON's move for boundary neighbors with full notification on AOI + case VON_Message.VON_MOVE: + case VON_Message.VON_MOVE_F: + case VON_Message.VON_MOVE_B: + case VON_Message.VON_MOVE_FB: { + + // we only take MOVE from known neighbors + if (_isNeighbor(from_id) === false) + break; + + // extract full node info or just position update + var node = new VAST.node(from_id); + node.parse(pack.msg); + + // if the remote node has just been disconnected, + // then no need to process MOVE message in queue + if (_updateNode(node) === false) + break; + + // records nodes requesting neighbor discovery check + if (pack.type == VON_Message.VON_MOVE_B || pack.type == VON_Message.VON_MOVE_FB) + _req_nodes[from_id] = true; + + // check for neighbor discovery + _checkNeighborDiscovery(); + + // remove neighbors I'm no longer interested + _removeNonOverlapped(); + } + break; + + // VON's disconnecting a remote node + case VON_Message.VON_BYE: { + + // TODO: check if from_id is certainly the sending node's ID + if (_neighbours.hasOwnProperty(from_id)) { + _checkConsistency(from_id); + _deleteNode(from_id); + } + + // physically disconnect the node (or it will be done by the remote node) + var result = _disconnect(from_id); + //log.debug('disconnect succcess: ' + result); + //log.debug('after removal, neighbor size: ' + Object.keys(_neighbours).length); + } + break; + + // Message from matcher layer being routed through VON to a point + case VON_Message.MATCHER_POINT: { + + var closest = _voro.closest_to(pack.msg.targetPos); + + // Add myself to the chain + pack.msg.chain.push(_self.id); + + // I am not the nearest peer so forward it to the nearest neighbour + if (closest !== _self.id){ + pack.targets = []; + pack.targets.push(closest); + _sendPack(pack, true); + } + + // I am the nearest peer, so my matcher should handle it + else if ((_my_matcher !== undefined) && + (typeof _my_matcher.handlePacket === 'function')){ + _my_matcher.handlePacket(pack.msg); + } + } + break; + + // Message from matcher layer being routed through VON to an area + case VON_Message.MATCHER_AREA: { + + var closest = _voro.closest_to(pack.msg.targetAoI.center); + var recipients = Object.values(pack.msg.recipients); + + // Add myself to the chain + pack.msg.chain.push(_self.id); + + // I contain the center but I have already received the message + // something went wrong + if ((closest === _self.id) && recipients.includes(_self.id)){ + //log.warn('Area Message received more than once by center ['+_self.id+']'); + } + + // I contain the center. I am the first recipient + // NOTE: the first pack recipient is the center of the aoi. + if ((closest == _self.id) && recipients.length == 0){ + recipients.push(_self.id); + pack.msg.recipients = recipients; + } + + //I am not the nearest peer to centre and I am not a recipient, still finding the center + if (closest !== _self.id && !recipients.includes(_self.id)){ + pack.targets = []; + pack.targets.push(closest); + + _sendPack(pack, true); + } + // The center was found, now forwarding to overlapping neighbours + else { + _forwardOverlapping(pack.msg, function(updatedPacket){ + // the updated packet contains the newly discovered recipients + + // Give the updated message to my matcher + if ((_my_matcher !== undefined) && + (typeof _my_matcher.handlePacket === 'function')){ + _my_matcher.handlePacket(updatedPacket); + } + }); + } + } + break + + default: + // packet unhandled + return false; + break; + } + + // successfully handle packet + return true; + } + + var _connHandler = this.connHandler = function (id) { + //log.debug('VON peer [' + id + '] connected'); + } + + var _disconnHandler = this.disconnHandler = function (id) { + //log.debug('VON peer [' + id + '] disconnected'); + + // generate a VON_BYE message + var pack = new VAST.pack( + VON_Message.VON_BYE, + {}, + VAST.priority.HIGHEST, + _self.id); + + _packetHandler(id, pack); + } + + ///////////////////// + // msg_handler methods + // + + // clean up all internal states for a new fresh join + var _initStates = this.initStates = function (msg_handler) { + + //log.debug('initStates called'); + + if (msg_handler !== undefined) { + + _msg_handler = msg_handler; + + var id = _msg_handler.getID(); + ////log.warn('VON_peer initStates called with msg_handler, id: ' + id); + + // add convenience references + _storeMapping = _msg_handler.storeMapping; + _getID = _msg_handler.getID; + _setID = _msg_handler.setID; + _disconnect = _msg_handler.disconnect; + _sendMessage = _msg_handler.sendMessage; + _sendPack = _msg_handler.sendPack; + } + + // node state definition + _state = VAST.state.ABSENT; + + // list of AOI neighbors (map from node id to node) + _neighbours = {}; + + // a list of perceived neighbours for each neighbour, and whether they are valid + _nghbrsNghbrs = {}; + _nghbrsNghbrsValid = {}; + + // list of new neighbors (learned via VON_NODE messages) + _new_neighbors = {}; + + // record on EN neighbors (& their states) for each of my neighbor (used in VON_EN) + _neighbor_states = {}; + + _updateStatus = {}; + _req_nodes = {}; + _time_drop = {}; + + _lastRemoveNonOverlapped = 0; + + // create an object to calculate Voronoi diagram for neighbor mangement/discovery + _voro = new Voronoi(); + + // init stat collection for selected messsage types + _stat = {}; + _stat[VON_Message.VON_NODE] = new VAST.ratio(); + + // clear meta data + _meta = {}; + } + + ///////////////////// + // constructor + // + //log.debug('VON_peer constructor called'); + + // + // constructor actions + // + var _my_matcher; + + // set default AOI buffer size + l_aoi_buffer = l_aoi_buffer || AOI_DETECTION_BUFFER; + + // check whether AOI neighbor is defined as nodes whose regions + // are completely inside AOI, default to be 'true' + l_aoi_use_strict = l_aoi_use_strict || true; + + // + // handler-related + // + + // register with an existing or new message handler + // NOTE: to register, must provide: connHandler, disconnHandler, packetHandler + var _msg_handler = undefined; + + // convenience references + var _storeMapping, _getID, _setID, _disconnect; + var _sendMessage, _sendPack; + + // + // internal states + // + + // reference to self (NOTE: need to be initialized in init()) + var _self = new VAST.node(); + + // callback to use once join is successful + var _join_onDone = undefined; + + // callback to use once init is successful (got self ID from server) + var _init_onDone = undefined; + + // node state definition + var _state; + + // list of AOI neighbors (map from node id to node) + var _neighbours; + + // Our neighbours' neighbours (according to our local voro) + // if a node is updated or removed, neighbour's neighbours could + // become invalid for some / all entries in nghbrsNghbrs[node.id]; + var _nghbrsNghbrs = {}; + var _nghbrsNghbrsValid = {}; + + // TODO: combine these structures into one? + var _new_neighbors; // nodes worth considering to connect (learned via VON_NODE messages) + var _neighbor_states; // neighbors' knowledge of my neighbors (for neighbor discovery check) + var _req_nodes; // nodes requesting neighbor discovery check + + var _updateStatus; // status about whether a neighbor is: 1: inserted, 2: deleted, 3: updated + + var _time_drop; + + var _lastRemoveNonOverlapped; // last timestamp when removeNonOverlapped is called + + //CFM + var _lastTick; //timestamp of last tick event + + // create an object to calculate Voronoi diagram for neighbor mangement/discovery + var _voro; + + // init stat collection for selected messsage types + var _stat; + + // app-specific meta data + var _meta; + +} // end of peer + +// NOTE: it's important to export VONPeer after the prototype declaration +// otherwise the exported method will not have unique msg_handler instance +// (that is, all msg_handler variables will become singleton, only one instance globally) +if (typeof module !== 'undefined'){ + module.exports = VONPeer; +} + + + + /* OLD FORWARDING ALGORITHM + + // forward message to all overlapping neighbours + this.forwardOverlapping = function(areaPacket, callback){ + // get an array of overlapping neighbours (list of nodes) + var overlapping = _getOverlappingNeighbours(areaPacket.targetAoI); + + // array of node IDs that have already received the message (not always complete) + var recipients = Object.values(areaPacket.recipients); + + var chain = Object.values(areaPacket.chain); // "source" of nodes the message came from + + var newNeighbours = []; // array of overlapping neighbours who don't have the message yet + var recNeighbours = []; // array of my neighbours that are already recipients + + var id, targetNode, targetPos, tempNode, minDist, tempDist, minID; + + // For each overlapping neighbour + for (var i = 0; i < overlapping.length; i++){ + id = overlapping[i]; + + // The neighbour has already received the message + if (recipients.includes(id)){ + recNeighbours.push(id); + } + // The neighbour has not received the message. + else{ + newNeighbours.push(id); + recipients.push(id); + } + } + + chain.push(_self.id); + areaPacket.chain = chain; + areaPacket.recipients = recipients; + + // pass updated packet back + if (typeof callback == 'function'){ + callback(areaPacket); + } + + var VON_pack = new VAST.pack(VON_Message.MATCHER_AREA, areaPacket, VAST.priority.HIGHEST) + + // for each new neighbour, see if we should forward it + for (var j = 0; j < newNeighbours.length; j++){ + targetNode = _getNode(newNeighbours[j]); + targetPos = targetNode.aoi.center; + // distance to myself + minDist = targetPos.distance(_self.aoi.center); + minID = _self.id; + + // For each received neighbour, check distance + for (var k = 0; k < recNeighbours.length; k++){ + tempNode = _getNode(recNeighbours[k]); + tempDist = targetPos.distance(tempNode.aoi.center); + if (tempDist === minDist){ + minID = tempNode.id < minID ? tempNode.id : minID; + } + else if (tempDist < minDist){ + minDist = tempDist; + minID = tempNode.id; + } + } + + // Am I the closest common neighbour? + if(minID === _self.id){ + VON_pack.targets.push(targetNode.id); + } + } + + // send the packet to the targets + //console.//LOG('ID: ' + _self.id + ' fowarding area packet: '); + //console.//LOG(areaPacket); + //console.//LOG('Targets: ', VON_pack.targets); + + _sendPack(VON_pack, true); + } + */ \ No newline at end of file diff --git a/lib/VON_peer_worker.js b/lib/VON_peer_worker.js new file mode 100644 index 00000000..c9e0b9ce --- /dev/null +++ b/lib/VON_peer_worker.js @@ -0,0 +1,77 @@ +// Created by CF Marais 2021 +// a bit of a hack / experiment to see if the VON peer could be run in a different +// thread to improve performance. + +// The von peer is created inside a worker that runs under the matcher main process +require('./common.js'); +const {parentPort, workerData} = require('worker_threads'); + +console.log('worker thread created'); + + +var _id = workerData.id; +var _localIP = workerData.localIP; +var _port = workerData.port; +var _GWaddr = workerData.GWaddr; +var _pos = new VAST.pos(workerData.x, workerData.y) +var _aoi = new VAST.area(_pos, workerData.radius); +var _that = this; + +var _handlePacket = this.handlePacket = function(pack){ + var message = { + type : Worker_Message.MATCHER_MESSAGE, + packet : pack + }; + parentPort.postMessage(message); +} + +var _onParentMessage = function(message){ + + //console.log('worker received message ', message); + + switch (message.type) { + case Worker_Message.POINT_MESSAGE : { + //console.log('VON worker given point message'); + peer.pointMessage(JSON.parse(message.packet)); + } + break; + + case Worker_Message.AREA_MESSAGE : { + //console.log('VON worker given area message'); + peer.areaMessage(JSON.parse(message.packet)); + } + break; + } +} + +// initialise peer +var peer = new VON.peer(); + +parentPort.on('message', function(message){ + _onParentMessage(message); +}); + +parentPort.on('error', function(e){ + console.log('error on parent port ', e); +}) + + +peer.init(_id, _localIP, _port, _that, function(local_addr){ + _addr = local_addr; + + peer.join(_GWaddr, _aoi, + + // when finished joining, do callback + function (id) { + _id = id; + var message = { + type : Worker_Message.INIT, + id : _id, + addr : _addr + }; + parentPort.postMessage(message); + + console.log('joined successfully! id: ' + id + '\n'); + } + ); +}); \ No newline at end of file diff --git a/lib/client.js b/lib/client.js new file mode 100644 index 00000000..32bce8eb --- /dev/null +++ b/lib/client.js @@ -0,0 +1,349 @@ + +require('./common'); + +var Client_Message = { + PING : 0, + PONG : 1, + MSG: 2 +} + +function client(host, port, id, x, y, radius, onMatcherAssigned){ + + var log = LOG.newLayer('Clients_logs', 'Client_logs', 'logs_and_events', 5, 5); + + const io = require('socket.io-client'); + const crypto = require('crypto'); + var _io; + + var _id = id || 0; + var _hostname = UTIL.getHostname(); + var _GWaddr = { host: host, port: port }; + var _matcherID = VAST.ID_UNASSIGNED; + var _matcherAddr; + var _onMatcherAssigned = onMatcherAssigned; + var _subscriptions = {}; + + var _x = x==null || x == undefined ? Math.random()*1000 : x; + var _y = y==null || y==undefined ? Math.random()*1000 : y; + var _radius = radius == null || radius == undefined ? 16 : radius; + var _pos = new VAST.pos(_x,_y); + + var _pubCount = 0; + + + // Performance Measurement - unused + /* + const PING_TIMEOUT = 10000; // 10s + var PONGS = {}; // record of responses + var PINGS = []; // array of pings we have received + + var numPINGs = 0; + var numPONGs = 0; + + // Only record PINGS and PONGS (messages between clients) + var bytesSent = 0; // bytes + var bytesReceived = 0; // bytess + var msgsSent = 0; // messages sent + var msgsReceived = 0; // messages received + */ + + // stuff used by simulator/visualiser 2022/02/14 + var _alias = 'unnamed_client'; + this.getMatcherID = function(){ + return _matcherID; + } + + this.setAlias = function(alias){ + _alias = alias; + } + + this.getAlias = function(){ + return _alias; + } + + // Create socket connection with given host, port + var _connect = this.connect = function(host, port){ + if(_io !== undefined){ + _io.close(); + } + _io = io.connect('http://'+host+':'+port); + + // initialise event listeners + _io.on('connect', function(){ + log.debug('Client['+_id+']: socket connected') + }); + + // Matcher requesting our info + _io.on('request_info', function(info){ + var myInfo = { + matcherID : _matcherID, + matcherAddr : _matcherAddr, + hostname : _hostname, + clientID : _id, + pos : _pos + } + _io.emit('client_info', myInfo); + }); + + // GW Matcher assigning an ID and host matcher + _io.on('assign_matcher', function(pack){ + + var newMatcher = (_matcherAddr !== pack.matcherAddr); + _matcherID = pack.matcherID; + _matcherAddr = pack.matcherAddr; + _matcherPos = pack.matcherPos; + _id = pack.clientID; + + log.debug('Client['+_id+']: being migrated to Matcher['+pack.matcherID+']'); + + if (newMatcher) + _connect(_matcherAddr.host, _matcherAddr.port); + }); + + // We are connected to our assigned matcher, so we are "properly" initialised + _io.on('confirm_matcher', function(pack){ + _matcherID = pack.matcherID + _matcherAddr = pack.matcherAddr; + _matcherPos = pack.matcherPos; + _id = pack.clientID; + + log.debug('Client['+_id+']: assigned to matcher['+_matcherID+']'); + + if(typeof _onMatcherAssigned == 'function'){ + _onMatcherAssigned(_id); + } + }); + + // Matcher confirming / updating subscription + _io.on('subscribe_r', function(sub){ + var sub = sub; + log.debug('Client['+_id+']: added a subscription:'); + log.debug(sub); + _subscriptions[sub.subID] = sub; + }); + + // Matcher confirming subscription deletion + _io.on('unsubscribe_r', function(sub){ + var sub = sub; + log.debug('Client['+_id+']: removed subID: ' + sub.subID); + delete _subscriptions[sub.subID]; + }); + + _io.on('publication', function(pub){ + _handlePublication(pub); + }) + + _io.on('disconnect', function(){ + log.debug('Client['+_id+']: disconnected from matcher['+_matcherID+']'); + _disconnect(); + }) + } + + var _move = this.move = function(x, y){ + _pos.parse({x : x, y : y}); + _io.emit('move', _pos); + } + + // A static subscription (does not move with client) + var _subscribe = this.subscribe = function(x, y, radius, channel){ + log.debug('Client['+_id+']: subscribing to channel['+channel+'] at AoI['+x+'; '+y+'; '+radius+']'); + var msg = { + x : x, + y : y, + followClient : 0, + radius : radius, + channel : channel + }; + _io.emit('subscribe', msg); + } + + // A mobile subscription (AoI around client on channel) + var _subscribeMobile = this.subscribeMobile = function(radius, channel){ + var msg = { + x : _pos.x, + y : _pos.y, + followClient : 1, + radius : radius, + channel : channel + }; + _io.emit('subscribe', msg); + } + + var _publish = this.publish = function(x, y, radius, payload, channel){ + log.debug('Client['+_id+']: publishing to channel['+channel+'] with payload: '+ payload); + _pubCount++; + + var pack = { + pubID : _id + '-' + _pubCount, + x : x, + y : y, + radius : radius, + payload : payload, + channel : channel + }; + _io.volatile.emit('publish', pack); + + //msgsSent += 1; + //bytesSent += UTIL.sizeof(pack); + } + + /* + var _sendPING = this.sendPING = function(x, y, radius, bytes, channel){ + + numPINGs += 1; + bytes = parseInt(bytes) || 64; + + var time = UTIL.getTimestamp(); + + var payload = { + type : Client_Message.PING, + sourcePos : _pos, + radius : radius, + pinger : _id, + pingID : _id + '-' + numPINGs, + sendTime : time, + bytes : crypto.randomBytes(bytes) + } + + // preallocate the response storage + PONGS[payload.pingID] = { + sendTime : payload.sendTime, + ids : [], + totLat : 0, + minLat : 0, + maxLat : 0, + avgLat : 0 + } + + _publish(x, y, radius, payload, channel); + + } + */ + + var _unsubscribe = this.unsubscribe = function(subID){ + _io.emit('unsubscribe', subID); + } + + var _clearSubscriptions = this.clearSubscriptions = function(){ + for (var key in _subscriptions){ + _unsubscribe(key); + } + } + + var _disconnect = this.disconnect = function(){ + _subscriptions = {}; + + } + + var _handlePublication = function(pub){ + var type = pub.payload.type; + + /* + bytesReceived += UTIL.sizeof(pub); + msgsReceived += 1; + */ + + switch (type) { + + default :{ + log.debug('Client['+_id+']: received publication from Client['+pub.clientID+'] with payload: '+pub.payload); + } + + /* + // received a PING, respond with PONG targeted at source + case Client_Message.PING:{ + //log.debug('received PING from client: ' + pub.payload.pinger); + + var pingID = pub.payload.pingID; + if (PINGS.includes(pingID)){ + var dup = { + type : 'PING', + sendTime : pub.payload.sendTime, + pingID : pub.payload.pingID, + fromID : pub.payload.pinger + } + recDuplicates.write(dup, 'client-' + _id + '-duplicates'); + log.debug('Client['+_id+']: Duplicate PING from: ' + pub.payload.pinger); + break; + } + + //PINGS.push(pingID); + + var x = pub.payload.sourcePos.x; + var y = pub.payload.sourcePos.y; + var radius = 0.1; // ~ point publication for PONG's + var payload = { + type : Client_Message.PONG, + sourcePos : _pos, + radius : pub.payload.radius, + pinger : pub.payload.pinger, + sendTime : pub.payload.sendTime, + pingID : pingID, + bytes : pub.payload.bytes + } + + _publish(x, y, radius, payload, payload.pinger); + } + break; + + // received a response for our PING + case Client_Message.PONG:{ + + //log.debug('received PONG from client: ' + pub.clientID); + var now = UTIL.getTimestamp(); + var sendTime = pub.payload.sendTime; + var lat = (now - sendTime)/2; + + // discard if this is not a response to our PING (spatial messages might overlap with our subs) + // also discard if it is too late + if (pub.payload.pinger !== _id || now - sendTime > PING_TIMEOUT){ + break; + } + + var pingID = pub.payload.pingID; + var fromID = pub.clientID; + + var pong = PONGS[pingID]; + + if(pong.ids.includes(fromID)){ + var dup = { + type : 'PONG', + sendTime : sendTime, + pingID : pingID, + fromID : fromID + } + recDuplicates.write(dup, 'client-' + _id + '-duplicates'); + log.debug('Client['+_id+']: received a duplicate PONG from: ' + fromID); + } else { + log.debug('Client['+_id+']: PONG from ' + fromID); + } + + pong.ids.push(fromID); + + // first response + if(pong.ids.length === 1){ + pong.minLat = lat; + pong.maxLat = lat; + }else{ + pong.minLat = lat < pong.minLat ? lat : pong.minLat; + pong.maxLat = lat > pong.maxLat ? lat : pong.maxLat; + } + + pong.totLat += lat; + pong.avgLat = pong.totLat / pong.ids.length; + + // add this pong to the list + PONGS[pingID] = pong; + + numPONGs += 1; + } + break; + */ + } + } + _connect(_GWaddr.host, _GWaddr.port); +} + +if (typeof module !== "undefined"){ + module.exports = client; +} \ No newline at end of file diff --git a/lib/common.js b/lib/common.js new file mode 100755 index 00000000..171e643a --- /dev/null +++ b/lib/common.js @@ -0,0 +1,143 @@ + +/* + common definitions for VAST.js +*/ + +// +// utilities +// + +// define log if not defined +if (typeof global.LOG === 'undefined') { + var logger = require('./common/logger'); + global.LOG = new logger(); +} + +// config for tests +global.CONF = { + msg_min_time : 1000, // min ms between message publications + msg_max_time : 2000, // max ms between message publications + msg_radius : 1000, // radius of published messages + x_lim : 1000, // size of "map" x[0...x_lim] + y_lim : 1000 +}; + + +// +// VAST & VON +// +global.UTIL = require('./common/util'); + +global.VAST = require('./types'); +global.VAST.net = require('./net/vast_net'); +//global.VAST.client = require('./client'); +//global.VAST.matcher = require('./matcher'); + +// ID definitions +global.VAST.ID_UNASSIGNED = 0; +global.VAST.ID_GATEWAY = 1; + +// msg types sent between VON peer worker and matcher +global.Worker_Message = { + INIT : 0, // When VON peer is joined + MATCHER_MESSAGE : 1, // when VON peer is giving a packet to the matcher + POINT_MESSAGE : 2, // when matcher is sending a point message to VON + AREA_MESSAGE : 3 // when matcher is sending an area message to VON +} + +// enumation of VON message +global.VON_Message = { + VON_BYE: 0, // VON's disconnect + VON_PING: 1, // VON's ping, to check if a connected neighbor is still alive + VON_QUERY: 2, // VON's query, to find an acceptor to a given point + VON_JOIN: 3, // VON's join, to learn of initial neighbors + VON_NODE: 4, // VON's notification of new nodes + VON_HELLO: 5, // VON's hello, to let a newly learned node to be mutually aware + VON_HELLO_R: 6, // VON's hello response + VON_EN: 7, // VON's enclosing neighbor inquiry (to see if my knowledge of EN is complete) + VON_MOVE: 8, // VON's move, to notify AOI neighbors of new/current position + VON_MOVE_F: 9, // VON's move, full notification on AOI + VON_MOVE_B: 10,// VON's move for boundary neighbors + VON_MOVE_FB: 11,// VON's move for boundary neighbors with full notification on AOI + MATCHER_POINT: 12,// Packets/Messages sent to a point, between matchers over VON + MATCHER_AREA: 13 // Packets/Messages sent to an area, between matchers over VON +}; + +global.VON_Message_String = [ + 'VON_BYE', + 'VON_PING', + 'VON_QUERY', + 'VON_JOIN', + 'VON_NODE', + 'VON_HELLO', + 'VON_HELLO_R', + 'VON_EN', + 'VON_MOVE', + 'VON_MOVE_F', + 'VON_MOVE_B', + 'VON_MOVE_FB', + 'MATCHER_POINT', + 'MATCHER_AREA' +]; + +// enumation of Matcher message +global.Matcher_Message = { + FIND_MATCHER: 0, // Find the matcher for a given position + FOUND_MATCHER: 1, // Found the matcher, receiving its info + PUB: 2, + PUB_MATCHED: 3, // sent a pub to the owner of a matching subscription + SUB_NEW: 4, + SUB_MIGRATE: 5, + SUB_UPDATE: 6, + SUB_DELETE: 7, + MOVE_CLIENT: 8, + MOVE_CLIENT_R: 9, + MOVE_SUBS: 10, + MOVE_SUBS_R: 11 + +}; + +global.Matcher_Event = { + MATCHER_JOIN : 0, + MATCHER_MOVE : 1, + CLIENT_JOIN : 2, + CLIENT_MOVE : 3, + CLIENT_LEAVE : 4, + SUB_NEW : 5, + SUB_UPDATE : 6, + SUB_DELETE : 7, + PUB : 8 +} + +// TODO: find a better way to store this? (maybe in msg_handler?) +global.VAST.state = { + ABSENT: 0, + // INIT: 1, // init done + JOINING: 2, // different stages of join + JOINED: 3 +}; + +global.VAST.priority = { + HIGHEST: 0, + HIGH: 1, + NORMAL: 2, + LOW: 3, + LOWEST: 4 +}; + +// TODO: combine into nicer-looking global +global.VAST.msgtype = { + BYE: 0, // disconnect + PUB: 1, // publish request + SUB: 2 // subscribe request +}; + +global.VAST.msgstr = [ + 'BYE', + 'PUB', + 'SUB' +]; + +global.VON = { + peer: require('./VON_peer') +}; diff --git a/lib/common/example.js b/lib/common/example.js new file mode 100644 index 00000000..558014c2 --- /dev/null +++ b/lib/common/example.js @@ -0,0 +1,23 @@ +require('../common.js'); + +// create logging layers +var layerA = LOG.newLayer('layerA', 'file1', 'textfiles'); +var layerB = LOG.newLayer('layerB', 'file2', 'textfiles'); + +// layers may write to the same file (file1 is shared) +var layerC = LOG.newLayer('layerC', 'file1', 'textfiles'); + +// set debug priotiry levels (display, recording) +layerA.setLevels(5, 5); // display all, print all +layerB.setLevels(5, 5); +layerC.setLevels(1, 5); // display only errors, print all + +layerA.debug('hello file 1. hello console.'); +layerB.debug('hello file 2, also in the console'); +layerC.debug('printing to file 1 again, but not shown in console'); + +layerC.error('Errors are still displayed in the console'); + +// change priority levels and test +layerC.setLevels(5, 0); // display all, do not print +layerC.debug('Im in the console only'); diff --git a/lib/common/logger.js b/lib/common/logger.js new file mode 100755 index 00000000..a5b12a9d --- /dev/null +++ b/lib/common/logger.js @@ -0,0 +1,197 @@ +/* + logger for vast.js + + To use, create a new layer (layers may be reused / shared) and call the + debug, sys, etc. functions. + + TODO: + - closeLayer() + - layer protections? write streams overwrite old files... + - potentially .csv functionality. Not a priority + +*/ + +let fs = require('fs'); + +function logger() { + + // Structures for logger layers, recording streams + let _layers = []; + let _streams = []; + + // color control codes + let _green = '\033[32m'; + let _red = '\033[31m'; + let _white = '\033[m'; + let _yellow = '\033[33m'; + + let _ERR = _red; + let _ERREND = _white + let _WARN = _yellow; + + // convert obj to msg + let _convert = function (obj) { + return (typeof obj === 'object' ? JSON.stringify(obj) : obj); + } + + // get current time + let _curr_time = function () { + var currDate = new Date(); + return currDate.getTime(); + //return '-' + currDate.getHours() + ':' + currDate.getMinutes() + '- '; + } + + // add a new layer + // TODO: add extensions? currently defaults to .txt in record.js + // TODO: merge layername and filename. No real need for both if its 1-to-1 relationship. Asking for bugsss.. + this.newLayer = function (layername, filename, directory, displayLevel, recordLevel){ + var path = directory+'/'+filename; + + // check if the layer already exists + if (_layers.hasOwnProperty(layername)){ + //_layers[layername].warn('Logging layer "' + layername + '" already exists.'); + } + + // create the new layer + else { + + // Check if an open write stream exists for this file. + // only create if recordLevel > 0 + if (!_streams.hasOwnProperty(path) && recordLevel > 0){ + _streams[path] = new stream(filename, directory); + } + + _layers[layername] = new layer(layername, displayLevel, recordLevel, _streams[path]); + } + + // return reference to layer + return _layers[layername]; + } + + let layer = function(layername, displayLevel, recordLevel, stream){ + let _layername = layername; + let _displayLevel = typeof(displayLevel) == 'number' ? displayLevel : 1; // by default, display errors only + let _recordLevel = typeof(displayLevel) == 'number' ? recordLevel : 0; // by default, do not write to a file + let _stream = stream; + + // SET LEVELS WILL BREAK IF RECORDLEVEL = 0 set to > 1 + // Do not reimplement unless ablsolutely neccessary + /* + this.setLevels = function(displayLevel, recordLevel){ + _displayLevel = displayLevel; + _recordLevel = recordLevel; + } + */ + + this.close = function(){ + delete _layers[_layername]; + } + + // going to be used for printing "event" or "state" type objects to a results file + + this.printObject = function(obj){ + var obj = JSON.stringify(obj); + + if (_displayLevel >= 1) + console.log(obj); + + if (_recordLevel >= 1) + _stream.writeLine(obj); + } + + + this.sys = function (msg) { + //msg = _curr_time()() + _convert(msg); + msg = _convert({time: _curr_time(), msg: msg}); + if (_displayLevel >= 4) + console.log(msg); + + if (_recordLevel >= 4) + _stream.writeLine(msg); + } + + this.debug = function (msg) { + msg = _convert({time: _curr_time(), msg: msg}); + if (_displayLevel >= 3) + console.log(msg); + + if (_recordLevel >= 3) + _stream.writeLine(msg); + } + + this.warn = function (msg) { + msg = _convert({time: _curr_time(), msg: msg}); + if (_displayLevel >= 2) + console.log(_WARN + msg + _ERREND); + + if (_recordLevel >= 2) + _stream.writeLine(msg); + } + + this.error = function (msg) { + msg = _convert({time: _curr_time(), msg: msg}); + if (_displayLevel >= 1) + console.log(_ERR + msg + _ERREND); + + if (_recordLevel >= 1) + _stream.writeLine(msg); + } + + this.stack = function () { + var e = new Error('dummy'); + var stack = e.stack.replace(/^[^\(]+?[\n$]/gm, '') + .replace(/^\s+at\s+/gm, '') + .replace(/^Object.\s*\(/gm, '{anonymous}()@') + .split('\n'); + console.log(stack); + } + } +} + +let stream = function(filename, directory, extension) { + let _filename = filename; + let _directory = directory; + let _extension = extension || '.txt'; + let _path = process.cwd(); + let _stream; + + let _init = function(){ + if (!fs.existsSync(_path+'/'+_directory)) { + console.log("creating directory " + _path+'/'+_directory) + fs.mkdirSync(_path+'/'+_directory, { recursive: true}, (error) => { + if (!error) + console.log("Directory created in here") + }); + } + + try { + _stream = fs.createWriteStream(_path+'/'+_directory+'/'+_filename+_extension); + } + catch (e) { + console.log("Cannot find directory. Create it"); + fs.mkdirSync(_path+'/'+_directory); + _stream = fs.createWriteStream(_path+'/'+_directory+'/'+_filename+_extension); + } + } + + this.writeLine = function(data) { + // only stringify if not already a string. (Avoid double quotations) + data = typeof data === 'object' ? JSON.stringify(data) + '\n' : data + '\n'; + try { + _stream.write(data); + } catch (e) { + console.log('Cannot write to ' + _path + '/' + _directory + '/' + _filename + _extension); + console.log('error:', e); + } + } + + this.close = function(){ + _stream.end(); + } + + _init(); +} + +if (typeof module !== 'undefined'){ + module.exports = logger; +} \ No newline at end of file diff --git a/lib/common/util.js b/lib/common/util.js new file mode 100755 index 00000000..9cedc811 --- /dev/null +++ b/lib/common/util.js @@ -0,0 +1,174 @@ + +/* + common utilities for vast.js +*/ + +const http = require('http'); +const https = require('https'); +const url = require('url'); + +// returns number of milliseconds since 1970 +exports.getTimestamp = function () { + var now = new Date(); + return now.getTime(); +} + +exports.parseAddress = function (ip_port) { + + var addr = {host: '', port: 0}; + + // check if this is port only + var idx = ip_port.search(':'); + + // ':' not found, port only + if (idx === (-1)) + addr.port = parseInt(ip_port); + else { + addr.host = ip_port.slice(0, idx); + addr.port = ip_port.slice(idx+1, ip_port.length); + } + + return addr; +} + +// +// support for HTTP requests (GET/POST) +// + +// helper to send HTTP post request to an URL with JSON parameters +// ref: http://stackoverflow.com/questions/6158933/http-post-request-in-node-js +// onDone = function(error, response) +var l_HTTPpost = exports.HTTPpost = function (url_request, data_obj, onDone) { + + // parse the url first to extract different fields + var parsed_url = url.parse(url_request); + + // Build the post string from an object to string format + //var data = querystring.stringify(data_obj); + var data = encodeURIComponent(JSON.stringify(data_obj)); + + //LOG.warn('POSTing to: ' + url_request + ':'); + //LOG.warn(data); + + // An object of options to indicate where to post to + var options = { + host: parsed_url.hostname, + port: parsed_url.port, + path: parsed_url.path, + method: 'POST', + headers: { + //'Connection': 'keep-alive', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': data.length + } + }; + + // setup server to HTTP or HTTPS + var server = (url_request.indexOf('https') === 0 ? https : http); + + // Set up the request + var req = server.request(options, function (res) { + + res.setEncoding('utf8'); + + // TODO: check for 'end' event? + res.on('data', function (chunk) { + LOG.sys('HTTP Post response: ' + chunk); + // return some positive data + //onDone(null, res, chunk); + onDone(chunk, res); + }); + }); + + req.on('error', function (e) { + LOG.error("HTTP post error: " + e.message); + onDone(e); + }); + + // post the data + req.write(data); + req.end(); +} + + +// helper to send a HTTP get request to an URL and get response +// TODO: this is borrowed from ImonCloud, possibly share them? +var l_HTTPget = exports.HTTPget = function (url, onDone) { + + LOG.warn(url); + + // send request to app server to get stat + http.get(url, function (res) { + + // temp buffer for incoming request + var data = ''; + + res.on('data', function (chunk) { + data += chunk; + }); + + res.on('end', function() { + + var JSONobj = undefined; + try { + if (data !== '') + JSONobj = JSON.parse(data); + } + catch (e) { + LOG.error('JSON parsing error for data: ' + data); + onDone(null); + } + + // return parsed JSON object + onDone(JSONobj); + }) + + }).on('error', function(e) { + + LOG.error("HTTP get error: " + e.message); + onDone(null); + }); +} + +// get my hostname +exports.getHostname = function(){ + var os = require('os'); + return os.hostname(); +} + + +// get the local IP address, only IPv4 +exports.getIPAddress = function (CB_done) { + var interfaces = require('os').networkInterfaces(); + for (var devName in interfaces) { + var iface = interfaces[devName]; + + for (var i = 0; i < iface.length; i++) { + var alias = iface[i]; + // Preferably, do not return '127.0.0.1'. Need to share our public address over the network + if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) + return CB_done(alias.address); + } + } + // return '127.0.0.1' if no other address is found + return CB_done('127.0.0.1'); +} + +exports.sizeof = function(obj){ + return Buffer.byteLength(JSON.stringify(obj)); +} + + +exports.lookupIP = function (hostname, CB_done){ + + require('dns').lookup(hostname, function (err, addr, fam) { + if (err) { + console.log(err + '. No IP for given hostname'); + } + else { + CB_done(addr); + } + }) +} + + diff --git a/lib/matcher.js b/lib/matcher.js new file mode 100755 index 00000000..8e6b5fcf --- /dev/null +++ b/lib/matcher.js @@ -0,0 +1,964 @@ +// Matcher for SPS system. + +const client = require('./client.js'); + +/* +TODO: + - Fix _unsubscribe(subID); + - Assign unique client IDs in distributed manner (so that multiple GWs may be used) + - Implement mobile client subscriptions (follow client position) + - Publication buffer / queue? +*/ + +//imports +require('./common.js'); + +// export the class with conditional check +if (typeof module !== "undefined") + module.exports = matcher; + +function matcher(x, y, radius, opts, onJoin) { + + // Define default options + let _default = { + alias : 'Matcher', // Used by the simulator to give each matcher a name other than it's ID. + isGateway : false, // Am i the gateway peer (for VON and for clients) + GW_host : '127.0.0.1', + GW_port : 8000, // The port of the VON gateway peer that i initially connect to + VON_port : 8001, // listen for other VON peers on this port (will increment until open port is found) + client_port : 20000, // listen for client connections on this port (will incrementv until open port is found) + useMQTT : false, // use with modified aedes MQTT broker? + clientDisconnectTime : 100, // timeout before subscriptions are assumed fully migrated between matchers + subLifeTime : 60000, // life without receiving heartbeat (1 min) + + // debug logs and events recording (for use in visualiser) + // TODO: merge layername and filename. No real need for both if its 1-to-1 relationship. Asking for bugsss.. + logLayer : 'Matcher_logs', + eventsLayer : 'Matcher_events', + logFile : 'Matcher_logs', + eventsFile : 'Matcher_events', + logDirectory : 'logs_and_events', + eventsDirectory : 'logs_and_events', + logRecordLevel : 0, + eventRecordLevel : 0, + logDisplayLevel : 3, + eventDisplayLevel : 0 + } + + // set modified options + let _opts = _default; + for (var option in opts){ + _opts[option] = opts[option]; + } + + // Assign alias, ID and GateWay address + var _alias = _opts.alias; + var _id = _opts.isGateway === true ? VAST.ID_GATEWAY : VAST.ID_UNASSIGNED; + var _GWaddr = { host: _opts.GW_host, port: _opts.GW_port }; + + // Assign my VON and client listening ports + var _VON_port = _opts.isGateway === true ? _opts.GW_port : _opts.VON_port; + var _client_port = _opts.client_port; + + // timeout for migrating subscriptions and KEEP ALIVE + var _clientDisconnectTime = _opts.clientDisconnectTime; + var _subLifeTimeout = _opts.subLifeTime; + + // Set up MQTT broker + var _useMQTT = _opts.useMQTT; + if (_useMQTT === true && typeof(_opts.broker) !== undefined){ + var _broker = this.broker = _opts.broker; + } + + // Define AoI and Position + var _x = x == null || x == undefined ? Math.random()*CONF.x_lim : x; + var _y = y == null || y == undefined ? Math.random()*CONF.y_lim : y; + var _radius = radius == undefined ? 1 : radius; + var _pos = new VAST.pos(_x,_y); + var _aoi = new VAST.area(_pos, _radius); + + + // Setup socket for client <--> matcher communication + const _http = require('http').createServer(); + const _io = require('socket.io')(_http, { + cors: { + origin: "*" + } + }); + + var _addr, _socketAddr; + + // set up log layers for debugging and for status updates + let log = LOG.newLayer(_opts.logLayer, _opts.logFile, _opts.logDirectory, _opts.logDisplayLevel, _opts.logRecordLevel); + let events = LOG.newLayer(_opts.eventsLayer, _opts.eventsFile, _opts.eventsDirectory, _opts.eventDisplayLevel, _opts.eventRecordLevel); + + // matches a socket to a connectionID + var _socketID2clientID = this.socketID2clientID = {}; + var _clientID2socket = this.clientID2socket = {} + + var _mqttID2clientID = this.mqttID2clientID = {}; + var _clientID2mqttID = this.clientID2mqttID = {}; + + var _clientList = {}; + var _leavingClients = {}; + var _pendingClients = {}; + + var _connectionCount = 0; + var _clientCount = 0; + + // list of subscriptions (clientID is primary key, subID is secondary key) + var _subscriptions = {}; + var _migratingSubs = {}; + + // convenient list of only subs hosted by me + var _hostSubs = {}; + + log.debug('Matcher['+_id+']: useMQTT: '+_useMQTT); + + // Reference to self + var _that = this; + + var _onJoin = onJoin; + + var _vonPeer = new VON.peer(); + + // _id must remane private + this.id = function(){ + return _id + } + + var _init = function(callback){ + + // initialise VON peer + _vonPeer.init(_id, _addr.host, _addr.port, _that, function(addr){ + _addr = addr; + + _vonPeer.join(_GWaddr, _aoi, function(id){ + _id = id; + log.debug('Matcher['+_id+']: VON peer joined successfully'); + + _initListeners(); + _listen(); + _checkSubscriptions(); + + if(typeof callback === 'function'){ + callback(); + } + if (typeof _onJoin == 'function'){ + _recordEvent(Matcher_Event.MATCHER_JOIN); + onJoin(_id); + } + }) + }) + } + + // This function is called in VON peer when a message of type VON_Message.MATCHER_FORWARD is received + // i.e. this packet comes from other matchers + this.handlePacket = function(pack){ + var msg = pack.msg; + + switch (pack.type) { + + // Overlapping / distant publication is being received by relevant matchers + case Matcher_Message.PUB: { + + log.debug('Matcher['+_id+']: Received Publication from Matcher['+pack.sender+']', msg); + + var pub = msg; + pub.recipients = pack.recipients; + pub.chain = pack.chain; + + _sendPublication(pub, true); + break; + } + + // A distant / overlapping subscription received a publication. The publication is now being forwarded to me + // because I am the host to the relevant client. (Unless the subscriptions are not yet migrated) + case Matcher_Message.PUB_MATCHED: { + + log.debug('Matcher['+_id+']: Matched Publication from Matcher['+pack.sender+']' + 'from Client['+pack.msg.clientID+']'); + + var pub = msg; + + _sendPublication(pub, false); + break; + } + + // A new subscription is being added in my area. + case Matcher_Message.SUB_NEW : { + log.debug('Matcher['+_id+']: New Sub from Matcher['+pack.sender+']', msg); + var sub = msg; + + // update recipients to the subscription + sub.recipients = pack.recipients + + _addSubscription(sub, false); + break; + } + + case Matcher_Message.SUB_UPDATE :{ + var sub = msg; + sub.recipients = pack.recipients; + _updateSubscription(sub); + } + break; + + // A subscription was deleted + case Matcher_Message.SUB_DELETE : { + log.debug('Matcher['+_id+']: Sub deletion from Matcher['+pack.sender+']', msg); +; + _deleteSubscription(msg); + } + break; + + // A client move request was received, the position is within my region + case Matcher_Message.MOVE_CLIENT : { + + // The message is not from me, so the client is moving into my region + // Respond with a MOVE_CLIENT_R message + if (pack.sender !== _id){ + + log.debug('Matcher['+_id+']: Migrate client['+msg.clientID+'] from matcher['+pack.sender+'] for pos['+pack.targetPos.x+'; '+ pack.targetPos.y+']'); + + //Add client to my pending list + _pendingClients[msg.clientID] = { + id: msg.clientID, + pos: msg.clientPos, + matcherID: _id, + matcherPos : _pos + } + + // TODO: clientAccept can be used to balance load/indicate overload + // send back my details so pending client can join + + let new_msg = { + clientAccept : true, + matcherID : _id, + matcherPos : _pos, + matcherAddr : _socketAddr, + clientID : msg.clientID, + clientPos : msg.pos + } + let new_pack = new VAST.pointPacket(Matcher_Message.MOVE_CLIENT_R, new_msg, _id, _pos, pack.sourcePos) + _vonPeer.pointMessage(new_pack); + } + + } + break; + + // A client is moving out of my region, i must migrate them to a new matcher + case Matcher_Message.MOVE_CLIENT_R :{ + // I am connected to the client + if (_clientList[msg.clientID] !== undefined && _clientID2socket[msg.clientID] !== undefined) { + + log.debug('Matcher['+_id+']: migrating client['+msg.clientID+'] to matcher['+msg.matcherID+']'); + + // I am receiving the details of the matcher to which this client must transfer. + // send the client's subs to the new matcher to prepare + + if (msg.clientAccept == true){ + + // give the new matcher an updated list (it must know it's the host) + let subs = _subscriptions[msg.clientID]; + for (var subID in subs){ + subs[subID].changeHost(msg.matcherID, msg.matcherPos); + } + + let new_msg = { + matcherID : _id, + matcherPos : _pos, + clientID : msg.clientID, + pos : msg.pos, + subs : subs + } + + let new_pack = new VAST.pointPacket(Matcher_Message.MOVE_SUBS, new_msg, _id, _pos, pack.sourcePos); + _vonPeer.pointMessage(new_pack); + } + // TODO: Client not accepted / overload procedure + //else + + + } + } + break; + + case Matcher_Message.MOVE_SUBS :{ + // I am receiving the subscriptions for one of my pending clients + let subs = msg.subs; + for(var subID in subs){ + _addSubscription(subs[subID], true); + } + + // send back my details so pending client can join + var new_msg = { + matcherID : _id, + matcherPos : _pos, + matcherAddr : _socketAddr, + clientID : msg.clientID, + pos : msg.pos + } + + var new_pack = new VAST.pointPacket(Matcher_Message.MOVE_SUBS_R, new_msg, _id, _pos, pack.sourcePos); + _vonPeer.pointMessage(new_pack); + } + break; + + // The new matcher for a client has received the subs. finalise client transfer + case Matcher_Message.MOVE_SUBS_R :{ + // I am still connected to the client + if (_clientList[msg.clientID] !== undefined && _clientID2socket[msg.clientID] !== undefined) { + + log.debug('Matcher['+_id+']: migrating client['+msg.clientID+'] to matcher['+msg.matcherID+']'); + + // send the new matcher details to the client for transfer + var client_pack = { + matcherID : msg.matcherID, + matcherAddr : msg.matcherAddr, + matcherPos : msg.matcherPos, + clientID : msg.clientID, + } + _clientID2socket[msg.clientID].emit('assign_matcher', client_pack); + + } + break; + } + + default: { + log.debug('Matcher['+_id+']: received an unknown packet type from Matcher['+pack.sender+']', pack); + + } + } + } + + // this initialises the listener for socket events between the client and matcher + var _initListeners = function(){ + + // Client connections + //-------------------- + _io.on('connection', function(socket){ + + _connectionCount++; + + socket.emit('request_info', _id); + + socket.on('client_info', function(info){ + + var clientID = info.clientID; + + // client is new and I am GW + if(_id == VAST.ID_GATEWAY && (clientID == 0 || info.matcherID == VAST.ID_UNASSIGNED)){ + // assign a clientID to the new client + _clientCount++; + clientID = clientID == 0 ? info.hostname + '-' + _clientCount : clientID; // multiple clients on same host + + // Add to client list + let client = { + id : clientID, + pos : info.pos, + matcherID : _id, + matcherPos : _pos + } + _clientList[clientID] = client; + + let client_pack = { + clientID : clientID, + matcherID : _id, + matcherPos : _pos, + matcherAddr : _socketAddr + } + //socket.emit('confirm_matcher', client_pack); + + // record event + _recordEvent(Matcher_Event.CLIENT_JOIN, client); + + + log.debug('Matcher['+_id+']: a new client has joined GW. Send MOVE request'); + _moveClient(clientID, info.pos.x, info.pos.y); + } + + // client already has an ID and claims to be assigned to me and I am expecting them + else if ((clientID != -1 || undefined) && (info.matcherID == _id) + && (_pendingClients[clientID] != 'undefined')){ + + // Add to my client list + let client = { + id : clientID, + pos : info.pos, + matcherID : _id, + matcherPos : _pos + } + _clientList[clientID] = client; + + let client_pack = { + clientID : clientID, + matcherID : _id, + matcherPos : _pos, + matcherAddr : _socketAddr + } + socket.emit('confirm_matcher', client_pack); + + // record event + _recordEvent(Matcher_Event.CLIENT_JOIN, client); + + log.debug('Matcher['+_id+']: Client['+clientID+'] has joined from pending list'); + } + // TODO: handle clients on leaving list. Possible reconnection attempt from client + + + // client is new but I am not GW. kick them and return + else{ + socket.disconnect(); + return; + } + + // Map the client ID to its socket + _socketID2clientID[socket.id] = clientID; + _clientID2socket[clientID] = socket; + + }); + + // handle a disconnect + socket.on('disconnect', function(){ + var clientID = _socketID2clientID[socket.id]; + + // Add the client to a leaving list for graceful removal + _clientLeave(clientID); + log.warn('Matcher['+_id+'] disconnected from Client['+clientID+']. Added to leaving list.'); + + return false; + }); + + // publish a message + socket.on('publish', function(data) { + var clientID = _socketID2clientID[socket.id]; + _publish(clientID, data.x, data.y, data.radius, data.payload, data.channel); + + }); + + // subscribe to an AOI + socket.on('subscribe', function(msg){ + var clientID = _socketID2clientID[socket.id]; + log.debug('Matcher['+_id+']: Received subscribe message from client['+clientID+']'); + _subscribe(clientID, msg.x, msg.y, msg.radius, msg.channel); + + }); + + // unsubscribe + socket.on('unsubscribe', function(subID){ + var clientID = _socketID2clientID[socket.id]; + log.debug('Matcher['+_id+']: Received unsubscribe message from client['+clientID+']'); + _unsubscribe(clientID, subID); + }); + + //move + socket.on('move', function(msg){ + var clientID = _socketID2clientID[socket.id]; + _moveClient(clientID, msg.x, msg.y); + }); + + }); + } + + // record updates to results file + var _recordEvent = function(event, msg){ + switch (event){ + + case Matcher_Event.MATCHER_JOIN :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.MATCHER_JOIN, + id : _id, + alias : _alias, + aoi: _aoi, + pos : _pos + } + + events.printObject(data); + } + break; + + /* + case Matcher_Event.MATCHER_MOVE :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.MATCHER_JOIN, + id : _id, + alias : _alias, + aoi: _aoi, + pos : _pos + } + + events.printObject(data); + } + break; + */ + + case Matcher_Event.CLIENT_JOIN :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.CLIENT_JOIN, + id : _id, + alias : _alias, + client : msg + } + events.printObject(data); + } + break; + + + case Matcher_Event.CLIENT_MOVE :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.CLIENT_MOVE, + id : _id, + alias : _alias, + client : msg.client + } + events.printObject(data); + } + break; + + case Matcher_Event.CLIENT_LEAVE :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.CLIENT_LEAVE, + id : _id, + alias : _alias, + client : msg.client + } + events.printObject(data); + } + break; + + case Matcher_Event.SUB_NEW :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.SUB_NEW, + id : _id, + alias : _alias, + sub : msg + } + events.printObject(data); + } + break; + + /* + case Matcher_Event.SUB_UPDATE :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.SUB_UPDATE, + id : _id, + alias : _alias, + sub : msg.sub + } + events.printObject(data); + } + break; + */ + + case Matcher_Event.SUB_DELETE :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.SUB_DELETE, + id : _id, + alias : _alias, + sub : msg.sub + } + events.printObject(data); + } + break; + + case Matcher_Event.PUB :{ + var data = { + time : UTIL.getTimestamp(), + event : Matcher_Event.PUB, + id : _id, + alias : _alias, + pub : msg.pub + } + events.printObject(data); + } + break; + } + } + + var _listen = function () { + log.debug('Matcher['+_id+']: listening on '+ _socketAddr.port); + + if (_http.listening){ + return; + } + + _http.on('error', (e) => { + + // address already in use + if (e.code === 'EADDRINUSE') { + log.error('Matcher['+_id+']: Address in use, changing port...'); + _socketAddr.port++; + _http.close(); + _listen(); + } + }); + + _http.listen(_socketAddr.port); + } + + // MOVING / MIGRATING CLIENTS + // TODO: Better function names? + + // send a move client message over VON to new client position + var _moveClient = function(clientID, x, y){ + // Creating new VAST.pos is pointless as functions will be lost when sent over socket + let newpos = {x: x, y: y}; + + log.debug('Matcher['+_id+']: move client['+clientID+'] to pos['+newpos.x+'; '+ newpos.y+']'); + + // update position of client object + _clientList[clientID].pos = newpos; + + // send the move client message over VON + let pack = new VAST.pointPacket(Matcher_Message.MOVE_CLIENT, {clientID : clientID, pos : newpos}, _id, _pos, newpos); + _vonPeer.pointMessage(pack); + + _recordEvent(Matcher_Event.CLIENT_MOVE, {client : _clientList[clientID]}); + } + + // Publications + + // when a new pub is sent by a client, send the pub over VON to relevant peers + var _publish = this.publish = function(clientID, x, y, radius, payload, channel, done){ + + if (_useMQTT == true) { + var mqttID = clientID + _setPublishCallback(done) + clientID = this.hashcode(mqttID) + } + + var aoi = new VAST.area(new VAST.pos(x, y), radius); + var pub = new VAST.pub(_id, clientID, aoi, payload, channel); + var areaPacket = new VAST.areaPacket(Matcher_Message.PUB, pub, _id, _pos, aoi); + _vonPeer.areaMessage(areaPacket); + + //inform GS + _recordEvent(Matcher_Event.PUB, {pub : pub}); + } + + // after receiveing publication, check subs and sned to matching clients or + // to the sub owner position + // forwardFurther sets wether the mathcer should foward the publication to + // externally matched subscriptions. + var _sendPublication = this.sendPublication = function(publication, allowForwarding){ + var pointPacket; + var pub = new VAST.pub(); + pub.parse(publication); + + var clientSubs, sub; + var matcherTargets = []; + + for (var clientID in _subscriptions) { + clientSubs = _subscriptions[clientID]; + + /* Allow clients to receive messages from themself? + if(i == pub.clientID){ + continue; + } + */ + + for (var subID in clientSubs){ + sub = clientSubs[subID]; + + if(sub.channel !== pub.channel){ + //Not on the right channel + continue; + } + + // the publication is covered by one of my subscriptions + if(sub.aoi.intersectsArea(pub.aoi)){ + + // I am the host to this subscription, send pub on the subbed client's socket + if(sub.hostID === _id){ + + // TODO: build a queue for clients still connecting + // for now, volatile emit for QoS = 0 + try { + + if (_useMQTT == true) { + + var packet = JSON.parse(pub.payload) + packet.payload = Buffer.from(packet.payload.data) + + //log.debug('Using MQTT to send spatial message to client with clientID '+sub.clientID) + //log.debug(clientID2mqttID) + + var mqttID = _clientID2mqttID[sub.clientID] + var client = _that.broker.clients[mqttID] + //log.debug('Using MQTT to send spatial message to client with mqttID '+mqttID) + //log.debug(client) + if (client) { + //log.debug('Client is defined to sending message') + client.publish(packet, client, _that.publishDone) + //log.debug('Done sending message') + } + } else { + _clientID2socket[sub.clientID].volatile.emit('publication', pub); + } + + } + catch { + log.error('Matcher['+_id+']: no socket for client[' + sub.clientID+']'); + } + } + + // I am not the host, so I must forward the publication to the owner if I am + // the nearest recipient to the host + else { + // only forward if the host to the matched sub has not yet received the publication + if (allowForwarding === true && pub.recipients.includes(sub.hostID) === false + && matcherTargets.includes(sub.hostID) === false){ + + matcherTargets.push(sub.hostID); + pointPacket = new VAST.pointPacket(Matcher_Message.PUB_MATCHED, pub, _id, _pos, sub.hostPos); + + // All the nodes that have received the publication AND are recipints to the current sub; + // ie, everybody on this list will want to send a pub_matched event to the host matcher. + var checklist = pub.recipients.filter(function(elem){ + return sub.recipients.includes(elem); + }); + + // set the checklist of the pointPacket + pointPacket.checklist = checklist; + + // will only forward if I am closest to the host between all nodes in checklist + _vonPeer.pointMessage(pointPacket, pub.recipients); + } + } + } + } + } + } + + + // Called when client requests removing a subscription. Remove sub object with unique ID + + var _unsubscribe = this.unsubscribe = function(clientID, subID) { + + log.debug('Matcher['+_id+']: unsubscribe called for Sub['+subID+'] by Client['+clientID+']'); + + var clientID = clientID; + if (_useMQTT == true) { + clientID = this.hashcode(clientID); + } + + if (_subscriptions.hasOwnProperty(clientID) && _subscriptions[clientID][subID] !== undefined) { + var sub = _subscriptions[clientID][subID]; + + // delete the subscription for myself + // _deleteSub() will be called twice because of sub_delete message, but must be called here to delete distant subs. + _deleteSubscription(sub); + + // send delete sub message to any other relevant matchers in the AoI + var areaPacket = new VAST.areaPacket(Matcher_Message.SUB_DELETE, sub, _id, _pos, sub.aoi); + _vonPeer.areaMessage(areaPacket); + } + + if (_useMQTT == false) { + _clientID2socket[clientID].emit('unsubscribe_r', sub); + //socket.emit('unsubscribe_r', sub); + } + } + + // Subscription adding and maintenance + + // Called when client requests a new subscription. Creates new sub object with unique ID + var _subscribe = this.subscribe = function(clientID, x, y, radius, channel) { + + var clientID = clientID + if (_useMQTT == true) { + var mqttID = clientID + clientID = this.hashcode(clientID) + + this.mqttID2clientID[mqttID] = clientID + this.clientID2mqttID[clientID] = mqttID + + /*log.debug("_mqttID2clientID:") + //log.debug(this._mqttID2clientID) + //log.debug("_clientID2mqttID: ") + log.debug(this._clientID2mqttID) + */ + } + + // create the new sub object + var aoi = new VAST.area(new VAST.pos(x, y), radius); + var subID = _generate_subID(clientID); + var sub = new VAST.sub(_id, _pos, clientID, subID, channel, aoi); + + // add the subscription to my list, and respond to client + _addSubscription(sub, true); + + // record event + _recordEvent(Matcher_Event.SUB_NEW, sub); + + if (_useMQTT == false) { + + try { + _clientID2socket[clientID].emit('subscribe_r', sub); + } catch { + log.error("Matcher["+_id+"]: no socket for Client["+clientID+"]"); + } + + } + + } + + var _updateSubscription = function(sub){ + if (_subscriptions.hasOwnProperty(sub.clientID) && _subscriptions[sub.clientID].hasOwnProperty(sub.subID)){ + _subscriptions[sub.clientID][sub.subID].parse(sub); + _subscriptions[sub.clientID][sub.subID].heartbeat = UTIL.getTimestamp(); + } else { + _addSubscription(sub, false); + } + } + + var _addSubscription = function (sub, forward) { + + var new_sub = new VAST.sub(); + new_sub.parse(sub); + new_sub.heartbeat = UTIL.getTimestamp(); + + // will simply update if there is an existing sub + + // add sub to list + var temp = _subscriptions[new_sub.clientID] || {}; + temp[new_sub.subID] = new_sub; + _subscriptions[new_sub.clientID] = temp; + + if (forward === true){ + var areaPacket = new VAST.areaPacket(Matcher_Message.SUB_NEW, new_sub, _id, _pos, new_sub.aoi); + _vonPeer.areaMessage(areaPacket); + } + } + + var _deleteSubscription = function(sub) { + + // check whether i actually have subs listed for this client + if (_subscriptions.hasOwnProperty(sub.clientID)){ + + // delete the subscription + delete _subscriptions[sub.clientID][sub.subID]; + + // if client list is empty, delete client reference + if (Object.keys(_subscriptions[sub.clientID]).length == 0){ + delete _subscriptions[sub.clientID]; + } + } + + _recordEvent(Matcher_Event.SUB_DELETE, {sub : sub}); + + log.debug('Matcher['+_id+']: deleting subscription for matcher['+_id+'], subID: '+sub.subID); + return true; + } + + var _clientLeave = function(clientID){ + // move client to leaving list and delete from normal clients + _leavingClients[clientID] = _clientList[clientID]; + + // set timeout before I delete the client and it's subs + setTimeout(function(){ + _deleteClient(clientID); + }, _clientDisconnectTime); + } + + var _deleteClient = function(clientID){ + + // ONLY remove subscriptions that are still hosted by me + // TODO: KEEP ALIVE will delete them naturally by other matchers + let subs = _subscriptions[clientID]; + for (var subID in subs){ + if (subs[subID].hostID === _id) { + _deleteSubscription(subs[subID]); + } + } + + + // notify visualiser + if (_leavingClients[clientID] !== undefined) + _recordEvent(Matcher_Event.CLIENT_LEAVE, {client : _leavingClients[clientID]}); + + try{ + delete _socketID2clientID[_clientID2socket[clientID].id]; + } + catch{ + + } + delete _clientID2socket[clientID]; + delete _leavingClients[clientID]; + + } + + var _checkSubscriptions = function(){ + for (var clientID in _subscriptions){ + for (var subID in _subscriptions[clientID]){ + let sub = _subscriptions[clientID][subID]; + + // the sub must be removed + if (UTIL.getTimestamp() - sub.heartbeat > _subLifeTimeout){ + _deleteSubscription(sub); + } + } + } + + setTimeout(_checkSubscriptions, 1000); + } + + // Helper Functions + + var _generate_subID = function(clientID){ + //check the list of existing IDs for client to avoid duplicates + var count = 0; + var newID = clientID+'-'+_randomString(5); + + /* + while(_client2subID[clientID].hasOwnProperty(newID) && count < 100){ + newID = 'M['+_id+']-C['+clientID+']-'+_randomString(5); + count++; + } + */ + return newID; + } + + var _randomString = function(length) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for ( var i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * + charactersLength)); + } + return result; + } + + //INIT + // get local IP + // set address and port for VON and client sockets + // only call init when this is set + UTIL.getIPAddress(function(localIP){ + + _addr = {host: localIP, port : _VON_port}; + + _socketAddr = {host: localIP, port: _client_port}; + + _init(); + }); + + var hashcode = this.hashcode = function(s) { + return s.split("").reduce(function (a, b) { + a = ((a << 5) - a) + b.charCodeAt(0); + return a & a + }, 0); + } + +} + + + diff --git a/lib/net/msg_handler.js b/lib/net/msg_handler.js new file mode 100755 index 00000000..93e09cde --- /dev/null +++ b/lib/net/msg_handler.js @@ -0,0 +1,275 @@ + +/* + * VAST, a scalable peer-to-peer network for virtual environments + * Copyright (C) 2005-2011 Shun-Yun Hu (syhu@ieee.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* + msg_handler.js + + a simple class to dispatch incoming messages to registered handlers, + while translating internal objects to outgoing message types (in JSON format) + + basic goals: + - allow multiple instances of the message handler be created, each responsible for a different //LOGic + - allow a single network layer be used by multiple handlers + - ease of development (handle writers need not know each other, can be independently plug in & out) + - automatic dispatching to the right handler for message handling + + supported functions: + + // basic callback / structure + addr = {host, port} + l_onDone(addr) + + // constructor + self_id id for self node + listen_port port to listen/bind locally + onDone callback to notify when binding is finished + + // basic functions + addHandler add a new handler to message handler + removeHandler remove an existing handler from message handler + sendMessage send a javascript object to a SINGLE target node (given message 'type' and 'priority') + sendPack send a pack object to its destinated targets + storeMapping store mapping between id and address + disconnect disconnect from a particular host id + close stop the underlying network layer + + // accessors + getAddress get locally detected & binded network address + getID get unique ID for the net layer + setID set unique ID for the net layer + + history: + 2012-10-03 initial version + 2012-11-04 add addHandler/removeHandler methods +*/ + +function msg_handler(l_self_id,l_localIP, l_listen_port, l_onDone) { + + // + // public methods (usable by classes that inherent the msg_handler class) + // + + // + // add a new handler to message handler, the handler should provide the following: + // connHandler handler for connection event + // disconnHandler handler for disconnection event + // packetHandler handler to process a packet, return 'true' if success + // + + this.addHandler = function (handler_class) { + + // first check if they're all valid + if (typeof handler_class.connHandler !== 'function') { + //LOG.error('addHandler: new handler does not have connHandler'); + return false; + } + + if(typeof handler_class.disconnHandler !== 'function') { + //LOG.error('addHandler: new handler does not have disconnHandler'); + return false; + } + + if(typeof handler_class.packetHandler !== 'function') { + //LOG.error('addHandler: new handler does not have packetHandler'); + return false; + } + + if(typeof handler_class.initStates !== 'function') { + //LOG.error('addHandler: new handler does not have initStates'); + return false; + } + + // store handlers + _handlers.push(handler_class); + + // store this msg_handler to the handler + handler_class.initStates(this); + + return true; + } + + // remove an existing handler from message handler + this.removeHandler = function (handler) { + + for (var i=0; i < _handlers.length; i++) + // handler found, remove it + if (_handlers[i] == handler) { + _handlers.splice(i, 1); + return true; + } + + // no matching handler found + return false; + } + + // send a javascript object to a SINGLE target node (given message 'type' and 'priority') + this.sendMessage = function (target, msg_type, js_obj, priority, is_reliable) { + + // create a delivery package to send + var pack = new VAST.pack( + msg_type, + js_obj, + priority); + + pack.targets.push(target); + + // convert pack to JSON or binary string + return _that.sendPack(pack, is_reliable); + } + + // send a pack object to its destinated targets + this.sendPack = function (pack, is_reliable) { + + // do nothing is target is empty + if (pack.targets.length === 0) + return; + + // go through each target and send + // TODO: optimize so only one message is sent to each physical host target + //for (var i=0; i < pack.targets.length; i++) + _net.send(pack.targets, pack, is_reliable); + } + + // store a network id to address mapping + this.storeMapping = function (id, addr) { + return _net.storeMapping(id, addr); + } + + // disconnect a remote host + this.disconnect = function (id) { + return _net.disconnect(id); + } + + // stop the underlying network layer + this.close = function () { + return _net.close(); + } + + // get locally detected & binded network address + this.getAddress = function () { + return _localAddress; + } + + // obtain self ID from network layer + this.getID = function () { + return _net.getID(); + } + + // set self ID to net layer + this.setID = function (id) { + return _net.setID(id); + } + + + // + // private methods (internal usage, some are replacable at inherted class) + // + + var _net = undefined; // a reference to vast_net + + // handlers registered to handle connect/disconnect/packet + var _handlers = []; + + // local IP & port + var _localAddress = {host: l_localIP, port: 0}; + + // keep local reference for 'this' + var _that = this; + + // NOTE: packet & message handlers cannot be of prototype-style, + // as they need to occupy memory independently for each msg handler instance + + // handler for incoming messages + var _packetHandler = function (from_id, pack) { + + // go through each packet handler and see which will handle it + for (var i=0; i < _handlers.length; i++) { + if (typeof _handlers[i].packetHandler === 'function') + if (_handlers[i].packetHandler(from_id, pack) === true) { + // successfully handle incoming packet, return + return true; + } + } + + //LOG.error('[' + _net.getID() + '] no packet handler for packet: ' + JSON.stringify(pack)); + return false; + } + + // handler for connection notification + var _connHandler = function (id) { + + // notify each registered handler for connection + for (var i=0; i < _handlers.length; i++) { + if (typeof _handlers[i].connHandler === 'function') + _handlers[i].connHandler(id); + } + } + + // handler for disconnection notification + var _disconnHandler = function (id) { + + // notify each registered handler for disconnection + for (var i=0; i < _handlers.length; i++) { + if (typeof _handlers[i].disconnHandler === 'function') + _handlers[i].disconnHandler(id); + } + } + + // + // constructor (record or create a new vast_net layer) + // + + // constructor + //LOG.debug('msg_handler init, l_self_id: ' + l_self_id); + + // create new net layer if does not exist + ////LOG.warn('creating new VASTnet... net: ' + typeof _net); + + // create network layer & start listening + // NOTE: internal handlers must be defined before creating the VAST.net instance + _net = new VAST.net(l_localIP, _packetHandler, _connHandler, _disconnHandler, l_self_id); + + //LOG.debug('calling getHost()'); + + // create self object + _net.getHost(function (local_IP) { + + //LOG.debug('local IP: ' + local_IP); + + // store my locally detected IP + _localAddress.host = local_IP; + + // return value is actual port binded + _net.listen(l_listen_port, function (actual_port) { + + // store actual port binded + _localAddress.port = actual_port; + + // notify port binding success + if (typeof l_onDone === 'function') + l_onDone(_localAddress); + }); + }); + +} // end msg_handler + +if (typeof module !== 'undefined') + module.exports = msg_handler; diff --git a/net_nodejs.js b/lib/net/net_nodejs.js old mode 100644 new mode 100755 similarity index 52% rename from net_nodejs.js rename to lib/net/net_nodejs.js index a474da91..aba168c6 --- a/net_nodejs.js +++ b/lib/net/net_nodejs.js @@ -22,7 +22,7 @@ /* net_nodejs.js - A network layer usable under node.js + A network connector usable under node.js ///////////////////////////// data structure / callback: @@ -35,6 +35,7 @@ onReceive(socket, msg) onConnect(socket) onDisconnect(socket) + onError(err) ///////////////////////////// supported functions: @@ -46,28 +47,31 @@ // make TCP connection to a given host_port // all received messages from this socket is return to 'onReceive' // connection & disconnection can be notified via callbacks (optional) - connect(host_port, data_callback, onConnect, onDisconnect) + connect(host_port) // disconnect current connection disconnect() - - // send a message 'msg' of length 'size' to current connection, - // optional 'socket' can be provided to respond requests from incoming clients - send(msg, socket) - - // send message 'msg' to a UDP channel (given by 'host_port') - send_udp(host_port, msg); - + // listen to a particular port for incoming connections / messages // all received messages are delivered to 'onReceive' // return port binded, or 0 to indicate error listen(port, onDone) + + // close the current listening server + close() + + // check if I'm a listening server + isServer() + + // check if a client socket is currently connected + isConnected() history: 2012-06-30 initial version (start from stretch) - + 2012-09-24 add is_connected() */ -require('./common.js'); + +require('../common.js'); var l_net = require('net'); // allow using network function net_nodejs(onReceive, onConnect, onDisconnect, onError) { @@ -75,200 +79,202 @@ function net_nodejs(onReceive, onConnect, onDisconnect, onError) { // a server object for listening to incoming connections var _server = undefined; - // a client object for making connection - var _client = undefined; + // a client object for making outgoing connection + var _socket = undefined; - // the IP & port of a host to be connected - //var _target = undefined; - - // check for connection validity and send to it) + // reference + var _that = this; + + // check for connection validity and send to it // ip_port is an object with 'host' and 'port' parameter this.connect = function (host_port) { - LOG.debug('connecting to: ' + host_port.host + ':' + host_port.port); + //LOG.debug('connecting to: ' + host_port.host + ':' + host_port.port); try { // connect to the given host & port, while providing a connection listener - _client = l_net.createConnection(host_port.port, host_port.host); + _socket = l_net.createConnection(host_port.port, host_port.host, function () { + + // store remote address & port + _socket.host = host_port.host; + _socket.port = host_port.port; + //LOG.debug('out connect success for: ' + _socket.host + ':' + _socket.port); + + // setup connected socket + setupSocket(_socket); + + // replace with custom disconnect handler + // TODO: needed? or we can use the same one for both incoming & outgoing? + _socket.disconnect = _that.disconnect; + }); + + /* + // if there's error on the connection, 'close' will follow + _socket.on('error', function(err){ + //LOG.error('out connect socket error: ' + err); + }); + */ } catch (e) { - LOG.error('net_nodejs: connect error: ' + e); + //LOG.error('net_nodejs: connect error: ' + e); if (typeof onError === 'function') - onError('connect'); + onError('connect'); } - - _client.on('connect', function () { - - LOG.debug('out connect success for: ' + host_port.host + ':' + host_port.port); - - // store remote address & port - _client.host = host_port.host; - _client.port = host_port.port; - - setupSocket(_client); - if (typeof onConnect === 'function') - onConnect(_client); - }); } // disconnect from a given socket id this.disconnect = function () { - if (_client === undefined) + if (_socket === undefined) { + //LOG.warn('net_nodejs: no socket established to disconnect'); return false; + } try { - LOG.debug('disconnecting from ' + _client.host + ':' + _client.port); - _client.end(); + //LOG.debug('disconnecting from ' + _socket.host + ':' + _socket.port); + _socket.end(); } catch (e) { - LOG.error('net_nodejs: disconnect error: ' + e); + //LOG.error('net_nodejs: disconnect error: ' + e); if (typeof onError === 'function') onError('disconnect'); } + return true; } - - // send a given message to a socket_id - this.send = function (msg, socket) { - //LOG.debug('sending to ' + socket + ' msg: ' + msg); - - try { - // if this is a connection - if (_client !== undefined) { - //LOG.debug('to client'); - _client.write(msg); - } - // if this is a listening server - else if (socket !== undefined) { - //LOG.debug('to socket'); - socket.write(msg); - } - // if neither - else - return false; - } - catch (e) { - LOG.debug('send fail for msg: ' + msg); - if (typeof onError === 'function') - onError('send'); - return false; - } - - return true; - } - - // send a given message to a UDP-style host:port - this.send_udp = function (host_port, msg) { - - } - // listen to a given port, while processing incoming messages at a callback this.listen = function (port, onDone) { - LOG.debug('listening at: ' + port); + //LOG.debug('net_nodejs, listening: ' + port); try { _server = l_net.createServer(setupSocket); - // attempt to re-try if bind fail + // pass back error for further processing _server.on('error', function (e) { - LOG.error('net_nodejs: listen error caught: ' + e); + + // NOTE: we do not display this as binding to a already binded port will cause this error + //LOG.error('net_nodejs: listen error caught: ' + e); + + //if (typeof onError === 'function') + // onError(e); + _server = undefined; if (typeof onDone === 'function') - onDone(0); + onDone(0); }); _server.listen(port, function () { - LOG.debug('server started at port: ' + port); + //LOG.debug('net_nodejs. server started at port: ' + port); if (typeof onDone === 'function') onDone(port); }); } catch (e) { - LOG.error('net_nodejs: listen error crashed: ' + e); + //LOG.error('net_nodejs: listen error crashed: ' + e.stack); if (typeof onError === 'function') onError('listen'); } } + // close the current listening server + this.close = function () { + try { + if (_server === undefined) { + //LOG.error('net_nodejs: server not started'); + return false; + } + _server.close(); + _server = undefined; + return true; + } + catch (e) { + //LOG.error('net_nodejs: server close error: ' + e.stack); + return false; + } + } + // check if this network socket is a listening server this.isServer = function () { return (_server !== undefined); } + + // check if the socket is currently connected + this.isConnected = function () { + ////LOG.warn('connected: ' + _socket.connected); + return (_socket !== undefined && _socket.connected === true); + } // setup a new usable socket with a socket handler //----------------------------------------- var setupSocket = function (socket) { + + ////LOG.debug('connection created: ' + socket.remoteAddress + ':' + socket.remotePort); - //LOG.debug('setupSocket called, onReceive: ' + typeof onReceive); - - socket.setEncoding('UTF8'); - socket.setKeepAlive(true, 20 * 1000); // 20 seconds keepalive + // if host & port are not yet known, it's an incoming connection + // NOTE: remoteAddress & remotePort are available for incoming connection, but not outgoing sockets + if (typeof socket.host === 'undefined') { + socket.host = socket.remoteAddress; + socket.port = socket.remotePort; + //LOG.warn('in connect success for ' + socket.host + ':' + socket.port); + } - // this is important to allow messages be delivered immediately after sending - socket.setNoDelay(true); + socket.connected = true; - // flag to indicate socket is already disconnected - socket.disconnected = false; + // attach convenience function + socket.disconnect = function () { + socket.end(); + } + + // notify connection, pass the connecting socket + if (typeof onConnect === 'function') + onConnect(socket); // call data callback to process data, if exists - // (this happens when setupSocket is called by a listening server for setup new socket) + // (this happens when called by a listening server to setup new socket) if (typeof onReceive === 'function') { - //LOG.debug('recv_CB provided, registered for data'); socket.on('data', function (data) { onReceive(socket, data); }); } - // when socket becomes empty again + // when socket becomes empty again, can now keep sending queued messages socket.on('drain', function () { - socket.resume(); + try { + socket.resume(); + } + catch (e) { + //LOG.error('net_nodejs: resume error: ' + e.stack); + } }); - socket.on('connect', function () { - - // NOTE: remoteAddress & remotePort are available for incoming connection, but not outgoing sockets - //LOG.debug('connection created: ' + socket.remoteAddress + ':' + socket.remotePort); - - socket.host = socket.remoteAddress; - socket.port = socket.remotePort; - LOG.debug('connection created: ' + socket.host + ':' + socket.port); - - // notify connection, pass the connecting socket - if (typeof onConnect === 'function') - onConnect(socket); - - socket.disconnected = false; - }); // handle connection error or close - var disconnect_handler = function (has_error) { - - // print error, if any - if (has_error) - LOG.error('socket closed due to error'); - + var disconnect_handler = function () { + // if we've already fire disconnect for this socket, ignore it // NOTE: as both 'close' and 'end' event could cause this callback be called // so we need to prevent a 2nd firing of the disconnect callback to application - if (socket.disconnected === true) + ////LOG.debug('disconnect_handler, socket.connected: ' + socket.connected); + if (socket.connected === false) return; - LOG.debug('connection ended. remote host is ' + socket.host + ':' + socket.port); + //LOG.debug('connection ended. remote host is ' + socket.host + ':' + socket.port); + + socket.connected = false; // notify application, if callback exists if (typeof onDisconnect === 'function') - onDisconnect(socket); - - socket.disconnected = true; + onDisconnect(socket); } // NOTE:: if remote host calls 'disconnect' to send a FIN packet, - // this host will receive 'end' + // this host will receive 'end' directly + // (but will 'close' be emitted?) // see: http://nodejs.org/api/net.html#net_event_close_1 socket.on('end', function () { - LOG.debug('connection closed by remote host'); + ////LOG.warn('socket [end] called'); + // NOTE: should not end connection here, as default behavior would close it // this allows still some messages to be sent over by this host, // even if remote hosts closes the connection @@ -276,12 +282,25 @@ function net_nodejs(onReceive, onConnect, onDisconnect, onError) { }); // NOTE: this is called if an existing connection is fully closed (by itself or remote host) - socket.on('close', disconnect_handler); + socket.on('close', function (has_error) { + ////LOG.warn('socket [close] called'); + // print error, if any + if (has_error) + //LOG.error('socket close error: ' + has_error); + + disconnect_handler(); + }); // if there's error on the connection, 'close' will follow - socket.on('error', function(err){ - LOG.error('socket error: ' + err); + socket.on('error', function (err){ + //LOG.error('socket error: ' + err); }); + + socket.setEncoding('UTF8'); + socket.setKeepAlive(true, 20 * 1000); // 20 seconds keepalive + + // this is important to allow messages be delivered immediately after sending + socket.setNoDelay(true); return socket; } diff --git a/lib/net/socket.io.js b/lib/net/socket.io.js new file mode 100644 index 00000000..827407bd --- /dev/null +++ b/lib/net/socket.io.js @@ -0,0 +1,8 @@ +/*! + * Socket.IO v2.1.0 + * (c) 2014-2018 Guillermo Rauch + * Released under the MIT License. + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.io=e():t.io=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";function r(t,e){"object"===("undefined"==typeof t?"undefined":o(t))&&(e=t,t=void 0),e=e||{};var n,r=i(t),s=r.source,p=r.id,h=r.path,f=u[p]&&h in u[p].nsps,l=e.forceNew||e["force new connection"]||!1===e.multiplex||f;return l?(c("ignoring socket cache for %s",s),n=a(s,e)):(u[p]||(c("new io instance for %s",s),u[p]=a(s,e)),n=u[p]),r.query&&!e.query&&(e.query=r.query),n.socket(r.path,e)}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=n(1),s=n(7),a=n(12),c=n(3)("socket.io-client");t.exports=e=r;var u=e.managers={};e.protocol=s.protocol,e.connect=r,e.Manager=n(12),e.Socket=n(37)},function(t,e,n){(function(e){"use strict";function r(t,n){var r=t;n=n||e.location,null==t&&(t=n.protocol+"//"+n.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?n.protocol+t:n.host+t),/^(https?|wss?):\/\//.test(t)||(i("protocol-less url %s",t),t="undefined"!=typeof n?n.protocol+"//"+t:"https://"+t),i("parse %s",t),r=o(t)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";var s=r.host.indexOf(":")!==-1,a=s?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+a+":"+r.port,r.href=r.protocol+"://"+a+(n&&n.port===r.port?"":":"+r.port),r}var o=n(2),i=n(3)("socket.io-client:url");t.exports=r}).call(e,function(){return this}())},function(t,e){var n=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,r=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];t.exports=function(t){var e=t,o=t.indexOf("["),i=t.indexOf("]");o!=-1&&i!=-1&&(t=t.substring(0,o)+t.substring(o,i).replace(/:/g,";")+t.substring(i,t.length));for(var s=n.exec(t||""),a={},c=14;c--;)a[r[c]]=s[c]||"";return o!=-1&&i!=-1&&(a.source=e,a.host=a.host.substring(1,a.host.length-1).replace(/;/g,":"),a.authority=a.authority.replace("[","").replace("]","").replace(/;/g,":"),a.ipv6uri=!0),a}},function(t,e,n){(function(r){function o(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n?" %c":" ")+t[0]+(n?"%c ":" ")+"+"+e.humanize(this.diff),n){var r="color: "+this.color;t.splice(1,0,r,"color: inherit");var o=0,i=0;t[0].replace(/%[a-zA-Z%]/g,function(t){"%%"!==t&&(o++,"%c"===t&&(i=o))}),t.splice(i,0,r)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=t}catch(n){}}function c(){var t;try{t=e.storage.debug}catch(n){}return!t&&"undefined"!=typeof r&&"env"in r&&(t=r.env.DEBUG),t}function u(){try{return window.localStorage}catch(t){}}e=t.exports=n(5),e.log=s,e.formatArgs=i,e.save=a,e.load=c,e.useColors=o,e.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:u(),e.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],e.formatters.j=function(t){try{return JSON.stringify(t)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}},e.enable(c())}).call(e,n(4))},function(t,e){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function o(t){if(p===setTimeout)return setTimeout(t,0);if((p===n||!p)&&setTimeout)return p=setTimeout,setTimeout(t,0);try{return p(t,0)}catch(e){try{return p.call(null,t,0)}catch(e){return p.call(this,t,0)}}}function i(t){if(h===clearTimeout)return clearTimeout(t);if((h===r||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(t);try{return h(t)}catch(e){try{return h.call(null,t)}catch(e){return h.call(this,t)}}}function s(){y&&l&&(y=!1,l.length?d=l.concat(d):m=-1,d.length&&a())}function a(){if(!y){var t=o(s);y=!0;for(var e=d.length;e;){for(l=d,d=[];++m1)for(var n=1;n100)){var e=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(t);if(e){var n=parseFloat(e[1]),r=(e[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*p;case"days":case"day":case"d":return n*u;case"hours":case"hour":case"hrs":case"hr":case"h":return n*c;case"minutes":case"minute":case"mins":case"min":case"m":return n*a;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function r(t){return t>=u?Math.round(t/u)+"d":t>=c?Math.round(t/c)+"h":t>=a?Math.round(t/a)+"m":t>=s?Math.round(t/s)+"s":t+"ms"}function o(t){return i(t,u,"day")||i(t,c,"hour")||i(t,a,"minute")||i(t,s,"second")||t+" ms"}function i(t,e,n){if(!(t0)return n(t);if("number"===i&&isNaN(t)===!1)return e["long"]?o(t):r(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))}},function(t,e,n){function r(){}function o(t){var n=""+t.type;if(e.BINARY_EVENT!==t.type&&e.BINARY_ACK!==t.type||(n+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(n+=t.nsp+","),null!=t.id&&(n+=t.id),null!=t.data){var r=i(t.data);if(r===!1)return g;n+=r}return f("encoded %j as %s",t,n),n}function i(t){try{return JSON.stringify(t)}catch(e){return!1}}function s(t,e){function n(t){var n=d.deconstructPacket(t),r=o(n.packet),i=n.buffers;i.unshift(r),e(i)}d.removeBlobs(t,n)}function a(){this.reconstructor=null}function c(t){var n=0,r={type:Number(t.charAt(0))};if(null==e.types[r.type])return h("unknown packet type "+r.type);if(e.BINARY_EVENT===r.type||e.BINARY_ACK===r.type){for(var o="";"-"!==t.charAt(++n)&&(o+=t.charAt(n),n!=t.length););if(o!=Number(o)||"-"!==t.charAt(n))throw new Error("Illegal attachments");r.attachments=Number(o)}if("/"===t.charAt(n+1))for(r.nsp="";++n;){var i=t.charAt(n);if(","===i)break;if(r.nsp+=i,n===t.length)break}else r.nsp="/";var s=t.charAt(n+1);if(""!==s&&Number(s)==s){for(r.id="";++n;){var i=t.charAt(n);if(null==i||Number(i)!=i){--n;break}if(r.id+=t.charAt(n),n===t.length)break}r.id=Number(r.id)}if(t.charAt(++n)){var a=u(t.substr(n)),c=a!==!1&&(r.type===e.ERROR||y(a));if(!c)return h("invalid payload");r.data=a}return f("decoded %s as %j",t,r),r}function u(t){try{return JSON.parse(t)}catch(e){return!1}}function p(t){this.reconPack=t,this.buffers=[]}function h(t){return{type:e.ERROR,data:"parser error: "+t}}var f=n(3)("socket.io-parser"),l=n(8),d=n(9),y=n(10),m=n(11);e.protocol=4,e.types=["CONNECT","DISCONNECT","EVENT","ACK","ERROR","BINARY_EVENT","BINARY_ACK"],e.CONNECT=0,e.DISCONNECT=1,e.EVENT=2,e.ACK=3,e.ERROR=4,e.BINARY_EVENT=5,e.BINARY_ACK=6,e.Encoder=r,e.Decoder=a;var g=e.ERROR+'"encode error"';r.prototype.encode=function(t,n){if(f("encoding packet %j",t),e.BINARY_EVENT===t.type||e.BINARY_ACK===t.type)s(t,n);else{var r=o(t);n([r])}},l(a.prototype),a.prototype.add=function(t){var n;if("string"==typeof t)n=c(t),e.BINARY_EVENT===n.type||e.BINARY_ACK===n.type?(this.reconstructor=new p(n),0===this.reconstructor.reconPack.attachments&&this.emit("decoded",n)):this.emit("decoded",n);else{if(!m(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");n=this.reconstructor.takeBinaryData(t),n&&(this.reconstructor=null,this.emit("decoded",n))}},a.prototype.destroy=function(){this.reconstructor&&this.reconstructor.finishedReconstruction()},p.prototype.takeBinaryData=function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=d.reconstructPacket(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null},p.prototype.finishedReconstruction=function(){this.reconPack=null,this.buffers=[]}},function(t,e,n){function r(t){if(t)return o(t)}function o(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}t.exports=r,r.prototype.on=r.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},r.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var r,o=0;o0&&!this.encoding){var t=this.packetBuffer.shift();this.packet(t)}},r.prototype.cleanup=function(){h("cleanup");for(var t=this.subs.length,e=0;e=this._reconnectionAttempts)h("reconnect failed"),this.backoff.reset(),this.emitAll("reconnect_failed"),this.reconnecting=!1;else{var e=this.backoff.duration();h("will wait %dms before reconnect attempt",e),this.reconnecting=!0;var n=setTimeout(function(){t.skipReconnect||(h("attempting reconnect"),t.emitAll("reconnect_attempt",t.backoff.attempts),t.emitAll("reconnecting",t.backoff.attempts),t.skipReconnect||t.open(function(e){e?(h("reconnect attempt error"),t.reconnecting=!1,t.reconnect(),t.emitAll("reconnect_error",e.data)):(h("reconnect success"),t.onreconnect())}))},e);this.subs.push({destroy:function(){clearTimeout(n)}})}},r.prototype.onreconnect=function(){var t=this.backoff.attempts;this.reconnecting=!1,this.backoff.reset(),this.updateSocketIds(),this.emitAll("reconnect",t)}},function(t,e,n){t.exports=n(14),t.exports.parser=n(21)},function(t,e,n){(function(e){function r(t,n){if(!(this instanceof r))return new r(t,n);n=n||{},t&&"object"==typeof t&&(n=t,t=null),t?(t=p(t),n.hostname=t.host,n.secure="https"===t.protocol||"wss"===t.protocol,n.port=t.port,t.query&&(n.query=t.query)):n.host&&(n.hostname=p(n.host).host),this.secure=null!=n.secure?n.secure:e.location&&"https:"===location.protocol,n.hostname&&!n.port&&(n.port=this.secure?"443":"80"),this.agent=n.agent||!1,this.hostname=n.hostname||(e.location?location.hostname:"localhost"),this.port=n.port||(e.location&&location.port?location.port:this.secure?443:80),this.query=n.query||{},"string"==typeof this.query&&(this.query=h.decode(this.query)),this.upgrade=!1!==n.upgrade,this.path=(n.path||"/engine.io").replace(/\/$/,"")+"/",this.forceJSONP=!!n.forceJSONP,this.jsonp=!1!==n.jsonp,this.forceBase64=!!n.forceBase64,this.enablesXDR=!!n.enablesXDR,this.timestampParam=n.timestampParam||"t",this.timestampRequests=n.timestampRequests,this.transports=n.transports||["polling","websocket"],this.transportOptions=n.transportOptions||{},this.readyState="",this.writeBuffer=[],this.prevBufferLen=0,this.policyPort=n.policyPort||843,this.rememberUpgrade=n.rememberUpgrade||!1,this.binaryType=null,this.onlyBinaryUpgrades=n.onlyBinaryUpgrades,this.perMessageDeflate=!1!==n.perMessageDeflate&&(n.perMessageDeflate||{}),!0===this.perMessageDeflate&&(this.perMessageDeflate={}),this.perMessageDeflate&&null==this.perMessageDeflate.threshold&&(this.perMessageDeflate.threshold=1024),this.pfx=n.pfx||null,this.key=n.key||null,this.passphrase=n.passphrase||null,this.cert=n.cert||null,this.ca=n.ca||null,this.ciphers=n.ciphers||null,this.rejectUnauthorized=void 0===n.rejectUnauthorized||n.rejectUnauthorized,this.forceNode=!!n.forceNode;var o="object"==typeof e&&e;o.global===o&&(n.extraHeaders&&Object.keys(n.extraHeaders).length>0&&(this.extraHeaders=n.extraHeaders),n.localAddress&&(this.localAddress=n.localAddress)),this.id=null,this.upgrades=null,this.pingInterval=null,this.pingTimeout=null,this.pingIntervalTimer=null,this.pingTimeoutTimer=null,this.open()}function o(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}var i=n(15),s=n(8),a=n(3)("engine.io-client:socket"),c=n(36),u=n(21),p=n(2),h=n(30);t.exports=r,r.priorWebsocketSuccess=!1,s(r.prototype),r.protocol=u.protocol,r.Socket=r,r.Transport=n(20),r.transports=n(15),r.parser=n(21),r.prototype.createTransport=function(t){a('creating transport "%s"',t);var e=o(this.query);e.EIO=u.protocol,e.transport=t;var n=this.transportOptions[t]||{};this.id&&(e.sid=this.id);var r=new i[t]({query:e,socket:this,agent:n.agent||this.agent,hostname:n.hostname||this.hostname,port:n.port||this.port,secure:n.secure||this.secure,path:n.path||this.path,forceJSONP:n.forceJSONP||this.forceJSONP,jsonp:n.jsonp||this.jsonp,forceBase64:n.forceBase64||this.forceBase64,enablesXDR:n.enablesXDR||this.enablesXDR,timestampRequests:n.timestampRequests||this.timestampRequests,timestampParam:n.timestampParam||this.timestampParam,policyPort:n.policyPort||this.policyPort,pfx:n.pfx||this.pfx,key:n.key||this.key,passphrase:n.passphrase||this.passphrase,cert:n.cert||this.cert,ca:n.ca||this.ca,ciphers:n.ciphers||this.ciphers,rejectUnauthorized:n.rejectUnauthorized||this.rejectUnauthorized,perMessageDeflate:n.perMessageDeflate||this.perMessageDeflate,extraHeaders:n.extraHeaders||this.extraHeaders,forceNode:n.forceNode||this.forceNode,localAddress:n.localAddress||this.localAddress,requestTimeout:n.requestTimeout||this.requestTimeout,protocols:n.protocols||void 0});return r},r.prototype.open=function(){var t;if(this.rememberUpgrade&&r.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1)t="websocket";else{if(0===this.transports.length){var e=this;return void setTimeout(function(){e.emit("error","No transports available")},0)}t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(n){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)},r.prototype.setTransport=function(t){a("setting transport %s",t.name);var e=this;this.transport&&(a("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=t,t.on("drain",function(){e.onDrain()}).on("packet",function(t){e.onPacket(t)}).on("error",function(t){e.onError(t)}).on("close",function(){e.onClose("transport close")})},r.prototype.probe=function(t){function e(){if(f.onlyBinaryUpgrades){var e=!this.supportsBinary&&f.transport.supportsBinary;h=h||e}h||(a('probe transport "%s" opened',t),p.send([{type:"ping",data:"probe"}]),p.once("packet",function(e){if(!h)if("pong"===e.type&&"probe"===e.data){if(a('probe transport "%s" pong',t),f.upgrading=!0,f.emit("upgrading",p),!p)return;r.priorWebsocketSuccess="websocket"===p.name,a('pausing current transport "%s"',f.transport.name),f.transport.pause(function(){h||"closed"!==f.readyState&&(a("changing transport and sending upgrade packet"),u(),f.setTransport(p),p.send([{type:"upgrade"}]),f.emit("upgrade",p),p=null,f.upgrading=!1,f.flush())})}else{a('probe transport "%s" failed',t);var n=new Error("probe error");n.transport=p.name,f.emit("upgradeError",n)}}))}function n(){h||(h=!0,u(),p.close(),p=null)}function o(e){var r=new Error("probe error: "+e);r.transport=p.name,n(),a('probe transport "%s" failed because of error: %s',t,e),f.emit("upgradeError",r)}function i(){o("transport closed")}function s(){o("socket closed")}function c(t){p&&t.name!==p.name&&(a('"%s" works - aborting "%s"',t.name,p.name),n())}function u(){p.removeListener("open",e),p.removeListener("error",o),p.removeListener("close",i),f.removeListener("close",s),f.removeListener("upgrading",c)}a('probing transport "%s"',t);var p=this.createTransport(t,{probe:1}),h=!1,f=this;r.priorWebsocketSuccess=!1,p.once("open",e),p.once("error",o),p.once("close",i),this.once("close",s),this.once("upgrading",c),p.open()},r.prototype.onOpen=function(){if(a("socket open"),this.readyState="open",r.priorWebsocketSuccess="websocket"===this.transport.name,this.emit("open"),this.flush(),"open"===this.readyState&&this.upgrade&&this.transport.pause){a("starting upgrade probes");for(var t=0,e=this.upgrades.length;t1?{type:b[o],data:t.substring(1)}:{type:b[o]}:w}var i=new Uint8Array(t),o=i[0],s=f(t,1);return k&&"blob"===n&&(s=new k([s])),{type:b[o],data:s}},e.decodeBase64Packet=function(t,e){var n=b[t.charAt(0)];if(!u)return{type:n,data:{base64:!0,data:t.substr(1)}};var r=u.decode(t.substr(1));return"blob"===e&&k&&(r=new k([r])),{type:n,data:r}},e.encodePayload=function(t,n,r){function o(t){return t.length+":"+t}function i(t,r){e.encodePacket(t,!!s&&n,!1,function(t){r(null,o(t))})}"function"==typeof n&&(r=n,n=null);var s=h(t);return n&&s?k&&!g?e.encodePayloadAsBlob(t,r):e.encodePayloadAsArrayBuffer(t,r):t.length?void c(t,i,function(t,e){return r(e.join(""))}):r("0:")},e.decodePayload=function(t,n,r){if("string"!=typeof t)return e.decodePayloadAsBinary(t,n,r);"function"==typeof n&&(r=n,n=null);var o;if(""===t)return r(w,0,1);for(var i,s,a="",c=0,u=t.length;c0;){for(var s=new Uint8Array(o),a=0===s[0],c="",u=1;255!==s[u];u++){if(c.length>310)return r(w,0,1);c+=s[u]}o=f(o,2+c.length),c=parseInt(c);var p=f(o,0,c);if(a)try{p=String.fromCharCode.apply(null,new Uint8Array(p))}catch(h){var l=new Uint8Array(p);p="";for(var u=0;ur&&(n=r),e>=r||e>=n||0===r)return new ArrayBuffer(0);for(var o=new Uint8Array(t),i=new Uint8Array(n-e),s=e,a=0;s=55296&&e<=56319&&o65535&&(e-=65536,o+=w(e>>>10&1023|55296),e=56320|1023&e),o+=w(e);return o}function c(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate U+"+t.toString(16).toUpperCase()+" is not a scalar value");return!1}return!0}function u(t,e){return w(t>>e&63|128)}function p(t,e){if(0==(4294967168&t))return w(t);var n="";return 0==(4294965248&t)?n=w(t>>6&31|192):0==(4294901760&t)?(c(t,e)||(t=65533),n=w(t>>12&15|224),n+=u(t,6)):0==(4292870144&t)&&(n=w(t>>18&7|240),n+=u(t,12),n+=u(t,6)),n+=w(63&t|128)}function h(t,e){e=e||{};for(var n,r=!1!==e.strict,o=s(t),i=o.length,a=-1,c="";++a=v)throw Error("Invalid byte index");var t=255&g[b];if(b++,128==(192&t))return 63&t;throw Error("Invalid continuation byte")}function l(t){var e,n,r,o,i;if(b>v)throw Error("Invalid byte index");if(b==v)return!1;if(e=255&g[b],b++,0==(128&e))return e;if(192==(224&e)){if(n=f(),i=(31&e)<<6|n,i>=128)return i;throw Error("Invalid continuation byte")}if(224==(240&e)){if(n=f(),r=f(),i=(15&e)<<12|n<<6|r,i>=2048)return c(i,t)?i:65533;throw Error("Invalid continuation byte")}if(240==(248&e)&&(n=f(),r=f(),o=f(),i=(7&e)<<18|n<<12|r<<6|o,i>=65536&&i<=1114111))return i;throw Error("Invalid UTF-8 detected")}function d(t,e){e=e||{};var n=!1!==e.strict;g=s(t),v=g.length,b=0;for(var r,o=[];(r=l(n))!==!1;)o.push(r);return a(o)}var y="object"==typeof e&&e,m=("object"==typeof t&&t&&t.exports==y&&t,"object"==typeof o&&o);m.global!==m&&m.window!==m||(i=m);var g,v,b,w=String.fromCharCode,k={version:"2.1.2",encode:h,decode:d};r=function(){return k}.call(e,n,e,t),!(void 0!==r&&(t.exports=r))}(this)}).call(e,n(27)(t),function(){return this}())},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children=[],t.webpackPolyfill=1),t}},function(t,e){!function(){"use strict";for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(256),r=0;r>2],i+=t[(3&r[n])<<4|r[n+1]>>4],i+=t[(15&r[n+1])<<2|r[n+2]>>6],i+=t[63&r[n+2]];return o%3===2?i=i.substring(0,i.length-1)+"=":o%3===1&&(i=i.substring(0,i.length-2)+"=="),i},e.decode=function(t){var e,r,o,i,s,a=.75*t.length,c=t.length,u=0;"="===t[t.length-1]&&(a--,"="===t[t.length-2]&&a--);var p=new ArrayBuffer(a),h=new Uint8Array(p);for(e=0;e>4,h[u++]=(15&o)<<4|i>>2,h[u++]=(3&i)<<6|63&s;return p}}()},function(t,e){(function(e){function n(t){for(var e=0;e0);return e}function r(t){var e=0;for(p=0;p';i=document.createElement(e)}catch(t){i=document.createElement("iframe"),i.name=o.iframeId,i.src="javascript:0"}i.id=o.iframeId,o.form.appendChild(i),o.iframe=i}var o=this;if(!this.form){var i,s=document.createElement("form"),a=document.createElement("textarea"),p=this.iframeId="eio_iframe_"+this.index;s.className="socketio",s.style.position="absolute",s.style.top="-1000px",s.style.left="-1000px",s.target=p,s.method="POST",s.setAttribute("accept-charset","utf-8"),a.name="d",s.appendChild(a),document.body.appendChild(s),this.form=s,this.area=a}this.form.action=this.uri(),r(),t=t.replace(u,"\\\n"),this.area.value=t.replace(c,"\\n");try{this.form.submit()}catch(h){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===o.iframe.readyState&&n()}:this.iframe.onload=n}}).call(e,function(){return this}())},function(t,e,n){(function(e){function r(t){var e=t&&t.forceBase64;e&&(this.supportsBinary=!1),this.perMessageDeflate=t.perMessageDeflate,this.usingBrowserWebSocket=h&&!t.forceNode,this.protocols=t.protocols,this.usingBrowserWebSocket||(l=o),i.call(this,t)}var o,i=n(20),s=n(21),a=n(30),c=n(31),u=n(32),p=n(3)("engine.io-client:websocket"),h=e.WebSocket||e.MozWebSocket;if("undefined"==typeof window)try{o=n(35)}catch(f){}var l=h;l||"undefined"!=typeof window||(l=o),t.exports=r,c(r,i),r.prototype.name="websocket",r.prototype.supportsBinary=!0,r.prototype.doOpen=function(){if(this.check()){var t=this.uri(),e=this.protocols,n={agent:this.agent,perMessageDeflate:this.perMessageDeflate};n.pfx=this.pfx,n.key=this.key,n.passphrase=this.passphrase,n.cert=this.cert,n.ca=this.ca,n.ciphers=this.ciphers,n.rejectUnauthorized=this.rejectUnauthorized,this.extraHeaders&&(n.headers=this.extraHeaders),this.localAddress&&(n.localAddress=this.localAddress);try{this.ws=this.usingBrowserWebSocket?e?new l(t,e):new l(t):new l(t,e,n)}catch(r){return this.emit("error",r)}void 0===this.ws.binaryType&&(this.supportsBinary=!1),this.ws.supports&&this.ws.supports.binary?(this.supportsBinary=!0,this.ws.binaryType="nodebuffer"):this.ws.binaryType="arraybuffer",this.addEventListeners()}},r.prototype.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.onOpen()},this.ws.onclose=function(){t.onClose()},this.ws.onmessage=function(e){t.onData(e.data)},this.ws.onerror=function(e){t.onError("websocket error",e)}},r.prototype.write=function(t){function n(){r.emit("flush"),setTimeout(function(){r.writable=!0,r.emit("drain")},0)}var r=this;this.writable=!1;for(var o=t.length,i=0,a=o;i0&&t.jitter<=1?t.jitter:0,this.attempts=0}t.exports=n,n.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n}return 0|Math.min(t,this.max)},n.prototype.reset=function(){this.attempts=0},n.prototype.setMin=function(t){this.ms=t},n.prototype.setMax=function(t){this.max=t},n.prototype.setJitter=function(t){this.jitter=t}}])}); +//# sourceMappingURL=socket.io.js.map \ No newline at end of file diff --git a/test_vast_net.js b/lib/net/test_vast_net.js old mode 100644 new mode 100755 similarity index 80% rename from test_vast_net.js rename to lib/net/test_vast_net.js index 0e6c005d..a7d8d925 --- a/test_vast_net.js +++ b/lib/net/test_vast_net.js @@ -8,20 +8,25 @@ var vast_net = require('./vast_net'); + var net = undefined; // set default IP/port -var ip_port = {host: "127.0.0.1", port: 37}; +var ip_port = {host: VAST.Settings.IP_gateway, port: 37}; // get input IP / port // check port input, if any var port = process.argv[2]; -if (port !== undefined) +if (port !== undefined) { + console.log('custom port: ' + port); ip_port.port = port; +} var host = process.argv[3]; -if (host !== undefined) +if (host !== undefined) { + console.log('custom host: ' + host); ip_port.host = host; +} // check whether to run server or not // server @@ -46,10 +51,14 @@ if (process.argv.length <= 3) { } ); - net.listen(ip_port.port); + net.listen(ip_port.port, function (port) { + console.log('listen success, port binded: ' + port); + }); } // client else { + + console.log('client host: ' + ip_port.host + ' port: ' + ip_port.port); net = new vast_net( function (id, msg) { diff --git a/lib/net/vast_net.js b/lib/net/vast_net.js new file mode 100755 index 00000000..0ec16e68 --- /dev/null +++ b/lib/net/vast_net.js @@ -0,0 +1,583 @@ + +/* + * VAST, a scalable peer-to-peer network for virtual environments + * Copyright (C) 2005-2011 Shun-Yun Hu (syhu@ieee.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* + A generic network wrapper for communicating real-time messages with remote hosts + + supported functions: + + // basic callback / structure + addr = {host, port} + onReceive(id, msg) + onConnect(id) + onDisconnect(id) + + // constructor + vast_net(onReceive, onConnect, onDisconnect); + + // basic functions + storeMapping(id, addr) store mapping from id to a particular host IP/port + setID(new_id, old_id) set self ID or change the id -> socket mapping for incoming connections + getID() get self ID (which may be assigned by remote host) + send([id], msg, reliable, onDone) send a message to a target 'id', initiate connection as needed + listen(port, onDone) start a server at a given 'port', port binded is returned via 'onDone', 0 indicates error + close() close a server + disconnect(id) disconnect connection to a remote node + + // socket related + id = openSocket(addr, onReceive); + closeSocket(id); + sendSocket(id, msg); + + // aux helper methods (info from physical host) + getHost(onDone); + + // state check methods + isJoined(); + isPublic(); + isEntry(id); + isConnected(id); + isSocketConnected(id); + + history: + 2012-06-29 initial version (from VASTnet.h) + 2012-07-05 first working version (storeMapping, switchID, send) + 2012-07-20 rename switchID -> setID (can set self ID) +*/ + +var os = require('os'); +var l_net = require('./net_nodejs'); // implementation-specific network layer +//var VAST.ID_UNASSIGNED = 0; + +// +// input: +// onReceive(id, msg) callback when a message is received +// onConnect(id) callback when a remote host connects +// onDisconnect(id) callback when a remote host disconnects +// id optional assigned id +// +function vast_net(_localIP, onReceive, onConnect, onDisconnect, id) { + + // + // aux methods + // + + // return the host IP for the current machine + this.getHost = function (onDone) { + + // if already available, return directly + if (_localIP !== undefined) + return onDone(_localIP); + + var hostname = os.hostname(); + //LOG.debug('getHost called, hostname: ' + hostname); + + // NOTE: if network is not connected, lookup might take a long, indefinite time + require('dns').lookup(hostname, function (err, addr, fam) { + + if (err) { + //LOG.warn(err + '. Assign 127.0.0.1 to host'); + _localIP = "127.0.0.1"; + } + else + _localIP = addr; + + onDone(_localIP); + }) + } + + // + // constructor + // + + // id for myself, created by an id_generator, if available + var _self_id = id || VAST.ID_UNASSIGNED; + + // mapping between id and address + // TODO: clear mapping once in a while? (for timeout mapping) + var _id2addr = {}; + + // records for connections + var _sockets = {}; + + // queue to store messages pending out-transmission after connection is made + var _msgqueue = {}; + + // net_nodejs object for acting as server (& listen to port) + var _server = undefined; + + // counter for assigning internal / local-only ids + // TODO: this should be removed in future, or need to re-use id + var _id_counter = (-1); + + // + // public methods + // + + // store mapping between id to a host address + // NOTE: mapping stored is from //LOGical (app-layer) id to a host/port pair + // *not* mapping from host_id (physical-layer) to host/port pair + this.storeMapping = function (id, addr) { + //LOG.debug('store mapping for [' + id + ']: ' + addr.toString()); + // simply replace any existing mapping + _id2addr[id] = addr; + } + + // switch an existing id to socket mapping + var l_setID = this.setID = function (new_id, old_id) { + + // check if setting self id + if (old_id === undefined) { + //LOG.warn('assigning id to net layer for 1st time: [' + new_id + ']'); + _self_id = new_id; + } + // rename connection ID + // NOTE: incoming only, as we should know the id of outgoing connections + else if (_sockets.hasOwnProperty(old_id)) { + + //LOG.debug('replacing old_id [' + old_id + '] with new_id [' + new_id + ']'); + + // set new ID for socket (very important for future incoming messages) + _sockets[old_id].id = new_id; + + _sockets[new_id] = _sockets[old_id]; + delete _sockets[old_id]; + } + else + return false; + + return true; + } + + // get self ID (which may be assigned by remote host) + this.getID = function () { + return _self_id; + } + + // actually sending the message (attaching '\n' to indicate termination) + // send all messages in pending queue + var l_sendPendingMessages = function (id) { + + // no messages to send + if (_msgqueue.hasOwnProperty(id) === false || _msgqueue[id].length === 0) + return false; + + // if target id does not exist, indicate error + if (_sockets.hasOwnProperty(id) === false) { + //LOG.error('socket not connected for send target id: ' + id); + return false; + } + + var socket = _sockets[id]; + + var list = _msgqueue[id]; + + // send out pending messages + ////LOG.debug('[' + _self_id + '] l_sendPendingMessages to [' + id + '], msgsize: ' + list.length); + + for (var i=0; i < list.length; i++) { + + try { + socket.write(list[i] + '\n'); + } + catch (e) { + //LOG.debug('l_sendPendingMessages fail: ' + list[i]); + if (typeof onError === 'function') + onError('send'); + return false; + } + } + + // clear queue + _msgqueue[id] = []; + return true; + } + + // make a connection to a target id + var l_connect = function (id) { + + // check if id to address mapping exist + ////LOG.debug('mapping: '); + ////LOG.debug(_id2addr); + + if (_id2addr.hasOwnProperty(id) === false) { + //LOG.error('no send target address info for id: ' + id); + return; + } + + // create a new out-going connection if not exist + var conn = new l_net( + + // receive callback + _processData, + + // connect callback + // NOTE: there will be a time gap between send() returns and when connect callbacak is called + // therefore it's possible more messages have been sent to this endpoint before + // the connect event is ever called + function (socket) { + //LOG.debug('[' + id + '] connected'); + + // store id to socket, so we can identify the source of received messages + socket.id = id; + + // store to socket list + _sockets[id] = socket; + if (id < 0) { + //LOG.error('connected socket id < 0: ' + id); + } + + // notify connection + if (typeof onConnect === 'function') + onConnect(id); + + // create queue for new socket if not exist + // TODO: investigate why this happens (msgqueue should've already been init before this) + // unless, a disconnect for this 'id' has occured + // (so that means, before a new connection is made, another connection with the same remote host + // has been disconnected) + if (_msgqueue.hasOwnProperty(id) === false) { + var mq_size = Object.keys(_msgqueue).length; + var s_size = Object.keys(_sockets).length; + //LOG.error('[' + _self_id + '] msgqueue has no target [' + id + ']. should not happen, mq: ' + mq_size + ' sock: ' + s_size); + _msgqueue[id] = []; + } + + l_sendPendingMessages(id); + }, + + // disconnect callback + function (socket) { + //LOG.debug('id: ' + id + ' disconnected'); + + // remove id + delete socket.id; + + // remove from socket list + delete _sockets[id]; + + // remove all pending messages + delete _msgqueue[id]; + + // notify disconnection + if (typeof onDisconnect === 'function') + onDisconnect(id); + }, + + // error callback + function (type) { + // TODO: do something? + } + ); + + // make connection + // NOTE: send will return immediately, so the actual send may not occur until later + // it's possible that after returning, upper layer starts to send messages + conn.connect(_id2addr[id]); + + return true; + + } + + // send a message to an id + var l_send = this.send = function (id_list, pack, is_reliable, onDone) { + + // default is reliable TCP transmission + is_reliable = is_reliable || true; + + // attach sender id to message + pack.src = _self_id; + + // serialize string + var encode_str = JSON.stringify(pack); + + var target_list = ''; + + // go through each target id to send + for (var i=0; i < id_list.length; i++) { + var id = id_list[i]; + + // check if there's existing connection, or id to address mapping + target_list += (id + ','); + + // check if it's a self message + if (id === _self_id) { + + //LOG.warn('send message to self [' + _self_id + ']'); + // pass message to upper layer for handling + if (typeof onReceive === 'function') { + onReceive(_self_id, pack); + } + continue; + } + + // store message to queue + // create queue for connection if not exist + if (_msgqueue.hasOwnProperty(id) === false) { + //LOG.warn('msgqueue for [' + id + '] not exist, create one...'); + _msgqueue[id] = []; + } + + // store message to pending queue + _msgqueue[id].push(encode_str); + + // if connections already exists, send directly, otherwise establish new connection + if (_sockets.hasOwnProperty(id)) { + //LOG.warn('socket for [' + id + '] exists, send directly...'); + l_sendPendingMessages(id); + } + else { + var str = ''; + var unknown_count = 0; + for (var s in _sockets) { + str += (_sockets[s].id + ' '); + if (_sockets[s].id < 0) + unknown_count++; + } + + var sock_size = Object.keys(_sockets).length; + if (unknown_count > 5) { + //LOG.warn('[' + _self_id + '] attempts to connect to [' + id + '] sock_size: ' + sock_size); + ////LOG.warn(str); + } + + //LOG.warn('socket for [' + id + '] not exiss, try to connect...'); + l_connect(id); + } + } + + //LOG.debug('[' + _self_id + '] SEND to [' + target_list + ']: ' + encode_str); + } + + // start a server at a given port + this.listen = function (port, onDone) { + + if (port === undefined || port < 0 || port >= 65536) { + //LOG.error('port not provided, cannot start listening'); + if (typeof onDone === 'function') + onDone(0); + return; + } + + // open server + _server = new l_net( + // receive callback + _processData, + + // connect callback + function (socket) { + + ////LOG.warn('new socket connected, id: ' + socket.id); + + // check if id doesn't exist, indicate it's unassigned + if (socket.hasOwnProperty(id) === false) { + socket.id = _id_counter--; + ////LOG.warn('assigning id: ' + socket.id); + } + + // record this socket + // NOTE: this is an important step, otherwise a server will not be + // able to respond to incoming clients + _sockets[socket.id] = socket; + + // notify connection + if (typeof onConnect === 'function') + onConnect(socket.id); + }, + + // disconnect callback + function (socket) { + //console.//LOG('disconnet occur'); + + // notify disconnection + if (typeof onDisconnect === 'function') + onDisconnect(socket.id); + }, + + // error callback + function (error_type) { + + } + ); + + // handler of the result of listening + var listen_handler = function (port_binded) { + + // check for success + if (port_binded != 0) { + //LOG.warn('port bind successful: ' + port_binded); + // return the actual port binded + if (typeof onDone === 'function') + onDone(port_binded); + return; + } + + port++; + //LOG.debug('retrying next port: ' + port); + + // re-try + setTimeout(function () { + _server.listen(port, listen_handler); + }, 10); + }; + + _server.listen(port, listen_handler); + } + + // close a server + this.close = function () { + if (_server === undefined){ + //LOG.error('vast_net: server not started, cannot close'); + } + else { + _server.close(); + _server = undefined; + } + } + + // remove an existing connection + this.disconnect = function (id) { + + if (_sockets.hasOwnProperty(id)) { + //LOG.debug('disconnect conn id: ' + id); + _sockets[id].disconnect(); + delete _sockets[id]; + delete _msgqueue[id]; + } + else { + //LOG.debug('cannot find id [' + id + '] to disconnect'); + return false; + } + return true; + } + + + // + // private methods + // + + var _processData = function (socket, data) { + + ////LOG.warn('processData, socket.id: ' + socket.id); + + // create buffer for partially received message, if not exist + if (typeof socket.recv_buf === 'undefined') + socket.recv_buf = ''; + + // store data to buffer directly first + socket.recv_buf += data; + + // start loop of checking for complete messages + while (true) { + + // check if it's a complete message (termined with '\n') + var idx = socket.recv_buf.search('\n'); + + // if no complete message exists (ending with \n), stop + if (idx === (-1)) + break; + + // get new message and update buffer + var str = socket.recv_buf.slice(0, idx); + socket.recv_buf = socket.recv_buf.substr(idx + 1); + + // deliver this parsed data for processing + if (str === undefined) { + //LOG.error('str is undefined, recv_buf: ' + socket.recv_buf + ' from id: ' + socket.id); + continue; + } + + // unpack packet + var pack; + + try { + // convert msg back to js_obj + pack = JSON.parse(str); + } + catch (e) { + //LOG.error('msgHandler: convert to js_obj fail: ' + e + ' str: ' + str); + continue; + } + + // if pack is invalid + if (pack.hasOwnProperty('src') === false || + pack.hasOwnProperty('type') === false || + pack.hasOwnProperty('msg') === false) { + //LOG.error('[' + _self_id + '] invalid packet to process: ' + str); + continue; + } + + //LOG.debug('RECV from [' + pack.src + ']: ' + str); + + if (socket.hasOwnProperty('id') === false) { + //LOG.warn('socket has not id assigned yet...assigning: ' + pack.src); + socket.id = parseInt(pack.src); + } + + var remote_id = socket.id; + + // check if remote connection sends in its ID initially + // NOTE: this check should be performed only once + // NOTE: as this check is before receiving new ID from remote host, + // the first node joining the system will be given the gateway's ID (1) + if (remote_id < VAST.ID_UNASSIGNED) { + + var sender_id = parseInt(pack.src); + + //LOG.debug('[' + _self_id + '] learns sender id: ' + sender_id); + + // store the remote ID as remote host's socket ID + if (sender_id !== VAST.ID_UNASSIGNED) { + + // if ID exists, then there's already an established connection + if (_sockets.hasOwnProperty(sender_id) === true) { + var size = Object.keys(_sockets).length; + //LOG.warn('[' + _self_id + '] redundent socket already exists: ' + sender_id + ' sock size: ' + size); + for (var sock_id in _sockets){ + //LOG.warn(sock_id); + } + + // disconnect remote host + // however, message still needs to deliver + //socket.end(); + } + else + l_setID(sender_id, socket.id); + + remote_id = sender_id; + } + } + + // pass message to upper layer for handling + if (typeof onReceive === 'function') { + //LOG.warn('[' + _self_id + '] process pack by upper layer from [' + remote_id + ']: '); + ////LOG.warn(pack); + // TODO: queue-up message to be processed later? + onReceive(remote_id, pack); + } + } + }; + +} // end vast_net() + +// export the class with conditional check +if (typeof module !== "undefined") + module.exports = vast_net; diff --git a/lib/types.js b/lib/types.js new file mode 100755 index 00000000..0fe0fb42 --- /dev/null +++ b/lib/types.js @@ -0,0 +1,754 @@ + +/* + * VAST, a scalable peer-to-peer network for virtual environments + * Copyright (C) 2005-2011 Shun-Yun Hu (syhu@ieee.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* + Basic data structures used by the VAST library + + supported structures + + vast_pos position = {x, y} + vast_area area = {pos, radius} + vast_addr address = {host, port} + vast_endpt endpoint = {host_id, lastAccessed, addr} + vast_node node = {id, endpt, aoi, time} +*/ + +// to be inherited by vast_pos +// to be inherited by vast_pos +var point2d = point2d || require( "./voronoi/point2d.js" ); +var segment = require("./voronoi/segment"); + +// common data structures + +// definition of a node position +var l_pos = exports.pos = function (x, y) { + + // set default + if (x === undefined) + x = 0; + if (y === undefined) + y = 0; + + this.x = x; + this.y = y; + + this.equals = function (other_pos) { + return (this.x === other_pos.x && this.y === other_pos.y); + } + + this.toString = function () { + return '(' + this.x + ', ' + this.y + ')'; + } + + // update info from existing object + this.update = function(new_info) { + this.x = new_info.x; + this.y = new_info.y; + } + + // convert from a generic javascript object + this.parse = function (js_obj) { + + try { + this.x = parseFloat(js_obj.x); + this.y = parseFloat(js_obj.y); + } + catch (e) { + console.log('pos parse error: ' + e); + } + } +} + +// make l_pos inherent all properties of point2d +l_pos.prototype = new point2d(); + +// definition for an area +// 'center': a vast_pos +var l_area = exports.area = function (center, radius) { + + // set default + if (center === undefined) + center = new l_pos(0, 0); + if (radius === undefined) + radius = 0; + + // store center & radius, with potential error checking + this.center = new l_pos(0, 0); + this.center.parse(center); + this.radius = parseFloat(radius); + + this.coversPoint = function (pos) { + // NOTE: current check allows nodes even at AOI boundary to be considered as covered + return (this.center.distance(pos) <= this.radius); + } + + this.intersectsArea = function (area){ + return (this.center.distance(area.center) <= (this.radius + area.radius)); + } + + + this.equals = function (other_area) { + return (this.center.equals(other_area.center) && this.radius === other_area.radius); + } + + this.toString = function () { + return 'area: ' + this.center.toString() + ' radius: ' + this.radius; + } + + // update info from existing object + this.update = function(new_info) { + this.center.update(new_info.center); + + // only update if radius is valid + if (new_info.hasOwnProperty('radius') && new_info.radius >= 0) + this.radius = new_info.radius; + } + + // convert from a generic javascript object + this.parse = function (js_obj) { + try { + this.center = new l_pos(); + this.center.parse(js_obj.center); + + // we make decoding radius optional + // NOTE: use negative radius, so it won't be updated when performing a 'update' + if (js_obj.hasOwnProperty('radius')) + this.radius = js_obj.radius; + else + this.radius = -1; + } + catch (e) { + console.log('area parse error: ' + e); + } + } +} + +// definition for a connectable IP/port pair (vast_addr) +var l_addr = exports.addr = function (host, port) { + + // set initial value or default + this.host = host || 0; + this.port = port || 0; + + // turn object to string representation + this.toString = function () { + return this.host + ':' + this.port; + } + + // check if address is unassigned + this.isEmpty = function () { + return (this.host === 0 || this.port === 0); + } + + // update info from existing object + this.update = function(new_info) { + if (new_info.host !== 0) + this.host = new_info.host; + if (new_info.port !== 0) + this.port = new_info.port; + } + + // convert from a generic javascript object + this.parse = function (js_obj) { + + try { + //console.log('js obj host: ' + js_obj.host + ' port: ' + js_obj.port); + if (js_obj.hasOwnProperty('host')) + this.host = js_obj.host; + + // port must be provided + this.port = js_obj.port; + } + catch (e) { + console.log('addr parse error: ' + e); + } + } +} + +// definition for a host address +var l_endpt = exports.endpt = function (host, port) { + + this.host_id = 0; + this.lastAccessed = 0; + this.addr = new l_addr(host, port); + + this.toString = function () { + return 'host [' + this.host_id + '] ' + this.addr.toString(); + } + + // update info from existing object + this.update = function (new_info) { + if (new_info.host_id !== 0) + this.host_id = new_info.host_id; + if (new_info.lastAccessed !== 0) + this.lastAccessed = new_info.lastAccessed; + this.addr.update(new_info.addr); + } + + // convert from a generic javascript object + this.parse = function (js_obj) { + + try { + this.host_id = js_obj.host_id; + this.lastAccessed = js_obj.lastAccessed; + this.addr = new l_addr(); + this.addr.parse(js_obj.addr); + } + catch (e) { + console.log('endpt parse error: ' + e); + } + } +} + +// definition for a node +// 'aoi': a vast_area object +// 'endpt': a vast_endpt object +var l_node = exports.node = function (id, endpt, aoi, time) { + + // set initial values or default + this.id = id || 0; // a node's unique ID + this.endpt = endpt || new l_endpt(); // a node's contact endpoint (host_id & address) + this.aoi = aoi || new l_area(); // a node's AOI (center + radius) + this.time = time || 0; // a node's last updated time (used to determine whether it contains newer info) + //this.meta = {}; // a node's meta-data, default to empty + + // update node info from another node + // NOTE: this is powerful as it replaces almost everything (perhaps ID shouldn't be replaced?) + // NOTE: we only replace if data is available + this.update = function (new_info) { + + if (new_info.id !== 0) + this.id = new_info.id; + + //if (typeof new_info.meta === 'object' && Object.keys(new_info.meta).length > 0) + // this.meta = new_info.meta; + + this.endpt.update(new_info.endpt); + this.aoi.update(new_info.aoi); + + if (new_info.time !== 0) + this.time = new_info.time; + } + + // parse a json object onto a node object + this.parse = function (js_obj) { + try { + this.id = parseInt(js_obj.id); + + // we make decoding end point optional + if (js_obj.hasOwnProperty('endpt')) + this.endpt.parse(js_obj.endpt); + + this.aoi = new l_area(); + this.aoi.parse(js_obj.aoi); + this.time = js_obj.time; + + //if (typeof js_obj.meta === 'object') + // this.meta = js_obj.meta; + } + catch (e) { + console.log('node parse error: ' + e.stack); + } + } + + // print out node info + this.toString = function () { + //return '[' + this.id + '] ' + this.endpt.toString() + ' ' + this.aoi.toString() + ' meta: ' + Object.keys(this.meta).length; + return '[' + this.id + ']: ' + this.endpt.toString() + ' ' + this.aoi.toString(); + } +} + +// definition for a network packet (sent via VON) +var l_pack = exports.pack = function (type, msg, priority, sender) { + + // the message type + this.type = type; + + // the message content + this.msg = msg; + + // default priority is 1 + this.priority = (priority === undefined ? 1 : priority); + + // target is a list of node IDs + this.targets = []; + + // sender id + this.src = sender || 0; +} + +// this pack is transported in msg of l_pack +// It is routed through VON until the accepting peer over targetPos is reached +// then is is passed to the matcher +var l_pointPacket = exports.pointPacket = function(type, msg, sender, sourcePos, targetPos){ + + // The Matcher_Message type + this.type = type; + + // The message content + this.msg = msg; + + // sender id + this.sender = sender || 0; + + // The source position + this.sourcePos = sourcePos; + + // list of target positions (point publications) + this.targetPos = targetPos; + + // each node the message has "hopped" along + // no functional purpose, only used for debugging to see how a message is forwarded between VON peers + this.chain = []; + + // The list of nodes a VON peer must check. It will only forward the message if this field is empty + // or if it is the closest node to th target in the list + this.checklist = []; + +} + +// this pack is transported in msg of l_pack +// It is routed through VON and sent to each node whose region overlaps +// with the target AoI. Recipients are used to avoid redundant messaging +var l_areaPacket = exports.areaPacket = function(type, msg, sender, sourcePos, targetAoI){ + + // The Matcher_Message type + this.type = type; + + // The message content + this.msg = msg;` ` + + // sender id + this.sender = sender || 0; + + // The source position + this.sourcePos = sourcePos; + + // target AoI) + this.targetAoI = targetAoI; + + // list of IDs nodes that already received the message + // the list is not exhaustive, but does contain all of the nodes needed for child selection + // (this list differs between nodes) + this.recipients = []; + + // each node the message has "hopped" along + // no functional purpose, only used for debugging to see how a message is forwarded between VON peers + this.chain = []; +} + + +// definition for a simple stat object (ratio) +var l_ratio = exports.ratio = function () { + + this.normal = 0; + this.total = 0; + + this.ratio = function () { + return normal / total; + } +} + +var l_pub = exports.pub = function(matcherID, clientID, aoi, payload, channel){ + matcherID = matcherID || 0; + clientID = clientID || 0; + aoi = aoi || new l_area(); + channel = channel || '0'; + + this.matcherID = matcherID; + this.clientID = clientID; + this.aoi = aoi; + this.payload = payload; + this.channel = channel; + this.recipients = []; + this.chain = []; + + this.parse = function(js_obj){ + this.matcherID = parseInt(js_obj.matcherID); + this.clientID = js_obj.clientID; + this.aoi.parse(js_obj.aoi); + this.payload = js_obj.payload; + this.channel = js_obj.channel; + this.recipients = Object.values(js_obj.recipients); + this.chain = Object.values(js_obj.chain); + } +} + + + + +// definition for a subscription +// 'host_id': to which host a matched publication should be sent +// 'id': unique subscription id +// 'layer': which layer the subscription belongs +// 'aoi': the aoi of the subscription + +var l_sub = exports.sub = function (hostID, hostPos, clientID, subID, channel, aoi) { + + hostID = hostID || 0; + hostPos = hostPos || new l_pos(); // Position to send matching pubs to + clientID = clientID || 0; + subID = subID || 0; + channel = channel || '0'; + aoi = aoi || new l_area(); + + this.hostID = hostID; + this.hostPos = hostPos; + this.clientID = clientID; + this.subID = subID; + this.channel = channel; + this.aoi = aoi; + this.recipients = []; + this.heartbeat = UTIL.getTimestamp(); + + this.changeHost = function(hostID, hostPos){ + this.hostID = hostID; + this.hostPos = hostPos; + } + + // parse a json object + this.parse = function (js_obj) { + try { + this.hostID = parseInt(js_obj.hostID); + this.hostPos.parse(js_obj.hostPos); + this.clientID = js_obj.clientID; + this.subID = js_obj.subID; + this.channel = js_obj.channel; + this.aoi.parse(js_obj.aoi); + this.recipients = Object.values(js_obj.recipients); + this.heartbeat = js_obj.heartbeat; + } + catch (e) { + console.log('sub parse error: ' + e); + } + } + + // print out node info + this.toString = function () { + return '[' + this.id + '] hostID: ' + hostID + ' layer: ' + this.layer + ' AOI: ' + this.aoi.toString(); + } +} + +var l_clientInfo = exports.clientInfo = function (matcherID, clientID, pos) { + + this.matcherID = matcherID; + this.clientID = clientID; + this.pos = l_pos(pos.x, pos.y); + + // update info from existing record + // NOTE: we only replace if data is available + this.update = function (matcherID,matcherAddr, clientID, pos) { + try{ + this.matcherID = matcherID; + this.matcherAddr = l_addr.parse(this.matcherAddr) + this.clientID = clientID; + this.pos = l_pos(pos.x, pos.y); + } + catch (e){ + console.log('client info update error' + e); + } + } + + // parse a json object onto a node object + this.parse = function (js_obj) { + try { + this.matcherID = parseInt(js_obj.matcherID); + this.id = parse(js_obj.clientID); + this.pos = l_pos.parse(js_obj.pos) + } + catch (e) { + console.log('clientInfo parse error: ' + e); + } + } +} + +// definition for a region (based off of cell in rhill-voronoi) +// site: the Voronoi site object associated with the Voronoi cell. +// halfedges: an array of Voronoi.Halfedge objects, ordered counterclockwise, +// defining the polygon for this Voronoi cell. +var l_region = exports.region = function (site, halfEdges, boundarySize, closeMe) { + this.site = site || new l_pos(); + this.halfedges = halfEdges || []; + this.boundaryEdges = []; + this.boundarySize = boundarySize || 24; + this.convertedEdges = []; + this.closeMe = closeMe || false; + + this.update = function (new_region) { + this.site.update(new_region.site); + this.halfedges = new_region.halfedges; + this.convertedEdges = []; + this.closeMe = new_region.closeMe; + }; + + this.parse = function(js_obj){ + this.site.parse(js_obj.site); + this.halfedges = Object.values(js_obj.halfedges); + this.boundaryEdges = Object.values(js_obj.boundaryEdges); + this.boundarySize = parseInt(js_obj.boundarySize); + this.closeMe = js_obj.closeMe || false; + } + + this.move = function(position) { + this.site.update(position); + this.halfedges = []; + this.closeMe = false; + } + + // initialise the site of a region that has already been created but not instantiated + // NOTE: the reason this field is not simply called 'aoi' to be aligned with 'node' API is because 'aoi' + // is significantly different in what it contains relative to 'site', and therefore cannot be named as such + // (hence the need for this function) + this.init = function (site) { + this.site.update(site); + } + + // converts the halfedges from the type given by the voronoi + // to type 'segment' from VAST + // also creates boundary region around the region for load balancing + this.convertingEdges = function () { + //console.log("Converting Edges"); + var edgeList = []; + var boundaryPoints = []; + var boundaryList = [] + var pt, pt2, pt3; + var point, point2; + + for (var i=0; i < this.halfedges.length; i++) { + //console.log(i); + pt1 = this.halfedges[i].getStartpoint(); + pt2 = this.halfedges[i].getEndpoint(); + + if ((i+1) == this.halfedges.length) { + pt3 = this.halfedges[0].getEndpoint(); + } else { + pt3 = this.halfedges[i+1].getEndpoint(); + } + + //console.log("Getting new boundary vertex with points: "); + //console.log("pt1:"); + //console.log(pt1); + //console.log("pt2: "); + //console.log(pt2); + //console.log("pt3:"); + //console.log(pt3); + point = _getBoundaryVertex(pt1,pt2,pt3, this.boundarySize); + + boundaryPoints.push(point); + + // create line segment + edgeList.push(new segment(new point2d(pt1.x,pt1.y), new point2d(pt2.x, pt2.y))); + } + + //console.log("Boundary points"); + //console.log(boundaryPoints); + for (var k = 0; k < boundaryPoints.length; k++) { + point1 = boundaryPoints[k]; + + if (k+1 != boundaryPoints.length) { + point2 = boundaryPoints[k+1]; + } else { + point2 = boundaryPoints[0]; + } + //console.log("Point 1"); + //console.log(point1); + //console.log("Point 2"); + //console.log(point2); + boundaryList.push(new segment(new point2d(point1.x,point1.y), new point2d(point2.x, point2.y))); + } + + this.boundaryEdges = boundaryList; + + this.convertedEdges = edgeList; + + return true; + } + + this.intersects = function (center, radius) { + if (this.convertedEdges.length === 0) { + console.log("There are no lengths to check intersection against"); + return false; + } + + if (typeof this.convertedEdges[0].intersects !== 'function') { + this.convertedEdges = _convertEdges(); + } + + //LOG.debug("Converted edges"); + //LOG.debug(this.convertedEdges); + + // check each line for intersection and return true if there is one + for (var i=0; i < this.convertedEdges.length; i++) { + if (this.convertedEdges[i].intersects(center, radius)) + return true; + } + //LOG.debug("returning false"); + return false; + } + + // check whether a point lies within a polygon + // reference: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + var _within = this.within = function(pos, region) { + //LOG.debug("Starting within"); + var polygon = true; + if (region == undefined) { + polygon = false; + region = this.boundaryEdges; + } + + var verty = []; + var vertx = []; + var pt1; + + for (var i=0; i < region.length; i++) { + pt1 = region[i].p1 === undefined ? region[i] : region[i].p1; + + // NOTE we only store one point, as the polygon should close itself + verty.push(pt1.y); + vertx.push(pt1.x); + } + + var nvert = region.length; + + //LOG.debug(nvert); + var i, j, c = 0; + + //LOG.debug("vertx"); + //LOG.debug(vertx); + //LOG.debug("verty"); + //LOG.debug(verty); + //LOG.debug("pos"); + //LOG.debug(pos); + + for (i = 0, j = nvert-1; i < nvert; j = i++) { + if ( ((verty[i] > pos.y) != (verty[j] > pos.y)) && + (pos.x < (vertx[j] - vertx[i]) * (pos.y - verty[i]) / (verty[j] - verty[i]) + vertx[i]) ) + c = !c; + } + + return (c != 0); + } + + // pt2 is the focal point + var _getBoundaryVertex = this.getBoundaryVertex = function(pt1,pt2,pt3, boundarySize) { + //console.log("Points") + //console.log(pt1); + //console.log(pt2); + //console.log(pt3); + var m1,m2,alpha,theta,dx,dy,xBar,yBar; + dx = pt2.x-pt1.x; + dy = pt2.y-pt1.y; + + if (dx != 0) { // line 1 vertical + //console.log("case 1"); + m1 = dy/dx; + //console.log("m1: " + m1); + + dx = pt3.x-pt2.x; + dy = pt3.y-pt2.y; + + if (dx != 0) { // line 2 vertical + //console.log("case 2"); + m2 = dy/dx; + ///console.log("m2: " + m2); + + if (m2*m1 != -1) { // perpendicular lines + //console.log("case 3"); + alpha = ((pt2.y>pt1.y && m1 > 0) || (m2<0 && m1==0)) ? Math.PI - Math.atan(Math.abs((m2-m1)/(1+m2*m1))) : Math.atan(Math.abs((m2-m1)/(1+m2*m1))); + + if (m1 > 0 && m2 > 0) { + theta = -alpha/2; + } else if (m1 < 0 && m2 > 0) { + theta = Math.PI + Math.atan(m1) + alpha/2; + } else if (m1 > 0 && m2 < 0) { + theta = -alpha/2 + Math.atan(m2); + } else if (m1 < 0 && m2 < 0){ + theta = alpha/2-Math.atan(m1); + } else if ((m2 == 0 && m1 > 0) || (m1 < 0 && m2 == 0)) { + theta = -alpha/2; + } else { + theta = alpha/2; + } + } else { + //console.log("case 4"); + alpha = Math.PI/2; + theta = m1 > 0 ? Math.atan(m2)-Math.atan(m1) : Math.atan(Math.abs(m2))-Math.atan(Math.abs(m1)); + } + } else { + //console.log("case 5"); + alpha = m1 < 0 ? Math.PI/2-Math.atan(m1) : m1 > 0 ? Math.PI/2- (Math.atan(m1)) : Math.PI/2; + theta = m1 <= 0 ? alpha/2 - Math.atan(Math.abs(m1)) : alpha/2 + Math.atan(m1); + } + } else { + //console.log("case 6"); + dx = pt3.x-pt2.x; + dy = pt3.y-pt2.y; + + //NOTE: dx will never be negative here because then the lines would be parallel, + // which is guaranteed not to happen for a convex polygon + m2 = dy/dx; + //console.log("m2: " + m2); + + alpha = Math.atan(m2)-Math.PI/2; + + if (pt3.x-pt1.x < 0) { + alpha += Math.PI; + theta = Math.PI/2 + alpha/2; + theta += Math.PI; + } else { + alpha -= Math.PI; + theta = Math.PI/2 + alpha/2; + } + } + + //console.log("Alpha: " + (alpha*180/Math.PI)); + //console.log("Theta: " + (theta*180/Math.PI)); + + xBar = pt2.x + boundarySize*Math.cos(theta); + yBar = pt2.y + boundarySize*Math.sin(theta); + + var pt = { + x: xBar, + y: yBar + } + + + if (_within(pt,[pt1,pt2,pt3])) { + theta += Math.PI; + //console.log("New theta: " + (theta*180/Math.PI)); + xBar = pt2.x + boundarySize*Math.cos(theta); + yBar = pt2.y + boundarySize*Math.sin(theta); + + pt = { + x: xBar, + y: yBar + } + } + + + + return pt + } + + this.toString = function () { + return "site: " + this.site.toString() + " halfedges: " + this.halfedges + " closeMe: " + this.closeMe; + } +} diff --git a/test_voro_rh (interactive).html b/lib/visualiser/test_voro_rh (specify points).html similarity index 51% rename from test_voro_rh (interactive).html rename to lib/visualiser/test_voro_rh (specify points).html index 3aa69832..62698f8a 100644 --- a/test_voro_rh (interactive).html +++ b/lib/visualiser/test_voro_rh (specify points).html @@ -3,33 +3,32 @@ - - - - - - + + + + + + @@ -316,25 +287,26 @@

Voronoi Test (Raymond Hill's)

Sites generator

- or sites randomly + or sites randomly +
-mouse_x: +mouse_x: -mouse_y: +mouse_y: -AOI radius: - +AOI radius: +
Display Type: -enclosing     +enclosing     boundary -
+

Canvas

- + - \ No newline at end of file + diff --git a/typedef/line2d.js b/lib/voronoi/line2d.js old mode 100644 new mode 100755 similarity index 100% rename from typedef/line2d.js rename to lib/voronoi/line2d.js diff --git a/typedef/point2d.js b/lib/voronoi/point2d.js old mode 100644 new mode 100755 similarity index 94% rename from typedef/point2d.js rename to lib/voronoi/point2d.js index a10181f4..2a26ca75 --- a/typedef/point2d.js +++ b/lib/voronoi/point2d.js @@ -1,21 +1,21 @@ function point2d(x, y) { - + this.x = (typeof x == 'undefined' ? 0 : x); this.y = (typeof y == 'undefined' ? 0 : y); - + // public variables & methods this.set = function (x, y) { this.x = (typeof x == 'undefined' ? 0 : x); this.y = (typeof y == 'undefined' ? 0 : y); } - + // check if this point is smaller than another point this.lessThan = function (a) { return (this.y < a.y ? true : (this.x < a.x)); } - + // compare this point with another point, and return (-1, 0, 1) for less than, equal, or greater than this.compareTo = function (a) { if (this.y < a.y) @@ -28,14 +28,14 @@ function point2d(x, y) { return (1); return (0); } - + // check distance of this point to another this.distance = function (p) { - + var dx = p.x - this.x; var dy = p.y - this.y; - //console.log ("point2d distance called, dx: " + dx + " dy: " + dy + " this.x: " + this.x); - + //console.log ("point2d distance called, dx: " + dx + " dy: " + dy + " this.x: " + this.x + " this.y: " + this.y + " p.x: " + p.x + " p.y: " + p.y); + return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); } @@ -44,7 +44,7 @@ function point2d(x, y) { var dy = p.y - this.y; return Math.pow(dx, 2) + Math.pow(dy, 2); } - + this.to_string = function () { return '(' + this.x + ', ' + this.y + ')'; } @@ -52,11 +52,11 @@ function point2d(x, y) { /* point2d.prototype.distance = function (p) { - + var dx = p.x - this.x; var dy = p.y - this.y; //console.log ("point2d distance called, dx: " + dx + " dy: " + dy + " this.x: " + this.x); - + return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); } */ diff --git a/lib/voronoi/rhill-voronoi-core.js b/lib/voronoi/rhill-voronoi-core.js new file mode 100755 index 00000000..64244287 --- /dev/null +++ b/lib/voronoi/rhill-voronoi-core.js @@ -0,0 +1,1727 @@ +/*! +Copyright (C) 2010-2013 Raymond Hill: https://github.com/gorhill/Javascript-Voronoi +MIT License: See https://github.com/gorhill/Javascript-Voronoi/LICENSE.md +*/ +/* +Author: Raymond Hill (rhill@raymondhill.net) +Contributor: Jesse Morgan (morgajel@gmail.com) +File: rhill-voronoi-core.js +Version: 0.98 +Date: January 21, 2013 +Description: This is my personal Javascript implementation of +Steven Fortune's algorithm to compute Voronoi diagrams. + +License: See https://github.com/gorhill/Javascript-Voronoi/LICENSE.md +Credits: See https://github.com/gorhill/Javascript-Voronoi/CREDITS.md +History: See https://github.com/gorhill/Javascript-Voronoi/CHANGELOG.md + +## Usage: + + var sites = [{x:300,y:300}, {x:100,y:100}, {x:200,y:500}, {x:250,y:450}, {x:600,y:150}]; + // xl, xr means x left, x right + // yt, yb means y top, y bottom + var bbox = {xl:0, xr:800, yt:0, yb:600}; + var voronoi = new Voronoi(); + // pass an object which exhibits xl, xr, yt, yb properties. The bounding + // box will be used to connect unbound edges, and to close open cells + result = voronoi.compute(sites, bbox); + // render, further analyze, etc. + +Return value: + An object with the following properties: + + result.vertices = an array of unordered, unique Voronoi.Vertex objects making + up the Voronoi diagram. + result.edges = an array of unordered, unique Voronoi.Edge objects making up + the Voronoi diagram. + result.cells = an array of Voronoi.Cell object making up the Voronoi diagram. + A Cell object might have an empty array of halfedges, meaning no Voronoi + cell could be computed for a particular cell. + result.execTime = the time it took to compute the Voronoi diagram, in + milliseconds. + +Voronoi.Vertex object: + x: The x position of the vertex. + y: The y position of the vertex. + +Voronoi.Edge object: + lSite: the Voronoi site object at the left of this Voronoi.Edge object. + rSite: the Voronoi site object at the right of this Voronoi.Edge object (can + be null). + va: an object with an 'x' and a 'y' property defining the start point + (relative to the Voronoi site on the left) of this Voronoi.Edge object. + vb: an object with an 'x' and a 'y' property defining the end point + (relative to Voronoi site on the left) of this Voronoi.Edge object. + + For edges which are used to close open cells (using the supplied bounding + box), the rSite property will be null. + +Voronoi.Cell object: + site: the Voronoi site object associated with the Voronoi cell. + halfedges: an array of Voronoi.Halfedge objects, ordered counterclockwise, + defining the polygon for this Voronoi cell. + +Voronoi.Halfedge object: + site: the Voronoi site object owning this Voronoi.Halfedge object. + edge: a reference to the unique Voronoi.Edge object underlying this + Voronoi.Halfedge object. + getStartpoint(): a method returning an object with an 'x' and a 'y' property + for the start point of this halfedge. Keep in mind halfedges are always + countercockwise. + getEndpoint(): a method returning an object with an 'x' and a 'y' property + for the end point of this halfedge. Keep in mind halfedges are always + countercockwise. + +TODO: Identify opportunities for performance improvement. + +TODO: Let the user close the Voronoi cells, do not do it automatically. Not only let + him close the cells, but also allow him to close more than once using a different + bounding box for the same Voronoi diagram. +*/ + +/*global Math */ + +// --------------------------------------------------------------------------- + +function Voronoi() { + this.vertices = null; + this.edges = null; + this.cells = null; + this.toRecycle = null; + this.beachsectionJunkyard = []; + this.circleEventJunkyard = []; + this.vertexJunkyard = []; + this.edgeJunkyard = []; + this.cellJunkyard = []; + } + +// --------------------------------------------------------------------------- + +Voronoi.prototype.reset = function() { + if (!this.beachline) { + this.beachline = new this.RBTree(); + } + // Move leftover beachsections to the beachsection junkyard. + if (this.beachline.root) { + var beachsection = this.beachline.getFirst(this.beachline.root); + while (beachsection) { + this.beachsectionJunkyard.push(beachsection); // mark for reuse + beachsection = beachsection.rbNext; + } + } + this.beachline.root = null; + if (!this.circleEvents) { + this.circleEvents = new this.RBTree(); + } + this.circleEvents.root = this.firstCircleEvent = null; + this.vertices = []; + this.edges = []; + this.cells = []; + }; + +Voronoi.prototype.sqrt = Math.sqrt; +Voronoi.prototype.abs = Math.abs; +Voronoi.prototype.ε = Voronoi.ε = 1e-9; +Voronoi.prototype.invε = Voronoi.invε = 1.0 / Voronoi.ε; +Voronoi.prototype.equalWithEpsilon = function(a,b){return this.abs(a-b)<1e-9;}; +Voronoi.prototype.greaterThanWithEpsilon = function(a,b){return a-b>1e-9;}; +Voronoi.prototype.greaterThanOrEqualWithEpsilon = function(a,b){return b-a<1e-9;}; +Voronoi.prototype.lessThanWithEpsilon = function(a,b){return b-a>1e-9;}; +Voronoi.prototype.lessThanOrEqualWithEpsilon = function(a,b){return a-b<1e-9;}; + +// --------------------------------------------------------------------------- +// Red-Black tree code (based on C version of "rbtree" by Franck Bui-Huu +// https://github.com/fbuihuu/libtree/blob/master/rb.c + +Voronoi.prototype.RBTree = function() { + this.root = null; + }; + +Voronoi.prototype.RBTree.prototype.rbInsertSuccessor = function(node, successor) { + var parent; + if (node) { + // >>> rhill 2011-05-27: Performance: cache previous/next nodes + successor.rbPrevious = node; + successor.rbNext = node.rbNext; + if (node.rbNext) { + node.rbNext.rbPrevious = successor; + } + node.rbNext = successor; + // <<< + if (node.rbRight) { + // in-place expansion of node.rbRight.getFirst(); + node = node.rbRight; + while (node.rbLeft) {node = node.rbLeft;} + node.rbLeft = successor; + } + else { + node.rbRight = successor; + } + parent = node; + } + // rhill 2011-06-07: if node is null, successor must be inserted + // to the left-most part of the tree + else if (this.root) { + node = this.getFirst(this.root); + // >>> Performance: cache previous/next nodes + successor.rbPrevious = null; + successor.rbNext = node; + node.rbPrevious = successor; + // <<< + node.rbLeft = successor; + parent = node; + } + else { + // >>> Performance: cache previous/next nodes + successor.rbPrevious = successor.rbNext = null; + // <<< + this.root = successor; + parent = null; + } + successor.rbLeft = successor.rbRight = null; + successor.rbParent = parent; + successor.rbRed = true; + // Fixup the modified tree by recoloring nodes and performing + // rotations (2 at most) hence the red-black tree properties are + // preserved. + var grandpa, uncle; + node = successor; + while (parent && parent.rbRed) { + grandpa = parent.rbParent; + if (parent === grandpa.rbLeft) { + uncle = grandpa.rbRight; + if (uncle && uncle.rbRed) { + parent.rbRed = uncle.rbRed = false; + grandpa.rbRed = true; + node = grandpa; + } + else { + if (node === parent.rbRight) { + this.rbRotateLeft(parent); + node = parent; + parent = node.rbParent; + } + parent.rbRed = false; + grandpa.rbRed = true; + this.rbRotateRight(grandpa); + } + } + else { + uncle = grandpa.rbLeft; + if (uncle && uncle.rbRed) { + parent.rbRed = uncle.rbRed = false; + grandpa.rbRed = true; + node = grandpa; + } + else { + if (node === parent.rbLeft) { + this.rbRotateRight(parent); + node = parent; + parent = node.rbParent; + } + parent.rbRed = false; + grandpa.rbRed = true; + this.rbRotateLeft(grandpa); + } + } + parent = node.rbParent; + } + this.root.rbRed = false; + }; + +Voronoi.prototype.RBTree.prototype.rbRemoveNode = function(node) { + // >>> rhill 2011-05-27: Performance: cache previous/next nodes + if (node.rbNext) { + node.rbNext.rbPrevious = node.rbPrevious; + } + if (node.rbPrevious) { + node.rbPrevious.rbNext = node.rbNext; + } + node.rbNext = node.rbPrevious = null; + // <<< + var parent = node.rbParent, + left = node.rbLeft, + right = node.rbRight, + next; + if (!left) { + next = right; + } + else if (!right) { + next = left; + } + else { + next = this.getFirst(right); + } + if (parent) { + if (parent.rbLeft === node) { + parent.rbLeft = next; + } + else { + parent.rbRight = next; + } + } + else { + this.root = next; + } + // enforce red-black rules + var isRed; + if (left && right) { + isRed = next.rbRed; + next.rbRed = node.rbRed; + next.rbLeft = left; + left.rbParent = next; + if (next !== right) { + parent = next.rbParent; + next.rbParent = node.rbParent; + node = next.rbRight; + parent.rbLeft = node; + next.rbRight = right; + right.rbParent = next; + } + else { + next.rbParent = parent; + parent = next; + node = next.rbRight; + } + } + else { + isRed = node.rbRed; + node = next; + } + // 'node' is now the sole successor's child and 'parent' its + // new parent (since the successor can have been moved) + if (node) { + node.rbParent = parent; + } + // the 'easy' cases + if (isRed) {return;} + if (node && node.rbRed) { + node.rbRed = false; + return; + } + // the other cases + var sibling; + do { + if (node === this.root) { + break; + } + if (node === parent.rbLeft) { + sibling = parent.rbRight; + if (sibling.rbRed) { + sibling.rbRed = false; + parent.rbRed = true; + this.rbRotateLeft(parent); + sibling = parent.rbRight; + } + if ((sibling.rbLeft && sibling.rbLeft.rbRed) || (sibling.rbRight && sibling.rbRight.rbRed)) { + if (!sibling.rbRight || !sibling.rbRight.rbRed) { + sibling.rbLeft.rbRed = false; + sibling.rbRed = true; + this.rbRotateRight(sibling); + sibling = parent.rbRight; + } + sibling.rbRed = parent.rbRed; + parent.rbRed = sibling.rbRight.rbRed = false; + this.rbRotateLeft(parent); + node = this.root; + break; + } + } + else { + sibling = parent.rbLeft; + if (sibling.rbRed) { + sibling.rbRed = false; + parent.rbRed = true; + this.rbRotateRight(parent); + sibling = parent.rbLeft; + } + if ((sibling.rbLeft && sibling.rbLeft.rbRed) || (sibling.rbRight && sibling.rbRight.rbRed)) { + if (!sibling.rbLeft || !sibling.rbLeft.rbRed) { + sibling.rbRight.rbRed = false; + sibling.rbRed = true; + this.rbRotateLeft(sibling); + sibling = parent.rbLeft; + } + sibling.rbRed = parent.rbRed; + parent.rbRed = sibling.rbLeft.rbRed = false; + this.rbRotateRight(parent); + node = this.root; + break; + } + } + sibling.rbRed = true; + node = parent; + parent = parent.rbParent; + } while (!node.rbRed); + if (node) {node.rbRed = false;} + }; + +Voronoi.prototype.RBTree.prototype.rbRotateLeft = function(node) { + var p = node, + q = node.rbRight, // can't be null + parent = p.rbParent; + if (parent) { + if (parent.rbLeft === p) { + parent.rbLeft = q; + } + else { + parent.rbRight = q; + } + } + else { + this.root = q; + } + q.rbParent = parent; + p.rbParent = q; + p.rbRight = q.rbLeft; + if (p.rbRight) { + p.rbRight.rbParent = p; + } + q.rbLeft = p; + }; + +Voronoi.prototype.RBTree.prototype.rbRotateRight = function(node) { + var p = node, + q = node.rbLeft, // can't be null + parent = p.rbParent; + if (parent) { + if (parent.rbLeft === p) { + parent.rbLeft = q; + } + else { + parent.rbRight = q; + } + } + else { + this.root = q; + } + q.rbParent = parent; + p.rbParent = q; + p.rbLeft = q.rbRight; + if (p.rbLeft) { + p.rbLeft.rbParent = p; + } + q.rbRight = p; + }; + +Voronoi.prototype.RBTree.prototype.getFirst = function(node) { + while (node.rbLeft) { + node = node.rbLeft; + } + return node; + }; + +Voronoi.prototype.RBTree.prototype.getLast = function(node) { + while (node.rbRight) { + node = node.rbRight; + } + return node; + }; + +// --------------------------------------------------------------------------- +// Diagram methods + +Voronoi.prototype.Diagram = function(site) { + this.site = site; + }; + +// --------------------------------------------------------------------------- +// Cell methods + +Voronoi.prototype.Cell = function(site) { + this.site = site; + this.halfedges = []; + this.closeMe = false; + }; + +Voronoi.prototype.Cell.prototype.init = function(site) { + this.site = site; + this.halfedges = []; + this.closeMe = false; + return this; + }; + +Voronoi.prototype.createCell = function(site) { + var cell = this.cellJunkyard.pop(); + if ( cell ) { + return cell.init(site); + } + return new this.Cell(site); + }; + +Voronoi.prototype.Cell.prototype.prepareHalfedges = function() { + var halfedges = this.halfedges, + iHalfedge = halfedges.length, + edge; + // get rid of unused halfedges + // rhill 2011-05-27: Keep it simple, no point here in trying + // to be fancy: dangling edges are a typically a minority. + while (iHalfedge--) { + edge = halfedges[iHalfedge].edge; + if (!edge.vb || !edge.va) { + halfedges.splice(iHalfedge,1); + } + } + + // rhill 2011-05-26: I tried to use a binary search at insertion + // time to keep the array sorted on-the-fly (in Cell.addHalfedge()). + // There was no real benefits in doing so, performance on + // Firefox 3.6 was improved marginally, while performance on + // Opera 11 was penalized marginally. + halfedges.sort(function(a,b){return b.angle-a.angle;}); + return halfedges.length; + }; + +// Return a list of the neighbor Ids +Voronoi.prototype.Cell.prototype.getNeighborIds = function() { + var neighbors = [], + iHalfedge = this.halfedges.length, + edge; + while (iHalfedge--){ + edge = this.halfedges[iHalfedge].edge; + if (edge.lSite !== null && edge.lSite.voronoiId != this.site.voronoiId) { + neighbors.push(edge.lSite.voronoiId); + } + else if (edge.rSite !== null && edge.rSite.voronoiId != this.site.voronoiId){ + neighbors.push(edge.rSite.voronoiId); + } + } + return neighbors; + }; + +// Compute bounding box +// +Voronoi.prototype.Cell.prototype.getBbox = function() { + var halfedges = this.halfedges, + iHalfedge = halfedges.length, + xmin = Infinity, + ymin = Infinity, + xmax = -Infinity, + ymax = -Infinity, + v, vx, vy; + while (iHalfedge--) { + v = halfedges[iHalfedge].getStartpoint(); + vx = v.x; + vy = v.y; + if (vx < xmin) {xmin = vx;} + if (vy < ymin) {ymin = vy;} + if (vx > xmax) {xmax = vx;} + if (vy > ymax) {ymax = vy;} + // we dont need to take into account end point, + // since each end point matches a start point + } + return { + x: xmin, + y: ymin, + width: xmax-xmin, + height: ymax-ymin + }; + }; + +// Return whether a point is inside, on, or outside the cell: +// -1: point is outside the perimeter of the cell +// 0: point is on the perimeter of the cell +// 1: point is inside the perimeter of the cell +// +Voronoi.prototype.Cell.prototype.pointIntersection = function(x, y) { + // Check if point in polygon. Since all polygons of a Voronoi + // diagram are convex, then: + // http://paulbourke.net/geometry/polygonmesh/ + // Solution 3 (2D): + // "If the polygon is convex then one can consider the polygon + // "as a 'path' from the first vertex. A point is on the interior + // "of this polygons if it is always on the same side of all the + // "line segments making up the path. ... + // "(y - y0) (x1 - x0) - (x - x0) (y1 - y0) + // "if it is less than 0 then P is to the right of the line segment, + // "if greater than 0 it is to the left, if equal to 0 then it lies + // "on the line segment" + var halfedges = this.halfedges, + iHalfedge = halfedges.length, + halfedge, + p0, p1, r; + while (iHalfedge--) { + halfedge = halfedges[iHalfedge]; + p0 = halfedge.getStartpoint(); + p1 = halfedge.getEndpoint(); + r = (y-p0.y)*(p1.x-p0.x)-(x-p0.x)*(p1.y-p0.y); + if (!r) { + return 0; + } + if (r > 0) { + return -1; + } + } + return 1; + }; + +// --------------------------------------------------------------------------- +// Edge methods +// + +Voronoi.prototype.Vertex = function(x, y) { + this.x = x; + this.y = y; + }; + +Voronoi.prototype.Edge = function(lSite, rSite) { + this.lSite = lSite; + this.rSite = rSite; + this.va = this.vb = null; + }; + +Voronoi.prototype.Halfedge = function(edge, lSite, rSite) { + this.site = lSite; + this.edge = edge; + // 'angle' is a value to be used for properly sorting the + // halfsegments counterclockwise. By convention, we will + // use the angle of the line defined by the 'site to the left' + // to the 'site to the right'. + // However, border edges have no 'site to the right': thus we + // use the angle of line perpendicular to the halfsegment (the + // edge should have both end points defined in such case.) + if (rSite) { + this.angle = Math.atan2(rSite.y-lSite.y, rSite.x-lSite.x); + } + else { + var va = edge.va, + vb = edge.vb; + // rhill 2011-05-31: used to call getStartpoint()/getEndpoint(), + // but for performance purpose, these are expanded in place here. + this.angle = edge.lSite === lSite ? + Math.atan2(vb.x-va.x, va.y-vb.y) : + Math.atan2(va.x-vb.x, vb.y-va.y); + } + }; + +Voronoi.prototype.createHalfedge = function(edge, lSite, rSite) { + return new this.Halfedge(edge, lSite, rSite); + }; + +Voronoi.prototype.Halfedge.prototype.getStartpoint = function() { + return this.edge.lSite === this.site ? this.edge.va : this.edge.vb; + }; + +Voronoi.prototype.Halfedge.prototype.getEndpoint = function() { + return this.edge.lSite === this.site ? this.edge.vb : this.edge.va; + }; + + + +// this create and add a vertex to the internal collection + +Voronoi.prototype.createVertex = function(x, y) { + var v = this.vertexJunkyard.pop(); + if ( !v ) { + v = new this.Vertex(x, y); + } + else { + v.x = x; + v.y = y; + } + this.vertices.push(v); + return v; + }; + +// this create and add an edge to internal collection, and also create +// two halfedges which are added to each site's counterclockwise array +// of halfedges. + +Voronoi.prototype.createEdge = function(lSite, rSite, va, vb) { + var edge = this.edgeJunkyard.pop(); + if ( !edge ) { + edge = new this.Edge(lSite, rSite); + } + else { + edge.lSite = lSite; + edge.rSite = rSite; + edge.va = edge.vb = null; + } + + this.edges.push(edge); + if (va) { + this.setEdgeStartpoint(edge, lSite, rSite, va); + } + if (vb) { + this.setEdgeEndpoint(edge, lSite, rSite, vb); + } + this.cells[lSite.voronoiId].halfedges.push(this.createHalfedge(edge, lSite, rSite)); + this.cells[rSite.voronoiId].halfedges.push(this.createHalfedge(edge, rSite, lSite)); + return edge; + }; + +Voronoi.prototype.createBorderEdge = function(lSite, va, vb) { + var edge = this.edgeJunkyard.pop(); + if ( !edge ) { + edge = new this.Edge(lSite, null); + } + else { + edge.lSite = lSite; + edge.rSite = null; + } + edge.va = va; + edge.vb = vb; + this.edges.push(edge); + return edge; + }; + +Voronoi.prototype.setEdgeStartpoint = function(edge, lSite, rSite, vertex) { + if (!edge.va && !edge.vb) { + edge.va = vertex; + edge.lSite = lSite; + edge.rSite = rSite; + } + else if (edge.lSite === rSite) { + edge.vb = vertex; + } + else { + edge.va = vertex; + } + }; + +Voronoi.prototype.setEdgeEndpoint = function(edge, lSite, rSite, vertex) { + this.setEdgeStartpoint(edge, rSite, lSite, vertex); + }; + +// --------------------------------------------------------------------------- +// Beachline methods + +// rhill 2011-06-07: For some reasons, performance suffers significantly +// when instanciating a literal object instead of an empty ctor +Voronoi.prototype.Beachsection = function() { + }; + +// rhill 2011-06-02: A lot of Beachsection instanciations +// occur during the computation of the Voronoi diagram, +// somewhere between the number of sites and twice the +// number of sites, while the number of Beachsections on the +// beachline at any given time is comparatively low. For this +// reason, we reuse already created Beachsections, in order +// to avoid new memory allocation. This resulted in a measurable +// performance gain. + +Voronoi.prototype.createBeachsection = function(site) { + var beachsection = this.beachsectionJunkyard.pop(); + if (!beachsection) { + beachsection = new this.Beachsection(); + } + beachsection.site = site; + return beachsection; + }; + +// calculate the left break point of a particular beach section, +// given a particular sweep line +Voronoi.prototype.leftBreakPoint = function(arc, directrix) { + // http://en.wikipedia.org/wiki/Parabola + // http://en.wikipedia.org/wiki/Quadratic_equation + // h1 = x1, + // k1 = (y1+directrix)/2, + // h2 = x2, + // k2 = (y2+directrix)/2, + // p1 = k1-directrix, + // a1 = 1/(4*p1), + // b1 = -h1/(2*p1), + // c1 = h1*h1/(4*p1)+k1, + // p2 = k2-directrix, + // a2 = 1/(4*p2), + // b2 = -h2/(2*p2), + // c2 = h2*h2/(4*p2)+k2, + // x = (-(b2-b1) + Math.sqrt((b2-b1)*(b2-b1) - 4*(a2-a1)*(c2-c1))) / (2*(a2-a1)) + // When x1 become the x-origin: + // h1 = 0, + // k1 = (y1+directrix)/2, + // h2 = x2-x1, + // k2 = (y2+directrix)/2, + // p1 = k1-directrix, + // a1 = 1/(4*p1), + // b1 = 0, + // c1 = k1, + // p2 = k2-directrix, + // a2 = 1/(4*p2), + // b2 = -h2/(2*p2), + // c2 = h2*h2/(4*p2)+k2, + // x = (-b2 + Math.sqrt(b2*b2 - 4*(a2-a1)*(c2-k1))) / (2*(a2-a1)) + x1 + + // change code below at your own risk: care has been taken to + // reduce errors due to computers' finite arithmetic precision. + // Maybe can still be improved, will see if any more of this + // kind of errors pop up again. + var site = arc.site, + rfocx = site.x, + rfocy = site.y, + pby2 = rfocy-directrix; + // parabola in degenerate case where focus is on directrix + if (!pby2) { + return rfocx; + } + var lArc = arc.rbPrevious; + if (!lArc) { + return -Infinity; + } + site = lArc.site; + var lfocx = site.x, + lfocy = site.y, + plby2 = lfocy-directrix; + // parabola in degenerate case where focus is on directrix + if (!plby2) { + return lfocx; + } + var hl = lfocx-rfocx, + aby2 = 1/pby2-1/plby2, + b = hl/plby2; + if (aby2) { + return (-b+this.sqrt(b*b-2*aby2*(hl*hl/(-2*plby2)-lfocy+plby2/2+rfocy-pby2/2)))/aby2+rfocx; + } + // both parabolas have same distance to directrix, thus break point is midway + return (rfocx+lfocx)/2; + }; + +// calculate the right break point of a particular beach section, +// given a particular directrix +Voronoi.prototype.rightBreakPoint = function(arc, directrix) { + var rArc = arc.rbNext; + if (rArc) { + return this.leftBreakPoint(rArc, directrix); + } + var site = arc.site; + return site.y === directrix ? site.x : Infinity; + }; + +Voronoi.prototype.detachBeachsection = function(beachsection) { + this.detachCircleEvent(beachsection); // detach potentially attached circle event + this.beachline.rbRemoveNode(beachsection); // remove from RB-tree + this.beachsectionJunkyard.push(beachsection); // mark for reuse + }; + +Voronoi.prototype.removeBeachsection = function(beachsection) { + var circle = beachsection.circleEvent, + x = circle.x, + y = circle.ycenter, + vertex = this.createVertex(x, y), + previous = beachsection.rbPrevious, + next = beachsection.rbNext, + disappearingTransitions = [beachsection], + abs_fn = Math.abs; + + // remove collapsed beachsection from beachline + this.detachBeachsection(beachsection); + + // there could be more than one empty arc at the deletion point, this + // happens when more than two edges are linked by the same vertex, + // so we will collect all those edges by looking up both sides of + // the deletion point. + // by the way, there is *always* a predecessor/successor to any collapsed + // beach section, it's just impossible to have a collapsing first/last + // beach sections on the beachline, since they obviously are unconstrained + // on their left/right side. + + // look left + var lArc = previous; + while (lArc.circleEvent && abs_fn(x-lArc.circleEvent.x)<1e-9 && abs_fn(y-lArc.circleEvent.ycenter)<1e-9) { + previous = lArc.rbPrevious; + disappearingTransitions.unshift(lArc); + this.detachBeachsection(lArc); // mark for reuse + lArc = previous; + } + // even though it is not disappearing, I will also add the beach section + // immediately to the left of the left-most collapsed beach section, for + // convenience, since we need to refer to it later as this beach section + // is the 'left' site of an edge for which a start point is set. + disappearingTransitions.unshift(lArc); + this.detachCircleEvent(lArc); + + // look right + var rArc = next; + while (rArc.circleEvent && abs_fn(x-rArc.circleEvent.x)<1e-9 && abs_fn(y-rArc.circleEvent.ycenter)<1e-9) { + next = rArc.rbNext; + disappearingTransitions.push(rArc); + this.detachBeachsection(rArc); // mark for reuse + rArc = next; + } + // we also have to add the beach section immediately to the right of the + // right-most collapsed beach section, since there is also a disappearing + // transition representing an edge's start point on its left. + disappearingTransitions.push(rArc); + this.detachCircleEvent(rArc); + + // walk through all the disappearing transitions between beach sections and + // set the start point of their (implied) edge. + var nArcs = disappearingTransitions.length, + iArc; + for (iArc=1; iArc falls somewhere before the left edge of the beachsection + if (dxl > 1e-9) { + // this case should never happen + // if (!node.rbLeft) { + // rArc = node.rbLeft; + // break; + // } + node = node.rbLeft; + } + else { + dxr = x-this.rightBreakPoint(node,directrix); + // x greaterThanWithEpsilon xr => falls somewhere after the right edge of the beachsection + if (dxr > 1e-9) { + if (!node.rbRight) { + lArc = node; + break; + } + node = node.rbRight; + } + else { + // x equalWithEpsilon xl => falls exactly on the left edge of the beachsection + if (dxl > -1e-9) { + lArc = node.rbPrevious; + rArc = node; + } + // x equalWithEpsilon xr => falls exactly on the right edge of the beachsection + else if (dxr > -1e-9) { + lArc = node; + rArc = node.rbNext; + } + // falls exactly somewhere in the middle of the beachsection + else { + lArc = rArc = node; + } + break; + } + } + } + // at this point, keep in mind that lArc and/or rArc could be + // undefined or null. + + // create a new beach section object for the site and add it to RB-tree + var newArc = this.createBeachsection(site); + this.beachline.rbInsertSuccessor(lArc, newArc); + + // cases: + // + + // [null,null] + // least likely case: new beach section is the first beach section on the + // beachline. + // This case means: + // no new transition appears + // no collapsing beach section + // new beachsection become root of the RB-tree + if (!lArc && !rArc) { + return; + } + + // [lArc,rArc] where lArc == rArc + // most likely case: new beach section split an existing beach + // section. + // This case means: + // one new transition appears + // the left and right beach section might be collapsing as a result + // two new nodes added to the RB-tree + if (lArc === rArc) { + // invalidate circle event of split beach section + this.detachCircleEvent(lArc); + + // split the beach section into two separate beach sections + rArc = this.createBeachsection(lArc.site); + this.beachline.rbInsertSuccessor(newArc, rArc); + + // since we have a new transition between two beach sections, + // a new edge is born + newArc.edge = rArc.edge = this.createEdge(lArc.site, newArc.site); + + // check whether the left and right beach sections are collapsing + // and if so create circle events, to be notified when the point of + // collapse is reached. + this.attachCircleEvent(lArc); + this.attachCircleEvent(rArc); + return; + } + + // [lArc,null] + // even less likely case: new beach section is the *last* beach section + // on the beachline -- this can happen *only* if *all* the previous beach + // sections currently on the beachline share the same y value as + // the new beach section. + // This case means: + // one new transition appears + // no collapsing beach section as a result + // new beach section become right-most node of the RB-tree + if (lArc && !rArc) { + newArc.edge = this.createEdge(lArc.site,newArc.site); + return; + } + + // [null,rArc] + // impossible case: because sites are strictly processed from top to bottom, + // and left to right, which guarantees that there will always be a beach section + // on the left -- except of course when there are no beach section at all on + // the beach line, which case was handled above. + // rhill 2011-06-02: No point testing in non-debug version + //if (!lArc && rArc) { + // throw "Voronoi.addBeachsection(): What is this I don't even"; + // } + + // [lArc,rArc] where lArc != rArc + // somewhat less likely case: new beach section falls *exactly* in between two + // existing beach sections + // This case means: + // one transition disappears + // two new transitions appear + // the left and right beach section might be collapsing as a result + // only one new node added to the RB-tree + if (lArc !== rArc) { + // invalidate circle events of left and right sites + this.detachCircleEvent(lArc); + this.detachCircleEvent(rArc); + + // an existing transition disappears, meaning a vertex is defined at + // the disappearance point. + // since the disappearance is caused by the new beachsection, the + // vertex is at the center of the circumscribed circle of the left, + // new and right beachsections. + // http://mathforum.org/library/drmath/view/55002.html + // Except that I bring the origin at A to simplify + // calculation + var lSite = lArc.site, + ax = lSite.x, + ay = lSite.y, + bx=site.x-ax, + by=site.y-ay, + rSite = rArc.site, + cx=rSite.x-ax, + cy=rSite.y-ay, + d=2*(bx*cy-by*cx), + hb=bx*bx+by*by, + hc=cx*cx+cy*cy, + vertex = this.createVertex((cy*hb-by*hc)/d+ax, (bx*hc-cx*hb)/d+ay); + + // one transition disappear + this.setEdgeStartpoint(rArc.edge, lSite, rSite, vertex); + + // two new transitions appear at the new vertex location + newArc.edge = this.createEdge(lSite, site, undefined, vertex); + rArc.edge = this.createEdge(site, rSite, undefined, vertex); + + // check whether the left and right beach sections are collapsing + // and if so create circle events, to handle the point of collapse. + this.attachCircleEvent(lArc); + this.attachCircleEvent(rArc); + return; + } + }; + +// --------------------------------------------------------------------------- +// Circle event methods + +// rhill 2011-06-07: For some reasons, performance suffers significantly +// when instanciating a literal object instead of an empty ctor +Voronoi.prototype.CircleEvent = function() { + // rhill 2013-10-12: it helps to state exactly what we are at ctor time. + this.arc = null; + this.rbLeft = null; + this.rbNext = null; + this.rbParent = null; + this.rbPrevious = null; + this.rbRed = false; + this.rbRight = null; + this.site = null; + this.x = this.y = this.ycenter = 0; + }; + +Voronoi.prototype.attachCircleEvent = function(arc) { + var lArc = arc.rbPrevious, + rArc = arc.rbNext; + if (!lArc || !rArc) {return;} // does that ever happen? + var lSite = lArc.site, + cSite = arc.site, + rSite = rArc.site; + + // If site of left beachsection is same as site of + // right beachsection, there can't be convergence + if (lSite===rSite) {return;} + + // Find the circumscribed circle for the three sites associated + // with the beachsection triplet. + // rhill 2011-05-26: It is more efficient to calculate in-place + // rather than getting the resulting circumscribed circle from an + // object returned by calling Voronoi.circumcircle() + // http://mathforum.org/library/drmath/view/55002.html + // Except that I bring the origin at cSite to simplify calculations. + // The bottom-most part of the circumcircle is our Fortune 'circle + // event', and its center is a vertex potentially part of the final + // Voronoi diagram. + var bx = cSite.x, + by = cSite.y, + ax = lSite.x-bx, + ay = lSite.y-by, + cx = rSite.x-bx, + cy = rSite.y-by; + + // If points l->c->r are clockwise, then center beach section does not + // collapse, hence it can't end up as a vertex (we reuse 'd' here, which + // sign is reverse of the orientation, hence we reverse the test. + // http://en.wikipedia.org/wiki/Curve_orientation#Orientation_of_a_simple_polygon + // rhill 2011-05-21: Nasty finite precision error which caused circumcircle() to + // return infinites: 1e-12 seems to fix the problem. + var d = 2*(ax*cy-ay*cx); + if (d >= -2e-12){return;} + + var ha = ax*ax+ay*ay, + hc = cx*cx+cy*cy, + x = (cy*ha-ay*hc)/d, + y = (ax*hc-cx*ha)/d, + ycenter = y+by; + + // Important: ybottom should always be under or at sweep, so no need + // to waste CPU cycles by checking + + // recycle circle event object if possible + var circleEvent = this.circleEventJunkyard.pop(); + if (!circleEvent) { + circleEvent = new this.CircleEvent(); + } + circleEvent.arc = arc; + circleEvent.site = cSite; + circleEvent.x = x+bx; + circleEvent.y = ycenter+this.sqrt(x*x+y*y); // y bottom + circleEvent.ycenter = ycenter; + arc.circleEvent = circleEvent; + + // find insertion point in RB-tree: circle events are ordered from + // smallest to largest + var predecessor = null, + node = this.circleEvents.root; + while (node) { + if (circleEvent.y < node.y || (circleEvent.y === node.y && circleEvent.x <= node.x)) { + if (node.rbLeft) { + node = node.rbLeft; + } + else { + predecessor = node.rbPrevious; + break; + } + } + else { + if (node.rbRight) { + node = node.rbRight; + } + else { + predecessor = node; + break; + } + } + } + this.circleEvents.rbInsertSuccessor(predecessor, circleEvent); + if (!predecessor) { + this.firstCircleEvent = circleEvent; + } + }; + +Voronoi.prototype.detachCircleEvent = function(arc) { + var circleEvent = arc.circleEvent; + if (circleEvent) { + if (!circleEvent.rbPrevious) { + this.firstCircleEvent = circleEvent.rbNext; + } + this.circleEvents.rbRemoveNode(circleEvent); // remove from RB-tree + this.circleEventJunkyard.push(circleEvent); + arc.circleEvent = null; + } + }; + +// --------------------------------------------------------------------------- +// Diagram completion methods + +// connect dangling edges (not if a cursory test tells us +// it is not going to be visible. +// return value: +// false: the dangling endpoint couldn't be connected +// true: the dangling endpoint could be connected +Voronoi.prototype.connectEdge = function(edge, bbox) { + // skip if end point already connected + var vb = edge.vb; + if (!!vb) {return true;} + + // make local copy for performance purpose + var va = edge.va, + xl = bbox.xl, + xr = bbox.xr, + yt = bbox.yt, + yb = bbox.yb, + lSite = edge.lSite, + rSite = edge.rSite, + lx = lSite.x, + ly = lSite.y, + rx = rSite.x, + ry = rSite.y, + fx = (lx+rx)/2, + fy = (ly+ry)/2, + fm, fb; + + // if we reach here, this means cells which use this edge will need + // to be closed, whether because the edge was removed, or because it + // was connected to the bounding box. + this.cells[lSite.voronoiId].closeMe = true; + this.cells[rSite.voronoiId].closeMe = true; + + // get the line equation of the bisector if line is not vertical + if (ry !== ly) { + fm = (lx-rx)/(ry-ly); + fb = fy-fm*fx; + } + + // remember, direction of line (relative to left site): + // upward: left.x < right.x + // downward: left.x > right.x + // horizontal: left.x == right.x + // upward: left.x < right.x + // rightward: left.y < right.y + // leftward: left.y > right.y + // vertical: left.y == right.y + + // depending on the direction, find the best side of the + // bounding box to use to determine a reasonable start point + + // rhill 2013-12-02: + // While at it, since we have the values which define the line, + // clip the end of va if it is outside the bbox. + // https://github.com/gorhill/Javascript-Voronoi/issues/15 + // TODO: Do all the clipping here rather than rely on Liang-Barsky + // which does not do well sometimes due to loss of arithmetic + // precision. The code here doesn't degrade if one of the vertex is + // at a huge distance. + + // special case: vertical line + if (fm === undefined) { + // doesn't intersect with viewport + if (fx < xl || fx >= xr) {return false;} + // downward + if (lx > rx) { + if (!va || va.y < yt) { + va = this.createVertex(fx, yt); + } + else if (va.y >= yb) { + return false; + } + vb = this.createVertex(fx, yb); + } + // upward + else { + if (!va || va.y > yb) { + va = this.createVertex(fx, yb); + } + else if (va.y < yt) { + return false; + } + vb = this.createVertex(fx, yt); + } + } + // closer to vertical than horizontal, connect start point to the + // top or bottom side of the bounding box + else if (fm < -1 || fm > 1) { + // downward + if (lx > rx) { + if (!va || va.y < yt) { + va = this.createVertex((yt-fb)/fm, yt); + } + else if (va.y >= yb) { + return false; + } + vb = this.createVertex((yb-fb)/fm, yb); + } + // upward + else { + if (!va || va.y > yb) { + va = this.createVertex((yb-fb)/fm, yb); + } + else if (va.y < yt) { + return false; + } + vb = this.createVertex((yt-fb)/fm, yt); + } + } + // closer to horizontal than vertical, connect start point to the + // left or right side of the bounding box + else { + // rightward + if (ly < ry) { + if (!va || va.x < xl) { + va = this.createVertex(xl, fm*xl+fb); + } + else if (va.x >= xr) { + return false; + } + vb = this.createVertex(xr, fm*xr+fb); + } + // leftward + else { + if (!va || va.x > xr) { + va = this.createVertex(xr, fm*xr+fb); + } + else if (va.x < xl) { + return false; + } + vb = this.createVertex(xl, fm*xl+fb); + } + } + edge.va = va; + edge.vb = vb; + + return true; + }; + +// line-clipping code taken from: +// Liang-Barsky function by Daniel White +// http://www.skytopia.com/project/articles/compsci/clipping.html +// Thanks! +// A bit modified to minimize code paths +Voronoi.prototype.clipEdge = function(edge, bbox) { + var ax = edge.va.x, + ay = edge.va.y, + bx = edge.vb.x, + by = edge.vb.y, + t0 = 0, + t1 = 1, + dx = bx-ax, + dy = by-ay; + // left + var q = ax-bbox.xl; + if (dx===0 && q<0) {return false;} + var r = -q/dx; + if (dx<0) { + if (r0) { + if (r>t1) {return false;} + if (r>t0) {t0=r;} + } + // right + q = bbox.xr-ax; + if (dx===0 && q<0) {return false;} + r = q/dx; + if (dx<0) { + if (r>t1) {return false;} + if (r>t0) {t0=r;} + } + else if (dx>0) { + if (r0) { + if (r>t1) {return false;} + if (r>t0) {t0=r;} + } + // bottom + q = bbox.yb-ay; + if (dy===0 && q<0) {return false;} + r = q/dy; + if (dy<0) { + if (r>t1) {return false;} + if (r>t0) {t0=r;} + } + else if (dy>0) { + if (r 0, va needs to change + // rhill 2011-06-03: we need to create a new vertex rather + // than modifying the existing one, since the existing + // one is likely shared with at least another edge + if (t0 > 0) { + edge.va = this.createVertex(ax+t0*dx, ay+t0*dy); + } + + // if t1 < 1, vb needs to change + // rhill 2011-06-03: we need to create a new vertex rather + // than modifying the existing one, since the existing + // one is likely shared with at least another edge + if (t1 < 1) { + edge.vb = this.createVertex(ax+t1*dx, ay+t1*dy); + } + + // va and/or vb were clipped, thus we will need to close + // cells which use this edge. + if ( t0 > 0 || t1 < 1 ) { + this.cells[edge.lSite.voronoiId].closeMe = true; + this.cells[edge.rSite.voronoiId].closeMe = true; + } + + return true; + }; + +// Connect/cut edges at bounding box +Voronoi.prototype.clipEdges = function(bbox) { + // connect all dangling edges to bounding box + // or get rid of them if it can't be done + var edges = this.edges, + iEdge = edges.length, + edge, + abs_fn = Math.abs; + + // iterate backward so we can splice safely + while (iEdge--) { + edge = edges[iEdge]; + // edge is removed if: + // it is wholly outside the bounding box + // it is looking more like a point than a line + if (!this.connectEdge(edge, bbox) || + !this.clipEdge(edge, bbox) || + (abs_fn(edge.va.x-edge.vb.x)<1e-9 && abs_fn(edge.va.y-edge.vb.y)<1e-9)) { + edge.va = edge.vb = null; + edges.splice(iEdge,1); + } + } + }; + +// Close the cells. +// The cells are bound by the supplied bounding box. +// Each cell refers to its associated site, and a list +// of halfedges ordered counterclockwise. +Voronoi.prototype.closeCells = function(bbox) { + var xl = bbox.xl, + xr = bbox.xr, + yt = bbox.yt, + yb = bbox.yb, + cells = this.cells, + iCell = cells.length, + cell, + iLeft, + halfedges, nHalfedges, + edge, + va, vb, vz, + lastBorderSegment, + abs_fn = Math.abs; + + while (iCell--) { + cell = cells[iCell]; + // prune, order halfedges counterclockwise, then add missing ones + // required to close cells + if (!cell.prepareHalfedges()) { + continue; + } + if (!cell.closeMe) { + continue; + } + // find first 'unclosed' point. + // an 'unclosed' point will be the end point of a halfedge which + // does not match the start point of the following halfedge + halfedges = cell.halfedges; + nHalfedges = halfedges.length; + // special case: only one site, in which case, the viewport is the cell + // ... + + // all other cases + iLeft = 0; + while (iLeft < nHalfedges) { + va = halfedges[iLeft].getEndpoint(); + vz = halfedges[(iLeft+1) % nHalfedges].getStartpoint(); + // if end point is not equal to start point, we need to add the missing + // halfedge(s) up to vz + if (abs_fn(va.x-vz.x)>=1e-9 || abs_fn(va.y-vz.y)>=1e-9) { + + // rhill 2013-12-02: + // "Holes" in the halfedges are not necessarily always adjacent. + // https://github.com/gorhill/Javascript-Voronoi/issues/16 + + // find entry point: + switch (true) { + + // walk downward along left side + case this.equalWithEpsilon(va.x,xl) && this.lessThanWithEpsilon(va.y,yb): + lastBorderSegment = this.equalWithEpsilon(vz.x,xl); + vb = this.createVertex(xl, lastBorderSegment ? vz.y : yb); + edge = this.createBorderEdge(cell.site, va, vb); + iLeft++; + halfedges.splice(iLeft, 0, this.createHalfedge(edge, cell.site, null)); + nHalfedges++; + if ( lastBorderSegment ) { break; } + va = vb; + // fall through + + // walk rightward along bottom side + case this.equalWithEpsilon(va.y,yb) && this.lessThanWithEpsilon(va.x,xr): + lastBorderSegment = this.equalWithEpsilon(vz.y,yb); + vb = this.createVertex(lastBorderSegment ? vz.x : xr, yb); + edge = this.createBorderEdge(cell.site, va, vb); + iLeft++; + halfedges.splice(iLeft, 0, this.createHalfedge(edge, cell.site, null)); + nHalfedges++; + if ( lastBorderSegment ) { break; } + va = vb; + // fall through + + // walk upward along right side + case this.equalWithEpsilon(va.x,xr) && this.greaterThanWithEpsilon(va.y,yt): + lastBorderSegment = this.equalWithEpsilon(vz.x,xr); + vb = this.createVertex(xr, lastBorderSegment ? vz.y : yt); + edge = this.createBorderEdge(cell.site, va, vb); + iLeft++; + halfedges.splice(iLeft, 0, this.createHalfedge(edge, cell.site, null)); + nHalfedges++; + if ( lastBorderSegment ) { break; } + va = vb; + // fall through + + // walk leftward along top side + case this.equalWithEpsilon(va.y,yt) && this.greaterThanWithEpsilon(va.x,xl): + lastBorderSegment = this.equalWithEpsilon(vz.y,yt); + vb = this.createVertex(lastBorderSegment ? vz.x : xl, yt); + edge = this.createBorderEdge(cell.site, va, vb); + iLeft++; + halfedges.splice(iLeft, 0, this.createHalfedge(edge, cell.site, null)); + nHalfedges++; + if ( lastBorderSegment ) { break; } + va = vb; + // fall through + + // walk downward along left side + lastBorderSegment = this.equalWithEpsilon(vz.x,xl); + vb = this.createVertex(xl, lastBorderSegment ? vz.y : yb); + edge = this.createBorderEdge(cell.site, va, vb); + iLeft++; + halfedges.splice(iLeft, 0, this.createHalfedge(edge, cell.site, null)); + nHalfedges++; + if ( lastBorderSegment ) { break; } + va = vb; + // fall through + + // walk rightward along bottom side + lastBorderSegment = this.equalWithEpsilon(vz.y,yb); + vb = this.createVertex(lastBorderSegment ? vz.x : xr, yb); + edge = this.createBorderEdge(cell.site, va, vb); + iLeft++; + halfedges.splice(iLeft, 0, this.createHalfedge(edge, cell.site, null)); + nHalfedges++; + if ( lastBorderSegment ) { break; } + va = vb; + // fall through + + // walk upward along right side + lastBorderSegment = this.equalWithEpsilon(vz.x,xr); + vb = this.createVertex(xr, lastBorderSegment ? vz.y : yt); + edge = this.createBorderEdge(cell.site, va, vb); + iLeft++; + halfedges.splice(iLeft, 0, this.createHalfedge(edge, cell.site, null)); + nHalfedges++; + if ( lastBorderSegment ) { break; } + // fall through + + default: + throw "Voronoi.closeCells() > this makes no sense!"; + } + } + iLeft++; + } + cell.closeMe = false; + } + }; + +// --------------------------------------------------------------------------- +// Debugging helper +/* +Voronoi.prototype.dumpBeachline = function(y) { + console.log('Voronoi.dumpBeachline(%f) > Beachsections, from left to right:', y); + if ( !this.beachline ) { + console.log(' None'); + } + else { + var bs = this.beachline.getFirst(this.beachline.root); + while ( bs ) { + console.log(' site %d: xl: %f, xr: %f', bs.site.voronoiId, this.leftBreakPoint(bs, y), this.rightBreakPoint(bs, y)); + bs = bs.rbNext; + } + } + }; +*/ + +// --------------------------------------------------------------------------- +// Helper: Quantize sites + +// rhill 2013-10-12: +// This is to solve https://github.com/gorhill/Javascript-Voronoi/issues/15 +// Since not all users will end up using the kind of coord values which would +// cause the issue to arise, I chose to let the user decide whether or not +// he should sanitize his coord values through this helper. This way, for +// those users who uses coord values which are known to be fine, no overhead is +// added. + +Voronoi.prototype.quantizeSites = function(sites) { + var ε = this.ε, + n = sites.length, + site; + while ( n-- ) { + site = sites[n]; + site.x = Math.floor(site.x / ε) * ε; + site.y = Math.floor(site.y / ε) * ε; + } + }; + +// --------------------------------------------------------------------------- +// Helper: Recycle diagram: all vertex, edge and cell objects are +// "surrendered" to the Voronoi object for reuse. +// TODO: rhill-voronoi-core v2: more performance to be gained +// when I change the semantic of what is returned. + +Voronoi.prototype.recycle = function(diagram) { + if ( diagram ) { + if ( diagram instanceof this.Diagram ) { + this.toRecycle = diagram; + } + else { + throw 'Voronoi.recycleDiagram() > Need a Diagram object.'; + } + } + }; + +// --------------------------------------------------------------------------- +// Top-level Fortune loop + +// rhill 2011-05-19: +// Voronoi sites are kept client-side now, to allow +// user to freely modify content. At compute time, +// *references* to sites are copied locally. + +Voronoi.prototype.compute = function(sites, bbox) { + // to measure execution time + var startTime = new Date(); + + // init internal state + this.reset(); + + // any diagram data available for recycling? + // I do that here so that this is included in execution time + if ( this.toRecycle ) { + this.vertexJunkyard = this.vertexJunkyard.concat(this.toRecycle.vertices); + this.edgeJunkyard = this.edgeJunkyard.concat(this.toRecycle.edges); + this.cellJunkyard = this.cellJunkyard.concat(this.toRecycle.cells); + this.toRecycle = null; + } + + // Initialize site event queue + var siteEvents = sites.slice(0); + siteEvents.sort(function(a,b){ + var r = b.y - a.y; + if (r) {return r;} + return b.x - a.x; + }); + + // process queue + var site = siteEvents.pop(), + siteid = 0, + xsitex, // to avoid duplicate sites + xsitey, + cells = this.cells, + circle; + + // main loop + for (;;) { + // we need to figure whether we handle a site or circle event + // for this we find out if there is a site event and it is + // 'earlier' than the circle event + circle = this.firstCircleEvent; + + // add beach section + if (site && (!circle || site.y < circle.y || (site.y === circle.y && site.x < circle.x))) { + // only if site is not a duplicate + if (site.x == xsitex && site.y == xsitey) { + site.x += Math.random()-0.1; + site.y += Math.random()-0.1; + } + // first create cell for new site + cells[siteid] = this.createCell(site); + site.voronoiId = siteid++; + // then create a beachsection for that site + this.addBeachsection(site); + // remember last site coords to detect duplicate + xsitey = site.y; + xsitex = site.x; + + site = siteEvents.pop(); + } + + // remove beach section + else if (circle) { + this.removeBeachsection(circle.arc); + } + + // all done, quit + else { + break; + } + } + + // wrapping-up: + // connect dangling edges to bounding box + // cut edges as per bounding box + // discard edges completely outside bounding box + // discard edges which are point-like + this.clipEdges(bbox); + + // add missing edges in order to close opened cells + this.closeCells(bbox); + + // to measure execution time + var stopTime = new Date(); + + // prepare return values + var diagram = new this.Diagram(); + diagram.cells = this.cells; + diagram.edges = this.edges; + diagram.vertices = this.vertices; + diagram.execTime = stopTime.getTime()-startTime.getTime(); + + // clean up + this.reset(); + + return diagram; + }; + +/******************************************************************************/ + +if ( typeof module !== 'undefined' ) { + module.exports = Voronoi; +} diff --git a/lib/voronoi/segment.js b/lib/voronoi/segment.js new file mode 100755 index 00000000..9ab73c7b --- /dev/null +++ b/lib/voronoi/segment.js @@ -0,0 +1,106 @@ +// Include the necessary modules. +//var sys = require( "util" ); + +var point2d = point2d || require( "./point2d.js" ); + +function segment(a, b) +{ + this.p1 = (a == undefined ? new point2d(0, 0) : a); // point2d type + this.p2 = (b == undefined ? new point2d(0, 0) : b); // point2d type + + var x, y; + + this.is_empty = function () + { + return (this.p1.x === 0 && this.p1.y === 0 && this.p2.x === 0 && this.p2.y === 0); + } + + this.is_inside = function (p) + { + var xmax, xmin, ymax, ymin; + + if (p1.x > p2.x) + { + xmax = p1.x; xmin = p2.x; + } + else + { + xmax = p2.x; xmin = p1.x; + } + if (p1.y > p2.y) + { + ymax = p1.y; ymin = p2.y; + } + else + { + ymax = p2.y; ymin = p1.y; + } + + return (xmin <= p.x && p.x <= xmax && ymin <= p.y && p.y <= ymax); + } + + this.intersectionPoint = function (p3, radius) { + return new point2d(x,y); + } + + this.intersects = function (p3, radius) + { + //console.log("p3:") + //console.log(p3); + //console.log("Radius: " + radius); + var u; // double + + // we should re-order p1 and p2's position such that p2 > p1 + var x1, x2, y1, y2; + + if (this.p2.x > this.p1.x) { + x1 = this.p1.x; y1 = this.p1.y; + x2 = this.p2.x; y2 = this.p2.y; + } + else { + x1 = this.p2.x; y1 = this.p2.y; + x2 = this.p1.x; y2 = this.p1.y; + } + + //console.log("x1:"); + //console.log(x1); + //console.log("x2:"); + //console.log(x2); + //console.log("y1:"); + //console.log(y1); + //console.log("y2:"); + //console.log(y2); + //console.log("p1:"); + //console.log(this.p1); + //console.log("p2:"); + //console.log(this.p2); + + // formula from http://astronomy.swin.edu.au/~pbourke/geometry/sphereline/ + u = ((p3.x - x1) * (x2 - x1) + (p3.y - y1) * (y2 - y1)) / + ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + + //console.log(u); + + if (u >= 0 && u <= 1) { + x = x1 + (x2 - x1) * u; + y = y1 + (y2 - y1) * u; + + var pt = new point2d(x, y); + return (pt.distance(p3) <= radius); + } + else { + return (_distance(p3,this.p1) <= radius || _distance(p3,this.p2) <= radius); + } + } + + var _distance = function (pt1,pt2){ + var dx = pt1.x - pt2.x; + var dy = pt1.y - pt2.y; + //console.log ("point2d distance called, dx: " + dx + " dy: " + dy + " this.x: " + this.x + " this.y: " + this.y + " p.x: " + p.x + " p.y: " + p.y); + + return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + } +}; + +if (typeof module !== 'undefined') + module.exports = segment; diff --git a/vast_voro.js b/lib/voronoi/vast_voro.js old mode 100644 new mode 100755 similarity index 60% rename from vast_voro.js rename to lib/voronoi/vast_voro.js index 508df501..e0a48917 --- a/vast_voro.js +++ b/lib/voronoi/vast_voro.js @@ -22,107 +22,127 @@ /* A Generic Voronoi wrapper for computing Voronoi Diagrams for VAST - supported functions: - + supported functions: + // the following insert/update/remove sites to the Voronoi - insert(id, pos) inserting a new site with a position and id + insert(id, pos) inserting a new site with a position and id remove(id) removing an existing site with an id update(id, pos) updating the position for a site given an id get(id) get stored position for a given id clear() clear all stored site positions - + // the following returns true/false - contains(id, pos) check if a given position is within the region for a site + contains(id, pos) check if a given position is within the region for a site is_boundary(id, pos, rad) check if a site is the boundary neighbor for a position with given radius is_enclosing(id, cent_id) check if a site is the enclosing neighbor for another site given the 'center id' overlaps(id, pos, rad, mode) check if a site's region overlaps with a given position & radius closest_to(pos) find the site closest to a particular position - + // the following returns an array - get_en(id, level) get an array of id's of the enclosing neighbors for a given site (under a certain level) - + get_en(id, level) get an array of id's of the enclosing neighbors for a given site (under a certain level) + // misc to_string() get a string represntations of all currently stored sites - + history: 2012-06-09 initial version (extract code from sf_voronoi.js) - 2012-06-25 first working version (porting done) + 2012-06-25 first working version (porting done) */ // if already defined (as included in website) then don't define -var point2d = point2d || require( "./typedef/point2d.js" ); -var segment = segment || require( "./typedef/segment.js" ); +var point2d = point2d || require( "./point2d.js" ); +var segment = segment || require( "./segment.js" ); //var Voronoi = Voronoi || require( "./sf_voronoi.js" ); var Voronoi = Voronoi || require( "./rhill-voronoi-core.js" ); +var logger = logger || require('../common/logger'); -var LOG = (typeof logger !== 'undefined' ? new logger() : (typeof global.LOG !== 'undefined' ? global.LOG : undefined)); -// vast_voro is used without including global, need to create one -if (LOG === undefined) { - var logger = require('./common/logger'); - LOG = new logger(); -} +//var LOG = (typeof logger !== 'undefined' ? new logger() : (typeof global.LOG !== 'undefined' ? global.LOG : undefined)); + -// this constant is to determine how far will two different points be considered the same -// potential BUG: is it small enough? -var EQUAL_DISTANCE = 1e-9; -function VAST_Voronoi(bbox) { +function VAST_Voronoi(bbox) { + // this constant is to determine how far will two different points be considered the same + // potential BUG: is it small enough? + var EQUAL_DISTANCE = 1e-9; + + // standard bbox size + var STANDARD_SIZE = 1000; + // // private variables - // + // + + // vast_voro is used without including global, need to create one + //if (LOG === undefined) { + //LOG = new logger(); + //} + + //log = LOG.newLayer('vast_voro', 'vast_voro', 'logs', 1, 0); // internal data to compute Voronoi diagram var voro = new Voronoi(); - + // storage of all the Voronoi sites given externally (a map from id to position) var sites = {}; - + // mapping from site id to index in sorted site list var id2idx = {}; - + // whether we need to re-calculate the edges (introduced by Peter Liao) var invalidated = false; - + // result of the Voronoi computation var result = undefined; // store bounding box or provide default (for RHVoronoi) // NOTE: boundaries are important, as it'll affect the range of calculation for the Voronoi // if input site positions are outside boundary, Voronoi won't be computed correctly - // NOTE: 'xl' must be less than 'xr', and 'yt' must be less than 'yb', + // NOTE: 'xl' must be less than 'xr', and 'yt' must be less than 'yb', // or else enclosing computation will be incorrect if (bbox === undefined) - bbox = {xl:-10000, xr:10000, yt:-10000, yb:10000}; - //bbox = {xl:0, xr:10000, yt:0, yb:10000}; + bbox = {xl:0, xr: STANDARD_SIZE, yt:0, yb: STANDARD_SIZE}; + //bbox = {xl:0, xr: CONF.x_lim, yt:0, yb: CONF.y_lim}; // // public methods // - + // insert a new site, the first inserted is myself var l_insert = this.insert = function (id, pos) { - - //LOG.debug('insert to voro id: ' + id + ' ' + typeof id); - + + ////log.debug('insert to voro id: ' + id + ' ' + typeof id); + // avoid duplicate insert if (sites.hasOwnProperty(id) === true) { - LOG.error('duplicate voro id exists: ' + id); - return false; + //log.error('duplicate voro id exists: ' + id); + return false; + } + + if (pos == undefined) { + //log.error('undefined node sent through'); + return false; } - + + ////log.debug(bbox); + ////log.debug(pos); + // perform boundary check and reject those outside of boundary - if ((pos.x > bbox.xl && pos.x < bbox.xr && pos.y > bbox.yt && pos.y < bbox.yb) === false) { - LOG.error('position of site outside of bounding box'); + if ((pos.x >= bbox.xl && pos.x <= bbox.xr && pos.y >= bbox.yt && pos.y <= bbox.yb) === false) { + //log.error('position of site outside of bounding box'); return false; } - + + if (_isOverlapped(pos, id)) { + pos = _adjustPos(pos,id); + } + invalidated = true; sites[id] = pos; - - //LOG.debug('site [' + id + '] added'); - + + ////log.debug('site [' + id + '] added'); + return true; } @@ -131,10 +151,11 @@ function VAST_Voronoi(bbox) { if (sites.hasOwnProperty(id) === false) return false; - + invalidated = true; + delete sites[id]; - + return true; } @@ -142,13 +163,16 @@ function VAST_Voronoi(bbox) { this.update = function (id, pos) { if (sites.hasOwnProperty(id) == true) { + if (_isOverlapped(pos, id)) { + pos = _adjustPos(pos,id); + } invalidated = true; sites[id] = pos; } // if id doesn't exist, we allow a new insertion else return l_insert(id, pos); - + return true; } @@ -161,12 +185,18 @@ function VAST_Voronoi(bbox) { return sites[id]; } + // get a cell from the voronoi diagram + this.getRegion = function (id) { + recompute(); + return result.cells[id2idx[id]]; + } + // remove all sites in the diagram //void clear (); this.clear = function () { invalidated = true; sites = {}; - //voro.clear(); + //voro.clear(); } // check if a point lies inside a particular region @@ -177,62 +207,142 @@ function VAST_Voronoi(bbox) { var idx = check_id (id); if (idx == -1) return false; - + // NOTE insideRegion takes 'index' (in mSites) as parameter return insideRegion(idx, pos); } // check if the node is a boundary neighbor - // NOTE: current check allows non-boundary neighbors but not fully enclosed ones to pass this test this.is_boundary = function (id, pos, radius) { var idx = check_id (id); if (idx == -1) return false; - // NOTE: cannot use simply not enclosed to test, as many other nodes will - // qualify as boundary sites - return !enclosed(idx, pos, radius); + var bound_list = get_bound(id, radius, pos.x, pos.y); + + // go through each boundary neighbour and check whether it matches the given ID + for (var i=0; i< bound_list.length; i++) { + if (bound_list[i] == id) { + return true; + } + } + + return false; } // check if the node 'id' is an enclosing neighbor of 'center_node_id' this.is_enclosing = function (id, center_node_id) { - // get index for the input node id + // get index for the input node id var idx = check_id(center_node_id); if (idx == -1) return false; - + var en_list = getNeighborSet(idx); - + // go through each enclosing neighbor return and check for match for (var i=0; i < en_list.length; i++) { - //LOG.debug('id: ' + id + ' en ' + (i+1) + ': ' + en_list[i]); + ////log.debug('id: ' + id + ' en ' + (i+1) + ': ' + en_list[i]); if (en_list[i] == id) return true; } - - return false; - - /* less code but more work version + + return false; + + /* less code but more work version var list = this.get_en(center_node_id); for (var i=0; i < list.length; i++) if (list[i] === id) return true; - return false; + return false; */ } + //get a list of boundary neighbours + var get_bound = this.get_bound = function (id, radius, x,y) { + //convert id into site idx + var idx = check_id(id); + if (idx == -1) + return false; + + //clear record of the site id of boundary neighbours + var bound_list = []; + + // create a copy of the sites object + //var temp_sites = JSON.parse(JSON.stringify(sites)); + + var site_list = []; //storage of sites before removal + + var AOI_list = {}; //temp list of AOI neighbours + + //var i; + + for (var key in sites){ + if (!withinAOI(sites[key],radius, x,y)){ + + site_list[key] = sites[key]; + l_remove(sites[key].id); + } else { + AOI_list[sites[key].id] = sites[key].voronoiId; + } + } + + /* + for (i=1; i <= result.cells.length; i++){ + //log.warn(i); + //log.warn(typeof i); + //log.warn(sites[1]); + //log.warn(sites["1"]); + //log.warn(sites[i]); + //log.warn(sites[i].x); + //look through sites and decide whether AOI neighbours or not + if (!withinAOI(sites[i],idx,radius, x,y)){ + + site_list[i] = sites[i]; + l_remove(sites[i].id); + } else { + AOI_list[sites[i].id] = sites[i].voronoiId; + } + } + */ + + recompute(); + + //look at AOI_list and decide which are fully enclosed by AOI and remove them. Place the rest in bound_list + var j,k; + + for (j=0; j < result.cells.length; j++) { + var voronoi_section = result.cells[j]; + for (k=0; k < voronoi_section.halfedges.length; k++){ + + //check to see if a vertex is out of the AOI + if (!withinAOI(voronoi_section.halfedges[k].edge.va,radius, x,y) || !withinAOI(voronoi_section.halfedges[k].edge.vb,radius, x,y)) { + bound_list.push(result.cells[j].site.id); + break; + } + } + } + + for (var id in site_list) { + l_insert (id, site_list[id]); + } + recompute(); + + + return bound_list; + } + // get a list of enclosing neighbors //vector &get_en (id_t id, int level = 1); // a more efficient version (avoids Voronoi rebuilt unless sites are removed by necessity) - this.get_en = function (id, lvl) { + var get_en = this.get_en = function (id, lvl) { + + ////log.debug('get_en: for id: ' + id); - //LOG.debug('get_en: for id: ' + id); - if (typeof id === 'undefined') return undefined; - + // level is default to 1 var level = (typeof lvl === 'undefined' ? 1 : lvl); @@ -246,29 +356,29 @@ function VAST_Voronoi(bbox) { var j; // int while (level > 0) { - + // remove enclosing neighbors already recorded, if any for (j = remove_count; j < en_list.length; j++) { // backup site info to be restored later var id = en_list[j]; site_list[id] = sites[id]; - + // remove it l_remove(id); remove_count++; } recompute(); - + // get enclosing neighbor id for the input node id - // NOTE: get_idx() should be called after recompute() otherwise it'll be invalid + // NOTE: get_idx() should be called after recompute() otherwise it'll be invalid // NOTE: the id_list returned contains id (not index) id_list = getNeighborSet(get_idx(id)); - // get a list of current enclosing neighbors to be stored away + // get a list of current enclosing neighbors to be stored away // store enclosing neighbor IDs (to be returned to caller) - for (var i = 0; i < id_list.length; i++) + for (var i = 0; i < id_list.length; i++) en_list.push(id_list[i]); level--; @@ -276,14 +386,43 @@ function VAST_Voronoi(bbox) { // add back the removed neighbors (when queries beyond 1st-level neighbors are made) for (var id in site_list) { - //LOG.debug('get_en put back ' + id + ' to list'); + ////log.debug('get_en put back ' + id + ' to list'); l_insert (id, site_list[id]); } - //LOG.debug('get_en found ' + en_list.length + ' neighbors'); + ////log.debug('get_en found ' + en_list.length + ' neighbors'); return en_list; } + // get a set of AOI neighbours + var get_AoI = this.get_AoI = function (id, radius) { + var neighbour_list = []; + for (var key in sites) + if (withinAOI(sites[id],radius, sites[key].x,sites[key].y)) + neighbour_list.push(key); + + return neighbour_list; + } + + // get a set of AoI and enclosing neighbours + this.get_neighbour = function (id,radius) { + if (!sites.hasOwnProperty(id)) + return []; + + // get a list of enclosing neighbours + var neighbour_list = get_en(id); + + // get a list of AoI neighbours and add it to the list of enclosing neighbours + for (var key in sites) { + if (!neighbour_list.includes(key)) { + if (withinAOI(sites[id],radius, sites[key].x,sites[key].y)) + neighbour_list.push(key); + } + } + + return neighbour_list; + } + // check if a circle overlaps with a particular region (given its id) // NOTE: that in non-accurate mode it's quicker but also more strict for overlap to occur // NOTE: in accurate mode, overlaps always returns 'false' if there's only one site @@ -292,26 +431,30 @@ function VAST_Voronoi(bbox) { var idx = check_id(id); if (idx == -1) return false; - + // default accurate mode to false var accurate_mode = (typeof mode === 'undefined' ? false : mode); - + var r = false; if (accurate_mode === true) { - // version 1: accurate but slower - //LOG.debug('idx: ' + idx + ' pos: ' + pos.toString()); - r = collides(idx, pos, (radius+5)); + // version 1: accurate but slower + ////log.debug('idx: ' + idx + ' pos: ' + pos.toString()); + r = collides(idx, pos, (radius+5)); } else { // version 2: simply check if the center of region is within AOI - var site_pos = sites[id]; - r = (site_pos.distance(pos) <= radius); + if (sites.hasOwnProperty(id)) { + var site_pos = sites[id]; + r = (site_pos.distance(pos) <= radius); + } else { + return false; + } } - //LOG.debug('if [' + id + '] overlaps with ' + pos.toString() + ' (radius: ' + radius + '): ' + r + ' accurate: ' + accurate_mode); + ////log.debug('if [' + id + '] overlaps with ' + pos.toString() + ' (radius: ' + radius + '): ' + r + ' accurate: ' + accurate_mode); return r; } - + // returns the closest site id to a point // Added 20080724 by Csc @@ -319,14 +462,14 @@ function VAST_Voronoi(bbox) { // (i.e. when two or more sites are both closest to the point, smaller ID is returned) this.closest_to = function (pos) { - // add function + // make sure position has a distance function if (typeof pos.distance !== 'function') pos = new point2d(pos.x, pos.y); - + // error checking if (Object.keys(sites).length === 0) return null; - + // id for the closest site, get first var closest; // id_t var min; // double @@ -334,6 +477,7 @@ function VAST_Voronoi(bbox) { // use the first record in sites as the starting point for (var key in sites) { + closest = key; min = pos.distance(sites[key]); break; @@ -342,10 +486,12 @@ function VAST_Voronoi(bbox) { var id; // id_t var p; // position + // go through each site's position and find the closest to point for (var key in sites) { - //LOG.debug('key: ' + key + ' type: ' + typeof key); + + ////log.debug('key: ' + key + ' type: ' + typeof key); id = key; p = sites[key]; @@ -369,25 +515,24 @@ function VAST_Voronoi(bbox) { // // accessor methods to Voronoi result // - + // get an array of computed edges in this Voronoi - - this.getedges = function () { - recompute(); + this.getedges = function () { + recompute(); return result.edges; } - /* + // get an array of all the sites in the voronoi this.get_sites = function () { - return sites; - } - */ - + return JSON.stringify(sites); + } + + // get result of computation this.get_result = function () { recompute(); return result; - } + } // obtain the bounding box for this Voronoi object // returns true if the box exists, false if one of the dimensions is empty @@ -395,7 +540,7 @@ function VAST_Voronoi(bbox) { this.get_bounding_box = function () { return bbox; } - + this.set_bounding_box = function (bounding_box) { bbox = bounding_box; } @@ -404,12 +549,12 @@ function VAST_Voronoi(bbox) { this.size = function () { return Object.keys(sites).length; } - + // lookup of index from id this.getidx = function (id) { return get_idx(id); } - + // return string representation of currently stored sites this.to_string = function () { var str = ''; @@ -430,128 +575,133 @@ function VAST_Voronoi(bbox) { return []; return voro.mSites[idx].edge_idxlist; - } + } */ - + // // private methods // - + // check validity for an action (node id exists, recompute is done, if required) // returns the index for the id or (-1) for failure var check_id = function (id) { recompute(); return get_idx(id); } - + // re-calculate Voronoi if sites have changed var recompute = function () { if (invalidated === true) { - - //LOG.debug('recomputing... sites size: ' + Object.keys(sites).length); + + ////log.debug('recomputing... sites size: ' + Object.keys(sites).length); var list = []; - + // translate sites to an array // TODO: use a tree to store site info directly into sorted list (better performance?) for (var key in sites) { sites[key].id = key; list.push(sites[key]); } - + // compute Voronoi & store resulting sites & edges to 'result' result = voro.compute(list, bbox); - + // NOTE: it may be relatively common for cell size < list size if (result.cells.length !== list.length) { - LOG.debug('init id2idx... mismatch! list size: ' + list.length + ' cell size: ' + result.cells.length); - + //log.debug('init id2idx... mismatch! list size: ' + list.length + ' cell size: ' + result.cells.length); + + /* for (var key in sites) { - LOG.debug('id: ' + sites[key].id + ' x: ' + sites[key].x + ' y: ' + sites[key].y); - } - } - - // get id to index mapping (in new site array) - id2idx = {}; + //log.debug('id: ' + sites[key].id + ' x: ' + sites[key].x + ' y: ' + sites[key].y); + } + */ + } + + // get id to index mapping (in new site array) + id2idx = {}; for (var i=0; i < result.cells.length; i++) { var cell = result.cells[i]; - - //LOG.debug('site id: ' + cell.site.id + ' (' + cell.site.x + ', ' + cell.site.y + ')'); + + ////log.debug('site id: ' + cell.site.id + ' (' + cell.site.x + ', ' + cell.site.y + ')'); id2idx[cell.site.id] = i; - + /* var halfedges = cell.halfedges; - + // print edges for (var j=0; j < halfedges.length; j++) { - LOG.debug('halfedge[' + j + '] idx: ' + halfedges[j]); - } + //log.debug('halfedge[' + j + '] idx: ' + halfedges[j]); + } */ - + } - + invalidated = false; } } - + // get id to index mapping var get_idx = function (id) { - + // NOTE: it may be relatively common to not be able to find index for an id // if the number of cells produced is less than the number of sites // we thus print 'debug' instead of 'error' here if (id2idx.hasOwnProperty(id) === false) { - if (isNaN(id)) - LOG.error('get_idx () cannot find index for id: ' + id); - else - LOG.debug('get_idx () cannot find index for id: ' + id); - + if (isNaN(id)){ + //log.error('get_idx () cannot find index for id: ' + id + ' (not a number)'); + } + else{ + //log.debug('get_idx () cannot find index for id: ' + id); + } + // check if index list and site list have equal length - if (Object.keys(id2idx).length !== Object.keys(sites).length) - LOG.debug('list size mismatch! there may be overlapped site coords. id2idx size: ' + Object.keys(id2idx).length + ' sites size: ' + Object.keys(sites).length); - - return (-1); + if (Object.keys(id2idx).length !== Object.keys(sites).length) { + //log.debug('list size mismatch! there may be overlapped site coords. id2idx size: ' + Object.keys(id2idx).length + ' sites size: ' + Object.keys(sites).length); + } + + return -1; } return id2idx[id]; } - + // // private support methods // - + // check whether a point lies within a polygon // reference: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html function insideRegion(index, p) { - + // produce x & y coordinate arrays var cell = result.cells[index]; var halfedges = cell.halfedges; - + var verty = []; var vertx = []; - var pt1; - + var pt1; + for (var i=0; i < halfedges.length; i++) { - + // NOTE: we use getStartpoint() and not edge.va, because the point ordering in edge may not be consistent pt1 = halfedges[i].getStartpoint(); //pt2 = halfedges[i].getEndpoint(); //va = halfedges[i].edge.va; //vb = halfedges[i].edge.vb; - - //LOG.debug('half ' + i + ': (' + pt1.x + ', ' + pt1.y + ') (' + pt2.x + ', ' + pt2.y + ')'); - //LOG.debug('edge ' + i + ': (' + va.x + ', ' + va.y + ') (' + vb.x + ', ' + vb.y + ')'); - //LOG.debug('half ' + i + ': ' + pt1.x + ' edge: ' + va.x); - + + ////log.debug('half ' + i + ': (' + pt1.x + ', ' + pt1.y + ') (' + pt2.x + ', ' + pt2.y + ')'); + ////log.debug('edge ' + i + ': (' + va.x + ', ' + va.y + ') (' + vb.x + ', ' + vb.y + ')'); + ////log.debug('half ' + i + ': ' + pt1.x + ' edge: ' + va.x); + // NOTE we only store one point, as the polygon should close itself verty.push(pt1.y); vertx.push(pt1.x); } - - //LOG.debug('\n'); - + + ////log.debug('\n'); + var nvert = halfedges.length; var i, j, c = 0; - + for (i = 0, j = nvert-1; i < nvert; j = i++) { if ( ((verty[i] > p.y) != (verty[j] > p.y)) && (p.x < (vertx[j] - vertx[i]) * (p.y - verty[i]) / (verty[j] - verty[i]) + vertx[i]) ) @@ -559,92 +709,104 @@ function VAST_Voronoi(bbox) { } return (c != 0); } - + + this.collidesID = function(id, center, radius){ + return collides(id2idx[id], center, radius); + } + //bool collides (int index, const point2d ¢er, int radius); // NOTE: a recentular overlap version is removed from this code, check original C++ version for it function collides(index, center, radius) { if (typeof center.distance !== 'function') { - LOG.debug('center does not have distance function'); + //log.debug('center does not have distance function'); return false; } - + // case 1: check if center lies inside the polygon if (insideRegion(index, center) == true) { - //LOG.debug('center ' + center.to_string() + ' inside polygon of site ' + result.cells[index].site.id); + ////log.debug('center ' + center.to_string() + ' inside polygon of site ' + result.cells[index].site.id); return true; } var halfedges = result.cells[index].halfedges; for (var j=0; j < halfedges.length; j++) { - + var edge = halfedges[j].edge; - - // case 2: check if *any* vertex of the region's edge lies inside the circle + + // case 2: check if *any* vertex of the region's edge lies inside the circle if (center.distance(edge.va) <= radius) { - //LOG.debug('circle with center ' + center.to_string() + ' contains va edge end '); + ////log.debug('circle with center ' + center.to_string() + ' contains va edge end '); return true; - } + } if (center.distance(edge.vb) <= radius) { - //LOG.debug('circle with center ' + center.to_string() + ' contains vb edge end '); + ////log.debug('circle with center ' + center.to_string() + ' contains vb edge end '); return true; } - + // case 3: check if the line seg intersects with the circle // TODO: possibly costly, do it just once instead of every time? var seg = new segment(edge.va, edge.vb); if (seg.intersects(center, radius) === true) { - LOG.debug('circle with center ' + center.to_string() + ' intersects with edge ends'); - return true; + //log.debug('circle with center ' + center.to_string() + ' intersects with edge ends'); + return true; } } - //printf ("[%d] doesn't overlap with (%.2f, %.2f)\n", index, center.x, center.y); + //log.warn(index+" doesn't overlap with ("+center.x+", "+center.y+")"); return false; } - + // get the set of enclosing neighbors for a site (given its index) // NOTE: nset returns site id (not index in result.cells) function getNeighborSet(cell_idx) { // reset return array var nset = []; - - //LOG.debug('getNeighborSet cell_idx: ' + cell_idx + ' cell size: ' + result.cells.length); - + + if (!result.cells.hasOwnProperty(cell_idx) || result.cells[cell_idx] == undefined) + { + //log.debug("No cell with that ID: " + cell_idx); + return nset; + } + + ////log.debug('getNeighborSet cell_idx: ' + cell_idx + ' cell size: ' + result.cells.length); + // check if index range is sensible - if (cell_idx >= 0 && cell_idx < result.cells.length) { + if (cell_idx >= 0 && cell_idx < result.cells.length && result.cells[cell_idx].site != undefined) { var cell_id = result.cells[cell_idx].site.id; var halfedges = result.cells[cell_idx].halfedges; - - //LOG.debug('halfedge count: ' + halfedges.length); - // go through each halfedge & check for edge's sites on two ends + ////log.debug(result.cells); + + ////log.debug('halfedge count: ' + halfedges.length); + + // go through each halfedge & check for edge's sites on two ends for (var i=0; i < halfedges.length; i++) { - - var edge = halfedges[i].edge; - - //LOG.debug('edge ' + i + ' site_id: ' + halfedges[i].site.id + ' va (' + edge.va.x + ', ' + edge.va.y + ') vb (' + edge.vb.x + ', ' + edge.vb.y + ')'); - //LOG.debug('lSite: ' + edge.lSite + ' id: ' + (edge.lSite !== null ? edge.lSite.id : 'null')); - //LOG.debug('rSite: ' + edge.rSite + ' id: ' + (edge.rSite !== null ? edge.rSite.id : 'null')); - - // take the bisector's site from the other side of current given index + + var edge = halfedges[i].edge; + /* + //log.debug('edge ' + i + ' site_id: ' + halfedges[i].site.id + ' va (' + edge.va.x + ', ' + edge.va.y + ') vb (' + edge.vb.x + ', ' + edge.vb.y + ')'); + //log.debug('lSite: ' + edge.lSite + ' id: ' + (edge.lSite !== null ? edge.lSite.id : 'null')); + //log.debug('rSite: ' + edge.rSite + ' id: ' + (edge.rSite !== null ? edge.rSite.id : 'null')); + */ + // take the bisector's site from the other side of current given index //var id = (edge.bisectingID[0] == index ? edge.bisectingID[1] : edge.bisectingID[0]); - var site = (edge.lSite.id === cell_id ? edge.rSite : edge.lSite); - //LOG.debug('lSite.id: ' + edge.lSite.id + ' cell_id: ' + cell_id + ' site: ' + site); - + var site = (edge.lSite.id === cell_id ? edge.rSite : edge.lSite); + ////log.debug('lSite.id: ' + edge.lSite.id + ' cell_id: ' + cell_id + ' site: ' + site); + if (site !== null) - nset.push(site.id); + nset.push(site.id); } } - + return nset; } - + // currently unused // TODO: should be used by is_boundary() check // check if a site of a given index is boundary (one endpoint for the edge is open / unassigned) @@ -657,38 +819,79 @@ function VAST_Voronoi(bbox) { if (edge.vertexIndex[0] == -1 || edge.vertexIndex[1] == -1) return true; - } + } return false; } // check if a given site (via its 'index') is fully enclosed within some center & radius function enclosed(index, center, radius) { - - //LOG.debug('enclosed(), checking whether index ' + index + ' is enclosed within (' + center.x + ', ' + center.y + ') radius: ' + radius); - + + ////log.debug('enclosed(), checking whether index ' + index + ' is enclosed within (' + center.x + ', ' + center.y + ') radius: ' + radius); + // check center for distance function if (typeof center.distance !== 'function') center = new point2d(center.x, center.y); - + var halfedges = result.cells[index].halfedges; var pt; - + for (var i=0; i < halfedges.length; i++) { - - // NOTE: we only need to check one edge point for each edge + + // NOTE: we only need to check one edge point for each edge // (it comes around in a circle) pt = halfedges[i].getStartpoint(); - - //LOG.debug('center: ' + center.to_string() + ' pt:(' + pt.x + ', ' + pt.y + ') dist: ' + center.distance(pt)); - + + ////log.debug('center: ' + center.to_string() + ' pt:(' + pt.x + ', ' + pt.y + ') dist: ' + center.distance(pt)); + if (center.distance (pt) >= radius) return false; } return true; } - + + function withinAOI(pos, radius, pos_x, pos_y) { + var dx = pos.x-pos_x; + var dy = pos.y-pos_y; + var dr = Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2)); + if (dr <= radius) { + return true; + } + return false; + } + + var _isOverlapped = function (pos, id) { + for (var key in sites) { + if (sites[key].x == pos.x && sites[key].y == pos.y && id != key) + return true; + } + return false + } + + var _adjustPos = function (pos, id) { + do { + // adjust position randomly between -0.1 and 0.1 + pos.x += Math.random()-0.1; + pos.y += Math.random()-0.1; + + // make sure the pos is within boundaries of region + pos = _bound(pos); + } while (_isOverlapped(pos, id)); + + return pos; + } + + // check that node is within the bounds of the bbox + var _bound = function (pos) { + if (pos.x <= bbox.xl+0.5) pos.x = bbox.xl+0.5; + if (pos.y <= bbox.yt+0.5) pos.y = bbox.yt+0.5; + if (pos.x >= bbox.xr-0.5) pos.x = bbox.xr-0.5; + if (pos.y >= bbox.yb-0.5) pos.y = bbox.yb-0.5; + return pos; + } + + } // end VAST_Voronoi // export the class with conditional check if (typeof module !== "undefined") - module.exports = VAST_Voronoi; \ No newline at end of file + module.exports = VAST_Voronoi; diff --git a/line2d.java b/line2d.java deleted file mode 100644 index 45fe4115..00000000 --- a/line2d.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * VAST, a scalable peer-to-peer network for virtual environments - * Copyright (C) 2006 Shun-Yun Hu (syhu@yahoo.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -package vast; - -public class line2d -{ - public double a,b,c; - public int bisectingID[] = new int[2]; // NOTE: we need to change this from storing node index to node id - public int vertexIndex[] = new int[2]; - public segment seg; - - public line2d (double x1, double y1, double x2 , double y2) - { - seg = new segment (x1, y1, x2, y2); - - if (y1 == y2) - { - a = 0; b = 1; c = y1; - } - else if (x1 == x2) - { - a = 1; b = 0; c = x1; - } - else - { - double dx = x1 - x2; - double dy = y1 - y2; - double m = dx / dy; - a = -1 * m; - b = 1; - c = a*x1 + b*y1; - } - } - - public line2d () - { - a = b = c = 0.0; - seg = new segment (0, 0, 0, 0); - - vertexIndex[0] = -1; - vertexIndex[1] = -1; - } - - public line2d (double A, double B, double C) - { - a = A; - b = B; - c = C; - seg = new segment (0, 0, 0, 0); - - vertexIndex[0] = -1; - vertexIndex[1] = -1; - } - - // BUG: possibily not storing p properly after calculation - boolean intersection (line2d l, point2d p) - { - //The polynomial judgement - double D = (a * l.b) - (b * l.a); - if (D == 0) - { - p.x = 0; - p.y = 0; - return false; - } - else - { - p.x=(c*l.b-b*l.c)/D/1.0; - p.y=(a*l.c-c*l.a)/D/1.0; - return true; - } - } - - double dist (point2d p) - { - /* - double u; - - // u = ((x3-x1)(x2-x1) + (y3-y1)(y2-y1)) / (p2.dist(p1)^2) - u = ((p.x - seg.p1.x) * (seg.p2.x - seg.p1.x) + - (p.y - seg.p1.y) * (seg.p2.y - seg.p1.y)) / - (seg.p1.dist (seg.p2)) - - double x = seg.p1.x + u * (seg.p2.x - seg.p1.x); - double y = seg.p1.y + u * (seg.p2.y - seg.p1.y); - - return p.dist (point2d (x, y)); - */ - - return Math.abs (a * p.x + b * p.y + c) / Math.sqrt (Math.pow (a, 2) + Math.pow (b, 2)); - } -}; - diff --git a/move_cluster.js b/move_cluster.js deleted file mode 100644 index d397df35..00000000 --- a/move_cluster.js +++ /dev/null @@ -1,199 +0,0 @@ - - -// -// cluster movement (originally written by Jiun-Shiang Chiou, adopted by Shun-Yun Hu) -// -// 2012-08-28 modified to javacript -// -// methods: -// clusterMovement(topleft, bottomright, num_nodes, speed) -// init() initialize positions & attractors -// move() move all nodes -// getpos(index) get a current position for a node of a given index -// - -var point2d = point2d || require( "./typedef/point2d.js" ); - -// % of chance of going to a random attractor -var PROB_RANDOM_ATTRACTOR = 20; -var ATTRACTOR_SPACE_MULTIPLIER = 3; - -// how likely a teleport will occur in every 10,000 moves -var TELEPORT_CHANCE = 5; - -// create a random position -var rand_pos = function (top_left, bottom_right) { - var pos = new point2d(top_left.x + Math.floor(Math.random() * (bottom_right.x - top_left.x)), - top_left.y + Math.floor(Math.random() * (bottom_right.y - top_left.y))); - return pos; -} - -// topleft / bottomright are of objects {x,y} -var clusterMovement = function (topleft, bottomright, l_num_nodes, l_speed) { - - // - // constructor - // - - // dimensions of the world nodes move in - var _dim = {x: bottomright.x - topleft.x, y: bottomright.y - topleft.y}; - - // current destination coordinates of all nodes - var _dest = []; - - // current positions for each node - var _pos = []; - - // number of attractors in the world - var _num_attractors = Math.floor((1.5 * Math.log(l_num_nodes)) > 1 ? (1.5 * Math.log(l_num_nodes)) : 1); - - // attractor positions (of size _num_attractors) - var _attractors = []; - - // setup attractor ranges - // sphere in which the attractor is effective - var _range = Math.sqrt ((_dim.x * _dim.y) / _num_attractors) / ATTRACTOR_SPACE_MULTIPLIER; - - - // - // public methods - // - - this.init = function () { - - // create new positions & destination waypoint targets - for (var i = 0; i < l_num_nodes; ++i) { - _pos[i] = rand_pos(topleft, bottomright); - _dest[i] = rand_pos(topleft, bottomright); - } - - reset_attractors(); - } - - // make each node move towards desintations - this.move = function () { - - var dist, ratio; - for (var i=0; i < l_num_nodes; ++i) { - - dist = _dest[i].distance(_pos[i]); - - // move towards the destination one step - var delta = new point2d(_dest[i].x - _pos[i].x, _dest[i].y - _pos[i].y); - - // adjust deltas for constant velocity - if ((ratio = dist / l_speed) > 1.0) { - delta.x /= ratio; - delta.y /= ratio; - } - - // make changes to position - _pos[i].x += delta.x; - _pos[i].y += delta.y; - - // set new destinations if already reached - if (dist < 0.1) - { - // random waypoint - var nearest; - - // 10% chance to go to a random attractor, otherwise go to nearest - if (Math.random() * 100 < PROB_RANDOM_ATTRACTOR) - nearest = Math.floor(Math.random() * _num_attractors); - else - nearest = find_nearest(_pos[i]); - - var tl = _attractors[nearest]; - tl.x -= _range; - tl.y -= _range; - tl = bound(tl); - - var br = _attractors[nearest]; - br.x += _range; - br.y += _range; - br = bound(br); - - // setup next destination - _dest[i] = rand_pos(tl, br); - } - - if (TELEPORT_CHANCE > 0) { - // a slight chance to simply teleport to a new location - if (Math.random() * 10000 < TELEPORT_CHANCE) { - _pos[i] = rand_pos(topleft, bottomright); - _dest[i] = rand_pos(topleft, bottomright); - } - } - } - - return true; - } - - // get current position for a particular node - this.getpos = function (index) { - if (index < 0 || index >= l_num_nodes) - return undefined; - return _pos[index]; - } - - - // - // internal methods - // - - var reset_attractors = function () { - - // setup attractor locations - var i,j; - for (i = 0; i < _num_attractors; ++i) { - do - { - _attractors[i] = rand_pos(topleft, bottomright); - - // check if the new attractor is far apart enough from existing ones - for (j=0; j bottomright.x) c.x = bottomright.x; - if (c.y > bottomright.y) c.y = bottomright.y; - return c; - } - - // find nearest attractors - var find_nearest = function (c) { - - // set up new destination around the nearest attractors - var min_dist = _dim.x + _dim.y; - var curr_dist; - var index = 0; - - // find the nearest attractor - for (var j=0; j < _num_attractors; j++) { - curr_dist = c.distance (_attractors[j]); - if (curr_dist < min_dist) { - min_dist = curr_dist; - index = j; - } - } - return index; - } -} // end clusterMovement - -// export the class with conditional check -if (typeof module !== "undefined") - module.exports = clusterMovement; - - - - diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 00000000..65a092cf --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,5304 @@ +0 info it worked if it ends with ok +1 verbose cli [ 'C:\\Program Files\\nodejs\\\\node.exe', +1 verbose cli 'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js', +1 verbose cli 'publish' ] +2 info using npm@1.2.18 +3 info using node@v0.10.6 +4 verbose node symlink C:\Program Files\nodejs\\node.exe +5 verbose publish [ '.' ] +6 verbose read json d:\syhu\Dropbox\work\vast.js\package.json +7 verbose cache add [ '.', null ] +8 verbose cache add name=undefined spec="." args=[".",null] +9 verbose parsed url { protocol: null, +9 verbose parsed url slashes: null, +9 verbose parsed url auth: null, +9 verbose parsed url host: null, +9 verbose parsed url port: null, +9 verbose parsed url hostname: null, +9 verbose parsed url hash: null, +9 verbose parsed url search: null, +9 verbose parsed url query: null, +9 verbose parsed url pathname: '.', +9 verbose parsed url path: '.', +9 verbose parsed url href: '.' } +10 silly lockFile 3a52ce78- . +11 verbose lock . C:\Users\syhu\AppData\Roaming\npm-cache\3a52ce78-.lock +12 verbose read json package.json +13 verbose tar pack [ 'C:\\Users\\syhu\\AppData\\Local\\Temp\\npm-6044\\1408350555041-0.2732422589324415\\tmp.tgz', +13 verbose tar pack '.' ] +14 verbose tarball C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz +15 verbose folder . +16 info prepublish vast.js@0.0.1-2 +17 silly lockFile 3a52ce78- . +18 verbose lock . C:\Users\syhu\AppData\Roaming\npm-cache\3a52ce78-.lock +19 silly lockFile 40fef38d-55041-0-2732422589324415-tmp-tgz C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz +20 verbose lock C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz C:\Users\syhu\AppData\Roaming\npm-cache\40fef38d-55041-0-2732422589324415-tmp-tgz.lock +21 silly lockFile 3a52ce78- . +22 silly lockFile 3a52ce78- . +23 silly lockFile 40fef38d-55041-0-2732422589324415-tmp-tgz C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz +24 silly lockFile 40fef38d-55041-0-2732422589324415-tmp-tgz C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz +25 verbose tar unpack C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz +26 silly lockFile 33aa78c8-55041-0-2732422589324415-package C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package +27 verbose lock C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package C:\Users\syhu\AppData\Roaming\npm-cache\33aa78c8-55041-0-2732422589324415-package.lock +28 silly lockFile 40fef38d-55041-0-2732422589324415-tmp-tgz C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz +29 verbose lock C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz C:\Users\syhu\AppData\Roaming\npm-cache\40fef38d-55041-0-2732422589324415-tmp-tgz.lock +30 silly gunzTarPerm modes [ '755', '644' ] +31 silly gunzTarPerm extractEntry package.json +32 silly gunzTarPerm modified mode [ 'package.json', 438, 420 ] +33 silly gunzTarPerm extractEntry .npmignore +34 silly gunzTarPerm modified mode [ '.npmignore', 438, 420 ] +35 silly gunzTarPerm extractEntry LICENSE +36 silly gunzTarPerm modified mode [ 'LICENSE', 438, 420 ] +37 silly gunzTarPerm extractEntry index.js +38 silly gunzTarPerm modified mode [ 'index.js', 438, 420 ] +39 silly gunzTarPerm extractEntry doc/misc/common_util.js +40 silly gunzTarPerm modified mode [ 'doc/misc/common_util.js', 438, 420 ] +41 silly gunzTarPerm extractEntry doc/misc/generic_net.js +42 silly gunzTarPerm modified mode [ 'doc/misc/generic_net.js', 438, 420 ] +43 silly gunzTarPerm extractEntry doc/misc/hash.js +44 silly gunzTarPerm modified mode [ 'doc/misc/hash.js', 438, 420 ] +45 silly gunzTarPerm extractEntry doc/misc/stable-proxy.js +46 silly gunzTarPerm modified mode [ 'doc/misc/stable-proxy.js', 438, 420 ] +47 silly gunzTarPerm extractEntry doc/misc/tools.js +48 silly gunzTarPerm modified mode [ 'doc/misc/tools.js', 438, 420 ] +49 silly gunzTarPerm extractEntry doc/misc/line2d.java +50 silly gunzTarPerm modified mode [ 'doc/misc/line2d.java', 438, 420 ] +51 silly gunzTarPerm extractEntry doc/misc/SFVoronoi.java +52 silly gunzTarPerm modified mode [ 'doc/misc/SFVoronoi.java', 438, 420 ] +53 silly gunzTarPerm extractEntry doc/VAST.js architecture.txt +54 silly gunzTarPerm modified mode [ 'doc/VAST.js architecture.txt', 438, 420 ] +55 silly gunzTarPerm extractEntry History.md +56 silly gunzTarPerm modified mode [ 'History.md', 438, 420 ] +57 silly gunzTarPerm extractEntry lib/index.js +58 silly gunzTarPerm modified mode [ 'lib/index.js', 438, 420 ] +59 silly gunzTarPerm extractEntry lib/original/README.md +60 silly gunzTarPerm modified mode [ 'lib/original/README.md', 438, 420 ] +61 silly gunzTarPerm extractEntry lib/original/wz_jsgraphics.js +62 silly gunzTarPerm modified mode [ 'lib/original/wz_jsgraphics.js', 438, 420 ] +63 silly gunzTarPerm extractEntry lib/original/voronoi.js +64 silly gunzTarPerm modified mode [ 'lib/original/voronoi.js', 438, 420 ] +65 silly gunzTarPerm extractEntry lib/original/VON_peer.js +66 silly gunzTarPerm modified mode [ 'lib/original/VON_peer.js', 438, 420 ] +67 silly gunzTarPerm extractEntry lib/original/rhill-voronoi-core-min.js +68 silly gunzTarPerm modified mode [ 'lib/original/rhill-voronoi-core-min.js', 438, 420 ] +69 silly gunzTarPerm extractEntry lib/original/move_cluster.js +70 silly gunzTarPerm modified mode [ 'lib/original/move_cluster.js', 438, 420 ] +71 silly gunzTarPerm extractEntry lib/original/sf_voronoi.js +72 silly gunzTarPerm modified mode [ 'lib/original/sf_voronoi.js', 438, 420 ] +73 silly gunzTarPerm extractEntry lib/original/vast_voro.js +74 silly gunzTarPerm modified mode [ 'lib/original/vast_voro.js', 438, 420 ] +75 silly gunzTarPerm extractEntry lib/original/vast_types.js +76 silly gunzTarPerm modified mode [ 'lib/original/vast_types.js', 438, 420 ] +77 silly gunzTarPerm extractEntry lib/original/VAST_matcher.js +78 silly gunzTarPerm modified mode [ 'lib/original/VAST_matcher.js', 438, 420 ] +79 silly gunzTarPerm extractEntry lib/original/VAST.js +80 silly gunzTarPerm modified mode [ 'lib/original/VAST.js', 438, 420 ] +81 silly gunzTarPerm extractEntry lib/original/VSO_peer.js +82 silly gunzTarPerm modified mode [ 'lib/original/VSO_peer.js', 438, 420 ] +83 silly gunzTarPerm extractEntry lib/original/VAST_client.js +84 silly gunzTarPerm modified mode [ 'lib/original/VAST_client.js', 438, 420 ] +85 silly gunzTarPerm extractEntry lib/original/rhill-voronoi-core.js +86 silly gunzTarPerm modified mode [ 'lib/original/rhill-voronoi-core.js', 438, 420 ] +87 silly gunzTarPerm extractEntry lib/original/typedef.js +88 silly gunzTarPerm modified mode [ 'lib/original/typedef.js', 438, 420 ] +89 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io-server.js +90 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io-server.js', 438, 420 ] +91 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io.js +92 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io.js', 438, 420 ] +93 silly gunzTarPerm extractEntry lib/original/vast.io/socket.io/socket.io.js +94 silly gunzTarPerm modified mode [ 'lib/original/vast.io/socket.io/socket.io.js', 438, 420 ] +95 silly gunzTarPerm extractEntry lib/original/vast.io/socket.io/socket.io.min.js +96 silly gunzTarPerm modified mode [ 'lib/original/vast.io/socket.io/socket.io.min.js', 438, 420 ] +97 silly gunzTarPerm extractEntry lib/original/vast.io/socket.io-client.html +98 silly gunzTarPerm modified mode [ 'lib/original/vast.io/socket.io-client.html', 438, 420 ] +99 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io-client (dev).html +100 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io-client (dev).html', 438, 420 ] +101 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io-client (gaiasup).html +102 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io-client (gaiasup).html', +102 silly gunzTarPerm 438, +102 silly gunzTarPerm 420 ] +103 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io-client (local).html +104 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io-client (local).html', 438, 420 ] +105 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io.bat +106 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io.bat', 438, 420 ] +107 silly gunzTarPerm extractEntry lib/original/common/logger.js +108 silly gunzTarPerm modified mode [ 'lib/original/common/logger.js', 438, 420 ] +109 silly gunzTarPerm extractEntry lib/original/common/util.js +110 silly gunzTarPerm modified mode [ 'lib/original/common/util.js', 438, 420 ] +111 silly gunzTarPerm extractEntry lib/original/typedef/line2d.js +112 silly gunzTarPerm modified mode [ 'lib/original/typedef/line2d.js', 438, 420 ] +113 silly gunzTarPerm extractEntry lib/original/typedef/point2d.js +114 silly gunzTarPerm modified mode [ 'lib/original/typedef/point2d.js', 438, 420 ] +115 silly gunzTarPerm extractEntry lib/original/typedef/segment.js +116 silly gunzTarPerm modified mode [ 'lib/original/typedef/segment.js', 438, 420 ] +117 silly gunzTarPerm extractEntry lib/original/net/msg_handler.js +118 silly gunzTarPerm modified mode [ 'lib/original/net/msg_handler.js', 438, 420 ] +119 silly gunzTarPerm extractEntry lib/original/net/net_nodejs.js +120 silly gunzTarPerm modified mode [ 'lib/original/net/net_nodejs.js', 438, 420 ] +121 silly gunzTarPerm extractEntry lib/original/net/test_vast_net.js +122 silly gunzTarPerm modified mode [ 'lib/original/net/test_vast_net.js', 438, 420 ] +123 silly gunzTarPerm extractEntry lib/original/net/vast_net.js +124 silly gunzTarPerm modified mode [ 'lib/original/net/vast_net.js', 438, 420 ] +125 silly gunzTarPerm extractEntry lib/original/INSTALL.txt +126 silly gunzTarPerm modified mode [ 'lib/original/INSTALL.txt', 438, 420 ] +127 silly gunzTarPerm extractEntry lib/original/VSS/directory.js +128 silly gunzTarPerm modified mode [ 'lib/original/VSS/directory.js', 438, 420 ] +129 silly gunzTarPerm extractEntry lib/original/VSS/handler.js +130 silly gunzTarPerm modified mode [ 'lib/original/VSS/handler.js', 438, 420 ] +131 silly gunzTarPerm extractEntry lib/original/VSS/logic.js +132 silly gunzTarPerm modified mode [ 'lib/original/VSS/logic.js', 438, 420 ] +133 silly gunzTarPerm extractEntry lib/original/VSS/router.js +134 silly gunzTarPerm modified mode [ 'lib/original/VSS/router.js', 438, 420 ] +135 silly gunzTarPerm extractEntry lib/original/VSS/server.js +136 silly gunzTarPerm modified mode [ 'lib/original/VSS/server.js', 438, 420 ] +137 silly gunzTarPerm extractEntry lib/original/VSS/VSS.js +138 silly gunzTarPerm modified mode [ 'lib/original/VSS/VSS.js', 438, 420 ] +139 silly gunzTarPerm extractEntry lib/original/backup +140 silly gunzTarPerm modified mode [ 'lib/original/backup', 438, 420 ] +141 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/package.json +142 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/package.json', 438, 420 ] +143 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/.npmignore +144 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/.npmignore', 438, 420 ] +145 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/LICENSE +146 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/LICENSE', 438, 420 ] +147 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/index.js +148 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/index.js', 438, 420 ] +149 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/latest +150 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/latest', 438, 420 ] +151 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/.travis.yml +152 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/.travis.yml', 438, 420 ] +153 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/History.md +154 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/History.md', 438, 420 ] +155 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/Makefile +156 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/Makefile', 438, 420 ] +157 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/Readme.md +158 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/Readme.md', 438, 420 ] +159 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/lib/client.js +160 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/lib/client.js', 438, 420 ] +161 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/lib/index.js +162 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/lib/index.js', 438, 420 ] +163 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/lib/namespace.js +164 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/lib/namespace.js', +164 silly gunzTarPerm 438, +164 silly gunzTarPerm 420 ] +165 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/lib/socket.js +166 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/lib/socket.js', 438, 420 ] +167 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/package.json +168 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/package.json', +168 silly gunzTarPerm 438, +168 silly gunzTarPerm 420 ] +169 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/.npmignore +170 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/.npmignore', +170 silly gunzTarPerm 438, +170 silly gunzTarPerm 420 ] +171 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/README.md +172 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/README.md', +172 silly gunzTarPerm 438, +172 silly gunzTarPerm 420 ] +173 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/index.js +174 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/index.js', +174 silly gunzTarPerm 438, +174 silly gunzTarPerm 420 ] +175 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/.travis.yml +176 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/.travis.yml', +176 silly gunzTarPerm 438, +176 silly gunzTarPerm 420 ] +177 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/History.md +178 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/History.md', +178 silly gunzTarPerm 438, +178 silly gunzTarPerm 420 ] +179 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/engine.io.js +180 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/engine.io.js', +180 silly gunzTarPerm 438, +180 silly gunzTarPerm 420 ] +181 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/server.js +182 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/server.js', +182 silly gunzTarPerm 438, +182 silly gunzTarPerm 420 ] +183 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/socket.js +184 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/socket.js', +184 silly gunzTarPerm 438, +184 silly gunzTarPerm 420 ] +185 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transport.js +186 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transport.js', +186 silly gunzTarPerm 438, +186 silly gunzTarPerm 420 ] +187 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/index.js +188 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/index.js', +188 silly gunzTarPerm 438, +188 silly gunzTarPerm 420 ] +189 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling-jsonp.js +190 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling-jsonp.js', +190 silly gunzTarPerm 438, +190 silly gunzTarPerm 420 ] +191 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling-xhr.js +192 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling-xhr.js', +192 silly gunzTarPerm 438, +192 silly gunzTarPerm 420 ] +193 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling.js +194 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling.js', +194 silly gunzTarPerm 438, +194 silly gunzTarPerm 420 ] +195 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/websocket.js +196 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/websocket.js', +196 silly gunzTarPerm 438, +196 silly gunzTarPerm 420 ] +197 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/Makefile +198 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/Makefile', +198 silly gunzTarPerm 438, +198 silly gunzTarPerm 420 ] +199 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/package.json +200 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/package.json', +200 silly gunzTarPerm 438, +200 silly gunzTarPerm 420 ] +201 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/.npmignore +202 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/.npmignore', +202 silly gunzTarPerm 438, +202 silly gunzTarPerm 420 ] +203 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/README.md +204 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/README.md', +204 silly gunzTarPerm 438, +204 silly gunzTarPerm 420 ] +205 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/lib/base64id.js +206 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/lib/base64id.js', +206 silly gunzTarPerm 438, +206 silly gunzTarPerm 420 ] +207 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/package.json +208 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/package.json', +208 silly gunzTarPerm 438, +208 silly gunzTarPerm 420 ] +209 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/.npmignore +210 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/.npmignore', +210 silly gunzTarPerm 438, +210 silly gunzTarPerm 420 ] +211 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/debug.js +212 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/debug.js', +212 silly gunzTarPerm 438, +212 silly gunzTarPerm 420 ] +213 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/index.js +214 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/index.js', +214 silly gunzTarPerm 438, +214 silly gunzTarPerm 420 ] +215 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/app.js +216 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/app.js', +216 silly gunzTarPerm 438, +216 silly gunzTarPerm 420 ] +217 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/wildcards.js +218 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/wildcards.js', +218 silly gunzTarPerm 438, +218 silly gunzTarPerm 420 ] +219 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/worker.js +220 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/worker.js', +220 silly gunzTarPerm 438, +220 silly gunzTarPerm 420 ] +221 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/browser.html +222 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/browser.html', +222 silly gunzTarPerm 438, +222 silly gunzTarPerm 420 ] +223 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/History.md +224 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/History.md', +224 silly gunzTarPerm 438, +224 silly gunzTarPerm 420 ] +225 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/lib/debug.js +226 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/lib/debug.js', +226 silly gunzTarPerm 438, +226 silly gunzTarPerm 420 ] +227 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/Makefile +228 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/Makefile', +228 silly gunzTarPerm 438, +228 silly gunzTarPerm 420 ] +229 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/Readme.md +230 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/Readme.md', +230 silly gunzTarPerm 438, +230 silly gunzTarPerm 420 ] +231 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/package.json +232 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/package.json', +232 silly gunzTarPerm 438, +232 silly gunzTarPerm 420 ] +233 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.npmignore +234 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.npmignore', +234 silly gunzTarPerm 438, +234 silly gunzTarPerm 420 ] +235 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/LICENSE +236 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/LICENSE', +236 silly gunzTarPerm 438, +236 silly gunzTarPerm 420 ] +237 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/index.js +238 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/index.js', +238 silly gunzTarPerm 438, +238 silly gunzTarPerm 420 ] +239 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/Readme.md +240 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/Readme.md', +240 silly gunzTarPerm 438, +240 silly gunzTarPerm 420 ] +241 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.travis.yml +242 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.travis.yml', +242 silly gunzTarPerm 438, +242 silly gunzTarPerm 420 ] +243 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.zuul.yml +244 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.zuul.yml', +244 silly gunzTarPerm 438, +244 silly gunzTarPerm 420 ] +245 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/Makefile +246 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/Makefile', +246 silly gunzTarPerm 438, +246 silly gunzTarPerm 420 ] +247 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/History.md +248 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/History.md', +248 silly gunzTarPerm 438, +248 silly gunzTarPerm 420 ] +249 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/browser.js +250 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/browser.js', +250 silly gunzTarPerm 438, +250 silly gunzTarPerm 420 ] +251 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js +252 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js', +252 silly gunzTarPerm 438, +252 silly gunzTarPerm 420 ] +253 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/keys.js +254 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/keys.js', +254 silly gunzTarPerm 438, +254 silly gunzTarPerm 420 ] +255 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/package.json +256 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/package.json', +256 silly gunzTarPerm 438, +256 silly gunzTarPerm 420 ] +257 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/.npmignore +258 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/.npmignore', +258 silly gunzTarPerm 438, +258 silly gunzTarPerm 420 ] +259 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/README.md +260 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/README.md', +260 silly gunzTarPerm 438, +260 silly gunzTarPerm 420 ] +261 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/LICENCE +262 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/LICENCE', +262 silly gunzTarPerm 438, +262 silly gunzTarPerm 420 ] +263 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/index.js +264 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/index.js', +264 silly gunzTarPerm 438, +264 silly gunzTarPerm 420 ] +265 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/.travis.yml +266 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/.travis.yml', +266 silly gunzTarPerm 438, +266 silly gunzTarPerm 420 ] +267 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/test/after-test.js +268 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/test/after-test.js', +268 silly gunzTarPerm 438, +268 silly gunzTarPerm 420 ] +269 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/package.json +270 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/package.json', +270 silly gunzTarPerm 438, +270 silly gunzTarPerm 420 ] +271 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/.npmignore +272 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/.npmignore', +272 silly gunzTarPerm 438, +272 silly gunzTarPerm 420 ] +273 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/README.md +274 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/README.md', +274 silly gunzTarPerm 438, +274 silly gunzTarPerm 420 ] +275 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/index.js +276 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/index.js', +276 silly gunzTarPerm 438, +276 silly gunzTarPerm 420 ] +277 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/Makefile +278 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/Makefile', +278 silly gunzTarPerm 438, +278 silly gunzTarPerm 420 ] +279 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/test/slice-buffer.js +280 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/test/slice-buffer.js', +280 silly gunzTarPerm 438, +280 silly gunzTarPerm 420 ] +281 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json +282 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json', +282 silly gunzTarPerm 438, +282 silly gunzTarPerm 420 ] +283 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.npmignore +284 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.npmignore', +284 silly gunzTarPerm 438, +284 silly gunzTarPerm 420 ] +285 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md +286 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md', +286 silly gunzTarPerm 438, +286 silly gunzTarPerm 420 ] +287 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/grunt.js +288 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/grunt.js', +288 silly gunzTarPerm 438, +288 silly gunzTarPerm 420 ] +289 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.travis.yml +290 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.travis.yml', +290 silly gunzTarPerm 438, +290 silly gunzTarPerm 420 ] +291 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js +292 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js', +292 silly gunzTarPerm 438, +292 silly gunzTarPerm 420 ] +293 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/LICENSE-MIT +294 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/LICENSE-MIT', +294 silly gunzTarPerm 438, +294 silly gunzTarPerm 420 ] +295 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json~ +296 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json~', +296 silly gunzTarPerm 438, +296 silly gunzTarPerm 420 ] +297 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md~ +298 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md~', +298 silly gunzTarPerm 438, +298 silly gunzTarPerm 420 ] +299 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js +300 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js', +300 silly gunzTarPerm 438, +300 silly gunzTarPerm 420 ] +301 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/package.json +302 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/package.json', +302 silly gunzTarPerm 438, +302 silly gunzTarPerm 420 ] +303 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/.npmignore +304 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/.npmignore', +304 silly gunzTarPerm 438, +304 silly gunzTarPerm 420 ] +305 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/README.md +306 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/README.md', +306 silly gunzTarPerm 438, +306 silly gunzTarPerm 420 ] +307 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/index.js +308 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/index.js', +308 silly gunzTarPerm 438, +308 silly gunzTarPerm 420 ] +309 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/.zuul.yml +310 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/.zuul.yml', +310 silly gunzTarPerm 438, +310 silly gunzTarPerm 420 ] +311 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/Makefile +312 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/Makefile', +312 silly gunzTarPerm 438, +312 silly gunzTarPerm 420 ] +313 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/test/index.js +314 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/test/index.js', +314 silly gunzTarPerm 438, +314 silly gunzTarPerm 420 ] +315 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/package.json +316 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/package.json', +316 silly gunzTarPerm 438, +316 silly gunzTarPerm 420 ] +317 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.npmignore +318 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.npmignore', +318 silly gunzTarPerm 438, +318 silly gunzTarPerm 420 ] +319 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/README.md +320 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/README.md', +320 silly gunzTarPerm 438, +320 silly gunzTarPerm 420 ] +321 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/x.js +322 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/x.js', +322 silly gunzTarPerm 438, +322 silly gunzTarPerm 420 ] +323 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/Gruntfile.js +324 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/Gruntfile.js', +324 silly gunzTarPerm 438, +324 silly gunzTarPerm 420 ] +325 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/utf8.js +326 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/utf8.js', +326 silly gunzTarPerm 438, +326 silly gunzTarPerm 420 ] +327 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.gitattributes +328 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.gitattributes', +328 silly gunzTarPerm 438, +328 silly gunzTarPerm 420 ] +329 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.travis.yml +330 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.travis.yml', +330 silly gunzTarPerm 438, +330 silly gunzTarPerm 420 ] +331 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/LICENSE-MIT.txt +332 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/LICENSE-MIT.txt', +332 silly gunzTarPerm 438, +332 silly gunzTarPerm 420 ] +333 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/bower.json +334 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/bower.json', +334 silly gunzTarPerm 438, +334 silly gunzTarPerm 420 ] +335 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/component.json +336 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/component.json', +336 silly gunzTarPerm 438, +336 silly gunzTarPerm 420 ] +337 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/tests.js +338 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/tests.js', +338 silly gunzTarPerm 438, +338 silly gunzTarPerm 420 ] +339 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/generate-test-data.py +340 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/generate-test-data.py', +340 silly gunzTarPerm 438, +340 silly gunzTarPerm 420 ] +341 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/index.html +342 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/index.html', +342 silly gunzTarPerm 438, +342 silly gunzTarPerm 420 ] +343 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.js +344 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.js', +344 silly gunzTarPerm 438, +344 silly gunzTarPerm 420 ] +345 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/index.html +346 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/index.html', +346 silly gunzTarPerm 438, +346 silly gunzTarPerm 420 ] +347 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/utf8.js.html +348 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/utf8.js.html', +348 silly gunzTarPerm 438, +348 silly gunzTarPerm 420 ] +349 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/index.html +350 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/index.html', +350 silly gunzTarPerm 438, +350 silly gunzTarPerm 420 ] +351 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.css +352 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.css', +352 silly gunzTarPerm 438, +352 silly gunzTarPerm 420 ] +353 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/LICENSE-GPL.txt +354 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/LICENSE-GPL.txt', +354 silly gunzTarPerm 438, +354 silly gunzTarPerm 420 ] +355 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/package.json +356 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/package.json', +356 silly gunzTarPerm 438, +356 silly gunzTarPerm 420 ] +357 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/.npmignore +358 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/.npmignore', +358 silly gunzTarPerm 438, +358 silly gunzTarPerm 420 ] +359 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/README.md +360 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/README.md', +360 silly gunzTarPerm 438, +360 silly gunzTarPerm 420 ] +361 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/index.js +362 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/index.js', +362 silly gunzTarPerm 438, +362 silly gunzTarPerm 420 ] +363 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/binding.gyp +364 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/binding.gyp', +364 silly gunzTarPerm 438, +364 silly gunzTarPerm 420 ] +365 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/builderror.log +366 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/builderror.log', +366 silly gunzTarPerm 438, +366 silly gunzTarPerm 420 ] +367 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/doc/ws.md +368 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/doc/ws.md', +368 silly gunzTarPerm 438, +368 silly gunzTarPerm 420 ] +369 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/ssl.js +370 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/ssl.js', +370 silly gunzTarPerm 438, +370 silly gunzTarPerm 420 ] +371 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/package.json +372 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/package.json', +372 silly gunzTarPerm 438, +372 silly gunzTarPerm 420 ] +373 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/.npmignore +374 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/.npmignore', +374 silly gunzTarPerm 438, +374 silly gunzTarPerm 420 ] +375 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/server.js +376 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/server.js', +376 silly gunzTarPerm 438, +376 silly gunzTarPerm 420 ] +377 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/app.js +378 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/app.js', +378 silly gunzTarPerm 438, +378 silly gunzTarPerm 420 ] +379 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/uploader.js +380 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/uploader.js', +380 silly gunzTarPerm 438, +380 silly gunzTarPerm 420 ] +381 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/index.html +382 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/index.html', +382 silly gunzTarPerm 438, +382 silly gunzTarPerm 420 ] +383 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/package.json +384 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/package.json', +384 silly gunzTarPerm 438, +384 silly gunzTarPerm 420 ] +385 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/server.js +386 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/server.js', +386 silly gunzTarPerm 438, +386 silly gunzTarPerm 420 ] +387 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/public/index.html +388 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/public/index.html', +388 silly gunzTarPerm 438, +388 silly gunzTarPerm 420 ] +389 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/package.json +390 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/package.json', +390 silly gunzTarPerm 438, +390 silly gunzTarPerm 420 ] +391 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/server.js +392 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/server.js', +392 silly gunzTarPerm 438, +392 silly gunzTarPerm 420 ] +393 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/public/index.html +394 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/public/index.html', +394 silly gunzTarPerm 438, +394 silly gunzTarPerm 420 ] +395 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/.travis.yml +396 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/.travis.yml', +396 silly gunzTarPerm 438, +396 silly gunzTarPerm 420 ] +397 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/autobahn-server.js +398 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/autobahn-server.js', +398 silly gunzTarPerm 438, +398 silly gunzTarPerm 420 ] +399 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocket.test.js +400 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocket.test.js', +400 silly gunzTarPerm 438, +400 silly gunzTarPerm 420 ] +401 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/hybi-common.js +402 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/hybi-common.js', +402 silly gunzTarPerm 438, +402 silly gunzTarPerm 420 ] +403 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Receiver.hixie.test.js +404 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Receiver.hixie.test.js', +404 silly gunzTarPerm 438, +404 silly gunzTarPerm 420 ] +405 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/BufferPool.test.js +406 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/BufferPool.test.js', +406 silly gunzTarPerm 438, +406 silly gunzTarPerm 420 ] +407 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/autobahn.js +408 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/autobahn.js', +408 silly gunzTarPerm 438, +408 silly gunzTarPerm 420 ] +409 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Sender.test.js +410 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Sender.test.js', +410 silly gunzTarPerm 438, +410 silly gunzTarPerm 420 ] +411 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/testserver.js +412 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/testserver.js', +412 silly gunzTarPerm 438, +412 silly gunzTarPerm 420 ] +413 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Validation.test.js +414 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Validation.test.js', +414 silly gunzTarPerm 438, +414 silly gunzTarPerm 420 ] +415 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocket.integration.js +416 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocket.integration.js', +416 silly gunzTarPerm 438, +416 silly gunzTarPerm 420 ] +417 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Receiver.test.js +418 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Receiver.test.js', +418 silly gunzTarPerm 438, +418 silly gunzTarPerm 420 ] +419 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocketServer.test.js +420 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocketServer.test.js', +420 silly gunzTarPerm 438, +420 silly gunzTarPerm 420 ] +421 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Sender.hixie.test.js +422 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Sender.hixie.test.js', +422 silly gunzTarPerm 438, +422 silly gunzTarPerm 420 ] +423 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/agent1-cert.pem +424 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/agent1-cert.pem', +424 silly gunzTarPerm 438, +424 silly gunzTarPerm 420 ] +425 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/agent1-key.pem +426 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/agent1-key.pem', +426 silly gunzTarPerm 438, +426 silly gunzTarPerm 420 ] +427 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/ca1-cert.pem +428 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/ca1-cert.pem', +428 silly gunzTarPerm 438, +428 silly gunzTarPerm 420 ] +429 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/ca1-key.pem +430 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/ca1-key.pem', +430 silly gunzTarPerm 438, +430 silly gunzTarPerm 420 ] +431 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/certificate.pem +432 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/certificate.pem', +432 silly gunzTarPerm 438, +432 silly gunzTarPerm 420 ] +433 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/key.pem +434 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/key.pem', +434 silly gunzTarPerm 438, +434 silly gunzTarPerm 420 ] +435 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/request.pem +436 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/request.pem', +436 silly gunzTarPerm 438, +436 silly gunzTarPerm 420 ] +437 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/textfile +438 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/textfile', +438 silly gunzTarPerm 438, +438 silly gunzTarPerm 420 ] +439 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/browser.js +440 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/browser.js', +440 silly gunzTarPerm 438, +440 silly gunzTarPerm 420 ] +441 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferUtil.js +442 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferUtil.js', +442 silly gunzTarPerm 438, +442 silly gunzTarPerm 420 ] +443 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/ErrorCodes.js +444 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/ErrorCodes.js', +444 silly gunzTarPerm 438, +444 silly gunzTarPerm 420 ] +445 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.hixie.js +446 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.hixie.js', +446 silly gunzTarPerm 438, +446 silly gunzTarPerm 420 ] +447 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferUtil.fallback.js +448 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferUtil.fallback.js', +448 silly gunzTarPerm 438, +448 silly gunzTarPerm 420 ] +449 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Sender.hixie.js +450 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Sender.hixie.js', +450 silly gunzTarPerm 438, +450 silly gunzTarPerm 420 ] +451 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Sender.js +452 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Sender.js', +452 silly gunzTarPerm 438, +452 silly gunzTarPerm 420 ] +453 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Validation.fallback.js +454 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Validation.fallback.js', +454 silly gunzTarPerm 438, +454 silly gunzTarPerm 420 ] +455 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Validation.js +456 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Validation.js', +456 silly gunzTarPerm 438, +456 silly gunzTarPerm 420 ] +457 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocket.js +458 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocket.js', +458 silly gunzTarPerm 438, +458 silly gunzTarPerm 420 ] +459 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferPool.js +460 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferPool.js', +460 silly gunzTarPerm 438, +460 silly gunzTarPerm 420 ] +461 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocketServer.js +462 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocketServer.js', +462 silly gunzTarPerm 438, +462 silly gunzTarPerm 420 ] +463 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js +464 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js', +464 silly gunzTarPerm 438, +464 silly gunzTarPerm 420 ] +465 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/Makefile +466 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/Makefile', +466 silly gunzTarPerm 438, +466 silly gunzTarPerm 420 ] +467 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/src/bufferutil.cc +468 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/src/bufferutil.cc', +468 silly gunzTarPerm 438, +468 silly gunzTarPerm 420 ] +469 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/src/validation.cc +470 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/src/validation.cc', +470 silly gunzTarPerm 438, +470 silly gunzTarPerm 420 ] +471 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/parser.benchmark.js +472 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/parser.benchmark.js', +472 silly gunzTarPerm 438, +472 silly gunzTarPerm 420 ] +473 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/sender.benchmark.js +474 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/sender.benchmark.js', +474 silly gunzTarPerm 438, +474 silly gunzTarPerm 420 ] +475 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/speed.js +476 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/speed.js', +476 silly gunzTarPerm 438, +476 silly gunzTarPerm 420 ] +477 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/util.js +478 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/util.js', +478 silly gunzTarPerm 438, +478 silly gunzTarPerm 420 ] +479 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bin/wscat +480 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bin/wscat', +480 silly gunzTarPerm 438, +480 silly gunzTarPerm 420 ] +481 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/History.md +482 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/History.md', +482 silly gunzTarPerm 438, +482 silly gunzTarPerm 420 ] +483 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/package.json +484 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/package.json', +484 silly gunzTarPerm 438, +484 silly gunzTarPerm 420 ] +485 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/.npmignore +486 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/.npmignore', +486 silly gunzTarPerm 438, +486 silly gunzTarPerm 420 ] +487 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/index.js +488 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/index.js', +488 silly gunzTarPerm 438, +488 silly gunzTarPerm 420 ] +489 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/.travis.yml +490 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/.travis.yml', +490 silly gunzTarPerm 438, +490 silly gunzTarPerm 420 ] +491 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/History.md +492 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/History.md', +492 silly gunzTarPerm 438, +492 silly gunzTarPerm 420 ] +493 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/lib/commander.js +494 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/lib/commander.js', +494 silly gunzTarPerm 438, +494 silly gunzTarPerm 420 ] +495 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/Makefile +496 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/Makefile', +496 silly gunzTarPerm 438, +496 silly gunzTarPerm 420 ] +497 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/Readme.md +498 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/Readme.md', +498 silly gunzTarPerm 438, +498 silly gunzTarPerm 420 ] +499 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/package.json +500 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/package.json', +500 silly gunzTarPerm 438, +500 silly gunzTarPerm 420 ] +501 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/README.md +502 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/README.md', +502 silly gunzTarPerm 438, +502 silly gunzTarPerm 420 ] +503 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/LICENSE +504 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/LICENSE', +504 silly gunzTarPerm 438, +504 silly gunzTarPerm 420 ] +505 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/.index.js +506 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/.index.js', +506 silly gunzTarPerm 438, +506 silly gunzTarPerm 420 ] +507 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/nan.h +508 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/nan.h', +508 silly gunzTarPerm 438, +508 silly gunzTarPerm 420 ] +509 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/package.json +510 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/package.json', +510 silly gunzTarPerm 438, +510 silly gunzTarPerm 420 ] +511 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/.npmignore +512 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/.npmignore', +512 silly gunzTarPerm 438, +512 silly gunzTarPerm 420 ] +513 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/README.md +514 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/README.md', +514 silly gunzTarPerm 438, +514 silly gunzTarPerm 420 ] +515 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/lib/options.js +516 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/lib/options.js', +516 silly gunzTarPerm 438, +516 silly gunzTarPerm 420 ] +517 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/Makefile +518 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/Makefile', +518 silly gunzTarPerm 438, +518 silly gunzTarPerm 420 ] +519 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/test/options.test.js +520 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/test/options.test.js', +520 silly gunzTarPerm 438, +520 silly gunzTarPerm 420 ] +521 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/test/fixtures/test.conf +522 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/test/fixtures/test.conf', +522 silly gunzTarPerm 438, +522 silly gunzTarPerm 420 ] +523 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/package.json +524 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/package.json', +524 silly gunzTarPerm 438, +524 silly gunzTarPerm 420 ] +525 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/.npmignore +526 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/.npmignore', +526 silly gunzTarPerm 438, +526 silly gunzTarPerm 420 ] +527 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/README.md +528 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/README.md', +528 silly gunzTarPerm 438, +528 silly gunzTarPerm 420 ] +529 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/example.js +530 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/example.js', +530 silly gunzTarPerm 438, +530 silly gunzTarPerm 420 ] +531 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/tinycolor.js +532 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/tinycolor.js', +532 silly gunzTarPerm 438, +532 silly gunzTarPerm 420 ] +533 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/package.json +534 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/package.json', +534 silly gunzTarPerm 438, +534 silly gunzTarPerm 420 ] +535 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/.npmignore +536 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/.npmignore', +536 silly gunzTarPerm 438, +536 silly gunzTarPerm 420 ] +537 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/README.md +538 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/README.md', +538 silly gunzTarPerm 438, +538 silly gunzTarPerm 420 ] +539 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/LICENSE +540 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/LICENSE', +540 silly gunzTarPerm 438, +540 silly gunzTarPerm 420 ] +541 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/index.js +542 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/index.js', +542 silly gunzTarPerm 438, +542 silly gunzTarPerm 420 ] +543 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/test.js +544 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/test.js', +544 silly gunzTarPerm 438, +544 silly gunzTarPerm 420 ] +545 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/Makefile +546 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/Makefile', +546 silly gunzTarPerm 438, +546 silly gunzTarPerm 420 ] +547 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/package.json +548 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/package.json', +548 silly gunzTarPerm 438, +548 silly gunzTarPerm 420 ] +549 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/README.md +550 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/README.md', +550 silly gunzTarPerm 438, +550 silly gunzTarPerm 420 ] +551 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/index.js +552 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/index.js', +552 silly gunzTarPerm 438, +552 silly gunzTarPerm 420 ] +553 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/build/build.js +554 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/build/build.js', +554 silly gunzTarPerm 438, +554 silly gunzTarPerm 420 ] +555 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/component.json +556 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/component.json', +556 silly gunzTarPerm 438, +556 silly gunzTarPerm 420 ] +557 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/package.json +558 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/package.json', +558 silly gunzTarPerm 438, +558 silly gunzTarPerm 420 ] +559 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/.npmignore +560 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/.npmignore', +560 silly gunzTarPerm 438, +560 silly gunzTarPerm 420 ] +561 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/index.js +562 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/index.js', +562 silly gunzTarPerm 438, +562 silly gunzTarPerm 420 ] +563 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/History.md +564 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/History.md', +564 silly gunzTarPerm 438, +564 silly gunzTarPerm 420 ] +565 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/Readme.md +566 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/Readme.md', +566 silly gunzTarPerm 438, +566 silly gunzTarPerm 420 ] +567 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/package.json +568 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/package.json', +568 silly gunzTarPerm 438, +568 silly gunzTarPerm 420 ] +569 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.npmignore +570 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.npmignore', +570 silly gunzTarPerm 438, +570 silly gunzTarPerm 420 ] +571 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/binary.js +572 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/binary.js', +572 silly gunzTarPerm 438, +572 silly gunzTarPerm 420 ] +573 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/index.js +574 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/index.js', +574 silly gunzTarPerm 438, +574 silly gunzTarPerm 420 ] +575 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.travis.yml +576 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.travis.yml', +576 silly gunzTarPerm 438, +576 silly gunzTarPerm 420 ] +577 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.zuul.yml +578 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.zuul.yml', +578 silly gunzTarPerm 438, +578 silly gunzTarPerm 420 ] +579 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/History.md +580 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/History.md', +580 silly gunzTarPerm 438, +580 silly gunzTarPerm 420 ] +581 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/Makefile +582 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/Makefile', +582 silly gunzTarPerm 438, +582 silly gunzTarPerm 420 ] +583 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/Readme.md +584 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/Readme.md', +584 silly gunzTarPerm 438, +584 silly gunzTarPerm 420 ] +585 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/package.json +586 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/package.json', +586 silly gunzTarPerm 438, +586 silly gunzTarPerm 420 ] +587 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/.npmignore +588 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/.npmignore', +588 silly gunzTarPerm 438, +588 silly gunzTarPerm 420 ] +589 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/index.js +590 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/index.js', +590 silly gunzTarPerm 438, +590 silly gunzTarPerm 420 ] +591 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/component.json +592 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/component.json', +592 silly gunzTarPerm 438, +592 silly gunzTarPerm 420 ] +593 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/History.md +594 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/History.md', +594 silly gunzTarPerm 438, +594 silly gunzTarPerm 420 ] +595 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/Makefile +596 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/Makefile', +596 silly gunzTarPerm 438, +596 silly gunzTarPerm 420 ] +597 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/Readme.md +598 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/Readme.md', +598 silly gunzTarPerm 438, +598 silly gunzTarPerm 420 ] +599 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/test/emitter.js +600 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/test/emitter.js', +600 silly gunzTarPerm 438, +600 silly gunzTarPerm 420 ] +601 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/package.json +602 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/package.json', +602 silly gunzTarPerm 438, +602 silly gunzTarPerm 420 ] +603 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/.npmignore +604 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/.npmignore', +604 silly gunzTarPerm 438, +604 silly gunzTarPerm 420 ] +605 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/index.js +606 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/index.js', +606 silly gunzTarPerm 438, +606 silly gunzTarPerm 420 ] +607 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/component.json +608 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/component.json', +608 silly gunzTarPerm 438, +608 silly gunzTarPerm 420 ] +609 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Makefile +610 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Makefile', +610 silly gunzTarPerm 438, +610 silly gunzTarPerm 420 ] +611 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Readme.md +612 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Readme.md', +612 silly gunzTarPerm 438, +612 silly gunzTarPerm 420 ] +613 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/package.json +614 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/package.json', +614 silly gunzTarPerm 438, +614 silly gunzTarPerm 420 ] +615 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/README.md +616 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/README.md', +616 silly gunzTarPerm 438, +616 silly gunzTarPerm 420 ] +617 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/index.js +618 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/index.js', +618 silly gunzTarPerm 438, +618 silly gunzTarPerm 420 ] +619 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/build/build.js +620 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/build/build.js', +620 silly gunzTarPerm 438, +620 silly gunzTarPerm 420 ] +621 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/component.json +622 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/component.json', +622 silly gunzTarPerm 438, +622 silly gunzTarPerm 420 ] +623 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/package.json +624 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/package.json', +624 silly gunzTarPerm 438, +624 silly gunzTarPerm 420 ] +625 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.npmignore +626 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.npmignore', +626 silly gunzTarPerm 438, +626 silly gunzTarPerm 420 ] +627 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/README.md +628 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/README.md', +628 silly gunzTarPerm 438, +628 silly gunzTarPerm 420 ] +629 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/LICENSE +630 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/LICENSE', +630 silly gunzTarPerm 438, +630 silly gunzTarPerm 420 ] +631 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.gitmodules +632 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.gitmodules', +632 silly gunzTarPerm 438, +632 silly gunzTarPerm 420 ] +633 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.jamignore +634 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.jamignore', +634 silly gunzTarPerm 438, +634 silly gunzTarPerm 420 ] +635 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.travis.yml +636 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.travis.yml', +636 silly gunzTarPerm 438, +636 silly gunzTarPerm 420 ] +637 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/coverage.json +638 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/coverage.json', +638 silly gunzTarPerm 438, +638 silly gunzTarPerm 420 ] +639 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.js +640 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.js', +640 silly gunzTarPerm 438, +640 silly gunzTarPerm 420 ] +641 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/lib/json3.js.html +642 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/lib/json3.js.html', +642 silly gunzTarPerm 438, +642 silly gunzTarPerm 420 ] +643 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.css +644 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.css', +644 silly gunzTarPerm 438, +644 silly gunzTarPerm 420 ] +645 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov.info +646 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov.info', +646 silly gunzTarPerm 438, +646 silly gunzTarPerm 420 ] +647 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/lib/json3.js +648 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/lib/json3.js', +648 silly gunzTarPerm 438, +648 silly gunzTarPerm 420 ] +649 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/lib/json3.min.js +650 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/lib/json3.min.js', +650 silly gunzTarPerm 438, +650 silly gunzTarPerm 420 ] +651 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/package.json +652 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/package.json', +652 silly gunzTarPerm 438, +652 silly gunzTarPerm 420 ] +653 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/.npmignore +654 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/.npmignore', +654 silly gunzTarPerm 438, +654 silly gunzTarPerm 420 ] +655 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/README.md +656 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/README.md', +656 silly gunzTarPerm 438, +656 silly gunzTarPerm 420 ] +657 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/index.js +658 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/index.js', +658 silly gunzTarPerm 438, +658 silly gunzTarPerm 420 ] +659 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/socket.io.js +660 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/socket.io.js', +660 silly gunzTarPerm 438, +660 silly gunzTarPerm 420 ] +661 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/History.md +662 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/History.md', +662 silly gunzTarPerm 438, +662 silly gunzTarPerm 420 ] +663 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/.travis.yml +664 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/.travis.yml', +664 silly gunzTarPerm 438, +664 silly gunzTarPerm 420 ] +665 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/Makefile +666 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/Makefile', +666 silly gunzTarPerm 438, +666 silly gunzTarPerm 420 ] +667 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/coverage.json +668 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/coverage.json', +668 silly gunzTarPerm 438, +668 silly gunzTarPerm 420 ] +669 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/prettify.js +670 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/prettify.js', +670 silly gunzTarPerm 438, +670 silly gunzTarPerm 420 ] +671 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/index.html +672 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/index.html', +672 silly gunzTarPerm 438, +672 silly gunzTarPerm 420 ] +673 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/lib/index.html +674 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/lib/index.html', +674 silly gunzTarPerm 438, +674 silly gunzTarPerm 420 ] +675 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/lib/url.js.html +676 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/lib/url.js.html', +676 silly gunzTarPerm 438, +676 silly gunzTarPerm 420 ] +677 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/prettify.css +678 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/prettify.css', +678 silly gunzTarPerm 438, +678 silly gunzTarPerm 420 ] +679 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/index.html +680 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/index.html', +680 silly gunzTarPerm 438, +680 silly gunzTarPerm 420 ] +681 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/index.js.html +682 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/index.js.html', +682 silly gunzTarPerm 438, +682 silly gunzTarPerm 420 ] +683 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/index.html +684 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/index.html', +684 silly gunzTarPerm 438, +684 silly gunzTarPerm 420 ] +685 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/index.js.html +686 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/index.js.html', +686 silly gunzTarPerm 438, +686 silly gunzTarPerm 420 ] +687 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/manager.js.html +688 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/manager.js.html', +688 silly gunzTarPerm 438, +688 silly gunzTarPerm 420 ] +689 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/on.js.html +690 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/on.js.html', +690 silly gunzTarPerm 438, +690 silly gunzTarPerm 420 ] +691 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/socket.js.html +692 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/socket.js.html', +692 silly gunzTarPerm 438, +692 silly gunzTarPerm 420 ] +693 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/url.js.html +694 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/url.js.html', +694 silly gunzTarPerm 438, +694 silly gunzTarPerm 420 ] +695 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov.info +696 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov.info', +696 silly gunzTarPerm 438, +696 silly gunzTarPerm 420 ] +697 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/.zuul.yml +698 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/.zuul.yml', +698 silly gunzTarPerm 438, +698 silly gunzTarPerm 420 ] +699 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/index.js +700 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/index.js', +700 silly gunzTarPerm 438, +700 silly gunzTarPerm 420 ] +701 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/manager.js +702 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/manager.js', +702 silly gunzTarPerm 438, +702 silly gunzTarPerm 420 ] +703 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/on.js +704 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/on.js', +704 silly gunzTarPerm 438, +704 silly gunzTarPerm 420 ] +705 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/socket.js +706 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/socket.js', +706 silly gunzTarPerm 438, +706 silly gunzTarPerm 420 ] +707 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/url.js +708 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/url.js', +708 silly gunzTarPerm 438, +708 silly gunzTarPerm 420 ] +709 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/package.json +710 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/package.json', +710 silly gunzTarPerm 438, +710 silly gunzTarPerm 420 ] +711 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/.npmignore +712 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/.npmignore', +712 silly gunzTarPerm 438, +712 silly gunzTarPerm 420 ] +713 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/index.js +714 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/index.js', +714 silly gunzTarPerm 438, +714 silly gunzTarPerm 420 ] +715 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/component.json +716 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/component.json', +716 silly gunzTarPerm 438, +716 silly gunzTarPerm 420 ] +717 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/History.md +718 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/History.md', +718 silly gunzTarPerm 438, +718 silly gunzTarPerm 420 ] +719 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/Makefile +720 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/Makefile', +720 silly gunzTarPerm 438, +720 silly gunzTarPerm 420 ] +721 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/Readme.md +722 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/Readme.md', +722 silly gunzTarPerm 438, +722 silly gunzTarPerm 420 ] +723 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/package.json +724 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/package.json', +724 silly gunzTarPerm 438, +724 silly gunzTarPerm 420 ] +725 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/.npmignore +726 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/.npmignore', +726 silly gunzTarPerm 438, +726 silly gunzTarPerm 420 ] +727 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/index.js +728 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/index.js', +728 silly gunzTarPerm 438, +728 silly gunzTarPerm 420 ] +729 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/.travis.yml +730 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/.travis.yml', +730 silly gunzTarPerm 438, +730 silly gunzTarPerm 420 ] +731 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/bower.json +732 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/bower.json', +732 silly gunzTarPerm 438, +732 silly gunzTarPerm 420 ] +733 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/component.json +734 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/component.json', +734 silly gunzTarPerm 438, +734 silly gunzTarPerm 420 ] +735 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/History.md +736 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/History.md', +736 silly gunzTarPerm 438, +736 silly gunzTarPerm 420 ] +737 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/Makefile +738 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/Makefile', +738 silly gunzTarPerm 438, +738 silly gunzTarPerm 420 ] +739 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/Readme.md +740 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/Readme.md', +740 silly gunzTarPerm 438, +740 silly gunzTarPerm 420 ] +741 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/package.json +742 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/package.json', +742 silly gunzTarPerm 438, +742 silly gunzTarPerm 420 ] +743 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.npmignore +744 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.npmignore', +744 silly gunzTarPerm 438, +744 silly gunzTarPerm 420 ] +745 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/README.md +746 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/README.md', +746 silly gunzTarPerm 438, +746 silly gunzTarPerm 420 ] +747 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/engine.io.js +748 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/engine.io.js', +748 silly gunzTarPerm 438, +748 silly gunzTarPerm 420 ] +749 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/index.js +750 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/index.js', +750 silly gunzTarPerm 438, +750 silly gunzTarPerm 420 ] +751 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/History.md +752 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/History.md', +752 silly gunzTarPerm 438, +752 silly gunzTarPerm 420 ] +753 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.travis.yml +754 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.travis.yml', +754 silly gunzTarPerm 438, +754 silly gunzTarPerm 420 ] +755 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/index.js +756 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/index.js', +756 silly gunzTarPerm 438, +756 silly gunzTarPerm 420 ] +757 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/socket.js +758 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/socket.js', +758 silly gunzTarPerm 438, +758 silly gunzTarPerm 420 ] +759 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transport.js +760 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transport.js', +760 silly gunzTarPerm 438, +760 silly gunzTarPerm 420 ] +761 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/xmlhttprequest.js +762 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/xmlhttprequest.js', +762 silly gunzTarPerm 438, +762 silly gunzTarPerm 420 ] +763 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/index.js +764 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/index.js', +764 silly gunzTarPerm 438, +764 silly gunzTarPerm 420 ] +765 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling-jsonp.js +766 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling-jsonp.js', +766 silly gunzTarPerm 438, +766 silly gunzTarPerm 420 ] +767 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling-xhr.js +768 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling-xhr.js', +768 silly gunzTarPerm 438, +768 silly gunzTarPerm 420 ] +769 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling.js +770 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling.js', +770 silly gunzTarPerm 438, +770 silly gunzTarPerm 420 ] +771 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/websocket.js +772 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/websocket.js', +772 silly gunzTarPerm 438, +772 silly gunzTarPerm 420 ] +773 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/Makefile +774 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/Makefile', +774 silly gunzTarPerm 438, +774 silly gunzTarPerm 420 ] +775 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.zuul.yml +776 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.zuul.yml', +776 silly gunzTarPerm 438, +776 silly gunzTarPerm 420 ] +777 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/package.json +778 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/package.json', +778 silly gunzTarPerm 438, +778 silly gunzTarPerm 420 ] +779 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/.npmignore +780 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/.npmignore', +780 silly gunzTarPerm 438, +780 silly gunzTarPerm 420 ] +781 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/index.js +782 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/index.js', +782 silly gunzTarPerm 438, +782 silly gunzTarPerm 420 ] +783 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/component.json +784 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/component.json', +784 silly gunzTarPerm 438, +784 silly gunzTarPerm 420 ] +785 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/History.md +786 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/History.md', +786 silly gunzTarPerm 438, +786 silly gunzTarPerm 420 ] +787 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/Makefile +788 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/Makefile', +788 silly gunzTarPerm 438, +788 silly gunzTarPerm 420 ] +789 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/Readme.md +790 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/Readme.md', +790 silly gunzTarPerm 438, +790 silly gunzTarPerm 420 ] +791 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/test/inherit.js +792 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/test/inherit.js', +792 silly gunzTarPerm 438, +792 silly gunzTarPerm 420 ] +793 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/package.json +794 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/package.json', +794 silly gunzTarPerm 438, +794 silly gunzTarPerm 420 ] +795 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.npmignore +796 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.npmignore', +796 silly gunzTarPerm 438, +796 silly gunzTarPerm 420 ] +797 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/LICENSE +798 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/LICENSE', +798 silly gunzTarPerm 438, +798 silly gunzTarPerm 420 ] +799 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/index.js +800 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/index.js', +800 silly gunzTarPerm 438, +800 silly gunzTarPerm 420 ] +801 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/Readme.md +802 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/Readme.md', +802 silly gunzTarPerm 438, +802 silly gunzTarPerm 420 ] +803 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.travis.yml +804 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.travis.yml', +804 silly gunzTarPerm 438, +804 silly gunzTarPerm 420 ] +805 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.zuul.yml +806 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.zuul.yml', +806 silly gunzTarPerm 438, +806 silly gunzTarPerm 420 ] +807 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/Makefile +808 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/Makefile', +808 silly gunzTarPerm 438, +808 silly gunzTarPerm 420 ] +809 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/History.md +810 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/History.md', +810 silly gunzTarPerm 438, +810 silly gunzTarPerm 420 ] +811 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/browser.js +812 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/browser.js', +812 silly gunzTarPerm 438, +812 silly gunzTarPerm 420 ] +813 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/index.js +814 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/index.js', +814 silly gunzTarPerm 438, +814 silly gunzTarPerm 420 ] +815 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/keys.js +816 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/keys.js', +816 silly gunzTarPerm 438, +816 silly gunzTarPerm 420 ] +817 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/package.json +818 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/package.json', +818 silly gunzTarPerm 438, +818 silly gunzTarPerm 420 ] +819 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/.npmignore +820 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/.npmignore', +820 silly gunzTarPerm 438, +820 silly gunzTarPerm 420 ] +821 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/README.md +822 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/README.md', +822 silly gunzTarPerm 438, +822 silly gunzTarPerm 420 ] +823 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/LICENCE +824 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/LICENCE', +824 silly gunzTarPerm 438, +824 silly gunzTarPerm 420 ] +825 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/index.js +826 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/index.js', +826 silly gunzTarPerm 438, +826 silly gunzTarPerm 420 ] +827 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/.travis.yml +828 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/.travis.yml', +828 silly gunzTarPerm 438, +828 silly gunzTarPerm 420 ] +829 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/test/after-test.js +830 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/test/after-test.js', +830 silly gunzTarPerm 438, +830 silly gunzTarPerm 420 ] +831 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/package.json +832 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/package.json', +832 silly gunzTarPerm 438, +832 silly gunzTarPerm 420 ] +833 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/.npmignore +834 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/.npmignore', +834 silly gunzTarPerm 438, +834 silly gunzTarPerm 420 ] +835 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/README.md +836 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/README.md', +836 silly gunzTarPerm 438, +836 silly gunzTarPerm 420 ] +837 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/index.js +838 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/index.js', +838 silly gunzTarPerm 438, +838 silly gunzTarPerm 420 ] +839 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/Makefile +840 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/Makefile', +840 silly gunzTarPerm 438, +840 silly gunzTarPerm 420 ] +841 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/test/slice-buffer.js +842 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/test/slice-buffer.js', +842 silly gunzTarPerm 438, +842 silly gunzTarPerm 420 ] +843 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json +844 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json', +844 silly gunzTarPerm 438, +844 silly gunzTarPerm 420 ] +845 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.npmignore +846 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.npmignore', +846 silly gunzTarPerm 438, +846 silly gunzTarPerm 420 ] +847 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md +848 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md', +848 silly gunzTarPerm 438, +848 silly gunzTarPerm 420 ] +849 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/grunt.js +850 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/grunt.js', +850 silly gunzTarPerm 438, +850 silly gunzTarPerm 420 ] +851 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.travis.yml +852 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.travis.yml', +852 silly gunzTarPerm 438, +852 silly gunzTarPerm 420 ] +853 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js +854 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js', +854 silly gunzTarPerm 438, +854 silly gunzTarPerm 420 ] +855 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/LICENSE-MIT +856 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/LICENSE-MIT', +856 silly gunzTarPerm 438, +856 silly gunzTarPerm 420 ] +857 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json~ +858 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json~', +858 silly gunzTarPerm 438, +858 silly gunzTarPerm 420 ] +859 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md~ +860 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md~', +860 silly gunzTarPerm 438, +860 silly gunzTarPerm 420 ] +861 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js +862 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js', +862 silly gunzTarPerm 438, +862 silly gunzTarPerm 420 ] +863 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/package.json +864 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/package.json', +864 silly gunzTarPerm 438, +864 silly gunzTarPerm 420 ] +865 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/.npmignore +866 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/.npmignore', +866 silly gunzTarPerm 438, +866 silly gunzTarPerm 420 ] +867 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/README.md +868 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/README.md', +868 silly gunzTarPerm 438, +868 silly gunzTarPerm 420 ] +869 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/index.js +870 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/index.js', +870 silly gunzTarPerm 438, +870 silly gunzTarPerm 420 ] +871 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/.zuul.yml +872 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/.zuul.yml', +872 silly gunzTarPerm 438, +872 silly gunzTarPerm 420 ] +873 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/Makefile +874 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/Makefile', +874 silly gunzTarPerm 438, +874 silly gunzTarPerm 420 ] +875 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/test/index.js +876 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/test/index.js', +876 silly gunzTarPerm 438, +876 silly gunzTarPerm 420 ] +877 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/package.json +878 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/package.json', +878 silly gunzTarPerm 438, +878 silly gunzTarPerm 420 ] +879 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.npmignore +880 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.npmignore', +880 silly gunzTarPerm 438, +880 silly gunzTarPerm 420 ] +881 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/README.md +882 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/README.md', +882 silly gunzTarPerm 438, +882 silly gunzTarPerm 420 ] +883 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/x.js +884 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/x.js', +884 silly gunzTarPerm 438, +884 silly gunzTarPerm 420 ] +885 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/Gruntfile.js +886 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/Gruntfile.js', +886 silly gunzTarPerm 438, +886 silly gunzTarPerm 420 ] +887 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/utf8.js +888 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/utf8.js', +888 silly gunzTarPerm 438, +888 silly gunzTarPerm 420 ] +889 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.gitattributes +890 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.gitattributes', +890 silly gunzTarPerm 438, +890 silly gunzTarPerm 420 ] +891 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.travis.yml +892 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.travis.yml', +892 silly gunzTarPerm 438, +892 silly gunzTarPerm 420 ] +893 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/LICENSE-MIT.txt +894 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/LICENSE-MIT.txt', +894 silly gunzTarPerm 438, +894 silly gunzTarPerm 420 ] +895 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/bower.json +896 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/bower.json', +896 silly gunzTarPerm 438, +896 silly gunzTarPerm 420 ] +897 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/component.json +898 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/component.json', +898 silly gunzTarPerm 438, +898 silly gunzTarPerm 420 ] +899 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/tests.js +900 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/tests.js', +900 silly gunzTarPerm 438, +900 silly gunzTarPerm 420 ] +901 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/generate-test-data.py +902 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/generate-test-data.py', +902 silly gunzTarPerm 438, +902 silly gunzTarPerm 420 ] +903 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/index.html +904 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/index.html', +904 silly gunzTarPerm 438, +904 silly gunzTarPerm 420 ] +905 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.js +906 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.js', +906 silly gunzTarPerm 438, +906 silly gunzTarPerm 420 ] +907 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/index.html +908 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/index.html', +908 silly gunzTarPerm 438, +908 silly gunzTarPerm 420 ] +909 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/utf8.js.html +910 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/utf8.js.html', +910 silly gunzTarPerm 438, +910 silly gunzTarPerm 420 ] +911 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/index.html +912 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/index.html', +912 silly gunzTarPerm 438, +912 silly gunzTarPerm 420 ] +913 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.css +914 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.css', +914 silly gunzTarPerm 438, +914 silly gunzTarPerm 420 ] +915 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/LICENSE-GPL.txt +916 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/LICENSE-GPL.txt', +916 silly gunzTarPerm 438, +916 silly gunzTarPerm 420 ] +917 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/package.json +918 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/package.json', +918 silly gunzTarPerm 438, +918 silly gunzTarPerm 420 ] +919 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/.npmignore +920 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/.npmignore', +920 silly gunzTarPerm 438, +920 silly gunzTarPerm 420 ] +921 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/index.js +922 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/index.js', +922 silly gunzTarPerm 438, +922 silly gunzTarPerm 420 ] +923 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/component.json +924 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/component.json', +924 silly gunzTarPerm 438, +924 silly gunzTarPerm 420 ] +925 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/History.md +926 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/History.md', +926 silly gunzTarPerm 438, +926 silly gunzTarPerm 420 ] +927 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/Makefile +928 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/Makefile', +928 silly gunzTarPerm 438, +928 silly gunzTarPerm 420 ] +929 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/Readme.md +930 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/Readme.md', +930 silly gunzTarPerm 438, +930 silly gunzTarPerm 420 ] +931 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/package.json +932 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/package.json', +932 silly gunzTarPerm 438, +932 silly gunzTarPerm 420 ] +933 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/.npmignore +934 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/.npmignore', +934 silly gunzTarPerm 438, +934 silly gunzTarPerm 420 ] +935 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/index.js +936 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/index.js', +936 silly gunzTarPerm 438, +936 silly gunzTarPerm 420 ] +937 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/component.json +938 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/component.json', +938 silly gunzTarPerm 438, +938 silly gunzTarPerm 420 ] +939 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/History.md +940 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/History.md', +940 silly gunzTarPerm 438, +940 silly gunzTarPerm 420 ] +941 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/Makefile +942 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/Makefile', +942 silly gunzTarPerm 438, +942 silly gunzTarPerm 420 ] +943 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/Readme.md +944 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/Readme.md', +944 silly gunzTarPerm 438, +944 silly gunzTarPerm 420 ] +945 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/mocha.js +946 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/mocha.js', +946 silly gunzTarPerm 438, +946 silly gunzTarPerm 420 ] +947 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/test.js +948 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/test.js', +948 silly gunzTarPerm 438, +948 silly gunzTarPerm 420 ] +949 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/index.html +950 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/index.html', +950 silly gunzTarPerm 438, +950 silly gunzTarPerm 420 ] +951 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/mocha.css +952 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/mocha.css', +952 silly gunzTarPerm 438, +952 silly gunzTarPerm 420 ] +953 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/package.json +954 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/package.json', +954 silly gunzTarPerm 438, +954 silly gunzTarPerm 420 ] +955 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/index.js +956 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/index.js', +956 silly gunzTarPerm 438, +956 silly gunzTarPerm 420 ] +957 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/test.js +958 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/test.js', +958 silly gunzTarPerm 438, +958 silly gunzTarPerm 420 ] +959 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/Makefile +960 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/Makefile', +960 silly gunzTarPerm 438, +960 silly gunzTarPerm 420 ] +961 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/package.json +962 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/package.json', +962 silly gunzTarPerm 438, +962 silly gunzTarPerm 420 ] +963 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/.npmignore +964 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/.npmignore', +964 silly gunzTarPerm 438, +964 silly gunzTarPerm 420 ] +965 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/example.js +966 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/example.js', +966 silly gunzTarPerm 438, +966 silly gunzTarPerm 420 ] +967 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/index.js +968 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/index.js', +968 silly gunzTarPerm 438, +968 silly gunzTarPerm 420 ] +969 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/History.md +970 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/History.md', +970 silly gunzTarPerm 438, +970 silly gunzTarPerm 420 ] +971 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/Makefile +972 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/Makefile', +972 silly gunzTarPerm 438, +972 silly gunzTarPerm 420 ] +973 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/Readme.md +974 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/Readme.md', +974 silly gunzTarPerm 438, +974 silly gunzTarPerm 420 ] +975 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/package.json +976 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/package.json', +976 silly gunzTarPerm 438, +976 silly gunzTarPerm 420 ] +977 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/.npmignore +978 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/.npmignore', +978 silly gunzTarPerm 438, +978 silly gunzTarPerm 420 ] +979 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/index.js +980 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/index.js', +980 silly gunzTarPerm 438, +980 silly gunzTarPerm 420 ] +981 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/History.md +982 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/History.md', +982 silly gunzTarPerm 438, +982 silly gunzTarPerm 420 ] +983 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/Makefile +984 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/Makefile', +984 silly gunzTarPerm 438, +984 silly gunzTarPerm 420 ] +985 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/Readme.md +986 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/Readme.md', +986 silly gunzTarPerm 438, +986 silly gunzTarPerm 420 ] +987 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/package.json +988 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/package.json', +988 silly gunzTarPerm 438, +988 silly gunzTarPerm 420 ] +989 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/index.js +990 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/index.js', +990 silly gunzTarPerm 438, +990 silly gunzTarPerm 420 ] +991 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/test.js +992 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/test.js', +992 silly gunzTarPerm 438, +992 silly gunzTarPerm 420 ] +993 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/Makefile +994 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/Makefile', +994 silly gunzTarPerm 438, +994 silly gunzTarPerm 420 ] +995 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/package.json +996 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/package.json', +996 silly gunzTarPerm 438, +996 silly gunzTarPerm 420 ] +997 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/.npmignore +998 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/.npmignore', +998 silly gunzTarPerm 438, +998 silly gunzTarPerm 420 ] +999 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/example.js +1000 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/example.js', +1000 silly gunzTarPerm 438, +1000 silly gunzTarPerm 420 ] +1001 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/index.js +1002 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/index.js', +1002 silly gunzTarPerm 438, +1002 silly gunzTarPerm 420 ] +1003 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/History.md +1004 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/History.md', +1004 silly gunzTarPerm 438, +1004 silly gunzTarPerm 420 ] +1005 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/Makefile +1006 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/Makefile', +1006 silly gunzTarPerm 438, +1006 silly gunzTarPerm 420 ] +1007 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/Readme.md +1008 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/Readme.md', +1008 silly gunzTarPerm 438, +1008 silly gunzTarPerm 420 ] +1009 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/package.json +1010 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/package.json', +1010 silly gunzTarPerm 438, +1010 silly gunzTarPerm 420 ] +1011 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/.npmignore +1012 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/.npmignore', +1012 silly gunzTarPerm 438, +1012 silly gunzTarPerm 420 ] +1013 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/index.js +1014 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/index.js', +1014 silly gunzTarPerm 438, +1014 silly gunzTarPerm 420 ] +1015 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/History.md +1016 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/History.md', +1016 silly gunzTarPerm 438, +1016 silly gunzTarPerm 420 ] +1017 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/Makefile +1018 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/Makefile', +1018 silly gunzTarPerm 438, +1018 silly gunzTarPerm 420 ] +1019 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/Readme.md +1020 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/Readme.md', +1020 silly gunzTarPerm 438, +1020 silly gunzTarPerm 420 ] +1021 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/package.json +1022 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/package.json', +1022 silly gunzTarPerm 438, +1022 silly gunzTarPerm 420 ] +1023 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/.npmignore +1024 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/.npmignore', +1024 silly gunzTarPerm 438, +1024 silly gunzTarPerm 420 ] +1025 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/README.md +1026 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/README.md', +1026 silly gunzTarPerm 438, +1026 silly gunzTarPerm 420 ] +1027 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/index.js +1028 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/index.js', +1028 silly gunzTarPerm 438, +1028 silly gunzTarPerm 420 ] +1029 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/binding.gyp +1030 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/binding.gyp', +1030 silly gunzTarPerm 438, +1030 silly gunzTarPerm 420 ] +1031 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/builderror.log +1032 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/builderror.log', +1032 silly gunzTarPerm 438, +1032 silly gunzTarPerm 420 ] +1033 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/doc/ws.md +1034 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/doc/ws.md', +1034 silly gunzTarPerm 438, +1034 silly gunzTarPerm 420 ] +1035 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/ssl.js +1036 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/ssl.js', +1036 silly gunzTarPerm 438, +1036 silly gunzTarPerm 420 ] +1037 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/package.json +1038 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/package.json', +1038 silly gunzTarPerm 438, +1038 silly gunzTarPerm 420 ] +1039 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/.npmignore +1040 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/.npmignore', +1040 silly gunzTarPerm 438, +1040 silly gunzTarPerm 420 ] +1041 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/server.js +1042 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/server.js', +1042 silly gunzTarPerm 438, +1042 silly gunzTarPerm 420 ] +1043 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/app.js +1044 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/app.js', +1044 silly gunzTarPerm 438, +1044 silly gunzTarPerm 420 ] +1045 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/uploader.js +1046 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/uploader.js', +1046 silly gunzTarPerm 438, +1046 silly gunzTarPerm 420 ] +1047 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/index.html +1048 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/index.html', +1048 silly gunzTarPerm 438, +1048 silly gunzTarPerm 420 ] +1049 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/package.json +1050 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/package.json', +1050 silly gunzTarPerm 438, +1050 silly gunzTarPerm 420 ] +1051 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/server.js +1052 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/server.js', +1052 silly gunzTarPerm 438, +1052 silly gunzTarPerm 420 ] +1053 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/public/index.html +1054 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/public/index.html', +1054 silly gunzTarPerm 438, +1054 silly gunzTarPerm 420 ] +1055 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/package.json +1056 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/package.json', +1056 silly gunzTarPerm 438, +1056 silly gunzTarPerm 420 ] +1057 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/server.js +1058 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/server.js', +1058 silly gunzTarPerm 438, +1058 silly gunzTarPerm 420 ] +1059 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/public/index.html +1060 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/public/index.html', +1060 silly gunzTarPerm 438, +1060 silly gunzTarPerm 420 ] +1061 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/.travis.yml +1062 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/.travis.yml', +1062 silly gunzTarPerm 438, +1062 silly gunzTarPerm 420 ] +1063 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/autobahn-server.js +1064 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/autobahn-server.js', +1064 silly gunzTarPerm 438, +1064 silly gunzTarPerm 420 ] +1065 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocket.test.js +1066 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocket.test.js', +1066 silly gunzTarPerm 438, +1066 silly gunzTarPerm 420 ] +1067 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/hybi-common.js +1068 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/hybi-common.js', +1068 silly gunzTarPerm 438, +1068 silly gunzTarPerm 420 ] +1069 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Receiver.hixie.test.js +1070 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Receiver.hixie.test.js', +1070 silly gunzTarPerm 438, +1070 silly gunzTarPerm 420 ] +1071 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/BufferPool.test.js +1072 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/BufferPool.test.js', +1072 silly gunzTarPerm 438, +1072 silly gunzTarPerm 420 ] +1073 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/autobahn.js +1074 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/autobahn.js', +1074 silly gunzTarPerm 438, +1074 silly gunzTarPerm 420 ] +1075 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Sender.test.js +1076 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Sender.test.js', +1076 silly gunzTarPerm 438, +1076 silly gunzTarPerm 420 ] +1077 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/testserver.js +1078 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/testserver.js', +1078 silly gunzTarPerm 438, +1078 silly gunzTarPerm 420 ] +1079 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Validation.test.js +1080 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Validation.test.js', +1080 silly gunzTarPerm 438, +1080 silly gunzTarPerm 420 ] +1081 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocket.integration.js +1082 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocket.integration.js', +1082 silly gunzTarPerm 438, +1082 silly gunzTarPerm 420 ] +1083 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Receiver.test.js +1084 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Receiver.test.js', +1084 silly gunzTarPerm 438, +1084 silly gunzTarPerm 420 ] +1085 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocketServer.test.js +1086 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocketServer.test.js', +1086 silly gunzTarPerm 438, +1086 silly gunzTarPerm 420 ] +1087 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Sender.hixie.test.js +1088 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Sender.hixie.test.js', +1088 silly gunzTarPerm 438, +1088 silly gunzTarPerm 420 ] +1089 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/agent1-cert.pem +1090 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/agent1-cert.pem', +1090 silly gunzTarPerm 438, +1090 silly gunzTarPerm 420 ] +1091 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/agent1-key.pem +1092 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/agent1-key.pem', +1092 silly gunzTarPerm 438, +1092 silly gunzTarPerm 420 ] +1093 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/ca1-cert.pem +1094 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/ca1-cert.pem', +1094 silly gunzTarPerm 438, +1094 silly gunzTarPerm 420 ] +1095 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/ca1-key.pem +1096 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/ca1-key.pem', +1096 silly gunzTarPerm 438, +1096 silly gunzTarPerm 420 ] +1097 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/certificate.pem +1098 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/certificate.pem', +1098 silly gunzTarPerm 438, +1098 silly gunzTarPerm 420 ] +1099 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/key.pem +1100 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/key.pem', +1100 silly gunzTarPerm 438, +1100 silly gunzTarPerm 420 ] +1101 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/request.pem +1102 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/request.pem', +1102 silly gunzTarPerm 438, +1102 silly gunzTarPerm 420 ] +1103 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/textfile +1104 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/textfile', +1104 silly gunzTarPerm 438, +1104 silly gunzTarPerm 420 ] +1105 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/browser.js +1106 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/browser.js', +1106 silly gunzTarPerm 438, +1106 silly gunzTarPerm 420 ] +1107 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferUtil.js +1108 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferUtil.js', +1108 silly gunzTarPerm 438, +1108 silly gunzTarPerm 420 ] +1109 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/ErrorCodes.js +1110 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/ErrorCodes.js', +1110 silly gunzTarPerm 438, +1110 silly gunzTarPerm 420 ] +1111 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Receiver.hixie.js +1112 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Receiver.hixie.js', +1112 silly gunzTarPerm 438, +1112 silly gunzTarPerm 420 ] +1113 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferUtil.fallback.js +1114 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferUtil.fallback.js', +1114 silly gunzTarPerm 438, +1114 silly gunzTarPerm 420 ] +1115 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Sender.hixie.js +1116 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Sender.hixie.js', +1116 silly gunzTarPerm 438, +1116 silly gunzTarPerm 420 ] +1117 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Sender.js +1118 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Sender.js', +1118 silly gunzTarPerm 438, +1118 silly gunzTarPerm 420 ] +1119 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Validation.fallback.js +1120 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Validation.fallback.js', +1120 silly gunzTarPerm 438, +1120 silly gunzTarPerm 420 ] +1121 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Validation.js +1122 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Validation.js', +1122 silly gunzTarPerm 438, +1122 silly gunzTarPerm 420 ] +1123 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/WebSocket.js +1124 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/WebSocket.js', +1124 silly gunzTarPerm 438, +1124 silly gunzTarPerm 420 ] +1125 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferPool.js +1126 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferPool.js', +1126 silly gunzTarPerm 438, +1126 silly gunzTarPerm 420 ] +1127 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/WebSocketServer.js +1128 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/WebSocketServer.js', +1128 silly gunzTarPerm 438, +1128 silly gunzTarPerm 420 ] +1129 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Receiver.js +1130 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Receiver.js', +1130 silly gunzTarPerm 438, +1130 silly gunzTarPerm 420 ] +1131 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/Makefile +1132 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/Makefile', +1132 silly gunzTarPerm 438, +1132 silly gunzTarPerm 420 ] +1133 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/src/bufferutil.cc +1134 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/src/bufferutil.cc', +1134 silly gunzTarPerm 438, +1134 silly gunzTarPerm 420 ] +1135 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/src/validation.cc +1136 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/src/validation.cc', +1136 silly gunzTarPerm 438, +1136 silly gunzTarPerm 420 ] +1137 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/parser.benchmark.js +1138 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/parser.benchmark.js', +1138 silly gunzTarPerm 438, +1138 silly gunzTarPerm 420 ] +1139 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/sender.benchmark.js +1140 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/sender.benchmark.js', +1140 silly gunzTarPerm 438, +1140 silly gunzTarPerm 420 ] +1141 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/speed.js +1142 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/speed.js', +1142 silly gunzTarPerm 438, +1142 silly gunzTarPerm 420 ] +1143 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/util.js +1144 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/util.js', +1144 silly gunzTarPerm 438, +1144 silly gunzTarPerm 420 ] +1145 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bin/wscat +1146 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bin/wscat', +1146 silly gunzTarPerm 438, +1146 silly gunzTarPerm 420 ] +1147 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/History.md +1148 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/History.md', +1148 silly gunzTarPerm 438, +1148 silly gunzTarPerm 420 ] +1149 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/package.json +1150 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/package.json', +1150 silly gunzTarPerm 438, +1150 silly gunzTarPerm 420 ] +1151 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/.npmignore +1152 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/.npmignore', +1152 silly gunzTarPerm 438, +1152 silly gunzTarPerm 420 ] +1153 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/index.js +1154 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/index.js', +1154 silly gunzTarPerm 438, +1154 silly gunzTarPerm 420 ] +1155 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/.travis.yml +1156 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/.travis.yml', +1156 silly gunzTarPerm 438, +1156 silly gunzTarPerm 420 ] +1157 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/History.md +1158 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/History.md', +1158 silly gunzTarPerm 438, +1158 silly gunzTarPerm 420 ] +1159 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/lib/commander.js +1160 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/lib/commander.js', +1160 silly gunzTarPerm 438, +1160 silly gunzTarPerm 420 ] +1161 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/Makefile +1162 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/Makefile', +1162 silly gunzTarPerm 438, +1162 silly gunzTarPerm 420 ] +1163 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/Readme.md +1164 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/Readme.md', +1164 silly gunzTarPerm 438, +1164 silly gunzTarPerm 420 ] +1165 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/package.json +1166 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/package.json', +1166 silly gunzTarPerm 438, +1166 silly gunzTarPerm 420 ] +1167 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/README.md +1168 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/README.md', +1168 silly gunzTarPerm 438, +1168 silly gunzTarPerm 420 ] +1169 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/LICENSE +1170 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/LICENSE', +1170 silly gunzTarPerm 438, +1170 silly gunzTarPerm 420 ] +1171 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/.index.js +1172 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/.index.js', +1172 silly gunzTarPerm 438, +1172 silly gunzTarPerm 420 ] +1173 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/nan.h +1174 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/nan.h', +1174 silly gunzTarPerm 438, +1174 silly gunzTarPerm 420 ] +1175 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/package.json +1176 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/package.json', +1176 silly gunzTarPerm 438, +1176 silly gunzTarPerm 420 ] +1177 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/.npmignore +1178 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/.npmignore', +1178 silly gunzTarPerm 438, +1178 silly gunzTarPerm 420 ] +1179 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/README.md +1180 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/README.md', +1180 silly gunzTarPerm 438, +1180 silly gunzTarPerm 420 ] +1181 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/lib/options.js +1182 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/lib/options.js', +1182 silly gunzTarPerm 438, +1182 silly gunzTarPerm 420 ] +1183 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/Makefile +1184 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/Makefile', +1184 silly gunzTarPerm 438, +1184 silly gunzTarPerm 420 ] +1185 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/test/options.test.js +1186 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/test/options.test.js', +1186 silly gunzTarPerm 438, +1186 silly gunzTarPerm 420 ] +1187 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/test/fixtures/test.conf +1188 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/test/fixtures/test.conf', +1188 silly gunzTarPerm 438, +1188 silly gunzTarPerm 420 ] +1189 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/package.json +1190 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/package.json', +1190 silly gunzTarPerm 438, +1190 silly gunzTarPerm 420 ] +1191 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/.npmignore +1192 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/.npmignore', +1192 silly gunzTarPerm 438, +1192 silly gunzTarPerm 420 ] +1193 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/README.md +1194 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/README.md', +1194 silly gunzTarPerm 438, +1194 silly gunzTarPerm 420 ] +1195 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/example.js +1196 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/example.js', +1196 silly gunzTarPerm 438, +1196 silly gunzTarPerm 420 ] +1197 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/tinycolor.js +1198 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/tinycolor.js', +1198 silly gunzTarPerm 438, +1198 silly gunzTarPerm 420 ] +1199 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/package.json +1200 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/package.json', +1200 silly gunzTarPerm 438, +1200 silly gunzTarPerm 420 ] +1201 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/README.md +1202 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/README.md', +1202 silly gunzTarPerm 438, +1202 silly gunzTarPerm 420 ] +1203 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/LICENSE +1204 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/LICENSE', +1204 silly gunzTarPerm 438, +1204 silly gunzTarPerm 420 ] +1205 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/autotest.watchr +1206 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/autotest.watchr', +1206 silly gunzTarPerm 438, +1206 silly gunzTarPerm 420 ] +1207 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/example/demo.js +1208 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/example/demo.js', +1208 silly gunzTarPerm 438, +1208 silly gunzTarPerm 420 ] +1209 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/lib/XMLHttpRequest.js +1210 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/lib/XMLHttpRequest.js', +1210 silly gunzTarPerm 438, +1210 silly gunzTarPerm 420 ] +1211 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-constants.js +1212 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-constants.js', +1212 silly gunzTarPerm 438, +1212 silly gunzTarPerm 420 ] +1213 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-events.js +1214 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-events.js', +1214 silly gunzTarPerm 438, +1214 silly gunzTarPerm 420 ] +1215 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-exceptions.js +1216 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-exceptions.js', +1216 silly gunzTarPerm 438, +1216 silly gunzTarPerm 420 ] +1217 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-headers.js +1218 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-headers.js', +1218 silly gunzTarPerm 438, +1218 silly gunzTarPerm 420 ] +1219 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-302.js +1220 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-302.js', +1220 silly gunzTarPerm 438, +1220 silly gunzTarPerm 420 ] +1221 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-303.js +1222 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-303.js', +1222 silly gunzTarPerm 438, +1222 silly gunzTarPerm 420 ] +1223 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-307.js +1224 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-307.js', +1224 silly gunzTarPerm 438, +1224 silly gunzTarPerm 420 ] +1225 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-request-methods.js +1226 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-request-methods.js', +1226 silly gunzTarPerm 438, +1226 silly gunzTarPerm 420 ] +1227 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-request-protocols.js +1228 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-request-protocols.js', +1228 silly gunzTarPerm 438, +1228 silly gunzTarPerm 420 ] +1229 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/testdata.txt +1230 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/testdata.txt', +1230 silly gunzTarPerm 438, +1230 silly gunzTarPerm 420 ] +1231 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/package.json +1232 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/package.json', +1232 silly gunzTarPerm 438, +1232 silly gunzTarPerm 420 ] +1233 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/.npmignore +1234 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/.npmignore', +1234 silly gunzTarPerm 438, +1234 silly gunzTarPerm 420 ] +1235 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/index.js +1236 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/index.js', +1236 silly gunzTarPerm 438, +1236 silly gunzTarPerm 420 ] +1237 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/component.json +1238 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/component.json', +1238 silly gunzTarPerm 438, +1238 silly gunzTarPerm 420 ] +1239 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/Makefile +1240 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/Makefile', +1240 silly gunzTarPerm 438, +1240 silly gunzTarPerm 420 ] +1241 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/Readme.md +1242 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/Readme.md', +1242 silly gunzTarPerm 438, +1242 silly gunzTarPerm 420 ] +1243 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/package.json +1244 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/package.json', +1244 silly gunzTarPerm 438, +1244 silly gunzTarPerm 420 ] +1245 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/.npmignore +1246 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/.npmignore', +1246 silly gunzTarPerm 438, +1246 silly gunzTarPerm 420 ] +1247 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/index.js +1248 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/index.js', +1248 silly gunzTarPerm 438, +1248 silly gunzTarPerm 420 ] +1249 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/component.json +1250 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/component.json', +1250 silly gunzTarPerm 438, +1250 silly gunzTarPerm 420 ] +1251 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/History.md +1252 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/History.md', +1252 silly gunzTarPerm 438, +1252 silly gunzTarPerm 420 ] +1253 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/Makefile +1254 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/Makefile', +1254 silly gunzTarPerm 438, +1254 silly gunzTarPerm 420 ] +1255 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/Readme.md +1256 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/Readme.md', +1256 silly gunzTarPerm 438, +1256 silly gunzTarPerm 420 ] +1257 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/test/object.js +1258 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/test/object.js', +1258 silly gunzTarPerm 438, +1258 silly gunzTarPerm 420 ] +1259 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/package.json +1260 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/package.json', +1260 silly gunzTarPerm 438, +1260 silly gunzTarPerm 420 ] +1261 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/index.js +1262 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/index.js', +1262 silly gunzTarPerm 438, +1262 silly gunzTarPerm 420 ] +1263 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/test.js +1264 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/test.js', +1264 silly gunzTarPerm 438, +1264 silly gunzTarPerm 420 ] +1265 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/History.md +1266 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/History.md', +1266 silly gunzTarPerm 438, +1266 silly gunzTarPerm 420 ] +1267 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/Makefile +1268 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/Makefile', +1268 silly gunzTarPerm 438, +1268 silly gunzTarPerm 420 ] +1269 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/package.json +1270 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/package.json', +1270 silly gunzTarPerm 438, +1270 silly gunzTarPerm 420 ] +1271 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/.npmignore +1272 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/.npmignore', +1272 silly gunzTarPerm 438, +1272 silly gunzTarPerm 420 ] +1273 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/example.js +1274 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/example.js', +1274 silly gunzTarPerm 438, +1274 silly gunzTarPerm 420 ] +1275 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/index.js +1276 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/index.js', +1276 silly gunzTarPerm 438, +1276 silly gunzTarPerm 420 ] +1277 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/History.md +1278 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/History.md', +1278 silly gunzTarPerm 438, +1278 silly gunzTarPerm 420 ] +1279 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/Makefile +1280 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/Makefile', +1280 silly gunzTarPerm 438, +1280 silly gunzTarPerm 420 ] +1281 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/Readme.md +1282 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/Readme.md', +1282 silly gunzTarPerm 438, +1282 silly gunzTarPerm 420 ] +1283 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/package.json +1284 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/package.json', +1284 silly gunzTarPerm 438, +1284 silly gunzTarPerm 420 ] +1285 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/.npmignore +1286 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/.npmignore', +1286 silly gunzTarPerm 438, +1286 silly gunzTarPerm 420 ] +1287 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/index.js +1288 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/index.js', +1288 silly gunzTarPerm 438, +1288 silly gunzTarPerm 420 ] +1289 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/History.md +1290 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/History.md', +1290 silly gunzTarPerm 438, +1290 silly gunzTarPerm 420 ] +1291 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/Makefile +1292 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/Makefile', +1292 silly gunzTarPerm 438, +1292 silly gunzTarPerm 420 ] +1293 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/Readme.md +1294 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/Readme.md', +1294 silly gunzTarPerm 438, +1294 silly gunzTarPerm 420 ] +1295 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/package.json +1296 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/package.json', +1296 silly gunzTarPerm 438, +1296 silly gunzTarPerm 420 ] +1297 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/.npmignore +1298 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/.npmignore', +1298 silly gunzTarPerm 438, +1298 silly gunzTarPerm 420 ] +1299 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/README.md +1300 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/README.md', +1300 silly gunzTarPerm 438, +1300 silly gunzTarPerm 420 ] +1301 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/LICENCE +1302 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/LICENCE', +1302 silly gunzTarPerm 438, +1302 silly gunzTarPerm 420 ] +1303 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/index.js +1304 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/index.js', +1304 silly gunzTarPerm 438, +1304 silly gunzTarPerm 420 ] +1305 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/package.json +1306 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/package.json', +1306 silly gunzTarPerm 438, +1306 silly gunzTarPerm 420 ] +1307 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/.npmignore +1308 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/.npmignore', +1308 silly gunzTarPerm 438, +1308 silly gunzTarPerm 420 ] +1309 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/binary.js +1310 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/binary.js', +1310 silly gunzTarPerm 438, +1310 silly gunzTarPerm 420 ] +1311 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/index.js +1312 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/index.js', +1312 silly gunzTarPerm 438, +1312 silly gunzTarPerm 420 ] +1313 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/.travis.yml +1314 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/.travis.yml', +1314 silly gunzTarPerm 438, +1314 silly gunzTarPerm 420 ] +1315 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/.zuul.yml +1316 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/.zuul.yml', +1316 silly gunzTarPerm 438, +1316 silly gunzTarPerm 420 ] +1317 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/History.md +1318 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/History.md', +1318 silly gunzTarPerm 438, +1318 silly gunzTarPerm 420 ] +1319 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/Makefile +1320 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/Makefile', +1320 silly gunzTarPerm 438, +1320 silly gunzTarPerm 420 ] +1321 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/Readme.md +1322 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/Readme.md', +1322 silly gunzTarPerm 438, +1322 silly gunzTarPerm 420 ] +1323 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/package.json +1324 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/package.json', +1324 silly gunzTarPerm 438, +1324 silly gunzTarPerm 420 ] +1325 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/.npmignore +1326 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/.npmignore', +1326 silly gunzTarPerm 438, +1326 silly gunzTarPerm 420 ] +1327 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/index.js +1328 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/index.js', +1328 silly gunzTarPerm 438, +1328 silly gunzTarPerm 420 ] +1329 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/component.json +1330 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/component.json', +1330 silly gunzTarPerm 438, +1330 silly gunzTarPerm 420 ] +1331 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/History.md +1332 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/History.md', +1332 silly gunzTarPerm 438, +1332 silly gunzTarPerm 420 ] +1333 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/Makefile +1334 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/Makefile', +1334 silly gunzTarPerm 438, +1334 silly gunzTarPerm 420 ] +1335 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/Readme.md +1336 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/Readme.md', +1336 silly gunzTarPerm 438, +1336 silly gunzTarPerm 420 ] +1337 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/test/emitter.js +1338 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/test/emitter.js', +1338 silly gunzTarPerm 438, +1338 silly gunzTarPerm 420 ] +1339 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/package.json +1340 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/package.json', +1340 silly gunzTarPerm 438, +1340 silly gunzTarPerm 420 ] +1341 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/.npmignore +1342 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/.npmignore', +1342 silly gunzTarPerm 438, +1342 silly gunzTarPerm 420 ] +1343 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/index.js +1344 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/index.js', +1344 silly gunzTarPerm 438, +1344 silly gunzTarPerm 420 ] +1345 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/component.json +1346 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/component.json', +1346 silly gunzTarPerm 438, +1346 silly gunzTarPerm 420 ] +1347 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Makefile +1348 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Makefile', +1348 silly gunzTarPerm 438, +1348 silly gunzTarPerm 420 ] +1349 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Readme.md +1350 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Readme.md', +1350 silly gunzTarPerm 438, +1350 silly gunzTarPerm 420 ] +1351 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/package.json +1352 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/package.json', +1352 silly gunzTarPerm 438, +1352 silly gunzTarPerm 420 ] +1353 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/README.md +1354 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/README.md', +1354 silly gunzTarPerm 438, +1354 silly gunzTarPerm 420 ] +1355 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/index.js +1356 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/index.js', +1356 silly gunzTarPerm 438, +1356 silly gunzTarPerm 420 ] +1357 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/build/build.js +1358 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/build/build.js', +1358 silly gunzTarPerm 438, +1358 silly gunzTarPerm 420 ] +1359 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/component.json +1360 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/component.json', +1360 silly gunzTarPerm 438, +1360 silly gunzTarPerm 420 ] +1361 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/package.json +1362 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/package.json', +1362 silly gunzTarPerm 438, +1362 silly gunzTarPerm 420 ] +1363 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.npmignore +1364 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.npmignore', +1364 silly gunzTarPerm 438, +1364 silly gunzTarPerm 420 ] +1365 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/README.md +1366 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/README.md', +1366 silly gunzTarPerm 438, +1366 silly gunzTarPerm 420 ] +1367 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/LICENSE +1368 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/LICENSE', +1368 silly gunzTarPerm 438, +1368 silly gunzTarPerm 420 ] +1369 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.gitmodules +1370 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.gitmodules', +1370 silly gunzTarPerm 438, +1370 silly gunzTarPerm 420 ] +1371 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.jamignore +1372 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.jamignore', +1372 silly gunzTarPerm 438, +1372 silly gunzTarPerm 420 ] +1373 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.travis.yml +1374 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.travis.yml', +1374 silly gunzTarPerm 438, +1374 silly gunzTarPerm 420 ] +1375 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/coverage.json +1376 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/coverage.json', +1376 silly gunzTarPerm 438, +1376 silly gunzTarPerm 420 ] +1377 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.js +1378 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.js', +1378 silly gunzTarPerm 438, +1378 silly gunzTarPerm 420 ] +1379 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/lib/json3.js.html +1380 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/lib/json3.js.html', +1380 silly gunzTarPerm 438, +1380 silly gunzTarPerm 420 ] +1381 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.css +1382 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.css', +1382 silly gunzTarPerm 438, +1382 silly gunzTarPerm 420 ] +1383 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov.info +1384 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov.info', +1384 silly gunzTarPerm 438, +1384 silly gunzTarPerm 420 ] +1385 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/lib/json3.js +1386 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/lib/json3.js', +1386 silly gunzTarPerm 438, +1386 silly gunzTarPerm 420 ] +1387 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/lib/json3.min.js +1388 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/lib/json3.min.js', +1388 silly gunzTarPerm 438, +1388 silly gunzTarPerm 420 ] +1389 silly gunzTarPerm extractEntry Readme.md +1390 silly gunzTarPerm modified mode [ 'Readme.md', 438, 420 ] +1391 verbose read json C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package\package.json +1392 silly lockFile 33aa78c8-55041-0-2732422589324415-package C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package +1393 silly lockFile 33aa78c8-55041-0-2732422589324415-package C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package +1394 silly lockFile 40fef38d-55041-0-2732422589324415-tmp-tgz C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz +1395 silly lockFile 40fef38d-55041-0-2732422589324415-tmp-tgz C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\tmp.tgz +1396 verbose from cache C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package\package.json +1397 verbose tar pack [ 'C:\\Users\\syhu\\AppData\\Roaming\\npm-cache\\vast.js\\0.0.1-2\\package.tgz', +1397 verbose tar pack 'C:\\Users\\syhu\\AppData\\Local\\Temp\\npm-6044\\1408350555041-0.2732422589324415\\package' ] +1398 verbose tarball C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +1399 verbose folder C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package +1400 silly lockFile 33aa78c8-55041-0-2732422589324415-package C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package +1401 verbose lock C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package C:\Users\syhu\AppData\Roaming\npm-cache\33aa78c8-55041-0-2732422589324415-package.lock +1402 silly lockFile 1d6723ff-ache-vast-js-0-0-1-2-package-tgz C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +1403 verbose lock C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz C:\Users\syhu\AppData\Roaming\npm-cache\1d6723ff-ache-vast-js-0-0-1-2-package-tgz.lock +1404 silly lockFile 33aa78c8-55041-0-2732422589324415-package C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package +1405 silly lockFile 33aa78c8-55041-0-2732422589324415-package C:\Users\syhu\AppData\Local\Temp\npm-6044\1408350555041-0.2732422589324415\package +1406 silly lockFile 1d6723ff-ache-vast-js-0-0-1-2-package-tgz C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +1407 silly lockFile 1d6723ff-ache-vast-js-0-0-1-2-package-tgz C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +1408 silly lockFile 85695f29-pm-cache-vast-js-0-0-1-2-package C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package +1409 verbose lock C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package C:\Users\syhu\AppData\Roaming\npm-cache\85695f29-pm-cache-vast-js-0-0-1-2-package.lock +1410 silly lockFile 85695f29-pm-cache-vast-js-0-0-1-2-package C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package +1411 silly lockFile 85695f29-pm-cache-vast-js-0-0-1-2-package C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package +1412 verbose tar unpack C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +1413 silly lockFile 85695f29-pm-cache-vast-js-0-0-1-2-package C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package +1414 verbose lock C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package C:\Users\syhu\AppData\Roaming\npm-cache\85695f29-pm-cache-vast-js-0-0-1-2-package.lock +1415 silly lockFile 1d6723ff-ache-vast-js-0-0-1-2-package-tgz C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +1416 verbose lock C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz C:\Users\syhu\AppData\Roaming\npm-cache\1d6723ff-ache-vast-js-0-0-1-2-package-tgz.lock +1417 silly gunzTarPerm modes [ '755', '644' ] +1418 silly gunzTarPerm extractEntry package.json +1419 silly gunzTarPerm modified mode [ 'package.json', 438, 420 ] +1420 silly gunzTarPerm extractEntry .npmignore +1421 silly gunzTarPerm modified mode [ '.npmignore', 438, 420 ] +1422 silly gunzTarPerm extractEntry LICENSE +1423 silly gunzTarPerm modified mode [ 'LICENSE', 438, 420 ] +1424 silly gunzTarPerm extractEntry index.js +1425 silly gunzTarPerm modified mode [ 'index.js', 438, 420 ] +1426 silly gunzTarPerm extractEntry doc/misc/common_util.js +1427 silly gunzTarPerm modified mode [ 'doc/misc/common_util.js', 438, 420 ] +1428 silly gunzTarPerm extractEntry doc/misc/generic_net.js +1429 silly gunzTarPerm modified mode [ 'doc/misc/generic_net.js', 438, 420 ] +1430 silly gunzTarPerm extractEntry doc/misc/hash.js +1431 silly gunzTarPerm modified mode [ 'doc/misc/hash.js', 438, 420 ] +1432 silly gunzTarPerm extractEntry doc/misc/stable-proxy.js +1433 silly gunzTarPerm modified mode [ 'doc/misc/stable-proxy.js', 438, 420 ] +1434 silly gunzTarPerm extractEntry doc/misc/tools.js +1435 silly gunzTarPerm modified mode [ 'doc/misc/tools.js', 438, 420 ] +1436 silly gunzTarPerm extractEntry doc/misc/line2d.java +1437 silly gunzTarPerm modified mode [ 'doc/misc/line2d.java', 438, 420 ] +1438 silly gunzTarPerm extractEntry doc/misc/SFVoronoi.java +1439 silly gunzTarPerm modified mode [ 'doc/misc/SFVoronoi.java', 438, 420 ] +1440 silly gunzTarPerm extractEntry doc/VAST.js architecture.txt +1441 silly gunzTarPerm modified mode [ 'doc/VAST.js architecture.txt', 438, 420 ] +1442 silly gunzTarPerm extractEntry History.md +1443 silly gunzTarPerm modified mode [ 'History.md', 438, 420 ] +1444 silly gunzTarPerm extractEntry lib/index.js +1445 silly gunzTarPerm modified mode [ 'lib/index.js', 438, 420 ] +1446 silly gunzTarPerm extractEntry lib/original/README.md +1447 silly gunzTarPerm modified mode [ 'lib/original/README.md', 438, 420 ] +1448 silly gunzTarPerm extractEntry lib/original/wz_jsgraphics.js +1449 silly gunzTarPerm modified mode [ 'lib/original/wz_jsgraphics.js', 438, 420 ] +1450 silly gunzTarPerm extractEntry lib/original/voronoi.js +1451 silly gunzTarPerm modified mode [ 'lib/original/voronoi.js', 438, 420 ] +1452 silly gunzTarPerm extractEntry lib/original/VON_peer.js +1453 silly gunzTarPerm modified mode [ 'lib/original/VON_peer.js', 438, 420 ] +1454 silly gunzTarPerm extractEntry lib/original/rhill-voronoi-core-min.js +1455 silly gunzTarPerm modified mode [ 'lib/original/rhill-voronoi-core-min.js', 438, 420 ] +1456 silly gunzTarPerm extractEntry lib/original/move_cluster.js +1457 silly gunzTarPerm modified mode [ 'lib/original/move_cluster.js', 438, 420 ] +1458 silly gunzTarPerm extractEntry lib/original/sf_voronoi.js +1459 silly gunzTarPerm modified mode [ 'lib/original/sf_voronoi.js', 438, 420 ] +1460 silly gunzTarPerm extractEntry lib/original/vast_voro.js +1461 silly gunzTarPerm modified mode [ 'lib/original/vast_voro.js', 438, 420 ] +1462 silly gunzTarPerm extractEntry lib/original/vast_types.js +1463 silly gunzTarPerm modified mode [ 'lib/original/vast_types.js', 438, 420 ] +1464 silly gunzTarPerm extractEntry lib/original/VAST_matcher.js +1465 silly gunzTarPerm modified mode [ 'lib/original/VAST_matcher.js', 438, 420 ] +1466 silly gunzTarPerm extractEntry lib/original/VAST.js +1467 silly gunzTarPerm modified mode [ 'lib/original/VAST.js', 438, 420 ] +1468 silly gunzTarPerm extractEntry lib/original/VSO_peer.js +1469 silly gunzTarPerm modified mode [ 'lib/original/VSO_peer.js', 438, 420 ] +1470 silly gunzTarPerm extractEntry lib/original/VAST_client.js +1471 silly gunzTarPerm modified mode [ 'lib/original/VAST_client.js', 438, 420 ] +1472 silly gunzTarPerm extractEntry lib/original/rhill-voronoi-core.js +1473 silly gunzTarPerm modified mode [ 'lib/original/rhill-voronoi-core.js', 438, 420 ] +1474 silly gunzTarPerm extractEntry lib/original/typedef.js +1475 silly gunzTarPerm modified mode [ 'lib/original/typedef.js', 438, 420 ] +1476 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io-server.js +1477 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io-server.js', 438, 420 ] +1478 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io.js +1479 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io.js', 438, 420 ] +1480 silly gunzTarPerm extractEntry lib/original/vast.io/socket.io/socket.io.js +1481 silly gunzTarPerm modified mode [ 'lib/original/vast.io/socket.io/socket.io.js', 438, 420 ] +1482 silly gunzTarPerm extractEntry lib/original/vast.io/socket.io/socket.io.min.js +1483 silly gunzTarPerm modified mode [ 'lib/original/vast.io/socket.io/socket.io.min.js', 438, 420 ] +1484 silly gunzTarPerm extractEntry lib/original/vast.io/socket.io-client.html +1485 silly gunzTarPerm modified mode [ 'lib/original/vast.io/socket.io-client.html', 438, 420 ] +1486 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io-client (dev).html +1487 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io-client (dev).html', 438, 420 ] +1488 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io-client (gaiasup).html +1489 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io-client (gaiasup).html', +1489 silly gunzTarPerm 438, +1489 silly gunzTarPerm 420 ] +1490 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io-client (local).html +1491 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io-client (local).html', 438, 420 ] +1492 silly gunzTarPerm extractEntry lib/original/vast.io/vast.io.bat +1493 silly gunzTarPerm modified mode [ 'lib/original/vast.io/vast.io.bat', 438, 420 ] +1494 silly gunzTarPerm extractEntry lib/original/common/logger.js +1495 silly gunzTarPerm modified mode [ 'lib/original/common/logger.js', 438, 420 ] +1496 silly gunzTarPerm extractEntry lib/original/common/util.js +1497 silly gunzTarPerm modified mode [ 'lib/original/common/util.js', 438, 420 ] +1498 silly gunzTarPerm extractEntry lib/original/typedef/line2d.js +1499 silly gunzTarPerm modified mode [ 'lib/original/typedef/line2d.js', 438, 420 ] +1500 silly gunzTarPerm extractEntry lib/original/typedef/point2d.js +1501 silly gunzTarPerm modified mode [ 'lib/original/typedef/point2d.js', 438, 420 ] +1502 silly gunzTarPerm extractEntry lib/original/typedef/segment.js +1503 silly gunzTarPerm modified mode [ 'lib/original/typedef/segment.js', 438, 420 ] +1504 silly gunzTarPerm extractEntry lib/original/net/msg_handler.js +1505 silly gunzTarPerm modified mode [ 'lib/original/net/msg_handler.js', 438, 420 ] +1506 silly gunzTarPerm extractEntry lib/original/net/net_nodejs.js +1507 silly gunzTarPerm modified mode [ 'lib/original/net/net_nodejs.js', 438, 420 ] +1508 silly gunzTarPerm extractEntry lib/original/net/test_vast_net.js +1509 silly gunzTarPerm modified mode [ 'lib/original/net/test_vast_net.js', 438, 420 ] +1510 silly gunzTarPerm extractEntry lib/original/net/vast_net.js +1511 silly gunzTarPerm modified mode [ 'lib/original/net/vast_net.js', 438, 420 ] +1512 silly gunzTarPerm extractEntry lib/original/INSTALL.txt +1513 silly gunzTarPerm modified mode [ 'lib/original/INSTALL.txt', 438, 420 ] +1514 silly gunzTarPerm extractEntry lib/original/VSS/directory.js +1515 silly gunzTarPerm modified mode [ 'lib/original/VSS/directory.js', 438, 420 ] +1516 silly gunzTarPerm extractEntry lib/original/VSS/handler.js +1517 silly gunzTarPerm modified mode [ 'lib/original/VSS/handler.js', 438, 420 ] +1518 silly gunzTarPerm extractEntry lib/original/VSS/logic.js +1519 silly gunzTarPerm modified mode [ 'lib/original/VSS/logic.js', 438, 420 ] +1520 silly gunzTarPerm extractEntry lib/original/VSS/router.js +1521 silly gunzTarPerm modified mode [ 'lib/original/VSS/router.js', 438, 420 ] +1522 silly gunzTarPerm extractEntry lib/original/VSS/server.js +1523 silly gunzTarPerm modified mode [ 'lib/original/VSS/server.js', 438, 420 ] +1524 silly gunzTarPerm extractEntry lib/original/VSS/VSS.js +1525 silly gunzTarPerm modified mode [ 'lib/original/VSS/VSS.js', 438, 420 ] +1526 silly gunzTarPerm extractEntry lib/original/backup +1527 silly gunzTarPerm modified mode [ 'lib/original/backup', 438, 420 ] +1528 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/package.json +1529 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/package.json', 438, 420 ] +1530 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/.npmignore +1531 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/.npmignore', 438, 420 ] +1532 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/LICENSE +1533 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/LICENSE', 438, 420 ] +1534 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/index.js +1535 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/index.js', 438, 420 ] +1536 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/latest +1537 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/latest', 438, 420 ] +1538 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/.travis.yml +1539 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/.travis.yml', 438, 420 ] +1540 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/History.md +1541 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/History.md', 438, 420 ] +1542 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/Makefile +1543 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/Makefile', 438, 420 ] +1544 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/Readme.md +1545 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/Readme.md', 438, 420 ] +1546 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/lib/client.js +1547 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/lib/client.js', 438, 420 ] +1548 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/lib/index.js +1549 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/lib/index.js', 438, 420 ] +1550 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/lib/namespace.js +1551 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/lib/namespace.js', +1551 silly gunzTarPerm 438, +1551 silly gunzTarPerm 420 ] +1552 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/lib/socket.js +1553 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/lib/socket.js', 438, 420 ] +1554 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/package.json +1555 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/package.json', +1555 silly gunzTarPerm 438, +1555 silly gunzTarPerm 420 ] +1556 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/.npmignore +1557 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/.npmignore', +1557 silly gunzTarPerm 438, +1557 silly gunzTarPerm 420 ] +1558 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/README.md +1559 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/README.md', +1559 silly gunzTarPerm 438, +1559 silly gunzTarPerm 420 ] +1560 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/index.js +1561 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/index.js', +1561 silly gunzTarPerm 438, +1561 silly gunzTarPerm 420 ] +1562 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/.travis.yml +1563 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/.travis.yml', +1563 silly gunzTarPerm 438, +1563 silly gunzTarPerm 420 ] +1564 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/History.md +1565 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/History.md', +1565 silly gunzTarPerm 438, +1565 silly gunzTarPerm 420 ] +1566 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/engine.io.js +1567 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/engine.io.js', +1567 silly gunzTarPerm 438, +1567 silly gunzTarPerm 420 ] +1568 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/server.js +1569 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/server.js', +1569 silly gunzTarPerm 438, +1569 silly gunzTarPerm 420 ] +1570 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/socket.js +1571 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/socket.js', +1571 silly gunzTarPerm 438, +1571 silly gunzTarPerm 420 ] +1572 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transport.js +1573 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transport.js', +1573 silly gunzTarPerm 438, +1573 silly gunzTarPerm 420 ] +1574 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/index.js +1575 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/index.js', +1575 silly gunzTarPerm 438, +1575 silly gunzTarPerm 420 ] +1576 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling-jsonp.js +1577 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling-jsonp.js', +1577 silly gunzTarPerm 438, +1577 silly gunzTarPerm 420 ] +1578 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling-xhr.js +1579 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling-xhr.js', +1579 silly gunzTarPerm 438, +1579 silly gunzTarPerm 420 ] +1580 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling.js +1581 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/polling.js', +1581 silly gunzTarPerm 438, +1581 silly gunzTarPerm 420 ] +1582 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/websocket.js +1583 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/lib/transports/websocket.js', +1583 silly gunzTarPerm 438, +1583 silly gunzTarPerm 420 ] +1584 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/Makefile +1585 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/Makefile', +1585 silly gunzTarPerm 438, +1585 silly gunzTarPerm 420 ] +1586 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/package.json +1587 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/package.json', +1587 silly gunzTarPerm 438, +1587 silly gunzTarPerm 420 ] +1588 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/.npmignore +1589 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/.npmignore', +1589 silly gunzTarPerm 438, +1589 silly gunzTarPerm 420 ] +1590 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/README.md +1591 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/README.md', +1591 silly gunzTarPerm 438, +1591 silly gunzTarPerm 420 ] +1592 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/lib/base64id.js +1593 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/base64id/lib/base64id.js', +1593 silly gunzTarPerm 438, +1593 silly gunzTarPerm 420 ] +1594 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/package.json +1595 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/package.json', +1595 silly gunzTarPerm 438, +1595 silly gunzTarPerm 420 ] +1596 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/.npmignore +1597 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/.npmignore', +1597 silly gunzTarPerm 438, +1597 silly gunzTarPerm 420 ] +1598 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/debug.js +1599 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/debug.js', +1599 silly gunzTarPerm 438, +1599 silly gunzTarPerm 420 ] +1600 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/index.js +1601 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/index.js', +1601 silly gunzTarPerm 438, +1601 silly gunzTarPerm 420 ] +1602 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/app.js +1603 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/app.js', +1603 silly gunzTarPerm 438, +1603 silly gunzTarPerm 420 ] +1604 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/wildcards.js +1605 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/wildcards.js', +1605 silly gunzTarPerm 438, +1605 silly gunzTarPerm 420 ] +1606 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/worker.js +1607 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/worker.js', +1607 silly gunzTarPerm 438, +1607 silly gunzTarPerm 420 ] +1608 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/browser.html +1609 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/example/browser.html', +1609 silly gunzTarPerm 438, +1609 silly gunzTarPerm 420 ] +1610 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/History.md +1611 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/History.md', +1611 silly gunzTarPerm 438, +1611 silly gunzTarPerm 420 ] +1612 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/lib/debug.js +1613 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/lib/debug.js', +1613 silly gunzTarPerm 438, +1613 silly gunzTarPerm 420 ] +1614 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/Makefile +1615 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/Makefile', +1615 silly gunzTarPerm 438, +1615 silly gunzTarPerm 420 ] +1616 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/Readme.md +1617 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/debug/Readme.md', +1617 silly gunzTarPerm 438, +1617 silly gunzTarPerm 420 ] +1618 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/package.json +1619 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/package.json', +1619 silly gunzTarPerm 438, +1619 silly gunzTarPerm 420 ] +1620 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.npmignore +1621 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.npmignore', +1621 silly gunzTarPerm 438, +1621 silly gunzTarPerm 420 ] +1622 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/LICENSE +1623 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/LICENSE', +1623 silly gunzTarPerm 438, +1623 silly gunzTarPerm 420 ] +1624 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/index.js +1625 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/index.js', +1625 silly gunzTarPerm 438, +1625 silly gunzTarPerm 420 ] +1626 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/Readme.md +1627 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/Readme.md', +1627 silly gunzTarPerm 438, +1627 silly gunzTarPerm 420 ] +1628 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.travis.yml +1629 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.travis.yml', +1629 silly gunzTarPerm 438, +1629 silly gunzTarPerm 420 ] +1630 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.zuul.yml +1631 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/.zuul.yml', +1631 silly gunzTarPerm 438, +1631 silly gunzTarPerm 420 ] +1632 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/Makefile +1633 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/Makefile', +1633 silly gunzTarPerm 438, +1633 silly gunzTarPerm 420 ] +1634 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/History.md +1635 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/History.md', +1635 silly gunzTarPerm 438, +1635 silly gunzTarPerm 420 ] +1636 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/browser.js +1637 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/browser.js', +1637 silly gunzTarPerm 438, +1637 silly gunzTarPerm 420 ] +1638 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js +1639 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/index.js', +1639 silly gunzTarPerm 438, +1639 silly gunzTarPerm 420 ] +1640 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/keys.js +1641 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/lib/keys.js', +1641 silly gunzTarPerm 438, +1641 silly gunzTarPerm 420 ] +1642 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/package.json +1643 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/package.json', +1643 silly gunzTarPerm 438, +1643 silly gunzTarPerm 420 ] +1644 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/.npmignore +1645 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/.npmignore', +1645 silly gunzTarPerm 438, +1645 silly gunzTarPerm 420 ] +1646 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/README.md +1647 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/README.md', +1647 silly gunzTarPerm 438, +1647 silly gunzTarPerm 420 ] +1648 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/LICENCE +1649 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/LICENCE', +1649 silly gunzTarPerm 438, +1649 silly gunzTarPerm 420 ] +1650 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/index.js +1651 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/index.js', +1651 silly gunzTarPerm 438, +1651 silly gunzTarPerm 420 ] +1652 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/.travis.yml +1653 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/.travis.yml', +1653 silly gunzTarPerm 438, +1653 silly gunzTarPerm 420 ] +1654 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/test/after-test.js +1655 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/after/test/after-test.js', +1655 silly gunzTarPerm 438, +1655 silly gunzTarPerm 420 ] +1656 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/package.json +1657 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/package.json', +1657 silly gunzTarPerm 438, +1657 silly gunzTarPerm 420 ] +1658 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/.npmignore +1659 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/.npmignore', +1659 silly gunzTarPerm 438, +1659 silly gunzTarPerm 420 ] +1660 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/README.md +1661 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/README.md', +1661 silly gunzTarPerm 438, +1661 silly gunzTarPerm 420 ] +1662 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/index.js +1663 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/index.js', +1663 silly gunzTarPerm 438, +1663 silly gunzTarPerm 420 ] +1664 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/Makefile +1665 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/Makefile', +1665 silly gunzTarPerm 438, +1665 silly gunzTarPerm 420 ] +1666 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/test/slice-buffer.js +1667 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/arraybuffer.slice/test/slice-buffer.js', +1667 silly gunzTarPerm 438, +1667 silly gunzTarPerm 420 ] +1668 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json +1669 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json', +1669 silly gunzTarPerm 438, +1669 silly gunzTarPerm 420 ] +1670 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.npmignore +1671 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.npmignore', +1671 silly gunzTarPerm 438, +1671 silly gunzTarPerm 420 ] +1672 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md +1673 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md', +1673 silly gunzTarPerm 438, +1673 silly gunzTarPerm 420 ] +1674 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/grunt.js +1675 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/grunt.js', +1675 silly gunzTarPerm 438, +1675 silly gunzTarPerm 420 ] +1676 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.travis.yml +1677 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.travis.yml', +1677 silly gunzTarPerm 438, +1677 silly gunzTarPerm 420 ] +1678 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js +1679 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js', +1679 silly gunzTarPerm 438, +1679 silly gunzTarPerm 420 ] +1680 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/LICENSE-MIT +1681 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/LICENSE-MIT', +1681 silly gunzTarPerm 438, +1681 silly gunzTarPerm 420 ] +1682 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json~ +1683 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json~', +1683 silly gunzTarPerm 438, +1683 silly gunzTarPerm 420 ] +1684 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md~ +1685 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md~', +1685 silly gunzTarPerm 438, +1685 silly gunzTarPerm 420 ] +1686 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js +1687 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js', +1687 silly gunzTarPerm 438, +1687 silly gunzTarPerm 420 ] +1688 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/package.json +1689 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/package.json', +1689 silly gunzTarPerm 438, +1689 silly gunzTarPerm 420 ] +1690 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/.npmignore +1691 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/.npmignore', +1691 silly gunzTarPerm 438, +1691 silly gunzTarPerm 420 ] +1692 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/README.md +1693 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/README.md', +1693 silly gunzTarPerm 438, +1693 silly gunzTarPerm 420 ] +1694 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/index.js +1695 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/index.js', +1695 silly gunzTarPerm 438, +1695 silly gunzTarPerm 420 ] +1696 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/.zuul.yml +1697 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/.zuul.yml', +1697 silly gunzTarPerm 438, +1697 silly gunzTarPerm 420 ] +1698 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/Makefile +1699 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/Makefile', +1699 silly gunzTarPerm 438, +1699 silly gunzTarPerm 420 ] +1700 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/test/index.js +1701 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/blob/test/index.js', +1701 silly gunzTarPerm 438, +1701 silly gunzTarPerm 420 ] +1702 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/package.json +1703 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/package.json', +1703 silly gunzTarPerm 438, +1703 silly gunzTarPerm 420 ] +1704 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.npmignore +1705 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.npmignore', +1705 silly gunzTarPerm 438, +1705 silly gunzTarPerm 420 ] +1706 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/README.md +1707 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/README.md', +1707 silly gunzTarPerm 438, +1707 silly gunzTarPerm 420 ] +1708 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/x.js +1709 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/x.js', +1709 silly gunzTarPerm 438, +1709 silly gunzTarPerm 420 ] +1710 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/Gruntfile.js +1711 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/Gruntfile.js', +1711 silly gunzTarPerm 438, +1711 silly gunzTarPerm 420 ] +1712 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/utf8.js +1713 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/utf8.js', +1713 silly gunzTarPerm 438, +1713 silly gunzTarPerm 420 ] +1714 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.gitattributes +1715 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.gitattributes', +1715 silly gunzTarPerm 438, +1715 silly gunzTarPerm 420 ] +1716 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.travis.yml +1717 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/.travis.yml', +1717 silly gunzTarPerm 438, +1717 silly gunzTarPerm 420 ] +1718 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/LICENSE-MIT.txt +1719 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/LICENSE-MIT.txt', +1719 silly gunzTarPerm 438, +1719 silly gunzTarPerm 420 ] +1720 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/bower.json +1721 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/bower.json', +1721 silly gunzTarPerm 438, +1721 silly gunzTarPerm 420 ] +1722 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/component.json +1723 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/component.json', +1723 silly gunzTarPerm 438, +1723 silly gunzTarPerm 420 ] +1724 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/tests.js +1725 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/tests.js', +1725 silly gunzTarPerm 438, +1725 silly gunzTarPerm 420 ] +1726 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/generate-test-data.py +1727 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/generate-test-data.py', +1727 silly gunzTarPerm 438, +1727 silly gunzTarPerm 420 ] +1728 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/index.html +1729 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/tests/index.html', +1729 silly gunzTarPerm 438, +1729 silly gunzTarPerm 420 ] +1730 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.js +1731 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.js', +1731 silly gunzTarPerm 438, +1731 silly gunzTarPerm 420 ] +1732 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/index.html +1733 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/index.html', +1733 silly gunzTarPerm 438, +1733 silly gunzTarPerm 420 ] +1734 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/utf8.js.html +1735 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/utf8.js.html', +1735 silly gunzTarPerm 438, +1735 silly gunzTarPerm 420 ] +1736 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/index.html +1737 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/index.html', +1737 silly gunzTarPerm 438, +1737 silly gunzTarPerm 420 ] +1738 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.css +1739 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.css', +1739 silly gunzTarPerm 438, +1739 silly gunzTarPerm 420 ] +1740 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/LICENSE-GPL.txt +1741 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/engine.io-parser/node_modules/utf8/LICENSE-GPL.txt', +1741 silly gunzTarPerm 438, +1741 silly gunzTarPerm 420 ] +1742 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/package.json +1743 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/package.json', +1743 silly gunzTarPerm 438, +1743 silly gunzTarPerm 420 ] +1744 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/.npmignore +1745 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/.npmignore', +1745 silly gunzTarPerm 438, +1745 silly gunzTarPerm 420 ] +1746 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/README.md +1747 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/README.md', +1747 silly gunzTarPerm 438, +1747 silly gunzTarPerm 420 ] +1748 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/index.js +1749 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/index.js', +1749 silly gunzTarPerm 438, +1749 silly gunzTarPerm 420 ] +1750 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/binding.gyp +1751 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/binding.gyp', +1751 silly gunzTarPerm 438, +1751 silly gunzTarPerm 420 ] +1752 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/builderror.log +1753 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/builderror.log', +1753 silly gunzTarPerm 438, +1753 silly gunzTarPerm 420 ] +1754 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/doc/ws.md +1755 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/doc/ws.md', +1755 silly gunzTarPerm 438, +1755 silly gunzTarPerm 420 ] +1756 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/ssl.js +1757 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/ssl.js', +1757 silly gunzTarPerm 438, +1757 silly gunzTarPerm 420 ] +1758 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/package.json +1759 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/package.json', +1759 silly gunzTarPerm 438, +1759 silly gunzTarPerm 420 ] +1760 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/.npmignore +1761 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/.npmignore', +1761 silly gunzTarPerm 438, +1761 silly gunzTarPerm 420 ] +1762 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/server.js +1763 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/server.js', +1763 silly gunzTarPerm 438, +1763 silly gunzTarPerm 420 ] +1764 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/app.js +1765 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/app.js', +1765 silly gunzTarPerm 438, +1765 silly gunzTarPerm 420 ] +1766 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/uploader.js +1767 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/uploader.js', +1767 silly gunzTarPerm 438, +1767 silly gunzTarPerm 420 ] +1768 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/index.html +1769 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/fileapi/public/index.html', +1769 silly gunzTarPerm 438, +1769 silly gunzTarPerm 420 ] +1770 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/package.json +1771 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/package.json', +1771 silly gunzTarPerm 438, +1771 silly gunzTarPerm 420 ] +1772 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/server.js +1773 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/server.js', +1773 silly gunzTarPerm 438, +1773 silly gunzTarPerm 420 ] +1774 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/public/index.html +1775 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats/public/index.html', +1775 silly gunzTarPerm 438, +1775 silly gunzTarPerm 420 ] +1776 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/package.json +1777 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/package.json', +1777 silly gunzTarPerm 438, +1777 silly gunzTarPerm 420 ] +1778 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/server.js +1779 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/server.js', +1779 silly gunzTarPerm 438, +1779 silly gunzTarPerm 420 ] +1780 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/public/index.html +1781 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/examples/serverstats-express_3/public/index.html', +1781 silly gunzTarPerm 438, +1781 silly gunzTarPerm 420 ] +1782 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/.travis.yml +1783 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/.travis.yml', +1783 silly gunzTarPerm 438, +1783 silly gunzTarPerm 420 ] +1784 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/autobahn-server.js +1785 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/autobahn-server.js', +1785 silly gunzTarPerm 438, +1785 silly gunzTarPerm 420 ] +1786 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocket.test.js +1787 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocket.test.js', +1787 silly gunzTarPerm 438, +1787 silly gunzTarPerm 420 ] +1788 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/hybi-common.js +1789 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/hybi-common.js', +1789 silly gunzTarPerm 438, +1789 silly gunzTarPerm 420 ] +1790 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Receiver.hixie.test.js +1791 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Receiver.hixie.test.js', +1791 silly gunzTarPerm 438, +1791 silly gunzTarPerm 420 ] +1792 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/BufferPool.test.js +1793 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/BufferPool.test.js', +1793 silly gunzTarPerm 438, +1793 silly gunzTarPerm 420 ] +1794 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/autobahn.js +1795 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/autobahn.js', +1795 silly gunzTarPerm 438, +1795 silly gunzTarPerm 420 ] +1796 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Sender.test.js +1797 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Sender.test.js', +1797 silly gunzTarPerm 438, +1797 silly gunzTarPerm 420 ] +1798 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/testserver.js +1799 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/testserver.js', +1799 silly gunzTarPerm 438, +1799 silly gunzTarPerm 420 ] +1800 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Validation.test.js +1801 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Validation.test.js', +1801 silly gunzTarPerm 438, +1801 silly gunzTarPerm 420 ] +1802 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocket.integration.js +1803 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocket.integration.js', +1803 silly gunzTarPerm 438, +1803 silly gunzTarPerm 420 ] +1804 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Receiver.test.js +1805 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Receiver.test.js', +1805 silly gunzTarPerm 438, +1805 silly gunzTarPerm 420 ] +1806 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocketServer.test.js +1807 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/WebSocketServer.test.js', +1807 silly gunzTarPerm 438, +1807 silly gunzTarPerm 420 ] +1808 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Sender.hixie.test.js +1809 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/Sender.hixie.test.js', +1809 silly gunzTarPerm 438, +1809 silly gunzTarPerm 420 ] +1810 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/agent1-cert.pem +1811 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/agent1-cert.pem', +1811 silly gunzTarPerm 438, +1811 silly gunzTarPerm 420 ] +1812 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/agent1-key.pem +1813 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/agent1-key.pem', +1813 silly gunzTarPerm 438, +1813 silly gunzTarPerm 420 ] +1814 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/ca1-cert.pem +1815 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/ca1-cert.pem', +1815 silly gunzTarPerm 438, +1815 silly gunzTarPerm 420 ] +1816 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/ca1-key.pem +1817 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/ca1-key.pem', +1817 silly gunzTarPerm 438, +1817 silly gunzTarPerm 420 ] +1818 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/certificate.pem +1819 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/certificate.pem', +1819 silly gunzTarPerm 438, +1819 silly gunzTarPerm 420 ] +1820 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/key.pem +1821 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/key.pem', +1821 silly gunzTarPerm 438, +1821 silly gunzTarPerm 420 ] +1822 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/request.pem +1823 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/request.pem', +1823 silly gunzTarPerm 438, +1823 silly gunzTarPerm 420 ] +1824 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/textfile +1825 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/test/fixtures/textfile', +1825 silly gunzTarPerm 438, +1825 silly gunzTarPerm 420 ] +1826 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/browser.js +1827 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/browser.js', +1827 silly gunzTarPerm 438, +1827 silly gunzTarPerm 420 ] +1828 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferUtil.js +1829 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferUtil.js', +1829 silly gunzTarPerm 438, +1829 silly gunzTarPerm 420 ] +1830 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/ErrorCodes.js +1831 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/ErrorCodes.js', +1831 silly gunzTarPerm 438, +1831 silly gunzTarPerm 420 ] +1832 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.hixie.js +1833 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.hixie.js', +1833 silly gunzTarPerm 438, +1833 silly gunzTarPerm 420 ] +1834 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferUtil.fallback.js +1835 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferUtil.fallback.js', +1835 silly gunzTarPerm 438, +1835 silly gunzTarPerm 420 ] +1836 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Sender.hixie.js +1837 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Sender.hixie.js', +1837 silly gunzTarPerm 438, +1837 silly gunzTarPerm 420 ] +1838 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Sender.js +1839 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Sender.js', +1839 silly gunzTarPerm 438, +1839 silly gunzTarPerm 420 ] +1840 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Validation.fallback.js +1841 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Validation.fallback.js', +1841 silly gunzTarPerm 438, +1841 silly gunzTarPerm 420 ] +1842 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Validation.js +1843 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Validation.js', +1843 silly gunzTarPerm 438, +1843 silly gunzTarPerm 420 ] +1844 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocket.js +1845 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocket.js', +1845 silly gunzTarPerm 438, +1845 silly gunzTarPerm 420 ] +1846 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferPool.js +1847 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/BufferPool.js', +1847 silly gunzTarPerm 438, +1847 silly gunzTarPerm 420 ] +1848 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocketServer.js +1849 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocketServer.js', +1849 silly gunzTarPerm 438, +1849 silly gunzTarPerm 420 ] +1850 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js +1851 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/Receiver.js', +1851 silly gunzTarPerm 438, +1851 silly gunzTarPerm 420 ] +1852 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/Makefile +1853 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/Makefile', +1853 silly gunzTarPerm 438, +1853 silly gunzTarPerm 420 ] +1854 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/src/bufferutil.cc +1855 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/src/bufferutil.cc', +1855 silly gunzTarPerm 438, +1855 silly gunzTarPerm 420 ] +1856 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/src/validation.cc +1857 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/src/validation.cc', +1857 silly gunzTarPerm 438, +1857 silly gunzTarPerm 420 ] +1858 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/parser.benchmark.js +1859 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/parser.benchmark.js', +1859 silly gunzTarPerm 438, +1859 silly gunzTarPerm 420 ] +1860 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/sender.benchmark.js +1861 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/sender.benchmark.js', +1861 silly gunzTarPerm 438, +1861 silly gunzTarPerm 420 ] +1862 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/speed.js +1863 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/speed.js', +1863 silly gunzTarPerm 438, +1863 silly gunzTarPerm 420 ] +1864 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/util.js +1865 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bench/util.js', +1865 silly gunzTarPerm 438, +1865 silly gunzTarPerm 420 ] +1866 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bin/wscat +1867 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/bin/wscat', +1867 silly gunzTarPerm 438, +1867 silly gunzTarPerm 420 ] +1868 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/History.md +1869 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/History.md', +1869 silly gunzTarPerm 438, +1869 silly gunzTarPerm 420 ] +1870 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/package.json +1871 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/package.json', +1871 silly gunzTarPerm 438, +1871 silly gunzTarPerm 420 ] +1872 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/.npmignore +1873 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/.npmignore', +1873 silly gunzTarPerm 438, +1873 silly gunzTarPerm 420 ] +1874 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/index.js +1875 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/index.js', +1875 silly gunzTarPerm 438, +1875 silly gunzTarPerm 420 ] +1876 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/.travis.yml +1877 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/.travis.yml', +1877 silly gunzTarPerm 438, +1877 silly gunzTarPerm 420 ] +1878 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/History.md +1879 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/History.md', +1879 silly gunzTarPerm 438, +1879 silly gunzTarPerm 420 ] +1880 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/lib/commander.js +1881 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/lib/commander.js', +1881 silly gunzTarPerm 438, +1881 silly gunzTarPerm 420 ] +1882 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/Makefile +1883 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/Makefile', +1883 silly gunzTarPerm 438, +1883 silly gunzTarPerm 420 ] +1884 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/Readme.md +1885 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/commander/Readme.md', +1885 silly gunzTarPerm 438, +1885 silly gunzTarPerm 420 ] +1886 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/package.json +1887 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/package.json', +1887 silly gunzTarPerm 438, +1887 silly gunzTarPerm 420 ] +1888 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/README.md +1889 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/README.md', +1889 silly gunzTarPerm 438, +1889 silly gunzTarPerm 420 ] +1890 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/LICENSE +1891 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/LICENSE', +1891 silly gunzTarPerm 438, +1891 silly gunzTarPerm 420 ] +1892 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/.index.js +1893 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/.index.js', +1893 silly gunzTarPerm 438, +1893 silly gunzTarPerm 420 ] +1894 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/nan.h +1895 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/nan/nan.h', +1895 silly gunzTarPerm 438, +1895 silly gunzTarPerm 420 ] +1896 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/package.json +1897 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/package.json', +1897 silly gunzTarPerm 438, +1897 silly gunzTarPerm 420 ] +1898 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/.npmignore +1899 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/.npmignore', +1899 silly gunzTarPerm 438, +1899 silly gunzTarPerm 420 ] +1900 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/README.md +1901 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/README.md', +1901 silly gunzTarPerm 438, +1901 silly gunzTarPerm 420 ] +1902 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/lib/options.js +1903 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/lib/options.js', +1903 silly gunzTarPerm 438, +1903 silly gunzTarPerm 420 ] +1904 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/Makefile +1905 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/Makefile', +1905 silly gunzTarPerm 438, +1905 silly gunzTarPerm 420 ] +1906 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/test/options.test.js +1907 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/test/options.test.js', +1907 silly gunzTarPerm 438, +1907 silly gunzTarPerm 420 ] +1908 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/test/fixtures/test.conf +1909 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/options/test/fixtures/test.conf', +1909 silly gunzTarPerm 438, +1909 silly gunzTarPerm 420 ] +1910 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/package.json +1911 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/package.json', +1911 silly gunzTarPerm 438, +1911 silly gunzTarPerm 420 ] +1912 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/.npmignore +1913 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/.npmignore', +1913 silly gunzTarPerm 438, +1913 silly gunzTarPerm 420 ] +1914 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/README.md +1915 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/README.md', +1915 silly gunzTarPerm 438, +1915 silly gunzTarPerm 420 ] +1916 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/example.js +1917 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/example.js', +1917 silly gunzTarPerm 438, +1917 silly gunzTarPerm 420 ] +1918 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/tinycolor.js +1919 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/tinycolor/tinycolor.js', +1919 silly gunzTarPerm 438, +1919 silly gunzTarPerm 420 ] +1920 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/package.json +1921 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/package.json', +1921 silly gunzTarPerm 438, +1921 silly gunzTarPerm 420 ] +1922 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/.npmignore +1923 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/.npmignore', +1923 silly gunzTarPerm 438, +1923 silly gunzTarPerm 420 ] +1924 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/README.md +1925 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/README.md', +1925 silly gunzTarPerm 438, +1925 silly gunzTarPerm 420 ] +1926 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/LICENSE +1927 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/LICENSE', +1927 silly gunzTarPerm 438, +1927 silly gunzTarPerm 420 ] +1928 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/index.js +1929 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/index.js', +1929 silly gunzTarPerm 438, +1929 silly gunzTarPerm 420 ] +1930 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/test.js +1931 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/test.js', +1931 silly gunzTarPerm 438, +1931 silly gunzTarPerm 420 ] +1932 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/Makefile +1933 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/Makefile', +1933 silly gunzTarPerm 438, +1933 silly gunzTarPerm 420 ] +1934 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/package.json +1935 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/package.json', +1935 silly gunzTarPerm 438, +1935 silly gunzTarPerm 420 ] +1936 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/README.md +1937 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/README.md', +1937 silly gunzTarPerm 438, +1937 silly gunzTarPerm 420 ] +1938 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/index.js +1939 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/index.js', +1939 silly gunzTarPerm 438, +1939 silly gunzTarPerm 420 ] +1940 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/build/build.js +1941 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/build/build.js', +1941 silly gunzTarPerm 438, +1941 silly gunzTarPerm 420 ] +1942 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/component.json +1943 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/has-binary-data/node_modules/isarray/component.json', +1943 silly gunzTarPerm 438, +1943 silly gunzTarPerm 420 ] +1944 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/package.json +1945 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/package.json', +1945 silly gunzTarPerm 438, +1945 silly gunzTarPerm 420 ] +1946 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/.npmignore +1947 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/.npmignore', +1947 silly gunzTarPerm 438, +1947 silly gunzTarPerm 420 ] +1948 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/index.js +1949 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/index.js', +1949 silly gunzTarPerm 438, +1949 silly gunzTarPerm 420 ] +1950 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/History.md +1951 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/History.md', +1951 silly gunzTarPerm 438, +1951 silly gunzTarPerm 420 ] +1952 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/Readme.md +1953 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/Readme.md', +1953 silly gunzTarPerm 438, +1953 silly gunzTarPerm 420 ] +1954 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/package.json +1955 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/package.json', +1955 silly gunzTarPerm 438, +1955 silly gunzTarPerm 420 ] +1956 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.npmignore +1957 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.npmignore', +1957 silly gunzTarPerm 438, +1957 silly gunzTarPerm 420 ] +1958 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/binary.js +1959 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/binary.js', +1959 silly gunzTarPerm 438, +1959 silly gunzTarPerm 420 ] +1960 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/index.js +1961 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/index.js', +1961 silly gunzTarPerm 438, +1961 silly gunzTarPerm 420 ] +1962 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.travis.yml +1963 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.travis.yml', +1963 silly gunzTarPerm 438, +1963 silly gunzTarPerm 420 ] +1964 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.zuul.yml +1965 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/.zuul.yml', +1965 silly gunzTarPerm 438, +1965 silly gunzTarPerm 420 ] +1966 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/History.md +1967 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/History.md', +1967 silly gunzTarPerm 438, +1967 silly gunzTarPerm 420 ] +1968 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/Makefile +1969 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/Makefile', +1969 silly gunzTarPerm 438, +1969 silly gunzTarPerm 420 ] +1970 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/Readme.md +1971 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/Readme.md', +1971 silly gunzTarPerm 438, +1971 silly gunzTarPerm 420 ] +1972 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/package.json +1973 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/package.json', +1973 silly gunzTarPerm 438, +1973 silly gunzTarPerm 420 ] +1974 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/.npmignore +1975 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/.npmignore', +1975 silly gunzTarPerm 438, +1975 silly gunzTarPerm 420 ] +1976 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/index.js +1977 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/index.js', +1977 silly gunzTarPerm 438, +1977 silly gunzTarPerm 420 ] +1978 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/component.json +1979 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/component.json', +1979 silly gunzTarPerm 438, +1979 silly gunzTarPerm 420 ] +1980 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/History.md +1981 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/History.md', +1981 silly gunzTarPerm 438, +1981 silly gunzTarPerm 420 ] +1982 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/Makefile +1983 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/Makefile', +1983 silly gunzTarPerm 438, +1983 silly gunzTarPerm 420 ] +1984 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/Readme.md +1985 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/Readme.md', +1985 silly gunzTarPerm 438, +1985 silly gunzTarPerm 420 ] +1986 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/test/emitter.js +1987 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/test/emitter.js', +1987 silly gunzTarPerm 438, +1987 silly gunzTarPerm 420 ] +1988 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/package.json +1989 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/package.json', +1989 silly gunzTarPerm 438, +1989 silly gunzTarPerm 420 ] +1990 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/.npmignore +1991 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/.npmignore', +1991 silly gunzTarPerm 438, +1991 silly gunzTarPerm 420 ] +1992 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/index.js +1993 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/index.js', +1993 silly gunzTarPerm 438, +1993 silly gunzTarPerm 420 ] +1994 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/component.json +1995 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/component.json', +1995 silly gunzTarPerm 438, +1995 silly gunzTarPerm 420 ] +1996 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Makefile +1997 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Makefile', +1997 silly gunzTarPerm 438, +1997 silly gunzTarPerm 420 ] +1998 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Readme.md +1999 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Readme.md', +1999 silly gunzTarPerm 438, +1999 silly gunzTarPerm 420 ] +2000 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/package.json +2001 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/package.json', +2001 silly gunzTarPerm 438, +2001 silly gunzTarPerm 420 ] +2002 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/README.md +2003 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/README.md', +2003 silly gunzTarPerm 438, +2003 silly gunzTarPerm 420 ] +2004 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/index.js +2005 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/index.js', +2005 silly gunzTarPerm 438, +2005 silly gunzTarPerm 420 ] +2006 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/build/build.js +2007 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/build/build.js', +2007 silly gunzTarPerm 438, +2007 silly gunzTarPerm 420 ] +2008 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/component.json +2009 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/isarray/component.json', +2009 silly gunzTarPerm 438, +2009 silly gunzTarPerm 420 ] +2010 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/package.json +2011 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/package.json', +2011 silly gunzTarPerm 438, +2011 silly gunzTarPerm 420 ] +2012 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.npmignore +2013 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.npmignore', +2013 silly gunzTarPerm 438, +2013 silly gunzTarPerm 420 ] +2014 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/README.md +2015 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/README.md', +2015 silly gunzTarPerm 438, +2015 silly gunzTarPerm 420 ] +2016 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/LICENSE +2017 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/LICENSE', +2017 silly gunzTarPerm 438, +2017 silly gunzTarPerm 420 ] +2018 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.gitmodules +2019 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.gitmodules', +2019 silly gunzTarPerm 438, +2019 silly gunzTarPerm 420 ] +2020 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.jamignore +2021 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.jamignore', +2021 silly gunzTarPerm 438, +2021 silly gunzTarPerm 420 ] +2022 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.travis.yml +2023 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/.travis.yml', +2023 silly gunzTarPerm 438, +2023 silly gunzTarPerm 420 ] +2024 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/coverage.json +2025 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/coverage.json', +2025 silly gunzTarPerm 438, +2025 silly gunzTarPerm 420 ] +2026 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.js +2027 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.js', +2027 silly gunzTarPerm 438, +2027 silly gunzTarPerm 420 ] +2028 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/lib/json3.js.html +2029 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/lib/json3.js.html', +2029 silly gunzTarPerm 438, +2029 silly gunzTarPerm 420 ] +2030 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.css +2031 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.css', +2031 silly gunzTarPerm 438, +2031 silly gunzTarPerm 420 ] +2032 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov.info +2033 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/coverage/lcov.info', +2033 silly gunzTarPerm 438, +2033 silly gunzTarPerm 420 ] +2034 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/lib/json3.js +2035 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/lib/json3.js', +2035 silly gunzTarPerm 438, +2035 silly gunzTarPerm 420 ] +2036 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/lib/json3.min.js +2037 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-adapter/node_modules/socket.io-parser/node_modules/json3/lib/json3.min.js', +2037 silly gunzTarPerm 438, +2037 silly gunzTarPerm 420 ] +2038 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/package.json +2039 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/package.json', +2039 silly gunzTarPerm 438, +2039 silly gunzTarPerm 420 ] +2040 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/.npmignore +2041 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/.npmignore', +2041 silly gunzTarPerm 438, +2041 silly gunzTarPerm 420 ] +2042 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/README.md +2043 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/README.md', +2043 silly gunzTarPerm 438, +2043 silly gunzTarPerm 420 ] +2044 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/index.js +2045 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/index.js', +2045 silly gunzTarPerm 438, +2045 silly gunzTarPerm 420 ] +2046 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/socket.io.js +2047 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/socket.io.js', +2047 silly gunzTarPerm 438, +2047 silly gunzTarPerm 420 ] +2048 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/History.md +2049 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/History.md', +2049 silly gunzTarPerm 438, +2049 silly gunzTarPerm 420 ] +2050 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/.travis.yml +2051 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/.travis.yml', +2051 silly gunzTarPerm 438, +2051 silly gunzTarPerm 420 ] +2052 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/Makefile +2053 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/Makefile', +2053 silly gunzTarPerm 438, +2053 silly gunzTarPerm 420 ] +2054 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/coverage.json +2055 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/coverage.json', +2055 silly gunzTarPerm 438, +2055 silly gunzTarPerm 420 ] +2056 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/prettify.js +2057 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/prettify.js', +2057 silly gunzTarPerm 438, +2057 silly gunzTarPerm 420 ] +2058 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/index.html +2059 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/index.html', +2059 silly gunzTarPerm 438, +2059 silly gunzTarPerm 420 ] +2060 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/lib/index.html +2061 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/lib/index.html', +2061 silly gunzTarPerm 438, +2061 silly gunzTarPerm 420 ] +2062 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/lib/url.js.html +2063 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/lib/url.js.html', +2063 silly gunzTarPerm 438, +2063 silly gunzTarPerm 420 ] +2064 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/prettify.css +2065 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/prettify.css', +2065 silly gunzTarPerm 438, +2065 silly gunzTarPerm 420 ] +2066 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/index.html +2067 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/index.html', +2067 silly gunzTarPerm 438, +2067 silly gunzTarPerm 420 ] +2068 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/index.js.html +2069 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/index.js.html', +2069 silly gunzTarPerm 438, +2069 silly gunzTarPerm 420 ] +2070 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/index.html +2071 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/index.html', +2071 silly gunzTarPerm 438, +2071 silly gunzTarPerm 420 ] +2072 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/index.js.html +2073 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/index.js.html', +2073 silly gunzTarPerm 438, +2073 silly gunzTarPerm 420 ] +2074 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/manager.js.html +2075 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/manager.js.html', +2075 silly gunzTarPerm 438, +2075 silly gunzTarPerm 420 ] +2076 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/on.js.html +2077 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/on.js.html', +2077 silly gunzTarPerm 438, +2077 silly gunzTarPerm 420 ] +2078 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/socket.js.html +2079 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/socket.js.html', +2079 silly gunzTarPerm 438, +2079 silly gunzTarPerm 420 ] +2080 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/url.js.html +2081 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov-report/socket.io-client/lib/url.js.html', +2081 silly gunzTarPerm 438, +2081 silly gunzTarPerm 420 ] +2082 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov.info +2083 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/coverage/lcov.info', +2083 silly gunzTarPerm 438, +2083 silly gunzTarPerm 420 ] +2084 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/.zuul.yml +2085 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/.zuul.yml', +2085 silly gunzTarPerm 438, +2085 silly gunzTarPerm 420 ] +2086 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/index.js +2087 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/index.js', +2087 silly gunzTarPerm 438, +2087 silly gunzTarPerm 420 ] +2088 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/manager.js +2089 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/manager.js', +2089 silly gunzTarPerm 438, +2089 silly gunzTarPerm 420 ] +2090 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/on.js +2091 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/on.js', +2091 silly gunzTarPerm 438, +2091 silly gunzTarPerm 420 ] +2092 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/socket.js +2093 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/socket.js', +2093 silly gunzTarPerm 438, +2093 silly gunzTarPerm 420 ] +2094 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/url.js +2095 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/lib/url.js', +2095 silly gunzTarPerm 438, +2095 silly gunzTarPerm 420 ] +2096 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/package.json +2097 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/package.json', +2097 silly gunzTarPerm 438, +2097 silly gunzTarPerm 420 ] +2098 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/.npmignore +2099 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/.npmignore', +2099 silly gunzTarPerm 438, +2099 silly gunzTarPerm 420 ] +2100 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/index.js +2101 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/index.js', +2101 silly gunzTarPerm 438, +2101 silly gunzTarPerm 420 ] +2102 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/component.json +2103 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/component.json', +2103 silly gunzTarPerm 438, +2103 silly gunzTarPerm 420 ] +2104 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/History.md +2105 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/History.md', +2105 silly gunzTarPerm 438, +2105 silly gunzTarPerm 420 ] +2106 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/Makefile +2107 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/Makefile', +2107 silly gunzTarPerm 438, +2107 silly gunzTarPerm 420 ] +2108 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/Readme.md +2109 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-bind/Readme.md', +2109 silly gunzTarPerm 438, +2109 silly gunzTarPerm 420 ] +2110 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/package.json +2111 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/package.json', +2111 silly gunzTarPerm 438, +2111 silly gunzTarPerm 420 ] +2112 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/.npmignore +2113 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/.npmignore', +2113 silly gunzTarPerm 438, +2113 silly gunzTarPerm 420 ] +2114 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/index.js +2115 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/index.js', +2115 silly gunzTarPerm 438, +2115 silly gunzTarPerm 420 ] +2116 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/.travis.yml +2117 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/.travis.yml', +2117 silly gunzTarPerm 438, +2117 silly gunzTarPerm 420 ] +2118 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/bower.json +2119 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/bower.json', +2119 silly gunzTarPerm 438, +2119 silly gunzTarPerm 420 ] +2120 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/component.json +2121 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/component.json', +2121 silly gunzTarPerm 438, +2121 silly gunzTarPerm 420 ] +2122 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/History.md +2123 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/History.md', +2123 silly gunzTarPerm 438, +2123 silly gunzTarPerm 420 ] +2124 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/Makefile +2125 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/Makefile', +2125 silly gunzTarPerm 438, +2125 silly gunzTarPerm 420 ] +2126 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/Readme.md +2127 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/component-emitter/Readme.md', +2127 silly gunzTarPerm 438, +2127 silly gunzTarPerm 420 ] +2128 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/package.json +2129 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/package.json', +2129 silly gunzTarPerm 438, +2129 silly gunzTarPerm 420 ] +2130 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.npmignore +2131 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.npmignore', +2131 silly gunzTarPerm 438, +2131 silly gunzTarPerm 420 ] +2132 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/README.md +2133 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/README.md', +2133 silly gunzTarPerm 438, +2133 silly gunzTarPerm 420 ] +2134 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/engine.io.js +2135 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/engine.io.js', +2135 silly gunzTarPerm 438, +2135 silly gunzTarPerm 420 ] +2136 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/index.js +2137 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/index.js', +2137 silly gunzTarPerm 438, +2137 silly gunzTarPerm 420 ] +2138 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/History.md +2139 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/History.md', +2139 silly gunzTarPerm 438, +2139 silly gunzTarPerm 420 ] +2140 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.travis.yml +2141 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.travis.yml', +2141 silly gunzTarPerm 438, +2141 silly gunzTarPerm 420 ] +2142 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/index.js +2143 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/index.js', +2143 silly gunzTarPerm 438, +2143 silly gunzTarPerm 420 ] +2144 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/socket.js +2145 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/socket.js', +2145 silly gunzTarPerm 438, +2145 silly gunzTarPerm 420 ] +2146 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transport.js +2147 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transport.js', +2147 silly gunzTarPerm 438, +2147 silly gunzTarPerm 420 ] +2148 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/xmlhttprequest.js +2149 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/xmlhttprequest.js', +2149 silly gunzTarPerm 438, +2149 silly gunzTarPerm 420 ] +2150 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/index.js +2151 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/index.js', +2151 silly gunzTarPerm 438, +2151 silly gunzTarPerm 420 ] +2152 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling-jsonp.js +2153 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling-jsonp.js', +2153 silly gunzTarPerm 438, +2153 silly gunzTarPerm 420 ] +2154 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling-xhr.js +2155 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling-xhr.js', +2155 silly gunzTarPerm 438, +2155 silly gunzTarPerm 420 ] +2156 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling.js +2157 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/polling.js', +2157 silly gunzTarPerm 438, +2157 silly gunzTarPerm 420 ] +2158 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/websocket.js +2159 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/lib/transports/websocket.js', +2159 silly gunzTarPerm 438, +2159 silly gunzTarPerm 420 ] +2160 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/Makefile +2161 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/Makefile', +2161 silly gunzTarPerm 438, +2161 silly gunzTarPerm 420 ] +2162 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.zuul.yml +2163 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/.zuul.yml', +2163 silly gunzTarPerm 438, +2163 silly gunzTarPerm 420 ] +2164 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/package.json +2165 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/package.json', +2165 silly gunzTarPerm 438, +2165 silly gunzTarPerm 420 ] +2166 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/.npmignore +2167 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/.npmignore', +2167 silly gunzTarPerm 438, +2167 silly gunzTarPerm 420 ] +2168 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/index.js +2169 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/index.js', +2169 silly gunzTarPerm 438, +2169 silly gunzTarPerm 420 ] +2170 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/component.json +2171 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/component.json', +2171 silly gunzTarPerm 438, +2171 silly gunzTarPerm 420 ] +2172 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/History.md +2173 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/History.md', +2173 silly gunzTarPerm 438, +2173 silly gunzTarPerm 420 ] +2174 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/Makefile +2175 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/Makefile', +2175 silly gunzTarPerm 438, +2175 silly gunzTarPerm 420 ] +2176 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/Readme.md +2177 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/Readme.md', +2177 silly gunzTarPerm 438, +2177 silly gunzTarPerm 420 ] +2178 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/test/inherit.js +2179 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/component-inherit/test/inherit.js', +2179 silly gunzTarPerm 438, +2179 silly gunzTarPerm 420 ] +2180 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/package.json +2181 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/package.json', +2181 silly gunzTarPerm 438, +2181 silly gunzTarPerm 420 ] +2182 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.npmignore +2183 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.npmignore', +2183 silly gunzTarPerm 438, +2183 silly gunzTarPerm 420 ] +2184 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/LICENSE +2185 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/LICENSE', +2185 silly gunzTarPerm 438, +2185 silly gunzTarPerm 420 ] +2186 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/index.js +2187 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/index.js', +2187 silly gunzTarPerm 438, +2187 silly gunzTarPerm 420 ] +2188 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/Readme.md +2189 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/Readme.md', +2189 silly gunzTarPerm 438, +2189 silly gunzTarPerm 420 ] +2190 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.travis.yml +2191 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.travis.yml', +2191 silly gunzTarPerm 438, +2191 silly gunzTarPerm 420 ] +2192 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.zuul.yml +2193 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/.zuul.yml', +2193 silly gunzTarPerm 438, +2193 silly gunzTarPerm 420 ] +2194 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/Makefile +2195 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/Makefile', +2195 silly gunzTarPerm 438, +2195 silly gunzTarPerm 420 ] +2196 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/History.md +2197 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/History.md', +2197 silly gunzTarPerm 438, +2197 silly gunzTarPerm 420 ] +2198 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/browser.js +2199 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/browser.js', +2199 silly gunzTarPerm 438, +2199 silly gunzTarPerm 420 ] +2200 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/index.js +2201 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/index.js', +2201 silly gunzTarPerm 438, +2201 silly gunzTarPerm 420 ] +2202 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/keys.js +2203 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/lib/keys.js', +2203 silly gunzTarPerm 438, +2203 silly gunzTarPerm 420 ] +2204 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/package.json +2205 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/package.json', +2205 silly gunzTarPerm 438, +2205 silly gunzTarPerm 420 ] +2206 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/.npmignore +2207 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/.npmignore', +2207 silly gunzTarPerm 438, +2207 silly gunzTarPerm 420 ] +2208 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/README.md +2209 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/README.md', +2209 silly gunzTarPerm 438, +2209 silly gunzTarPerm 420 ] +2210 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/LICENCE +2211 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/LICENCE', +2211 silly gunzTarPerm 438, +2211 silly gunzTarPerm 420 ] +2212 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/index.js +2213 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/index.js', +2213 silly gunzTarPerm 438, +2213 silly gunzTarPerm 420 ] +2214 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/.travis.yml +2215 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/.travis.yml', +2215 silly gunzTarPerm 438, +2215 silly gunzTarPerm 420 ] +2216 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/test/after-test.js +2217 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/after/test/after-test.js', +2217 silly gunzTarPerm 438, +2217 silly gunzTarPerm 420 ] +2218 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/package.json +2219 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/package.json', +2219 silly gunzTarPerm 438, +2219 silly gunzTarPerm 420 ] +2220 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/.npmignore +2221 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/.npmignore', +2221 silly gunzTarPerm 438, +2221 silly gunzTarPerm 420 ] +2222 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/README.md +2223 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/README.md', +2223 silly gunzTarPerm 438, +2223 silly gunzTarPerm 420 ] +2224 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/index.js +2225 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/index.js', +2225 silly gunzTarPerm 438, +2225 silly gunzTarPerm 420 ] +2226 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/Makefile +2227 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/Makefile', +2227 silly gunzTarPerm 438, +2227 silly gunzTarPerm 420 ] +2228 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/test/slice-buffer.js +2229 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/arraybuffer.slice/test/slice-buffer.js', +2229 silly gunzTarPerm 438, +2229 silly gunzTarPerm 420 ] +2230 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json +2231 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json', +2231 silly gunzTarPerm 438, +2231 silly gunzTarPerm 420 ] +2232 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.npmignore +2233 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.npmignore', +2233 silly gunzTarPerm 438, +2233 silly gunzTarPerm 420 ] +2234 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md +2235 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md', +2235 silly gunzTarPerm 438, +2235 silly gunzTarPerm 420 ] +2236 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/grunt.js +2237 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/grunt.js', +2237 silly gunzTarPerm 438, +2237 silly gunzTarPerm 420 ] +2238 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.travis.yml +2239 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/.travis.yml', +2239 silly gunzTarPerm 438, +2239 silly gunzTarPerm 420 ] +2240 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js +2241 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/lib/base64-arraybuffer.js', +2241 silly gunzTarPerm 438, +2241 silly gunzTarPerm 420 ] +2242 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/LICENSE-MIT +2243 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/LICENSE-MIT', +2243 silly gunzTarPerm 438, +2243 silly gunzTarPerm 420 ] +2244 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json~ +2245 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/package.json~', +2245 silly gunzTarPerm 438, +2245 silly gunzTarPerm 420 ] +2246 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md~ +2247 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/README.md~', +2247 silly gunzTarPerm 438, +2247 silly gunzTarPerm 420 ] +2248 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js +2249 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/base64-arraybuffer/test/base64-arraybuffer_test.js', +2249 silly gunzTarPerm 438, +2249 silly gunzTarPerm 420 ] +2250 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/package.json +2251 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/package.json', +2251 silly gunzTarPerm 438, +2251 silly gunzTarPerm 420 ] +2252 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/.npmignore +2253 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/.npmignore', +2253 silly gunzTarPerm 438, +2253 silly gunzTarPerm 420 ] +2254 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/README.md +2255 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/README.md', +2255 silly gunzTarPerm 438, +2255 silly gunzTarPerm 420 ] +2256 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/index.js +2257 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/index.js', +2257 silly gunzTarPerm 438, +2257 silly gunzTarPerm 420 ] +2258 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/.zuul.yml +2259 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/.zuul.yml', +2259 silly gunzTarPerm 438, +2259 silly gunzTarPerm 420 ] +2260 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/Makefile +2261 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/Makefile', +2261 silly gunzTarPerm 438, +2261 silly gunzTarPerm 420 ] +2262 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/test/index.js +2263 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/blob/test/index.js', +2263 silly gunzTarPerm 438, +2263 silly gunzTarPerm 420 ] +2264 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/package.json +2265 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/package.json', +2265 silly gunzTarPerm 438, +2265 silly gunzTarPerm 420 ] +2266 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.npmignore +2267 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.npmignore', +2267 silly gunzTarPerm 438, +2267 silly gunzTarPerm 420 ] +2268 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/README.md +2269 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/README.md', +2269 silly gunzTarPerm 438, +2269 silly gunzTarPerm 420 ] +2270 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/x.js +2271 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/x.js', +2271 silly gunzTarPerm 438, +2271 silly gunzTarPerm 420 ] +2272 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/Gruntfile.js +2273 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/Gruntfile.js', +2273 silly gunzTarPerm 438, +2273 silly gunzTarPerm 420 ] +2274 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/utf8.js +2275 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/utf8.js', +2275 silly gunzTarPerm 438, +2275 silly gunzTarPerm 420 ] +2276 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.gitattributes +2277 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.gitattributes', +2277 silly gunzTarPerm 438, +2277 silly gunzTarPerm 420 ] +2278 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.travis.yml +2279 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/.travis.yml', +2279 silly gunzTarPerm 438, +2279 silly gunzTarPerm 420 ] +2280 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/LICENSE-MIT.txt +2281 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/LICENSE-MIT.txt', +2281 silly gunzTarPerm 438, +2281 silly gunzTarPerm 420 ] +2282 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/bower.json +2283 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/bower.json', +2283 silly gunzTarPerm 438, +2283 silly gunzTarPerm 420 ] +2284 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/component.json +2285 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/component.json', +2285 silly gunzTarPerm 438, +2285 silly gunzTarPerm 420 ] +2286 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/tests.js +2287 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/tests.js', +2287 silly gunzTarPerm 438, +2287 silly gunzTarPerm 420 ] +2288 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/generate-test-data.py +2289 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/generate-test-data.py', +2289 silly gunzTarPerm 438, +2289 silly gunzTarPerm 420 ] +2290 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/index.html +2291 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/tests/index.html', +2291 silly gunzTarPerm 438, +2291 silly gunzTarPerm 420 ] +2292 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.js +2293 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.js', +2293 silly gunzTarPerm 438, +2293 silly gunzTarPerm 420 ] +2294 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/index.html +2295 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/index.html', +2295 silly gunzTarPerm 438, +2295 silly gunzTarPerm 420 ] +2296 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/utf8.js.html +2297 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/utf8.js/utf8.js.html', +2297 silly gunzTarPerm 438, +2297 silly gunzTarPerm 420 ] +2298 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/index.html +2299 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/index.html', +2299 silly gunzTarPerm 438, +2299 silly gunzTarPerm 420 ] +2300 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.css +2301 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/coverage/prettify.css', +2301 silly gunzTarPerm 438, +2301 silly gunzTarPerm 420 ] +2302 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/LICENSE-GPL.txt +2303 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/engine.io-parser/node_modules/utf8/LICENSE-GPL.txt', +2303 silly gunzTarPerm 438, +2303 silly gunzTarPerm 420 ] +2304 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/package.json +2305 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/package.json', +2305 silly gunzTarPerm 438, +2305 silly gunzTarPerm 420 ] +2306 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/.npmignore +2307 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/.npmignore', +2307 silly gunzTarPerm 438, +2307 silly gunzTarPerm 420 ] +2308 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/index.js +2309 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/index.js', +2309 silly gunzTarPerm 438, +2309 silly gunzTarPerm 420 ] +2310 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/component.json +2311 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/component.json', +2311 silly gunzTarPerm 438, +2311 silly gunzTarPerm 420 ] +2312 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/History.md +2313 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/History.md', +2313 silly gunzTarPerm 438, +2313 silly gunzTarPerm 420 ] +2314 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/Makefile +2315 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/Makefile', +2315 silly gunzTarPerm 438, +2315 silly gunzTarPerm 420 ] +2316 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/Readme.md +2317 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/Readme.md', +2317 silly gunzTarPerm 438, +2317 silly gunzTarPerm 420 ] +2318 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/package.json +2319 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/package.json', +2319 silly gunzTarPerm 438, +2319 silly gunzTarPerm 420 ] +2320 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/.npmignore +2321 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/.npmignore', +2321 silly gunzTarPerm 438, +2321 silly gunzTarPerm 420 ] +2322 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/index.js +2323 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/index.js', +2323 silly gunzTarPerm 438, +2323 silly gunzTarPerm 420 ] +2324 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/component.json +2325 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/component.json', +2325 silly gunzTarPerm 438, +2325 silly gunzTarPerm 420 ] +2326 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/History.md +2327 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/History.md', +2327 silly gunzTarPerm 438, +2327 silly gunzTarPerm 420 ] +2328 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/Makefile +2329 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/Makefile', +2329 silly gunzTarPerm 438, +2329 silly gunzTarPerm 420 ] +2330 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/Readme.md +2331 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/Readme.md', +2331 silly gunzTarPerm 438, +2331 silly gunzTarPerm 420 ] +2332 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/mocha.js +2333 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/mocha.js', +2333 silly gunzTarPerm 438, +2333 silly gunzTarPerm 420 ] +2334 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/test.js +2335 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/test.js', +2335 silly gunzTarPerm 438, +2335 silly gunzTarPerm 420 ] +2336 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/index.html +2337 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/index.html', +2337 silly gunzTarPerm 438, +2337 silly gunzTarPerm 420 ] +2338 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/mocha.css +2339 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/has-cors/node_modules/global/test/mocha.css', +2339 silly gunzTarPerm 438, +2339 silly gunzTarPerm 420 ] +2340 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/package.json +2341 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/package.json', +2341 silly gunzTarPerm 438, +2341 silly gunzTarPerm 420 ] +2342 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/index.js +2343 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/index.js', +2343 silly gunzTarPerm 438, +2343 silly gunzTarPerm 420 ] +2344 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/test.js +2345 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/test.js', +2345 silly gunzTarPerm 438, +2345 silly gunzTarPerm 420 ] +2346 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/Makefile +2347 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/Makefile', +2347 silly gunzTarPerm 438, +2347 silly gunzTarPerm 420 ] +2348 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/package.json +2349 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/package.json', +2349 silly gunzTarPerm 438, +2349 silly gunzTarPerm 420 ] +2350 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/.npmignore +2351 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/.npmignore', +2351 silly gunzTarPerm 438, +2351 silly gunzTarPerm 420 ] +2352 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/example.js +2353 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/example.js', +2353 silly gunzTarPerm 438, +2353 silly gunzTarPerm 420 ] +2354 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/index.js +2355 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/index.js', +2355 silly gunzTarPerm 438, +2355 silly gunzTarPerm 420 ] +2356 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/History.md +2357 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/History.md', +2357 silly gunzTarPerm 438, +2357 silly gunzTarPerm 420 ] +2358 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/Makefile +2359 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/Makefile', +2359 silly gunzTarPerm 438, +2359 silly gunzTarPerm 420 ] +2360 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/Readme.md +2361 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/Readme.md', +2361 silly gunzTarPerm 438, +2361 silly gunzTarPerm 420 ] +2362 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/package.json +2363 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/package.json', +2363 silly gunzTarPerm 438, +2363 silly gunzTarPerm 420 ] +2364 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/.npmignore +2365 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/.npmignore', +2365 silly gunzTarPerm 438, +2365 silly gunzTarPerm 420 ] +2366 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/index.js +2367 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/index.js', +2367 silly gunzTarPerm 438, +2367 silly gunzTarPerm 420 ] +2368 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/History.md +2369 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/History.md', +2369 silly gunzTarPerm 438, +2369 silly gunzTarPerm 420 ] +2370 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/Makefile +2371 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/Makefile', +2371 silly gunzTarPerm 438, +2371 silly gunzTarPerm 420 ] +2372 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/Readme.md +2373 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parsejson/node_modules/better-assert/node_modules/callsite/Readme.md', +2373 silly gunzTarPerm 438, +2373 silly gunzTarPerm 420 ] +2374 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/package.json +2375 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/package.json', +2375 silly gunzTarPerm 438, +2375 silly gunzTarPerm 420 ] +2376 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/index.js +2377 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/index.js', +2377 silly gunzTarPerm 438, +2377 silly gunzTarPerm 420 ] +2378 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/test.js +2379 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/test.js', +2379 silly gunzTarPerm 438, +2379 silly gunzTarPerm 420 ] +2380 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/Makefile +2381 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/Makefile', +2381 silly gunzTarPerm 438, +2381 silly gunzTarPerm 420 ] +2382 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/package.json +2383 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/package.json', +2383 silly gunzTarPerm 438, +2383 silly gunzTarPerm 420 ] +2384 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/.npmignore +2385 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/.npmignore', +2385 silly gunzTarPerm 438, +2385 silly gunzTarPerm 420 ] +2386 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/example.js +2387 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/example.js', +2387 silly gunzTarPerm 438, +2387 silly gunzTarPerm 420 ] +2388 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/index.js +2389 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/index.js', +2389 silly gunzTarPerm 438, +2389 silly gunzTarPerm 420 ] +2390 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/History.md +2391 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/History.md', +2391 silly gunzTarPerm 438, +2391 silly gunzTarPerm 420 ] +2392 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/Makefile +2393 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/Makefile', +2393 silly gunzTarPerm 438, +2393 silly gunzTarPerm 420 ] +2394 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/Readme.md +2395 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/Readme.md', +2395 silly gunzTarPerm 438, +2395 silly gunzTarPerm 420 ] +2396 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/package.json +2397 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/package.json', +2397 silly gunzTarPerm 438, +2397 silly gunzTarPerm 420 ] +2398 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/.npmignore +2399 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/.npmignore', +2399 silly gunzTarPerm 438, +2399 silly gunzTarPerm 420 ] +2400 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/index.js +2401 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/index.js', +2401 silly gunzTarPerm 438, +2401 silly gunzTarPerm 420 ] +2402 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/History.md +2403 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/History.md', +2403 silly gunzTarPerm 438, +2403 silly gunzTarPerm 420 ] +2404 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/Makefile +2405 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/Makefile', +2405 silly gunzTarPerm 438, +2405 silly gunzTarPerm 420 ] +2406 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/Readme.md +2407 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/parseqs/node_modules/better-assert/node_modules/callsite/Readme.md', +2407 silly gunzTarPerm 438, +2407 silly gunzTarPerm 420 ] +2408 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/package.json +2409 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/package.json', +2409 silly gunzTarPerm 438, +2409 silly gunzTarPerm 420 ] +2410 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/.npmignore +2411 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/.npmignore', +2411 silly gunzTarPerm 438, +2411 silly gunzTarPerm 420 ] +2412 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/README.md +2413 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/README.md', +2413 silly gunzTarPerm 438, +2413 silly gunzTarPerm 420 ] +2414 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/index.js +2415 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/index.js', +2415 silly gunzTarPerm 438, +2415 silly gunzTarPerm 420 ] +2416 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/binding.gyp +2417 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/binding.gyp', +2417 silly gunzTarPerm 438, +2417 silly gunzTarPerm 420 ] +2418 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/builderror.log +2419 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/builderror.log', +2419 silly gunzTarPerm 438, +2419 silly gunzTarPerm 420 ] +2420 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/doc/ws.md +2421 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/doc/ws.md', +2421 silly gunzTarPerm 438, +2421 silly gunzTarPerm 420 ] +2422 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/ssl.js +2423 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/ssl.js', +2423 silly gunzTarPerm 438, +2423 silly gunzTarPerm 420 ] +2424 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/package.json +2425 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/package.json', +2425 silly gunzTarPerm 438, +2425 silly gunzTarPerm 420 ] +2426 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/.npmignore +2427 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/.npmignore', +2427 silly gunzTarPerm 438, +2427 silly gunzTarPerm 420 ] +2428 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/server.js +2429 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/server.js', +2429 silly gunzTarPerm 438, +2429 silly gunzTarPerm 420 ] +2430 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/app.js +2431 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/app.js', +2431 silly gunzTarPerm 438, +2431 silly gunzTarPerm 420 ] +2432 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/uploader.js +2433 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/uploader.js', +2433 silly gunzTarPerm 438, +2433 silly gunzTarPerm 420 ] +2434 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/index.html +2435 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/fileapi/public/index.html', +2435 silly gunzTarPerm 438, +2435 silly gunzTarPerm 420 ] +2436 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/package.json +2437 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/package.json', +2437 silly gunzTarPerm 438, +2437 silly gunzTarPerm 420 ] +2438 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/server.js +2439 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/server.js', +2439 silly gunzTarPerm 438, +2439 silly gunzTarPerm 420 ] +2440 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/public/index.html +2441 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats/public/index.html', +2441 silly gunzTarPerm 438, +2441 silly gunzTarPerm 420 ] +2442 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/package.json +2443 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/package.json', +2443 silly gunzTarPerm 438, +2443 silly gunzTarPerm 420 ] +2444 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/server.js +2445 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/server.js', +2445 silly gunzTarPerm 438, +2445 silly gunzTarPerm 420 ] +2446 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/public/index.html +2447 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/examples/serverstats-express_3/public/index.html', +2447 silly gunzTarPerm 438, +2447 silly gunzTarPerm 420 ] +2448 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/.travis.yml +2449 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/.travis.yml', +2449 silly gunzTarPerm 438, +2449 silly gunzTarPerm 420 ] +2450 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/autobahn-server.js +2451 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/autobahn-server.js', +2451 silly gunzTarPerm 438, +2451 silly gunzTarPerm 420 ] +2452 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocket.test.js +2453 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocket.test.js', +2453 silly gunzTarPerm 438, +2453 silly gunzTarPerm 420 ] +2454 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/hybi-common.js +2455 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/hybi-common.js', +2455 silly gunzTarPerm 438, +2455 silly gunzTarPerm 420 ] +2456 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Receiver.hixie.test.js +2457 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Receiver.hixie.test.js', +2457 silly gunzTarPerm 438, +2457 silly gunzTarPerm 420 ] +2458 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/BufferPool.test.js +2459 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/BufferPool.test.js', +2459 silly gunzTarPerm 438, +2459 silly gunzTarPerm 420 ] +2460 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/autobahn.js +2461 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/autobahn.js', +2461 silly gunzTarPerm 438, +2461 silly gunzTarPerm 420 ] +2462 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Sender.test.js +2463 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Sender.test.js', +2463 silly gunzTarPerm 438, +2463 silly gunzTarPerm 420 ] +2464 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/testserver.js +2465 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/testserver.js', +2465 silly gunzTarPerm 438, +2465 silly gunzTarPerm 420 ] +2466 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Validation.test.js +2467 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Validation.test.js', +2467 silly gunzTarPerm 438, +2467 silly gunzTarPerm 420 ] +2468 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocket.integration.js +2469 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocket.integration.js', +2469 silly gunzTarPerm 438, +2469 silly gunzTarPerm 420 ] +2470 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Receiver.test.js +2471 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Receiver.test.js', +2471 silly gunzTarPerm 438, +2471 silly gunzTarPerm 420 ] +2472 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocketServer.test.js +2473 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/WebSocketServer.test.js', +2473 silly gunzTarPerm 438, +2473 silly gunzTarPerm 420 ] +2474 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Sender.hixie.test.js +2475 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/Sender.hixie.test.js', +2475 silly gunzTarPerm 438, +2475 silly gunzTarPerm 420 ] +2476 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/agent1-cert.pem +2477 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/agent1-cert.pem', +2477 silly gunzTarPerm 438, +2477 silly gunzTarPerm 420 ] +2478 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/agent1-key.pem +2479 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/agent1-key.pem', +2479 silly gunzTarPerm 438, +2479 silly gunzTarPerm 420 ] +2480 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/ca1-cert.pem +2481 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/ca1-cert.pem', +2481 silly gunzTarPerm 438, +2481 silly gunzTarPerm 420 ] +2482 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/ca1-key.pem +2483 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/ca1-key.pem', +2483 silly gunzTarPerm 438, +2483 silly gunzTarPerm 420 ] +2484 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/certificate.pem +2485 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/certificate.pem', +2485 silly gunzTarPerm 438, +2485 silly gunzTarPerm 420 ] +2486 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/key.pem +2487 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/key.pem', +2487 silly gunzTarPerm 438, +2487 silly gunzTarPerm 420 ] +2488 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/request.pem +2489 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/request.pem', +2489 silly gunzTarPerm 438, +2489 silly gunzTarPerm 420 ] +2490 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/textfile +2491 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/test/fixtures/textfile', +2491 silly gunzTarPerm 438, +2491 silly gunzTarPerm 420 ] +2492 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/browser.js +2493 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/browser.js', +2493 silly gunzTarPerm 438, +2493 silly gunzTarPerm 420 ] +2494 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferUtil.js +2495 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferUtil.js', +2495 silly gunzTarPerm 438, +2495 silly gunzTarPerm 420 ] +2496 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/ErrorCodes.js +2497 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/ErrorCodes.js', +2497 silly gunzTarPerm 438, +2497 silly gunzTarPerm 420 ] +2498 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Receiver.hixie.js +2499 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Receiver.hixie.js', +2499 silly gunzTarPerm 438, +2499 silly gunzTarPerm 420 ] +2500 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferUtil.fallback.js +2501 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferUtil.fallback.js', +2501 silly gunzTarPerm 438, +2501 silly gunzTarPerm 420 ] +2502 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Sender.hixie.js +2503 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Sender.hixie.js', +2503 silly gunzTarPerm 438, +2503 silly gunzTarPerm 420 ] +2504 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Sender.js +2505 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Sender.js', +2505 silly gunzTarPerm 438, +2505 silly gunzTarPerm 420 ] +2506 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Validation.fallback.js +2507 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Validation.fallback.js', +2507 silly gunzTarPerm 438, +2507 silly gunzTarPerm 420 ] +2508 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Validation.js +2509 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Validation.js', +2509 silly gunzTarPerm 438, +2509 silly gunzTarPerm 420 ] +2510 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/WebSocket.js +2511 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/WebSocket.js', +2511 silly gunzTarPerm 438, +2511 silly gunzTarPerm 420 ] +2512 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferPool.js +2513 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/BufferPool.js', +2513 silly gunzTarPerm 438, +2513 silly gunzTarPerm 420 ] +2514 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/WebSocketServer.js +2515 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/WebSocketServer.js', +2515 silly gunzTarPerm 438, +2515 silly gunzTarPerm 420 ] +2516 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Receiver.js +2517 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/lib/Receiver.js', +2517 silly gunzTarPerm 438, +2517 silly gunzTarPerm 420 ] +2518 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/Makefile +2519 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/Makefile', +2519 silly gunzTarPerm 438, +2519 silly gunzTarPerm 420 ] +2520 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/src/bufferutil.cc +2521 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/src/bufferutil.cc', +2521 silly gunzTarPerm 438, +2521 silly gunzTarPerm 420 ] +2522 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/src/validation.cc +2523 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/src/validation.cc', +2523 silly gunzTarPerm 438, +2523 silly gunzTarPerm 420 ] +2524 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/parser.benchmark.js +2525 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/parser.benchmark.js', +2525 silly gunzTarPerm 438, +2525 silly gunzTarPerm 420 ] +2526 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/sender.benchmark.js +2527 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/sender.benchmark.js', +2527 silly gunzTarPerm 438, +2527 silly gunzTarPerm 420 ] +2528 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/speed.js +2529 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/speed.js', +2529 silly gunzTarPerm 438, +2529 silly gunzTarPerm 420 ] +2530 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/util.js +2531 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bench/util.js', +2531 silly gunzTarPerm 438, +2531 silly gunzTarPerm 420 ] +2532 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bin/wscat +2533 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/bin/wscat', +2533 silly gunzTarPerm 438, +2533 silly gunzTarPerm 420 ] +2534 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/History.md +2535 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/History.md', +2535 silly gunzTarPerm 438, +2535 silly gunzTarPerm 420 ] +2536 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/package.json +2537 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/package.json', +2537 silly gunzTarPerm 438, +2537 silly gunzTarPerm 420 ] +2538 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/.npmignore +2539 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/.npmignore', +2539 silly gunzTarPerm 438, +2539 silly gunzTarPerm 420 ] +2540 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/index.js +2541 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/index.js', +2541 silly gunzTarPerm 438, +2541 silly gunzTarPerm 420 ] +2542 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/.travis.yml +2543 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/.travis.yml', +2543 silly gunzTarPerm 438, +2543 silly gunzTarPerm 420 ] +2544 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/History.md +2545 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/History.md', +2545 silly gunzTarPerm 438, +2545 silly gunzTarPerm 420 ] +2546 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/lib/commander.js +2547 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/lib/commander.js', +2547 silly gunzTarPerm 438, +2547 silly gunzTarPerm 420 ] +2548 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/Makefile +2549 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/Makefile', +2549 silly gunzTarPerm 438, +2549 silly gunzTarPerm 420 ] +2550 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/Readme.md +2551 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/commander/Readme.md', +2551 silly gunzTarPerm 438, +2551 silly gunzTarPerm 420 ] +2552 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/package.json +2553 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/package.json', +2553 silly gunzTarPerm 438, +2553 silly gunzTarPerm 420 ] +2554 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/README.md +2555 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/README.md', +2555 silly gunzTarPerm 438, +2555 silly gunzTarPerm 420 ] +2556 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/LICENSE +2557 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/LICENSE', +2557 silly gunzTarPerm 438, +2557 silly gunzTarPerm 420 ] +2558 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/.index.js +2559 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/.index.js', +2559 silly gunzTarPerm 438, +2559 silly gunzTarPerm 420 ] +2560 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/nan.h +2561 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/nan/nan.h', +2561 silly gunzTarPerm 438, +2561 silly gunzTarPerm 420 ] +2562 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/package.json +2563 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/package.json', +2563 silly gunzTarPerm 438, +2563 silly gunzTarPerm 420 ] +2564 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/.npmignore +2565 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/.npmignore', +2565 silly gunzTarPerm 438, +2565 silly gunzTarPerm 420 ] +2566 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/README.md +2567 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/README.md', +2567 silly gunzTarPerm 438, +2567 silly gunzTarPerm 420 ] +2568 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/lib/options.js +2569 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/lib/options.js', +2569 silly gunzTarPerm 438, +2569 silly gunzTarPerm 420 ] +2570 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/Makefile +2571 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/Makefile', +2571 silly gunzTarPerm 438, +2571 silly gunzTarPerm 420 ] +2572 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/test/options.test.js +2573 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/test/options.test.js', +2573 silly gunzTarPerm 438, +2573 silly gunzTarPerm 420 ] +2574 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/test/fixtures/test.conf +2575 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/options/test/fixtures/test.conf', +2575 silly gunzTarPerm 438, +2575 silly gunzTarPerm 420 ] +2576 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/package.json +2577 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/package.json', +2577 silly gunzTarPerm 438, +2577 silly gunzTarPerm 420 ] +2578 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/.npmignore +2579 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/.npmignore', +2579 silly gunzTarPerm 438, +2579 silly gunzTarPerm 420 ] +2580 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/README.md +2581 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/README.md', +2581 silly gunzTarPerm 438, +2581 silly gunzTarPerm 420 ] +2582 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/example.js +2583 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/example.js', +2583 silly gunzTarPerm 438, +2583 silly gunzTarPerm 420 ] +2584 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/tinycolor.js +2585 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws/node_modules/tinycolor/tinycolor.js', +2585 silly gunzTarPerm 438, +2585 silly gunzTarPerm 420 ] +2586 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/package.json +2587 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/package.json', +2587 silly gunzTarPerm 438, +2587 silly gunzTarPerm 420 ] +2588 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/README.md +2589 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/README.md', +2589 silly gunzTarPerm 438, +2589 silly gunzTarPerm 420 ] +2590 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/LICENSE +2591 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/LICENSE', +2591 silly gunzTarPerm 438, +2591 silly gunzTarPerm 420 ] +2592 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/autotest.watchr +2593 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/autotest.watchr', +2593 silly gunzTarPerm 438, +2593 silly gunzTarPerm 420 ] +2594 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/example/demo.js +2595 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/example/demo.js', +2595 silly gunzTarPerm 438, +2595 silly gunzTarPerm 420 ] +2596 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/lib/XMLHttpRequest.js +2597 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/lib/XMLHttpRequest.js', +2597 silly gunzTarPerm 438, +2597 silly gunzTarPerm 420 ] +2598 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-constants.js +2599 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-constants.js', +2599 silly gunzTarPerm 438, +2599 silly gunzTarPerm 420 ] +2600 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-events.js +2601 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-events.js', +2601 silly gunzTarPerm 438, +2601 silly gunzTarPerm 420 ] +2602 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-exceptions.js +2603 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-exceptions.js', +2603 silly gunzTarPerm 438, +2603 silly gunzTarPerm 420 ] +2604 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-headers.js +2605 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-headers.js', +2605 silly gunzTarPerm 438, +2605 silly gunzTarPerm 420 ] +2606 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-302.js +2607 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-302.js', +2607 silly gunzTarPerm 438, +2607 silly gunzTarPerm 420 ] +2608 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-303.js +2609 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-303.js', +2609 silly gunzTarPerm 438, +2609 silly gunzTarPerm 420 ] +2610 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-307.js +2611 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-redirect-307.js', +2611 silly gunzTarPerm 438, +2611 silly gunzTarPerm 420 ] +2612 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-request-methods.js +2613 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-request-methods.js', +2613 silly gunzTarPerm 438, +2613 silly gunzTarPerm 420 ] +2614 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-request-protocols.js +2615 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/test-request-protocols.js', +2615 silly gunzTarPerm 438, +2615 silly gunzTarPerm 420 ] +2616 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/testdata.txt +2617 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest/tests/testdata.txt', +2617 silly gunzTarPerm 438, +2617 silly gunzTarPerm 420 ] +2618 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/package.json +2619 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/package.json', +2619 silly gunzTarPerm 438, +2619 silly gunzTarPerm 420 ] +2620 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/.npmignore +2621 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/.npmignore', +2621 silly gunzTarPerm 438, +2621 silly gunzTarPerm 420 ] +2622 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/index.js +2623 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/index.js', +2623 silly gunzTarPerm 438, +2623 silly gunzTarPerm 420 ] +2624 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/component.json +2625 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/component.json', +2625 silly gunzTarPerm 438, +2625 silly gunzTarPerm 420 ] +2626 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/Makefile +2627 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/Makefile', +2627 silly gunzTarPerm 438, +2627 silly gunzTarPerm 420 ] +2628 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/Readme.md +2629 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/indexof/Readme.md', +2629 silly gunzTarPerm 438, +2629 silly gunzTarPerm 420 ] +2630 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/package.json +2631 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/package.json', +2631 silly gunzTarPerm 438, +2631 silly gunzTarPerm 420 ] +2632 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/.npmignore +2633 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/.npmignore', +2633 silly gunzTarPerm 438, +2633 silly gunzTarPerm 420 ] +2634 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/index.js +2635 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/index.js', +2635 silly gunzTarPerm 438, +2635 silly gunzTarPerm 420 ] +2636 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/component.json +2637 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/component.json', +2637 silly gunzTarPerm 438, +2637 silly gunzTarPerm 420 ] +2638 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/History.md +2639 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/History.md', +2639 silly gunzTarPerm 438, +2639 silly gunzTarPerm 420 ] +2640 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/Makefile +2641 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/Makefile', +2641 silly gunzTarPerm 438, +2641 silly gunzTarPerm 420 ] +2642 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/Readme.md +2643 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/Readme.md', +2643 silly gunzTarPerm 438, +2643 silly gunzTarPerm 420 ] +2644 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/test/object.js +2645 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/object-component/test/object.js', +2645 silly gunzTarPerm 438, +2645 silly gunzTarPerm 420 ] +2646 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/package.json +2647 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/package.json', +2647 silly gunzTarPerm 438, +2647 silly gunzTarPerm 420 ] +2648 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/index.js +2649 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/index.js', +2649 silly gunzTarPerm 438, +2649 silly gunzTarPerm 420 ] +2650 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/test.js +2651 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/test.js', +2651 silly gunzTarPerm 438, +2651 silly gunzTarPerm 420 ] +2652 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/History.md +2653 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/History.md', +2653 silly gunzTarPerm 438, +2653 silly gunzTarPerm 420 ] +2654 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/Makefile +2655 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/Makefile', +2655 silly gunzTarPerm 438, +2655 silly gunzTarPerm 420 ] +2656 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/package.json +2657 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/package.json', +2657 silly gunzTarPerm 438, +2657 silly gunzTarPerm 420 ] +2658 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/.npmignore +2659 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/.npmignore', +2659 silly gunzTarPerm 438, +2659 silly gunzTarPerm 420 ] +2660 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/example.js +2661 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/example.js', +2661 silly gunzTarPerm 438, +2661 silly gunzTarPerm 420 ] +2662 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/index.js +2663 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/index.js', +2663 silly gunzTarPerm 438, +2663 silly gunzTarPerm 420 ] +2664 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/History.md +2665 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/History.md', +2665 silly gunzTarPerm 438, +2665 silly gunzTarPerm 420 ] +2666 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/Makefile +2667 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/Makefile', +2667 silly gunzTarPerm 438, +2667 silly gunzTarPerm 420 ] +2668 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/Readme.md +2669 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/Readme.md', +2669 silly gunzTarPerm 438, +2669 silly gunzTarPerm 420 ] +2670 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/package.json +2671 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/package.json', +2671 silly gunzTarPerm 438, +2671 silly gunzTarPerm 420 ] +2672 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/.npmignore +2673 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/.npmignore', +2673 silly gunzTarPerm 438, +2673 silly gunzTarPerm 420 ] +2674 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/index.js +2675 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/index.js', +2675 silly gunzTarPerm 438, +2675 silly gunzTarPerm 420 ] +2676 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/History.md +2677 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/History.md', +2677 silly gunzTarPerm 438, +2677 silly gunzTarPerm 420 ] +2678 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/Makefile +2679 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/Makefile', +2679 silly gunzTarPerm 438, +2679 silly gunzTarPerm 420 ] +2680 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/Readme.md +2681 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/parseuri/node_modules/better-assert/node_modules/callsite/Readme.md', +2681 silly gunzTarPerm 438, +2681 silly gunzTarPerm 420 ] +2682 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/package.json +2683 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/package.json', +2683 silly gunzTarPerm 438, +2683 silly gunzTarPerm 420 ] +2684 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/.npmignore +2685 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/.npmignore', +2685 silly gunzTarPerm 438, +2685 silly gunzTarPerm 420 ] +2686 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/README.md +2687 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/README.md', +2687 silly gunzTarPerm 438, +2687 silly gunzTarPerm 420 ] +2688 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/LICENCE +2689 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/LICENCE', +2689 silly gunzTarPerm 438, +2689 silly gunzTarPerm 420 ] +2690 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/index.js +2691 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-client/node_modules/to-array/index.js', +2691 silly gunzTarPerm 438, +2691 silly gunzTarPerm 420 ] +2692 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/package.json +2693 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/package.json', +2693 silly gunzTarPerm 438, +2693 silly gunzTarPerm 420 ] +2694 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/.npmignore +2695 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/.npmignore', +2695 silly gunzTarPerm 438, +2695 silly gunzTarPerm 420 ] +2696 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/binary.js +2697 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/binary.js', +2697 silly gunzTarPerm 438, +2697 silly gunzTarPerm 420 ] +2698 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/index.js +2699 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/index.js', +2699 silly gunzTarPerm 438, +2699 silly gunzTarPerm 420 ] +2700 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/.travis.yml +2701 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/.travis.yml', +2701 silly gunzTarPerm 438, +2701 silly gunzTarPerm 420 ] +2702 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/.zuul.yml +2703 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/.zuul.yml', +2703 silly gunzTarPerm 438, +2703 silly gunzTarPerm 420 ] +2704 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/History.md +2705 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/History.md', +2705 silly gunzTarPerm 438, +2705 silly gunzTarPerm 420 ] +2706 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/Makefile +2707 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/Makefile', +2707 silly gunzTarPerm 438, +2707 silly gunzTarPerm 420 ] +2708 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/Readme.md +2709 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/Readme.md', +2709 silly gunzTarPerm 438, +2709 silly gunzTarPerm 420 ] +2710 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/package.json +2711 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/package.json', +2711 silly gunzTarPerm 438, +2711 silly gunzTarPerm 420 ] +2712 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/.npmignore +2713 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/.npmignore', +2713 silly gunzTarPerm 438, +2713 silly gunzTarPerm 420 ] +2714 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/index.js +2715 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/index.js', +2715 silly gunzTarPerm 438, +2715 silly gunzTarPerm 420 ] +2716 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/component.json +2717 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/component.json', +2717 silly gunzTarPerm 438, +2717 silly gunzTarPerm 420 ] +2718 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/History.md +2719 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/History.md', +2719 silly gunzTarPerm 438, +2719 silly gunzTarPerm 420 ] +2720 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/Makefile +2721 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/Makefile', +2721 silly gunzTarPerm 438, +2721 silly gunzTarPerm 420 ] +2722 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/Readme.md +2723 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/Readme.md', +2723 silly gunzTarPerm 438, +2723 silly gunzTarPerm 420 ] +2724 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/test/emitter.js +2725 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/test/emitter.js', +2725 silly gunzTarPerm 438, +2725 silly gunzTarPerm 420 ] +2726 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/package.json +2727 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/package.json', +2727 silly gunzTarPerm 438, +2727 silly gunzTarPerm 420 ] +2728 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/.npmignore +2729 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/.npmignore', +2729 silly gunzTarPerm 438, +2729 silly gunzTarPerm 420 ] +2730 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/index.js +2731 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/index.js', +2731 silly gunzTarPerm 438, +2731 silly gunzTarPerm 420 ] +2732 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/component.json +2733 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/component.json', +2733 silly gunzTarPerm 438, +2733 silly gunzTarPerm 420 ] +2734 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Makefile +2735 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Makefile', +2735 silly gunzTarPerm 438, +2735 silly gunzTarPerm 420 ] +2736 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Readme.md +2737 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/emitter/node_modules/indexof/Readme.md', +2737 silly gunzTarPerm 438, +2737 silly gunzTarPerm 420 ] +2738 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/package.json +2739 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/package.json', +2739 silly gunzTarPerm 438, +2739 silly gunzTarPerm 420 ] +2740 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/README.md +2741 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/README.md', +2741 silly gunzTarPerm 438, +2741 silly gunzTarPerm 420 ] +2742 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/index.js +2743 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/index.js', +2743 silly gunzTarPerm 438, +2743 silly gunzTarPerm 420 ] +2744 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/build/build.js +2745 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/build/build.js', +2745 silly gunzTarPerm 438, +2745 silly gunzTarPerm 420 ] +2746 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/component.json +2747 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/isarray/component.json', +2747 silly gunzTarPerm 438, +2747 silly gunzTarPerm 420 ] +2748 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/package.json +2749 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/package.json', +2749 silly gunzTarPerm 438, +2749 silly gunzTarPerm 420 ] +2750 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.npmignore +2751 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.npmignore', +2751 silly gunzTarPerm 438, +2751 silly gunzTarPerm 420 ] +2752 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/README.md +2753 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/README.md', +2753 silly gunzTarPerm 438, +2753 silly gunzTarPerm 420 ] +2754 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/LICENSE +2755 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/LICENSE', +2755 silly gunzTarPerm 438, +2755 silly gunzTarPerm 420 ] +2756 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.gitmodules +2757 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.gitmodules', +2757 silly gunzTarPerm 438, +2757 silly gunzTarPerm 420 ] +2758 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.jamignore +2759 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.jamignore', +2759 silly gunzTarPerm 438, +2759 silly gunzTarPerm 420 ] +2760 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.travis.yml +2761 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/.travis.yml', +2761 silly gunzTarPerm 438, +2761 silly gunzTarPerm 420 ] +2762 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/coverage.json +2763 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/coverage.json', +2763 silly gunzTarPerm 438, +2763 silly gunzTarPerm 420 ] +2764 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.js +2765 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.js', +2765 silly gunzTarPerm 438, +2765 silly gunzTarPerm 420 ] +2766 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/lib/json3.js.html +2767 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/lib/json3.js.html', +2767 silly gunzTarPerm 438, +2767 silly gunzTarPerm 420 ] +2768 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.css +2769 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov-report/prettify.css', +2769 silly gunzTarPerm 438, +2769 silly gunzTarPerm 420 ] +2770 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov.info +2771 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/coverage/lcov.info', +2771 silly gunzTarPerm 438, +2771 silly gunzTarPerm 420 ] +2772 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/lib/json3.js +2773 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/lib/json3.js', +2773 silly gunzTarPerm 438, +2773 silly gunzTarPerm 420 ] +2774 silly gunzTarPerm extractEntry lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/lib/json3.min.js +2775 silly gunzTarPerm modified mode [ 'lib/original/node_modules/socket.io/node_modules/socket.io-parser/node_modules/json3/lib/json3.min.js', +2775 silly gunzTarPerm 438, +2775 silly gunzTarPerm 420 ] +2776 silly gunzTarPerm extractEntry Readme.md +2777 silly gunzTarPerm modified mode [ 'Readme.md', 438, 420 ] +2778 verbose read json C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package\package.json +2779 silly lockFile 85695f29-pm-cache-vast-js-0-0-1-2-package C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package +2780 silly lockFile 85695f29-pm-cache-vast-js-0-0-1-2-package C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package +2781 silly lockFile 1d6723ff-ache-vast-js-0-0-1-2-package-tgz C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +2782 silly lockFile 1d6723ff-ache-vast-js-0-0-1-2-package-tgz C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +2783 silly shasum updated bytes 65536 +2784 silly shasum updated bytes 65536 +2785 silly shasum updated bytes 65536 +2786 silly shasum updated bytes 65536 +2787 silly shasum updated bytes 65536 +2788 silly shasum updated bytes 65536 +2789 silly shasum updated bytes 65536 +2790 silly shasum updated bytes 65536 +2791 silly shasum updated bytes 65536 +2792 silly shasum updated bytes 65536 +2793 silly shasum updated bytes 65536 +2794 silly shasum updated bytes 65536 +2795 silly shasum updated bytes 33914 +2796 info shasum d27e942d9642cc6fa634b849a0e44c45ff66fd65 +2796 info shasum C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +2797 verbose from cache C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package\package.json +2798 verbose chmod C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz 644 +2799 silly chown skipping for windows C:\Users\syhu\AppData\Roaming\npm-cache\vast.js\0.0.1-2\package.tgz +2800 silly lockFile 3a52ce78- . +2801 silly publish { name: 'vast.js', +2801 silly publish version: '0.0.1-2', +2801 silly publish description: 'a P2P library for spatial publish subscribe (SPS)', +2801 silly publish main: 'index.js', +2801 silly publish scripts: { test: 'echo "Error: no test specified" && exit 1' }, +2801 silly publish repository: { type: 'git', url: 'git://github.com/Imonology/VAST.js' }, +2801 silly publish dependencies: { 'socket.io': '1.0.6', debug: '0.7.4' }, +2801 silly publish keywords: +2801 silly publish [ 'peer-to-peer', +2801 silly publish 'P2P', +2801 silly publish 'spatial', +2801 silly publish 'publish', +2801 silly publish 'subscribe', +2801 silly publish 'pubsub', +2801 silly publish 'real-time', +2801 silly publish 'games', +2801 silly publish 'vast' ], +2801 silly publish author: { name: 'Shun-Yun Hu' }, +2801 silly publish license: 'GPLv3', +2801 silly publish bugs: { url: 'https://github.com/Imonology/VAST.js/issues' }, +2801 silly publish homepage: 'https://github.com/Imonology/VAST.js', +2801 silly publish readme: '\n# vast.js\n\n## How to use\n\nThe following example initializes vast.js to a plain Node.JS\nHTTP server listening on port `3000`.\n\n```js\nvar server = require(\'http\').Server();\nvar vast = require(\'vast.js\')(server);\n\nvast.on(\'connection\', function (socket) {\n\n\t// to perform a spatial publication\n\tsocket.publish({name: John}, {center: [35, 45], radius: 100});\n\t\n\t// to subscribe a radius\n\tsocket.subscribe({center: [50, 33], radius: 100}, function (node) {\n\t\t// move subscribed area to another center point\n\t\tnode.move({center: [55, 33]});\n\t});\n \n\t// receive subscribed messages\n\tsocket.on(\'message\', function (data){});\n\t\n\t// receive enter / leave messages\n\tsocket.on(\'enter\', function (node){});\n\tsocket.on(\'leave\', function (node){});\n\n\t// process disconnection from network\n\tsocket.on(\'disconnect\', function(){});\n});\nserver.listen(3000);\n```\n\n### Standalone\n\n```js\nvar vast = require(\'vast.js\')();\nvast.on(\'connection\', function(socket){});\nvast.listen(3000);\n```\n\n### In conjunction with ImonCloud\n\n\n\n## License\n\nGPLv3\n', +2801 silly publish readmeFilename: 'Readme.md', +2801 silly publish _id: 'vast.js@0.0.1-2', +2801 silly publish dist: { shasum: 'd27e942d9642cc6fa634b849a0e44c45ff66fd65' }, +2801 silly publish _from: '.' } +2802 error need auth auth and email required for publishing +2802 error need auth You need to authorize this machine using `npm adduser` +2803 error System Windows_NT 6.1.7601 +2804 error command "C:\\Program Files\\nodejs\\\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "publish" +2805 error cwd d:\syhu\Dropbox\work\vast.js +2806 error node -v v0.10.6 +2807 error npm -v 1.2.18 +2808 error code ENEEDAUTH +2809 verbose exit [ 1, true ] diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..204f8070 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2138 @@ +{ + "name": "vast.js", + "version": "0.0.1-2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@opencensus/core": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz", + "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==", + "requires": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^5.5.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "@opencensus/propagation-b3": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz", + "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==", + "requires": { + "@opencensus/core": "^0.0.8", + "uuid": "^3.2.1" + }, + "dependencies": { + "@opencensus/core": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz", + "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==", + "requires": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^5.5.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "@pm2/agent": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.1.tgz", + "integrity": "sha512-QKHMm6yexcvdDfcNE7PL9D6uEjoQPGRi+8dh+rc4Hwtbpsbh5IAvZbz3BVGjcd4HaX6pt2xGpOohG7/Y2L4QLw==", + "requires": { + "async": "~3.2.0", + "chalk": "~3.0.0", + "dayjs": "~1.8.24", + "debug": "~4.3.1", + "eventemitter2": "~5.0.1", + "fast-json-patch": "^3.0.0-1", + "fclone": "~1.0.11", + "nssocket": "0.6.0", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.0", + "proxy-agent": "~5.0.0", + "semver": "~7.2.0", + "ws": "~7.4.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + }, + "semver": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.3.tgz", + "integrity": "sha512-utbW9Z7ZxVvwiIWkdOMLOR9G/NFXh2aRucghkVrEMJWuC++r3lCkBC3LwqBinyHzGMAJxY5tn6VakZGHObq5ig==" + } + } + }, + "@pm2/io": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@pm2/io/-/io-5.0.0.tgz", + "integrity": "sha512-3rToDVJaRoob5Lq8+7Q2TZFruoEkdORxwzFpZaqF4bmH6Bkd7kAbdPrI/z8X6k1Meq5rTtScM7MmDgppH6aLlw==", + "requires": { + "@opencensus/core": "0.0.9", + "@opencensus/propagation-b3": "0.0.8", + "async": "~2.6.1", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "require-in-the-middle": "^5.0.0", + "semver": "6.3.0", + "shimmer": "^1.2.0", + "signal-exit": "^3.0.3", + "tslib": "1.9.3" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + }, + "eventemitter2": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", + "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + } + } + }, + "@pm2/js-api": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz", + "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==", + "requires": { + "async": "^2.6.3", + "axios": "^0.21.0", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "ws": "^7.0.0" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + }, + "eventemitter2": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", + "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==" + } + } + }, + "@pm2/pm2-version-check": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", + "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", + "requires": { + "debug": "^4.3.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@socket.io/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==" + }, + "@socket.io/component-emitter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz", + "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "@types/component-emitter": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", + "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" + }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + }, + "@types/node": { + "version": "17.0.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", + "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "amp": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", + "integrity": "sha1-at+NWKdPNh6CwfqNOJwHnhOfxH0=" + }, + "amp-message": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", + "integrity": "sha1-p48cmJlQh602GSpBKY5NtJ49/EU=", + "requires": { + "amp": "0.3.1" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + } + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "requires": { + "tslib": "^2.0.1" + } + }, + "async": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==" + }, + "async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "requires": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "blessed": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", + "integrity": "sha1-+WLWh+wsNpVwrnGvhDJW5tDKESk=" + }, + "bodec": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz", + "integrity": "sha1-vIUVVUMPI8n3ZQp172TGqUw0GMw=" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "bootstrap": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", + "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "charm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", + "integrity": "sha1-BsIe7RobBq62dVPNxT4jJ0usIpY=" + }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "cli-tableau": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", + "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", + "requires": { + "chalk": "3.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "requires": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cron": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz", + "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==", + "requires": { + "moment-timezone": "^0.5.x" + } + }, + "culvert": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", + "integrity": "sha1-lQL18BVKLVoioCPnn3HMk2+m728=" + }, + "data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==" + }, + "dayjs": { + "version": "1.8.36", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", + "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" + }, + "debug": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz", + "integrity": "sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=" + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "degenerator": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.1.tgz", + "integrity": "sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ==", + "requires": { + "ast-types": "^0.13.2", + "escodegen": "^1.8.1", + "esprima": "^4.0.0", + "vm2": "^3.9.3" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "requires": { + "shimmer": "^1.2.0" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "engine.io": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.2.tgz", + "integrity": "sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ==", + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.0", + "ws": "~7.4.2" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "engine.io-client": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz", + "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", + "requires": { + "@socket.io/component-emitter": "~3.0.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.0", + "has-cors": "1.1.0", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "engine.io-parser": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", + "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", + "requires": { + "@socket.io/base64-arraybuffer": "~1.0.2" + } + }, + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" + } + } + }, + "engine.io-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", + "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", + "requires": { + "base64-arraybuffer": "0.1.4" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "eventemitter2": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", + "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "fast-json-patch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.0.tgz", + "integrity": "sha512-IhpytlsVTRndz0hU5t0/MGzS/etxLlfrpG5V5M9mVbuj9TrJLWaMfsox9REM5rkuGX0T+5qjpe8XA1o0gZ42nA==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=" + }, + "file-uri-to-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", + "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "follow-redirects": { + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "requires": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", + "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", + "requires": { + "@tootallnate/once": "1", + "data-uri-to-buffer": "3", + "debug": "4", + "file-uri-to-path": "2", + "fs-extra": "^8.1.0", + "ftp": "^0.3.10" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "git-node-fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz", + "integrity": "sha1-SbIV4kLr5Dqkx1Ybu6SZUhdSCA8=" + }, + "git-sha1": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz", + "integrity": "sha1-WZrBkrcYdYJeE6RF86bgURjC90U=" + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "jquery": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" + }, + "js-git": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", + "integrity": "sha1-UvplWrYYd9bxB578ZTS1VPMeVEQ=", + "requires": { + "bodec": "^0.1.0", + "culvert": "^0.1.2", + "git-sha1": "^0.1.2", + "pako": "^0.2.5" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "optional": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lazy": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", + "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" + }, + "mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "requires": { + "mime-db": "1.49.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "module-details-from-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "moment-timezone": { + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "needle": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", + "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "nssocket": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz", + "integrity": "sha1-Wflvb/MhVm8zxw99vu7N/cBxVPo=", + "requires": { + "eventemitter2": "~0.4.14", + "lazy": "~1.0.11" + }, + "dependencies": { + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=" + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-sizeof": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/object-sizeof/-/object-sizeof-1.6.1.tgz", + "integrity": "sha512-gNKGcRnDRXwEpAdwUY3Ef+aVZIrcQVXozSaVzHz6Pv4JxysH8vf5F+nIgsqW5T/YNwZNveh0mIW7PEH1O2MrDw==", + "requires": { + "buffer": "^5.6.0" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "pac-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", + "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4", + "get-uri": "3", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "5", + "pac-resolver": "^5.0.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "5" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "pac-resolver": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.0.tgz", + "integrity": "sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA==", + "requires": { + "degenerator": "^3.0.1", + "ip": "^1.1.5", + "netmask": "^2.0.1" + } + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=" + }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + }, + "pidusage": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "requires": { + "safe-buffer": "^5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "pm2": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.1.2.tgz", + "integrity": "sha512-2nJQeCWjkN0WnTkWctaoZpqrJTiUN/Icw76IMVHHzPhr/p7yQYlEQgHzlL5IFWxO2N1HdBNXNdZft2p4HUmUcA==", + "requires": { + "@pm2/agent": "~2.0.0", + "@pm2/io": "~5.0.0", + "@pm2/js-api": "~0.6.7", + "@pm2/pm2-version-check": "^1.0.4", + "async": "~3.2.0", + "blessed": "0.1.81", + "chalk": "3.0.0", + "chokidar": "^3.5.1", + "cli-tableau": "^2.0.0", + "commander": "2.15.1", + "cron": "1.8.2", + "dayjs": "~1.8.25", + "debug": "^4.3.1", + "enquirer": "2.3.6", + "eventemitter2": "5.0.1", + "fclone": "1.0.11", + "mkdirp": "1.0.4", + "needle": "2.4.0", + "pidusage": "2.0.21", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.1", + "pm2-deploy": "~1.0.2", + "pm2-multimeter": "^0.1.2", + "pm2-sysmonit": "^1.2.8", + "promptly": "^2", + "semver": "^7.2", + "source-map-support": "0.5.19", + "sprintf-js": "1.1.2", + "vizion": "~2.2.1", + "yamljs": "0.3.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "pm2-axon": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz", + "integrity": "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==", + "requires": { + "amp": "~0.3.1", + "amp-message": "~0.1.1", + "debug": "^4.3.1", + "escape-string-regexp": "^4.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "pm2-axon-rpc": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz", + "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==", + "requires": { + "debug": "^4.3.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "pm2-deploy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", + "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==", + "requires": { + "run-series": "^1.1.8", + "tv4": "^1.3.0" + } + }, + "pm2-multimeter": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", + "integrity": "sha1-Gh5VFT1BoFU0zqI8/oYKuqDrSs4=", + "requires": { + "charm": "~0.1.1" + } + }, + "pm2-sysmonit": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz", + "integrity": "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==", + "optional": true, + "requires": { + "async": "^3.2.0", + "debug": "^4.3.1", + "pidusage": "^2.0.21", + "systeminformation": "^5.7", + "tx2": "~1.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "optional": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "promptly": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", + "integrity": "sha1-KhP6BjaIoqWYOxYf/wEIoH0m/HQ=", + "requires": { + "read": "^1.0.4" + } + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", + "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", + "requires": { + "agent-base": "^6.0.0", + "debug": "4", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "lru-cache": "^5.1.1", + "pac-proxy-agent": "^5.0.0", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^5.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "requires": { + "mute-stream": "~0.0.4" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-in-the-middle": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", + "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", + "requires": { + "debug": "^4.1.1", + "module-details-from-path": "^1.0.3", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "run-series": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, + "signal-exit": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socket.io": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", + "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", + "requires": { + "@types/cookie": "^0.4.0", + "@types/cors": "^2.8.8", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.1", + "engine.io": "~4.1.0", + "socket.io-adapter": "~2.1.0", + "socket.io-parser": "~4.0.3" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "socket.io-adapter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", + "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==" + }, + "socket.io-client": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.1.tgz", + "integrity": "sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==", + "requires": { + "@socket.io/component-emitter": "~3.0.0", + "backo2": "~1.0.2", + "debug": "~4.3.2", + "engine.io-client": "~6.1.1", + "parseuri": "0.0.6", + "socket.io-parser": "~4.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "socket.io-parser": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.2.tgz", + "integrity": "sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog==", + "requires": { + "@socket.io/component-emitter": "~3.0.0", + "debug": "~4.3.1" + } + } + } + }, + "socket.io-parser": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "requires": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "socks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", + "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", + "requires": { + "agent-base": "^6.0.2", + "debug": "4", + "socks": "^2.3.3" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "systeminformation": { + "version": "5.9.7", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.9.7.tgz", + "integrity": "sha512-Vcmc8HaWPMFM4DoasuKN2lpvIwS2AqaoPuEGZc4HCT6tlRJH+IQ5GhA2BrUgjpBDJjFMj2Bti6qLOzP3T1arCw==", + "optional": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "tv4": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", + "integrity": "sha1-0CDIRvrdUMhVq7JeuuzGj8EPeWM=" + }, + "tx2": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tx2/-/tx2-1.0.4.tgz", + "integrity": "sha512-rU+y30nUY3PyIi+znvv74HzxlpULKwMPAyRK+YiCjvGkk3rY3fic3D6Z+avLpun3V5A6HFwPQ9JrBTMNEV/dxg==", + "optional": true, + "requires": { + "json-stringify-safe": "^5.0.1" + } + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "vizion": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz", + "integrity": "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==", + "requires": { + "async": "^2.6.3", + "git-node-fs": "^1.0.0", + "ini": "^1.3.5", + "js-git": "^0.7.8" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + } + } + }, + "vm2": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.5.tgz", + "integrity": "sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "worker-threads": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/worker-threads/-/worker-threads-1.0.0.tgz", + "integrity": "sha512-vK6Hhvph8oLxocEJIlc3YfGAZhm210uGzjZsXSu+JYLAQ/s/w4Tqgl60JrdH58hW8NSGP4m3bp8a92qPXgX05w==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + }, + "xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" + }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "requires": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..029fc5a6 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "vast.js", + "version": "0.0.1-2", + "description": "a P2P library for spatial publish subscribe (SPS)", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git://github.com/Imonology/VAST.js" + }, + "dependencies": { + "bootstrap": "^5.1.3", + "debug": "0.8.1", + "express": "^4.17.1", + "jquery": "^3.6.0", + "object-sizeof": "^1.6.1", + "pm2": "^5.1.2", + "socket.io": "^3.1.2", + "socket.io-client": "^4.4.1", + "worker-threads": "^1.0.0" + }, + "keywords": [ + "peer-to-peer", + "P2P", + "spatial", + "publish", + "subscribe", + "pubsub", + "real-time", + "games", + "vast" + ], + "author": "Shun-Yun Hu", + "license": "GPLv3", + "bugs": { + "url": "https://github.com/Imonology/VAST.js/issues" + }, + "homepage": "https://github.com/Imonology/VAST.js" +} diff --git a/rhill-voronoi-core-min.js b/rhill-voronoi-core-min.js deleted file mode 100644 index 37164c92..00000000 --- a/rhill-voronoi-core-min.js +++ /dev/null @@ -1,112 +0,0 @@ -/*! -A custom Javascript implementation of Steven J. Fortune's algorithm to -compute Voronoi diagrams. -Copyright (C) 2010 Raymond Hill - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -***** - -Author: Raymond Hill (rhill@raymondhill.net) -File: rhill-voronoi-core.js -Version: 0.9 -Date: Sep. 21, 2010 -Description: This is my personal Javascript implementation of -Steven Fortune's algorithm to generate Voronoi diagrams. - -Portions of this software use, or depend on the work of: - - "Fortune's algorithm" by Steven J. Fortune: For his clever - algorithm to compute Voronoi diagrams. - http://ect.bell-labs.com/who/sjf/ - - "The Liang-Barsky line clipping algorithm in a nutshell!" by Daniel White, - to efficiently clip a line within a rectangle. - http://www.skytopia.com/project/articles/compsci/clipping.html - -***** - -Usage: - - var vertices = [{x:300,y:300}, {x:100,y:100}, {x:200,y:500}, {x:250,y:450}, {x:600,y:150}]; - // xl, xr means x left, x right - // yt, yb means y top, y bottom - var bbox = {xl:0, xr:800, yt:0, yb:600}; - var voronoi = new Voronoi(); - // pass an array of objects, each of which exhibits x and y properties - voronoi.setSites(vertices); - // pass an object which exhibits xl, xr, yt, yb properties. The bounding - // box will be used to connect unbound edges, and to close open cells - result = voronoi.compute(bbox); - // render, further analyze, etc. - -Return value: - An object with the following properties: - - result.sites = an array of unordered, unique Voronoi.Site objects underlying the Voronoi diagram. - result.edges = an array of unordered, unique Voronoi.Edge objects making up the Voronoi diagram. - result.cells = a dictionary of Voronoi.Cell object making up the Voronoi diagram. The Voronoi.Cell - in the dictionary are keyed on their associated Voronoi.Site's unique id. - result.execTime = the time it took to compute the Voronoi diagram, in milliseconds. - -Voronoi.Site object: - id: a unique id identifying this Voronoi site. - x: the x position of this Voronoi site. - y: the y position of this Voronoi site. - destroy(): mark this Voronoi site object as destroyed, it will be removed from the - internal collection and won't be part of the next Voronoi diagram computation. - - When adding vertices to the Voronoi object, through Voronoi.setSites() or - Voronoi.addSites(), an internal collection of matching Voronoi.Site object is maintained, - which is read accessible at all time through Voronoi.getSites(). You are allowed to - change the x and/or y properties of any Voronoi.Site object in the array, before - launching the computation of the Voronoi diagram. However, do *not* change the id - of any Voronoi.Site object, this could break the computation of the Voronoi diagram. - -Voronoi.Edge object: - id: a unique id identifying this Voronoi edge. - lSite: the Voronoi.Site object at the left of this Voronoi.Edge object. - rSite: the Voronoi.Site object at the right of this Voronoi.Edge object (can be null). - va: the Voronoi.Vertex object defining the start point (relative to the Voronoi.Site - on the left) of this Voronoi.Edge object. - vb: the Voronoi.Vertex object defining the end point (relative to Voronoi.Site on - the left) of this Voronoi.Edge object. - - For edges which are used to close open cells (using the supplied bounding box), the - rSite property will be null. - -Voronoi.Cells object: - A collection of Voronoi.Cell objects, keyed on the id of the associated Voronoi.Site - object. - numCells: the number of Voronoi.Cell objects in the collection. - -Voronoi.Cell object: - site: the Voronoi.Site object associated with the Voronoi cell. - halfedges: an array of Voronoi.Halfedge objects, ordered counterclockwise, defining the - polygon for this Voronoi cell. - -Voronoi.Halfedge object: - site: the Voronoi.Site object owning this Voronoi.Halfedge object. - edge: a reference to the unique Voronoi.Edge object underlying this Voronoi.Halfedge object. - getStartpoint(): a method returning a Voronoi.Vertex for the start point of this - halfedge. Keep in mind halfedges are always countercockwise. - getEndpoint(): a method returning a Voronoi.Vertex for the end point of this - halfedge. Keep in mind halfedges are always countercockwise. - -Voronoi.Vertex object: - x: the x coordinate. - y: the y coordinate. - -*/ -function Voronoi(){this.sites=[];this.siteEvents=[];this.circEvents=[];this.arcs=[];this.edges=[];this.cells=new this.Cells()}Voronoi.prototype.SITE_EVENT=0;Voronoi.prototype.CIRCLE_EVENT=1;Voronoi.prototype.VOID_EVENT=-1;Voronoi.prototype.sqrt=self.Math.sqrt;Voronoi.prototype.abs=self.Math.abs;Voronoi.prototype.floor=self.Math.floor;Voronoi.prototype.random=self.Math.random;Voronoi.prototype.round=self.Math.round;Voronoi.prototype.min=self.Math.min;Voronoi.prototype.max=self.Math.max;Voronoi.prototype.pow=self.Math.pow;Voronoi.prototype.isNaN=self.isNaN;Voronoi.prototype.PI=self.Math.PI;Voronoi.prototype.EPSILON=0.00001;Voronoi.prototype.equalWithEpsilon=function(d,c){return this.abs(d-c)<0.00001};Voronoi.prototype.greaterThanWithEpsilon=function(d,c){return(d-c)>0.00001};Voronoi.prototype.greaterThanOrEqualWithEpsilon=function(d,c){return(c-d)<0.00001};Voronoi.prototype.lessThanWithEpsilon=function(d,c){return(c-d)>0.00001};Voronoi.prototype.lessThanOrEqualWithEpsilon=function(d,c){return(d-c)<0.00001};Voronoi.prototype.Beachsection=function(a){this.site=a;this.edge=null;this.sweep=-Infinity;this.lid=0;this.circleEvent=undefined};Voronoi.prototype.Beachsection.prototype.sqrt=self.Math.sqrt;Voronoi.prototype.Beachsection.prototype._leftParabolicCut=function(a,e,f){var m=a.x;var l=a.y;if(l==f){return m}var h=e.x;var g=e.y;if(g==f){return h}if(l==g){return(m+h)/2}var k=l-f;var d=g-f;var c=h-m;var j=1/k-1/d;var i=c/d;return(-i+this.sqrt(i*i-2*j*(c*c/(-2*d)-g+d/2+l-k/2)))/j+m};Voronoi.prototype.Beachsection.prototype.leftParabolicCut=function(b,a){if(this.sweep!==a||this.lid!==b.id){this.sweep=a;this.lid=b.id;this.lBreak=this._leftParabolicCut(this.site,b,a)}return this.lBreak};Voronoi.prototype.Beachsection.prototype.isCollapsing=function(){return this.circleEvent!==undefined&&this.circleEvent.type===Voronoi.prototype.CIRCLE_EVENT};Voronoi.prototype.Site=function(a,b){this.id=this.constructor.prototype.idgenerator++;this.x=a;this.y=b};Voronoi.prototype.Site.prototype.destroy=function(){this.id=0};Voronoi.prototype.Vertex=function(a,b){this.x=a;this.y=b};Voronoi.prototype.Edge=function(b,a){this.id=this.constructor.prototype.idgenerator++;this.lSite=b;this.rSite=a;this.va=this.vb=undefined};Voronoi.prototype.Halfedge=function(a,b){this.site=a;this.edge=b};Voronoi.prototype.Cell=function(a){this.site=a;this.halfedges=[]};Voronoi.prototype.Cells=function(){this.numCells=0};Voronoi.prototype.Cells.prototype.addCell=function(a){this[a.site.id]=a;this.numCells++};Voronoi.prototype.Cells.prototype.removeCell=function(a){delete this[a.site.id];this.numCells--};Voronoi.prototype.Site.prototype.idgenerator=1;Voronoi.prototype.Edge.prototype.isLineSegment=function(){return this.id!==0&&Boolean(this.va)&&Boolean(this.vb)};Voronoi.prototype.Edge.prototype.idgenerator=1;Voronoi.prototype.Halfedge.prototype.isLineSegment=function(){return this.edge.id!==0&&Boolean(this.edge.va)&&Boolean(this.edge.vb)};Voronoi.prototype.Halfedge.prototype.getStartpoint=function(){return this.edge.lSite.id==this.site.id?this.edge.va:this.edge.vb};Voronoi.prototype.Halfedge.prototype.getEndpoint=function(){return this.edge.lSite.id==this.site.id?this.edge.vb:this.edge.va};Voronoi.prototype.leftBreakPoint=function(d,c){var b=this.arcs[d];var a=b.site;if(a.y==c){return a.x}if(d===0){return -Infinity}return b.leftParabolicCut(this.arcs[d-1].site,c)};Voronoi.prototype.rightBreakPoint=function(c,b){if(c>1;if(this.lessThanWithEpsilon(a,this.leftBreakPoint(c,e))){d=c;continue}if(this.greaterThanOrEqualWithEpsilon(a,this.rightBreakPoint(c,e))){b=c+1;continue}return c}return b};Voronoi.prototype.findDeletionPoint=function(a,e){var g=this.arcs.length;if(!g){return 0}var b=0;var d=g;var c;var f;while(b>1;f=this.leftBreakPoint(c,e);if(this.lessThanWithEpsilon(a,f)){d=c;continue}if(this.greaterThanWithEpsilon(a,f)){b=c+1;continue}f=this.rightBreakPoint(c,e);if(this.greaterThanWithEpsilon(a,f)){b=c+1;continue}if(this.lessThanWithEpsilon(a,f)){d=c;continue}return c}};Voronoi.prototype.createEdge=function(e,a,d,b){var c=new this.Edge(e,a);this.edges.push(c);if(d!==undefined){this.setEdgeStartpoint(c,e,a,d)}if(b!==undefined){this.setEdgeEndpoint(c,e,a,b)}this.cells[e.id].halfedges.push(new this.Halfedge(e,c));this.cells[a.id].halfedges.push(new this.Halfedge(a,c));return c};Voronoi.prototype.createBorderEdge=function(d,c,a){var b=new this.Edge(d,null);b.va=c;b.vb=a;this.edges.push(b);return b};Voronoi.prototype.destroyEdge=function(a){a.id=0};Voronoi.prototype.setEdgeStartpoint=function(b,d,a,c){if(b.va===undefined&&b.vb===undefined){b.va=c;b.lSite=d;b.rSite=a}else{if(b.lSite.id==a.id){b.vb=c}else{b.va=c}}};Voronoi.prototype.setEdgeEndpoint=function(b,d,a,c){this.setEdgeStartpoint(b,a,d,c)};Voronoi.prototype.removeArc=function(a){var g=a.center.x;var d=a.center.y;var i=a.y;var e=this.findDeletionPoint(g,i);var c=e;while(c-1>0&&this.equalWithEpsilon(g,this.leftBreakPoint(c-1,i))){c--}var h=e;while(h+10&&this.equalWithEpsilon(a.x,this.rightBreakPoint(b-1,a.y))&&this.equalWithEpsilon(a.x,this.leftBreakPoint(b,a.y))){c=this.arcs[b-1];f=this.arcs[b];this.voidCircleEvents(b-1,b);var d=this.circumcircle(c.site,a,f.site);this.setEdgeStartpoint(f.edge,c.site,f.site,new this.Vertex(d.x,d.y));e.edge=this.createEdge(c.site,e.site,undefined,new this.Vertex(d.x,d.y));f.edge=this.createEdge(e.site,f.site,undefined,new this.Vertex(d.x,d.y));this.arcs.splice(b,0,e);this.addCircleEvents(b-1,a.y);this.addCircleEvents(b+1,a.y);return}this.voidCircleEvents(b);c=this.arcs[b];f=new this.Beachsection(c.site);this.arcs.splice(b+1,0,e,f);e.edge=f.edge=this.createEdge(c.site,e.site);this.addCircleEvents(b,a.y);this.addCircleEvents(b+2,a.y)};Voronoi.prototype.circumcircle=function(q,o,l){var e=q.x;var r=q.y;var m=o.x-e;var k=o.y-r;var g=l.x-e;var f=l.y-r;var j=2*(m*f-k*g);var i=m*m+k*k;var h=g*g+f*f;var p=(f*i-k*h)/j;var n=(m*h-g*i)/j;return{x:p+e,y:n+r,radius:this.sqrt(p*p+n*n)}};Voronoi.prototype.addCircleEvents=function(g,i){if(g<=0||g>=this.arcs.length-1){return}var d=this.arcs[g];var a=this.arcs[g-1].site;var h=this.arcs[g].site;var e=this.arcs[g+1].site;if(a.id==e.id||a.id==h.id||h.id==e.id){return}if((a.y-h.y)*(e.x-h.x)<=(a.x-h.x)*(e.y-h.y)){return}var c=this.circumcircle(a,h,e);var f=c.y+c.radius;if(!this.greaterThanOrEqualWithEpsilon(f,i)){return}var b={type:this.CIRCLE_EVENT,site:h,x:c.x,y:f,center:{x:c.x,y:c.y}};d.circleEvent=b;this.queuePushCircle(b)};Voronoi.prototype.voidCircleEvents=function(c,b){if(b===undefined){b=c}c=this.max(c,0);b=this.min(b,this.arcs.length-1);while(c<=b){var a=this.arcs[c];if(a.circleEvent!==undefined){a.circleEvent.type=this.VOID_EVENT;a.circleEvent=undefined}c++}};Voronoi.prototype.queueSanitize=function(){var d=this.circEvents;var c=d.length;if(!c){return}var e=c;while(e&&d[e-1].type===this.VOID_EVENT){e--}var b=c-e;if(b){d.splice(e,b)}var a=this.arcs.length;if(d.length0&&d[c-1].type!==this.VOID_EVENT){c--}if(c<=0){break}e=c-1;while(e>0&&d[e-1].type===this.VOID_EVENT){e--}b=c-e;d.splice(e,b);if(d.length0?this.siteEvents[this.siteEvents.length-1]:null;var b=this.circEvents.length>0?this.circEvents[this.circEvents.length-1]:null;if(Boolean(a)!==Boolean(b)){return a?this.siteEvents.pop():this.circEvents.pop()}if(!a){return null}if(a.y>1;g=f.y-e[b].y;if(!g){g=f.x-e[b].x}if(g>0){d=b}else{if(g<0){a=b+1}else{return}}}e.splice(a,0,f)}else{e.push(f)}};Voronoi.prototype.queuePushCircle=function(f){var e=this.circEvents;var d=e.length;if(d){var a=0;var b,g;while(a>1;g=f.y-e[b].y;if(!g){g=f.x-e[b].x}if(g>0){d=b}else{a=b+1}}e.splice(a,0,f)}else{e.push(f)}};Voronoi.prototype.getBisector=function(c,a){var b={x:(c.x+a.x)/2,y:(c.y+a.y)/2};if(a.y==c.y){return b}b.m=(c.x-a.x)/(a.y-c.y);b.b=b.y-b.m*b.x;return b};Voronoi.prototype.connectEdge=function(b,l){var i=b.vb;if(!!i){return true}var j=b.va;var g=l.xl;var c=l.xr;var k=l.yt;var h=l.yb;var a=b.lSite;var d=b.rSite;var e=this.getBisector(a,d);if(e.m===undefined){if(e.x=c){return false}if(a.x>d.x){if(j===undefined){j=new this.Vertex(e.x,k)}else{if(j.y>=h){return false}}i=new this.Vertex(e.x,h)}else{if(j===undefined){j=new this.Vertex(e.x,h)}else{if(j.y=c){return false}}i=new this.Vertex(c,e.m*c+e.b)}else{if(j===undefined){j=new this.Vertex(c,e.m*c+e.b)}else{if(j.xd.x){if(j===undefined){j=new this.Vertex((k-e.b)/e.m,k)}else{if(j.y>=h){return false}}i=new this.Vertex((h-e.b)/e.m,h)}else{if(j===undefined){j=new this.Vertex((h-e.b)/e.m,h)}else{if(j.y0){if(a>e){return false}else{if(a>f){f=a}}}}c=i.xr-b;if(k===0&&c<0){return false}a=c/k;if(k<0){if(a>e){return false}else{if(a>f){f=a}}}else{if(k>0){if(a0){if(a>e){return false}else{if(a>f){f=a}}}}c=i.yb-l;if(j===0&&c<0){return false}a=c/j;if(j<0){if(a>e){return false}else{if(a>f){f=a}}}else{if(j>0){if(a=0;b-=1){c=a[b];if(!this.connectEdge(c,d)||!this.clipEdge(c,d)||this.verticesAreEqual(c.va,c.vb)){this.destroyEdge(c);a.splice(b,1)}}};Voronoi.prototype.verticesAreEqual=function(d,c){return this.equalWithEpsilon(d.x,c.x)&&this.equalWithEpsilon(d.y,c.y)};Voronoi.prototype.sortHalfedgesCallback=function(d,c){var f=d.getStartpoint();var e=d.getEndpoint();var h=c.getStartpoint();var g=c.getEndpoint();return self.Math.atan2(g.y-h.y,g.x-h.x)-self.Math.atan2(e.y-f.y,e.x-f.x)};Voronoi.prototype.closeCells=function(o){var g=o.xl;var d=o.xr;var l=o.yt;var h=o.yb;this.clipEdges(o);var q=this.cells;var m;var f,k;var n,c;var b;var e,p;var j,i;for(var a in q){m=q[a];if(!(m instanceof this.Cell)){continue}n=m.halfedges;f=n.length;while(f){k=f;while(k>0&&n[k-1].isLineSegment()){k--}f=k;while(f>0&&!n[f-1].isLineSegment()){f--}if(f===k){break}n.splice(f,k-f)}if(n.length===0){q.removeCell(m);continue}n.sort(this.sortHalfedgesCallback);c=n.length;f=0;while(f=0;b--){c=this.sites[b];if(!c.id){this.sites.splice(b,1)}else{this.queuePushSite({type:this.SITE_EVENT,x:c.x,y:c.y,site:c})}}this.arcs=[];this.edges=[];this.cells=new this.Cells();var g=this.queuePop();while(g){if(g.type===this.SITE_EVENT){this.cells.addCell(new this.Cell(g.site));this.addArc(g.site)}else{if(g.type===this.CIRCLE_EVENT){this.removeArc(g)}else{this.queueSanitize()}}g=this.queuePop()}this.closeCells(h);var d=new Date();var a={sites:this.sites,cells:this.cells,edges:this.edges,execTime:d.getTime()-f.getTime()};this.arcs=[];this.edges=[];this.cells=new this.Cells();return a}; diff --git a/rhill-voronoi-core.js b/rhill-voronoi-core.js deleted file mode 100644 index 6fab882a..00000000 --- a/rhill-voronoi-core.js +++ /dev/null @@ -1,1458 +0,0 @@ -/*! -Author: Raymond Hill (rhill@raymondhill.net) -File: rhill-voronoi-core.js -Version: 0.96 -Date: May 26, 2011 -Description: This is my personal Javascript implementation of -Steven Fortune's algorithm to compute Voronoi diagrams. - -Copyright (C) 2010,2011 Raymond Hill -https://github.com/gorhill/Javascript-Voronoi - -Licensed under The MIT License -http://en.wikipedia.org/wiki/MIT_License - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -***** - -Portions of this software use, depend, or was inspired by the work of: - - "Fortune's algorithm" by Steven J. Fortune: For his clever - algorithm to compute Voronoi diagrams. - http://ect.bell-labs.com/who/sjf/ - - "The Liang-Barsky line clipping algorithm in a nutshell!" by Daniel White, - to efficiently clip a line within a rectangle. - http://www.skytopia.com/project/articles/compsci/clipping.html - - "rbtree" by Franck Bui-Huu - https://github.com/fbuihuu/libtree/blob/master/rb.c - I ported to Javascript the C code of a Red-Black tree implementation by - Franck Bui-Huu, and further altered the code for Javascript efficiency - and to very specifically fit the purpose of holding the beachline (the key - is a variable range rather than an unmutable data point), and unused - code paths have been removed. Each node in the tree is actually a beach - section on the beachline. Using a tree structure for the beachline remove - the need to lookup the beach section in the array at removal time, as - now a circle event can safely hold a reference to its associated - beach section (thus findDeletionPoint() is no longer needed). This - finally take care of nagging finite arithmetic precision issues arising - at lookup time, such that epsilon could be brought down to 1e-9 (from 1e-4). - rhill 2011-05-27: added a 'previous' and 'next' members which keeps track - of previous and next nodes, and remove the need for Beachsection.getPrevious() - and Beachsection.getNext(). - -***** - -History: - -0.96 (26 May 2011): - Returned diagram.cells is now an array, whereas the index of a cell - matches the index of its associated site in the array of sites passed - to Voronoi.compute(). This allowed some gain in performance. The - 'voronoiId' member is still used internally by the Voronoi object. - The Voronoi.Cells object is no longer necessary and has been removed. - -0.95 (19 May 2011): - No longer using Javascript array to keep track of the beach sections of - the beachline, now using Red-Black tree. - - The move to a binary tree was unavoidable, as I ran into finite precision - arithmetic problems when I started to use sites with fractional values. - The problem arose when the code had to find the arc associated with a - triggered Fortune circle event: the collapsing arc was not always properly - found due to finite precision arithmetic-related errors. Using a tree structure - eliminate the need to look-up a beachsection in the array structure - (findDeletionPoint()), and allowed to bring back epsilon down to 1e-9. - -0.91(21 September 2010): - Lower epsilon from 1e-5 to 1e-4, to fix problem reported at - http://www.raymondhill.net/blog/?p=9#comment-1414 - -0.90 (21 September 2010): - First version. - -***** - -Usage: - - var sites = [{x:300,y:300}, {x:100,y:100}, {x:200,y:500}, {x:250,y:450}, {x:600,y:150}]; - // xl, xr means x left, x right - // yt, yb means y top, y bottom - var bbox = {xl:0, xr:800, yt:0, yb:600}; - var voronoi = new Voronoi(); - // pass an object which exhibits xl, xr, yt, yb properties. The bounding - // box will be used to connect unbound edges, and to close open cells - result = voronoi.compute(sites, bbox); - // render, further analyze, etc. - -Return value: - An object with the following properties: - - result.edges = an array of unordered, unique Voronoi.Edge objects making up the Voronoi diagram. - result.cells = an array of Voronoi.Cell object making up the Voronoi diagram. A Cell object - might have an empty array of halfedges, meaning no Voronoi cell could be computed for a - particular cell. - result.execTime = the time it took to compute the Voronoi diagram, in milliseconds. - -Voronoi.Edge object: - lSite: the Voronoi site object at the left of this Voronoi.Edge object. - rSite: the Voronoi site object at the right of this Voronoi.Edge object (can be null). - va: an object with an 'x' and a 'y' property defining the start point - (relative to the Voronoi site on the left) of this Voronoi.Edge object. - vb: an object with an 'x' and a 'y' property defining the end point - (relative to Voronoi site on the left) of this Voronoi.Edge object. - - For edges which are used to close open cells (using the supplied bounding box), the - rSite property will be null. - -Voronoi.Cell object: - site: the Voronoi site object associated with the Voronoi cell. - halfedges: an array of Voronoi.Halfedge objects, ordered counterclockwise, defining the - polygon for this Voronoi cell. - -Voronoi.Halfedge object: - site: the Voronoi site object owning this Voronoi.Halfedge object. - edge: a reference to the unique Voronoi.Edge object underlying this Voronoi.Halfedge object. - getStartpoint(): a method returning an object with an 'x' and a 'y' property for - the start point of this halfedge. Keep in mind halfedges are always countercockwise. - getEndpoint(): a method returning an object with an 'x' and a 'y' property for - the end point of this halfedge. Keep in mind halfedges are always countercockwise. - -TODO: Identify opportunities for performance improvement. -TODO: Let the user close the Voronoi cells, do not do it automatically. Not only let - him close the cells, but also allow him to close more than once using a different - bounding box for the same Voronoi diagram. -*/ - -/*global Math */ - -function Voronoi() { - this.edges = null; - this.cells = null; - this.beachsectionJunkyard = []; - this.circleEventJunkyard = []; - } - -Voronoi.prototype.reset = function() { - if (!this.beachline) { - this.beachline = new this.RBTree(); - } - // Move leftover beachsections to the beachsection junkyard. - if (this.beachline.root) { - var beachsection = this.beachline.getFirst(this.beachline.root); - while (beachsection) { - this.beachsectionJunkyard.push(beachsection); // mark for reuse - beachsection = beachsection.rbNext; - } - } - this.beachline.root = null; - if (!this.circleEvents) { - this.circleEvents = new this.RBTree(); - } - this.circleEvents.root = this.firstCircleEvent = null; - this.edges = []; - this.cells = []; - }; - -Voronoi.prototype.sqrt = Math.sqrt; -Voronoi.prototype.abs = Math.abs; -Voronoi.prototype.EPSILON = 1e-9; -Voronoi.prototype.equalWithEpsilon = function(a,b){return this.abs(a-b)<1e-9;}; -Voronoi.prototype.greaterThanWithEpsilon = function(a,b){return a-b>1e-9;}; -Voronoi.prototype.greaterThanOrEqualWithEpsilon = function(a,b){return b-a<1e-9;}; -Voronoi.prototype.lessThanWithEpsilon = function(a,b){return b-a>1e-9;}; -Voronoi.prototype.lessThanOrEqualWithEpsilon = function(a,b){return a-b<1e-9;}; - -// --------------------------------------------------------------------------- -// Red-Black tree code (based on C version of "rbtree" by Franck Bui-Huu -// https://github.com/fbuihuu/libtree/blob/master/rb.c - -Voronoi.prototype.RBTree = function() { - this.root = null; - }; - -Voronoi.prototype.RBTree.prototype.rbInsertSuccessor = function(node, successor) { - var parent; - if (node) { - // >>> rhill 2011-05-27: Performance: cache previous/next nodes - successor.rbPrevious = node; - successor.rbNext = node.rbNext; - if (node.rbNext) { - node.rbNext.rbPrevious = successor; - } - node.rbNext = successor; - // <<< - if (node.rbRight) { - // in-place expansion of node.rbRight.getFirst(); - node = node.rbRight; - while (node.rbLeft) {node = node.rbLeft;} - node.rbLeft = successor; - } - else { - node.rbRight = successor; - } - parent = node; - } - // rhill 2011-06-07: if node is null, successor must be inserted - // to the left-most part of the tree - else if (this.root) { - node = this.getFirst(this.root); - // >>> Performance: cache previous/next nodes - successor.rbPrevious = null; - successor.rbNext = node; - node.rbPrevious = successor; - // <<< - node.rbLeft = successor; - parent = node; - } - else { - // >>> Performance: cache previous/next nodes - successor.rbPrevious = successor.rbNext = null; - // <<< - this.root = successor; - parent = null; - } - successor.rbLeft = successor.rbRight = null; - successor.rbParent = parent; - successor.rbRed = true; - // Fixup the modified tree by recoloring nodes and performing - // rotations (2 at most) hence the red-black tree properties are - // preserved. - var grandpa, uncle; - node = successor; - while (parent && parent.rbRed) { - grandpa = parent.rbParent; - if (parent === grandpa.rbLeft) { - uncle = grandpa.rbRight; - if (uncle && uncle.rbRed) { - parent.rbRed = uncle.rbRed = false; - grandpa.rbRed = true; - node = grandpa; - } - else { - if (node === parent.rbRight) { - this.rbRotateLeft(parent); - node = parent; - parent = node.rbParent; - } - parent.rbRed = false; - grandpa.rbRed = true; - this.rbRotateRight(grandpa); - } - } - else { - uncle = grandpa.rbLeft; - if (uncle && uncle.rbRed) { - parent.rbRed = uncle.rbRed = false; - grandpa.rbRed = true; - node = grandpa; - } - else { - if (node === parent.rbLeft) { - this.rbRotateRight(parent); - node = parent; - parent = node.rbParent; - } - parent.rbRed = false; - grandpa.rbRed = true; - this.rbRotateLeft(grandpa); - } - } - parent = node.rbParent; - } - this.root.rbRed = false; - }; - -Voronoi.prototype.RBTree.prototype.rbRemoveNode = function(node) { - // >>> rhill 2011-05-27: Performance: cache previous/next nodes - if (node.rbNext) { - node.rbNext.rbPrevious = node.rbPrevious; - } - if (node.rbPrevious) { - node.rbPrevious.rbNext = node.rbNext; - } - node.rbNext = node.rbPrevious = null; - // <<< - var parent = node.rbParent, - left = node.rbLeft, - right = node.rbRight, - next; - if (!left) { - next = right; - } - else if (!right) { - next = left; - } - else { - next = this.getFirst(right); - } - if (parent) { - if (parent.rbLeft === node) { - parent.rbLeft = next; - } - else { - parent.rbRight = next; - } - } - else { - this.root = next; - } - // enforce red-black rules - var isRed; - if (left && right) { - isRed = next.rbRed; - next.rbRed = node.rbRed; - next.rbLeft = left; - left.rbParent = next; - if (next !== right) { - parent = next.rbParent; - next.rbParent = node.rbParent; - node = next.rbRight; - parent.rbLeft = node; - next.rbRight = right; - right.rbParent = next; - } - else { - next.rbParent = parent; - parent = next; - node = next.rbRight; - } - } - else { - isRed = node.rbRed; - node = next; - } - // 'node' is now the sole successor's child and 'parent' its - // new parent (since the successor can have been moved) - if (node) { - node.rbParent = parent; - } - // the 'easy' cases - if (isRed) {return;} - if (node && node.rbRed) { - node.rbRed = false; - return; - } - // the other cases - var sibling; - do { - if (node === this.root) { - break; - } - if (node === parent.rbLeft) { - sibling = parent.rbRight; - if (sibling.rbRed) { - sibling.rbRed = false; - parent.rbRed = true; - this.rbRotateLeft(parent); - sibling = parent.rbRight; - } - if ((sibling.rbLeft && sibling.rbLeft.rbRed) || (sibling.rbRight && sibling.rbRight.rbRed)) { - if (!sibling.rbRight || !sibling.rbRight.rbRed) { - sibling.rbLeft.rbRed = false; - sibling.rbRed = true; - this.rbRotateRight(sibling); - sibling = parent.rbRight; - } - sibling.rbRed = parent.rbRed; - parent.rbRed = sibling.rbRight.rbRed = false; - this.rbRotateLeft(parent); - node = this.root; - break; - } - } - else { - sibling = parent.rbLeft; - if (sibling.rbRed) { - sibling.rbRed = false; - parent.rbRed = true; - this.rbRotateRight(parent); - sibling = parent.rbLeft; - } - if ((sibling.rbLeft && sibling.rbLeft.rbRed) || (sibling.rbRight && sibling.rbRight.rbRed)) { - if (!sibling.rbLeft || !sibling.rbLeft.rbRed) { - sibling.rbRight.rbRed = false; - sibling.rbRed = true; - this.rbRotateLeft(sibling); - sibling = parent.rbLeft; - } - sibling.rbRed = parent.rbRed; - parent.rbRed = sibling.rbLeft.rbRed = false; - this.rbRotateRight(parent); - node = this.root; - break; - } - } - sibling.rbRed = true; - node = parent; - parent = parent.rbParent; - } while (!node.rbRed); - if (node) {node.rbRed = false;} - }; - -Voronoi.prototype.RBTree.prototype.rbRotateLeft = function(node) { - var p = node, - q = node.rbRight, // can't be null - parent = p.rbParent; - if (parent) { - if (parent.rbLeft === p) { - parent.rbLeft = q; - } - else { - parent.rbRight = q; - } - } - else { - this.root = q; - } - q.rbParent = parent; - p.rbParent = q; - p.rbRight = q.rbLeft; - if (p.rbRight) { - p.rbRight.rbParent = p; - } - q.rbLeft = p; - }; - -Voronoi.prototype.RBTree.prototype.rbRotateRight = function(node) { - var p = node, - q = node.rbLeft, // can't be null - parent = p.rbParent; - if (parent) { - if (parent.rbLeft === p) { - parent.rbLeft = q; - } - else { - parent.rbRight = q; - } - } - else { - this.root = q; - } - q.rbParent = parent; - p.rbParent = q; - p.rbLeft = q.rbRight; - if (p.rbLeft) { - p.rbLeft.rbParent = p; - } - q.rbRight = p; - }; - -Voronoi.prototype.RBTree.prototype.getFirst = function(node) { - while (node.rbLeft) { - node = node.rbLeft; - } - return node; - }; - -Voronoi.prototype.RBTree.prototype.getLast = function(node) { - while (node.rbRight) { - node = node.rbRight; - } - return node; - }; - -// --------------------------------------------------------------------------- -// Cell methods - -Voronoi.prototype.Cell = function(site) { - this.site = site; - this.halfedges = []; - }; - -Voronoi.prototype.Cell.prototype.prepare = function() { - var halfedges = this.halfedges, - iHalfedge = halfedges.length, - edge; - // get rid of unused halfedges - // rhill 2011-05-27: Keep it simple, no point here in trying - // to be fancy: dangling edges are a typically a minority. - while (iHalfedge--) { - edge = halfedges[iHalfedge].edge; - if (!edge.vb || !edge.va) { - halfedges.splice(iHalfedge,1); - } - } - // rhill 2011-05-26: I tried to use a binary search at insertion - // time to keep the array sorted on-the-fly (in Cell.addHalfedge()). - // There was no real benefits in doing so, performance on - // Firefox 3.6 was improved marginally, while performance on - // Opera 11 was penalized marginally. - halfedges.sort(function(a,b){return b.angle-a.angle;}); - return halfedges.length; - }; - -// --------------------------------------------------------------------------- -// Edge methods -// - -Voronoi.prototype.Vertex = function(x, y) { - this.x = x; - this.y = y; - }; - -Voronoi.prototype.Edge = function(lSite, rSite) { - this.lSite = lSite; - this.rSite = rSite; - this.va = this.vb = null; - }; - -Voronoi.prototype.Halfedge = function(edge, lSite, rSite) { - this.site = lSite; - this.edge = edge; - // 'angle' is a value to be used for properly sorting the - // halfsegments counterclockwise. By convention, we will - // use the angle of the line defined by the 'site to the left' - // to the 'site to the right'. - // However, border edges have no 'site to the right': thus we - // use the angle of line perpendicular to the halfsegment (the - // edge should have both end points defined in such case.) - if (rSite) { - this.angle = Math.atan2(rSite.y-lSite.y, rSite.x-lSite.x); - } - else { - var va = edge.va, - vb = edge.vb; - // rhill 2011-05-31: used to call getStartpoint()/getEndpoint(), - // but for performance purpose, these are expanded in place here. - this.angle = edge.lSite === lSite ? Math.atan2(vb.x-va.x, va.y-vb.y) - : Math.atan2(va.x-vb.x, vb.y-va.y); - } - }; - -Voronoi.prototype.Halfedge.prototype.getStartpoint = function() { - return this.edge.lSite === this.site ? this.edge.va : this.edge.vb; - }; - -Voronoi.prototype.Halfedge.prototype.getEndpoint = function() { - return this.edge.lSite === this.site ? this.edge.vb : this.edge.va; - }; - -// this create and add an edge to internal collection, and also create -// two halfedges which are added to each site's counterclockwise array -// of halfedges. -Voronoi.prototype.createEdge = function(lSite, rSite, va, vb) { - var edge = new this.Edge(lSite, rSite); - this.edges.push(edge); - if (va) { - this.setEdgeStartpoint(edge, lSite, rSite, va); - } - if (vb) { - this.setEdgeEndpoint(edge, lSite, rSite, vb); - } - this.cells[lSite.voronoiId].halfedges.push(new this.Halfedge(edge, lSite, rSite)); - this.cells[rSite.voronoiId].halfedges.push(new this.Halfedge(edge, rSite, lSite)); - return edge; - }; - -Voronoi.prototype.createBorderEdge = function(lSite, va, vb) { - var edge = new this.Edge(lSite, null); - edge.va = va; - edge.vb = vb; - this.edges.push(edge); - return edge; - }; - -Voronoi.prototype.setEdgeStartpoint = function(edge, lSite, rSite, vertex) { - if (!edge.va && !edge.vb) { - edge.va = vertex; - edge.lSite = lSite; - edge.rSite = rSite; - } - else if (edge.lSite === rSite) { - edge.vb = vertex; - } - else { - edge.va = vertex; - } - }; - -Voronoi.prototype.setEdgeEndpoint = function(edge, lSite, rSite, vertex) { - this.setEdgeStartpoint(edge, rSite, lSite, vertex); - }; - -// --------------------------------------------------------------------------- -// Beachline methods - -// rhill 2011-06-07: For some reasons, performance suffers significantly -// when instanciating a literal object instead of an empty ctor -Voronoi.prototype.Beachsection = function(site) { - this.site = site; - }; - -// rhill 2011-06-02: A lot of Beachsection instanciations -// occur during the computation of the Voronoi diagram, -// somewhere between the number of sites and twice the -// number of sites, while the number of Beachsections on the -// beachline at any given time is comparatively low. For this -// reason, we reuse already created Beachsections, in order -// to avoid new memory allocation. This resulted in a measurable -// performance gain. -Voronoi.prototype.createBeachsection = function(site) { - var beachsection = this.beachsectionJunkyard.pop(); - if (beachsection) { - beachsection.site = site; - } - else { - beachsection = new this.Beachsection(site); - } - return beachsection; - }; - -// calculate the left break point of a particular beach section, -// given a particular sweep line -Voronoi.prototype.leftBreakPoint = function(arc, directrix) { - // http://en.wikipedia.org/wiki/Parabola - // http://en.wikipedia.org/wiki/Quadratic_equation - // h1 = x1, - // k1 = (y1+directrix)/2, - // h2 = x2, - // k2 = (y2+directrix)/2, - // p1 = k1-directrix, - // a1 = 1/(4*p1), - // b1 = -h1/(2*p1), - // c1 = h1*h1/(4*p1)+k1, - // p2 = k2-directrix, - // a2 = 1/(4*p2), - // b2 = -h2/(2*p2), - // c2 = h2*h2/(4*p2)+k2, - // x = (-(b2-b1) + Math.sqrt((b2-b1)*(b2-b1) - 4*(a2-a1)*(c2-c1))) / (2*(a2-a1)) - // When x1 become the x-origin: - // h1 = 0, - // k1 = (y1+directrix)/2, - // h2 = x2-x1, - // k2 = (y2+directrix)/2, - // p1 = k1-directrix, - // a1 = 1/(4*p1), - // b1 = 0, - // c1 = k1, - // p2 = k2-directrix, - // a2 = 1/(4*p2), - // b2 = -h2/(2*p2), - // c2 = h2*h2/(4*p2)+k2, - // x = (-b2 + Math.sqrt(b2*b2 - 4*(a2-a1)*(c2-k1))) / (2*(a2-a1)) + x1 - - // change code below at your own risk: care has been taken to - // reduce errors due to computers' finite arithmetic precision. - // Maybe can still be improved, will see if any more of this - // kind of errors pop up again. - var site = arc.site, - rfocx = site.x, - rfocy = site.y, - pby2 = rfocy-directrix; - // parabola in degenerate case where focus is on directrix - if (!pby2) { - return rfocx; - } - var lArc = arc.rbPrevious; - if (!lArc) { - return -Infinity; - } - site = lArc.site; - var lfocx = site.x, - lfocy = site.y, - plby2 = lfocy-directrix; - // parabola in degenerate case where focus is on directrix - if (!plby2) { - return lfocx; - } - var hl = lfocx-rfocx, - aby2 = 1/pby2-1/plby2, - b = hl/plby2; - if (aby2) { - return (-b+this.sqrt(b*b-2*aby2*(hl*hl/(-2*plby2)-lfocy+plby2/2+rfocy-pby2/2)))/aby2+rfocx; - } - // both parabolas have same distance to directrix, thus break point is midway - return (rfocx+lfocx)/2; - }; - -// calculate the right break point of a particular beach section, -// given a particular directrix -Voronoi.prototype.rightBreakPoint = function(arc, directrix) { - var rArc = arc.rbNext; - if (rArc) { - return this.leftBreakPoint(rArc, directrix); - } - var site = arc.site; - return site.y === directrix ? site.x : Infinity; - }; - -Voronoi.prototype.detachBeachsection = function(beachsection) { - this.detachCircleEvent(beachsection); // detach potentially attached circle event - this.beachline.rbRemoveNode(beachsection); // remove from RB-tree - this.beachsectionJunkyard.push(beachsection); // mark for reuse - }; - -Voronoi.prototype.removeBeachsection = function(beachsection) { - var circle = beachsection.circleEvent, - x = circle.x, - y = circle.ycenter, - vertex = new this.Vertex(x, y), - previous = beachsection.rbPrevious, - next = beachsection.rbNext, - disappearingTransitions = [beachsection], - abs_fn = Math.abs; - - // remove collapsed beachsection from beachline - this.detachBeachsection(beachsection); - - // there could be more than one empty arc at the deletion point, this - // happens when more than two edges are linked by the same vertex, - // so we will collect all those edges by looking up both sides of - // the deletion point. - // by the way, there is *always* a predecessor/successor to any collapsed - // beach section, it's just impossible to have a collapsing first/last - // beach sections on the beachline, since they obviously are unconstrained - // on their left/right side. - - // look left - var lArc = previous; - while (lArc.circleEvent && abs_fn(x-lArc.circleEvent.x)<1e-9 && abs_fn(y-lArc.circleEvent.ycenter)<1e-9) { - previous = lArc.rbPrevious; - disappearingTransitions.unshift(lArc); - this.detachBeachsection(lArc); // mark for reuse - lArc = previous; - } - // even though it is not disappearing, I will also add the beach section - // immediately to the left of the left-most collapsed beach section, for - // convenience, since we need to refer to it later as this beach section - // is the 'left' site of an edge for which a start point is set. - disappearingTransitions.unshift(lArc); - this.detachCircleEvent(lArc); - - // look right - var rArc = next; - while (rArc.circleEvent && abs_fn(x-rArc.circleEvent.x)<1e-9 && abs_fn(y-rArc.circleEvent.ycenter)<1e-9) { - next = rArc.rbNext; - disappearingTransitions.push(rArc); - this.detachBeachsection(rArc); // mark for reuse - rArc = next; - } - // we also have to add the beach section immediately to the right of the - // right-most collapsed beach section, since there is also a disappearing - // transition representing an edge's start point on its left. - disappearingTransitions.push(rArc); - this.detachCircleEvent(rArc); - - // walk through all the disappearing transitions between beach sections and - // set the start point of their (implied) edge. - var nArcs = disappearingTransitions.length, - iArc; - for (iArc=1; iArc falls somewhere before the left edge of the beachsection - if (dxl > 1e-9) { - // this case should never happen - // if (!node.rbLeft) { - // rArc = node.rbLeft; - // break; - // } - node = node.rbLeft; - } - else { - dxr = x-this.rightBreakPoint(node,directrix); - // x greaterThanWithEpsilon xr => falls somewhere after the right edge of the beachsection - if (dxr > 1e-9) { - if (!node.rbRight) { - lArc = node; - break; - } - node = node.rbRight; - } - else { - // x equalWithEpsilon xl => falls exactly on the left edge of the beachsection - if (dxl > -1e-9) { - lArc = node.rbPrevious; - rArc = node; - } - // x equalWithEpsilon xr => falls exactly on the right edge of the beachsection - else if (dxr > -1e-9) { - lArc = node; - rArc = node.rbNext; - } - // falls exactly somewhere in the middle of the beachsection - else { - lArc = rArc = node; - } - break; - } - } - } - // at this point, keep in mind that lArc and/or rArc could be - // undefined or null. - - // create a new beach section object for the site and add it to RB-tree - var newArc = this.createBeachsection(site); - this.beachline.rbInsertSuccessor(lArc, newArc); - - // cases: - // - - // [null,null] - // least likely case: new beach section is the first beach section on the - // beachline. - // This case means: - // no new transition appears - // no collapsing beach section - // new beachsection become root of the RB-tree - if (!lArc && !rArc) { - return; - } - - // [lArc,rArc] where lArc == rArc - // most likely case: new beach section split an existing beach - // section. - // This case means: - // one new transition appears - // the left and right beach section might be collapsing as a result - // two new nodes added to the RB-tree - if (lArc === rArc) { - // invalidate circle event of split beach section - this.detachCircleEvent(lArc); - - // split the beach section into two separate beach sections - rArc = this.createBeachsection(lArc.site); - this.beachline.rbInsertSuccessor(newArc, rArc); - - // since we have a new transition between two beach sections, - // a new edge is born - newArc.edge = rArc.edge = this.createEdge(lArc.site, newArc.site); - - // check whether the left and right beach sections are collapsing - // and if so create circle events, to be notified when the point of - // collapse is reached. - this.attachCircleEvent(lArc); - this.attachCircleEvent(rArc); - return; - } - - // [lArc,null] - // even less likely case: new beach section is the *last* beach section - // on the beachline -- this can happen *only* if *all* the previous beach - // sections currently on the beachline share the same y value as - // the new beach section. - // This case means: - // one new transition appears - // no collapsing beach section as a result - // new beach section become right-most node of the RB-tree - if (lArc && !rArc) { - newArc.edge = this.createEdge(lArc.site,newArc.site); - return; - } - - // [null,rArc] - // impossible case: because sites are strictly processed from top to bottom, - // and left to right, which guarantees that there will always be a beach section - // on the left -- except of course when there are no beach section at all on - // the beach line, which case was handled above. - // rhill 2011-06-02: No point testing in non-debug version - //if (!lArc && rArc) { - // throw "Voronoi.addBeachsection(): What is this I don't even"; - // } - - // [lArc,rArc] where lArc != rArc - // somewhat less likely case: new beach section falls *exactly* in between two - // existing beach sections - // This case means: - // one transition disappears - // two new transitions appear - // the left and right beach section might be collapsing as a result - // only one new node added to the RB-tree - if (lArc !== rArc) { - // invalidate circle events of left and right sites - this.detachCircleEvent(lArc); - this.detachCircleEvent(rArc); - - // an existing transition disappears, meaning a vertex is defined at - // the disappearance point. - // since the disappearance is caused by the new beachsection, the - // vertex is at the center of the circumscribed circle of the left, - // new and right beachsections. - // http://mathforum.org/library/drmath/view/55002.html - // Except that I bring the origin at A to simplify - // calculation - var lSite = lArc.site, - ax = lSite.x, - ay = lSite.y, - bx=site.x-ax, - by=site.y-ay, - rSite = rArc.site, - cx=rSite.x-ax, - cy=rSite.y-ay, - d=2*(bx*cy-by*cx), - hb=bx*bx+by*by, - hc=cx*cx+cy*cy, - vertex = new this.Vertex((cy*hb-by*hc)/d+ax, (bx*hc-cx*hb)/d+ay); - - // one transition disappear - this.setEdgeStartpoint(rArc.edge, lSite, rSite, vertex); - - // two new transitions appear at the new vertex location - newArc.edge = this.createEdge(lSite, site, undefined, vertex); - rArc.edge = this.createEdge(site, rSite, undefined, vertex); - - // check whether the left and right beach sections are collapsing - // and if so create circle events, to handle the point of collapse. - this.attachCircleEvent(lArc); - this.attachCircleEvent(rArc); - return; - } - }; - -// --------------------------------------------------------------------------- -// Circle event methods - -// rhill 2011-06-07: For some reasons, performance suffers significantly -// when instanciating a literal object instead of an empty ctor -Voronoi.prototype.CircleEvent = function() { - }; - -Voronoi.prototype.attachCircleEvent = function(arc) { - var lArc = arc.rbPrevious, - rArc = arc.rbNext; - if (!lArc || !rArc) {return;} // does that ever happen? - var lSite = lArc.site, - cSite = arc.site, - rSite = rArc.site; - - // If site of left beachsection is same as site of - // right beachsection, there can't be convergence - if (lSite===rSite) {return;} - - // Find the circumscribed circle for the three sites associated - // with the beachsection triplet. - // rhill 2011-05-26: It is more efficient to calculate in-place - // rather than getting the resulting circumscribed circle from an - // object returned by calling Voronoi.circumcircle() - // http://mathforum.org/library/drmath/view/55002.html - // Except that I bring the origin at cSite to simplify calculations. - // The bottom-most part of the circumcircle is our Fortune 'circle - // event', and its center is a vertex potentially part of the final - // Voronoi diagram. - var bx = cSite.x, - by = cSite.y, - ax = lSite.x-bx, - ay = lSite.y-by, - cx = rSite.x-bx, - cy = rSite.y-by; - - // If points l->c->r are clockwise, then center beach section does not - // collapse, hence it can't end up as a vertex (we reuse 'd' here, which - // sign is reverse of the orientation, hence we reverse the test. - // http://en.wikipedia.org/wiki/Curve_orientation#Orientation_of_a_simple_polygon - // rhill 2011-05-21: Nasty finite precision error which caused circumcircle() to - // return infinites: 1e-12 seems to fix the problem. - var d = 2*(ax*cy-ay*cx); - if (d >= -2e-12){return;} - - var ha = ax*ax+ay*ay, - hc = cx*cx+cy*cy, - x = (cy*ha-ay*hc)/d, - y = (ax*hc-cx*ha)/d, - ycenter = y+by; - - // Important: ybottom should always be under or at sweep, so no need - // to waste CPU cycles by checking - - // recycle circle event object if possible - var circleEvent = this.circleEventJunkyard.pop(); - if (!circleEvent) { - circleEvent = new this.CircleEvent(); - } - circleEvent.arc = arc; - circleEvent.site = cSite; - circleEvent.x = x+bx; - circleEvent.y = ycenter+this.sqrt(x*x+y*y); // y bottom - circleEvent.ycenter = ycenter; - arc.circleEvent = circleEvent; - - // find insertion point in RB-tree: circle events are ordered from - // smallest to largest - var predecessor = null, - node = this.circleEvents.root; - while (node) { - if (circleEvent.y < node.y || (circleEvent.y === node.y && circleEvent.x <= node.x)) { - if (node.rbLeft) { - node = node.rbLeft; - } - else { - predecessor = node.rbPrevious; - break; - } - } - else { - if (node.rbRight) { - node = node.rbRight; - } - else { - predecessor = node; - break; - } - } - } - this.circleEvents.rbInsertSuccessor(predecessor, circleEvent); - if (!predecessor) { - this.firstCircleEvent = circleEvent; - } - }; - -Voronoi.prototype.detachCircleEvent = function(arc) { - var circle = arc.circleEvent; - if (circle) { - if (!circle.rbPrevious) { - this.firstCircleEvent = circle.rbNext; - } - this.circleEvents.rbRemoveNode(circle); // remove from RB-tree - this.circleEventJunkyard.push(circle); - arc.circleEvent = null; - } - }; - -// --------------------------------------------------------------------------- -// Diagram completion methods - -// connect dangling edges (not if a cursory test tells us -// it is not going to be visible. -// return value: -// false: the dangling endpoint couldn't be connected -// true: the dangling endpoint could be connected -Voronoi.prototype.connectEdge = function(edge, bbox) { - // skip if end point already connected - var vb = edge.vb; - if (!!vb) {return true;} - - // make local copy for performance purpose - var va = edge.va, - xl = bbox.xl, - xr = bbox.xr, - yt = bbox.yt, - yb = bbox.yb, - lSite = edge.lSite, - rSite = edge.rSite, - lx = lSite.x, - ly = lSite.y, - rx = rSite.x, - ry = rSite.y, - fx = (lx+rx)/2, - fy = (ly+ry)/2, - fm, fb; - - // get the line equation of the bisector if line is not vertical - if (ry !== ly) { - fm = (lx-rx)/(ry-ly); - fb = fy-fm*fx; - } - - // remember, direction of line (relative to left site): - // upward: left.x < right.x - // downward: left.x > right.x - // horizontal: left.x == right.x - // upward: left.x < right.x - // rightward: left.y < right.y - // leftward: left.y > right.y - // vertical: left.y == right.y - - // depending on the direction, find the best side of the - // bounding box to use to determine a reasonable start point - - // special case: vertical line - if (fm === undefined) { - // doesn't intersect with viewport - if (fx < xl || fx >= xr) {return false;} - // downward - if (lx > rx) { - if (!va) { - va = new this.Vertex(fx, yt); - } - else if (va.y >= yb) { - return false; - } - vb = new this.Vertex(fx, yb); - } - // upward - else { - if (!va) { - va = new this.Vertex(fx, yb); - } - else if (va.y < yt) { - return false; - } - vb = new this.Vertex(fx, yt); - } - } - // closer to vertical than horizontal, connect start point to the - // top or bottom side of the bounding box - else if (fm < -1 || fm > 1) { - // downward - if (lx > rx) { - if (!va) { - va = new this.Vertex((yt-fb)/fm, yt); - } - else if (va.y >= yb) { - return false; - } - vb = new this.Vertex((yb-fb)/fm, yb); - } - // upward - else { - if (!va) { - va = new this.Vertex((yb-fb)/fm, yb); - } - else if (va.y < yt) { - return false; - } - vb = new this.Vertex((yt-fb)/fm, yt); - } - } - // closer to horizontal than vertical, connect start point to the - // left or right side of the bounding box - else { - // rightward - if (ly < ry) { - if (!va) { - va = new this.Vertex(xl, fm*xl+fb); - } - else if (va.x >= xr) { - return false; - } - vb = new this.Vertex(xr, fm*xr+fb); - } - // leftward - else { - if (!va) { - va = new this.Vertex(xr, fm*xr+fb); - } - else if (va.x < xl) { - return false; - } - vb = new this.Vertex(xl, fm*xl+fb); - } - } - edge.va = va; - edge.vb = vb; - return true; - }; - -// line-clipping code taken from: -// Liang-Barsky function by Daniel White -// http://www.skytopia.com/project/articles/compsci/clipping.html -// Thanks! -// A bit modified to minimize code paths -Voronoi.prototype.clipEdge = function(edge, bbox) { - var ax = edge.va.x, - ay = edge.va.y, - bx = edge.vb.x, - by = edge.vb.y, - t0 = 0, - t1 = 1, - dx = bx-ax, - dy = by-ay; - // left - var q = ax-bbox.xl; - if (dx===0 && q<0) {return false;} - var r = -q/dx; - if (dx<0) { - if (r0) { - if (r>t1) {return false;} - else if (r>t0) {t0=r;} - } - // right - q = bbox.xr-ax; - if (dx===0 && q<0) {return false;} - r = q/dx; - if (dx<0) { - if (r>t1) {return false;} - else if (r>t0) {t0=r;} - } - else if (dx>0) { - if (r0) { - if (r>t1) {return false;} - else if (r>t0) {t0=r;} - } - // bottom - q = bbox.yb-ay; - if (dy===0 && q<0) {return false;} - r = q/dy; - if (dy<0) { - if (r>t1) {return false;} - else if (r>t0) {t0=r;} - } - else if (dy>0) { - if (r 0, va needs to change - // rhill 2011-06-03: we need to create a new vertex rather - // than modifying the existing one, since the existing - // one is likely shared with at least another edge - if (t0 > 0) { - edge.va = new this.Vertex(ax+t0*dx, ay+t0*dy); - } - - // if t1 < 1, vb needs to change - // rhill 2011-06-03: we need to create a new vertex rather - // than modifying the existing one, since the existing - // one is likely shared with at least another edge - if (t1 < 1) { - edge.vb = new this.Vertex(ax+t1*dx, ay+t1*dy); - } - - return true; - }; - -// Connect/cut edges at bounding box -Voronoi.prototype.clipEdges = function(bbox) { - // connect all dangling edges to bounding box - // or get rid of them if it can't be done - var edges = this.edges, - iEdge = edges.length, - edge, - abs_fn = Math.abs; - - // iterate backward so we can splice safely - while (iEdge--) { - edge = edges[iEdge]; - // edge is removed if: - // it is wholly outside the bounding box - // it is actually a point rather than a line - if (!this.connectEdge(edge, bbox) || !this.clipEdge(edge, bbox) || (abs_fn(edge.va.x-edge.vb.x)<1e-9 && abs_fn(edge.va.y-edge.vb.y)<1e-9)) { - edge.va = edge.vb = null; - edges.splice(iEdge,1); - } - } - }; - -// Close the cells. -// The cells are bound by the supplied bounding box. -// Each cell refers to its associated site, and a list -// of halfedges ordered counterclockwise. -Voronoi.prototype.closeCells = function(bbox) { - // prune, order halfedges, then add missing ones - // required to close cells - var xl = bbox.xl, - xr = bbox.xr, - yt = bbox.yt, - yb = bbox.yb, - cells = this.cells, - iCell = cells.length, - cell, - iLeft, iRight, - halfedges, nHalfedges, - edge, - startpoint, endpoint, - va, vb, - abs_fn = Math.abs; - - while (iCell--) { - cell = cells[iCell]; - // trim non fully-defined halfedges and sort them counterclockwise - if (!cell.prepare()) { - continue; - } - // close open cells - // step 1: find first 'unclosed' point, if any. - // an 'unclosed' point will be the end point of a halfedge which - // does not match the start point of the following halfedge - halfedges = cell.halfedges; - nHalfedges = halfedges.length; - // special case: only one site, in which case, the viewport is the cell - // ... - // all other cases - iLeft = 0; - while (iLeft < nHalfedges) { - iRight = (iLeft+1) % nHalfedges; - endpoint = halfedges[iLeft].getEndpoint(); - startpoint = halfedges[iRight].getStartpoint(); - // if end point is not equal to start point, we need to add the missing - // halfedge(s) to close the cell - if (abs_fn(endpoint.x-startpoint.x)>=1e-9 || abs_fn(endpoint.y-startpoint.y)>=1e-9) { - // if we reach this point, cell needs to be closed by walking - // counterclockwise along the bounding box until it connects - // to next halfedge in the list - va = endpoint; - // walk downward along left side - if (this.equalWithEpsilon(endpoint.x,xl) && this.lessThanWithEpsilon(endpoint.y,yb)) { - vb = new this.Vertex(xl, this.equalWithEpsilon(startpoint.x,xl) ? startpoint.y : yb); - } - // walk rightward along bottom side - else if (this.equalWithEpsilon(endpoint.y,yb) && this.lessThanWithEpsilon(endpoint.x,xr)) { - vb = new this.Vertex(this.equalWithEpsilon(startpoint.y,yb) ? startpoint.x : xr, yb); - } - // walk upward along right side - else if (this.equalWithEpsilon(endpoint.x,xr) && this.greaterThanWithEpsilon(endpoint.y,yt)) { - vb = new this.Vertex(xr, this.equalWithEpsilon(startpoint.x,xr) ? startpoint.y : yt); - } - // walk leftward along top side - else if (this.equalWithEpsilon(endpoint.y,yt) && this.greaterThanWithEpsilon(endpoint.x,xl)) { - vb = new this.Vertex(this.equalWithEpsilon(startpoint.y,yt) ? startpoint.x : xl, yt); - } - edge = this.createBorderEdge(cell.site, va, vb); - halfedges.splice(iLeft+1, 0, new this.Halfedge(edge, cell.site, null)); - nHalfedges = halfedges.length; - } - iLeft++; - } - } - }; - -// --------------------------------------------------------------------------- -// Top-level Fortune loop - -// rhill 2011-05-19: -// Voronoi sites are kept client-side now, to allow -// user to freely modify content. At compute time, -// *references* to sites are copied locally. -Voronoi.prototype.compute = function(sites, bbox) { - // to measure execution time - var startTime = new Date(); - - // init internal state - this.reset(); - - // Initialize site event queue - var siteEvents = sites.slice(0); - siteEvents.sort(function(a,b){ - var r = b.y - a.y; - if (r) {return r;} - return b.x - a.x; - }); - - // process queue - var site = siteEvents.pop(), - siteid = 0, - xsitex = Number.MIN_VALUE, // to avoid duplicate sites - xsitey = Number.MIN_VALUE, - cells = this.cells, - circle; - - // main loop - for (;;) { - // we need to figure whether we handle a site or circle event - // for this we find out if there is a site event and it is - // 'earlier' than the circle event - circle = this.firstCircleEvent; - - // add beach section - if (site && (!circle || site.y < circle.y || (site.y === circle.y && site.x < circle.x))) { - // only if site is not a duplicate - if (site.x !== xsitex || site.y !== xsitey) { - // first create cell for new site - cells[siteid] = new this.Cell(site); - site.voronoiId = siteid++; - // then create a beachsection for that site - this.addBeachsection(site); - // remember last site coords to detect duplicate - xsitey = site.y; - xsitex = site.x; - } - site = siteEvents.pop(); - } - - // remove beach section - else if (circle) { - this.removeBeachsection(circle.arc); - } - - // all done, quit - else { - break; - } - } - - // wrapping-up: - // connect dangling edges to bounding box - // cut edges as per bounding box - // discard edges completely outside bounding box - // discard edges which are point-like - this.clipEdges(bbox); - - // add missing edges in order to close opened cells - this.closeCells(bbox); - - // to measure execution time - var stopTime = new Date(); - - // prepare return values - var result = { - cells: this.cells, - edges: this.edges, - execTime: stopTime.getTime()-startTime.getTime() - }; - - // clean up - this.reset(); - - return result; - }; - -// 2012-06-15 syhu: export for node.js to use -if (typeof module !== "undefined") - module.exports = Voronoi; diff --git a/scale.bat b/scale.bat deleted file mode 100644 index 214dbc5e..00000000 --- a/scale.bat +++ /dev/null @@ -1 +0,0 @@ -node test_VON_scale 37700 %1 diff --git a/server.js b/server.js deleted file mode 100644 index fc28e6b1..00000000 --- a/server.js +++ /dev/null @@ -1,18 +0,0 @@ - -var net = require('net'); - -var server = net.createServer(function (socket) { - - socket.addListener('error', function(e){ - console.log("error occur: " + e); - }); - - socket.write("Echo server\r\n"); - socket.pipe(socket); -}); - - - -server.listen(1037, "127.0.0.1"); -console.log( "server now listens at port 1037" ); - diff --git a/sf_voronoi.js b/sf_voronoi.js deleted file mode 100644 index 0602c2a4..00000000 --- a/sf_voronoi.js +++ /dev/null @@ -1,1151 +0,0 @@ -/* - * The author of this software is Steven Fortune. - * Copyright (c) 1994 by AT&T Bell Laboratories. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - */ - -/* - * VAST, a scalable peer-to-peer network for virtual environments - * Copyright (C) 2005-2011 Shun-Yun Hu (syhu@ieee.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -// converted from C version to C++, modified by Guan-Ming Liao (gm.liao@msa.hinet.net) -// converted from C++ version to javascript, modified by Shun-Yun Hu (syhu@ieee.org) -// -// history: -// 2012-02-21 replace usage of HEcreate() with new Halfedge() directly -// 2012-06-04 1st converted version working -// - -/* - -Usage: - - var sites = [{x:300,y:300}, {x:100,y:100}, {x:200,y:500}, {x:250,y:450}, {x:600,y:150}]; - // xl, xr means x left, x right - // yt, yb means y top, y bottom - var bbox = {xl:0, xr:800, yt:0, yb:600}; - var voronoi = new Voronoi(); - // pass an object which exhibits xl, xr, yt, yb properties. The bounding - // box will be used to connect unbound edges, and to close open cells - result = voronoi.compute(sites, bbox); - // render, further analyze, etc. - -Return value: - An object with the following properties: - - result.edges = an array of unordered, unique Voronoi.Edge objects making up the Voronoi diagram. - result.cells = an array of Voronoi.Cell object making up the Voronoi diagram. A Cell object - might have an empty array of halfedges, meaning no Voronoi cell could be computed for a - particular cell. - result.execTime = the time it took to compute the Voronoi diagram, in milliseconds. - -Voronoi.Edge object: - lSite: the Voronoi site object at the left of this Voronoi.Edge object. - rSite: the Voronoi site object at the right of this Voronoi.Edge object (can be null). - va: an object with an 'x' and a 'y' property defining the start point - (relative to the Voronoi site on the left) of this Voronoi.Edge object. - vb: an object with an 'x' and a 'y' property defining the end point - (relative to Voronoi site on the left) of this Voronoi.Edge object. - - For edges which are used to close open cells (using the supplied bounding box), the - rSite property will be null. - -Voronoi.Cell object: - site: the Voronoi site object associated with the Voronoi cell. - halfedges: an array of Voronoi.Halfedge objects, ordered counterclockwise, defining the - polygon for this Voronoi cell. - -Voronoi.Halfedge object: - site: the Voronoi site object owning this Voronoi.Halfedge object. - edge: a reference to the unique Voronoi.Edge object underlying this Voronoi.Halfedge object. - getStartpoint(): a method returning an object with an 'x' and a 'y' property for - the start point of this halfedge. Keep in mind halfedges are always countercockwise. - getEndpoint(): a method returning an object with an 'x' and a 'y' property for - the end point of this halfedge. Keep in mind halfedges are always countercockwise. - -*/ - -// if already defined (as included in website) then don't define -var point2d = point2d || require( "./typedef/point2d.js" ); -var segment = segment || require( "./typedef/segment.js" ); -var line2d = line2d || require( "./typedef/line2d.js" ); - -// -// Data Structures -// -function Site(x, y) -{ - // NOTE that coordinates should be accessed via the 'coord' public variable - this.coord = new point2d(x, y); - this.site_num = 0; // sitenbr (NOTE: this is dual-use, one for storing ID of input sites, another for labeling vertex number when calculating edges) - this.ref_count = 0; - - this.edge_idxlist = []; //std::set edge_idxlist; - - // calculate distance between two sites - this.distance = function (another) { - var dist = this.coord.distance(another.coord); - return dist; - } - - // increase reference count for this site - this.ref = function () { - this.ref_count++; - } - - // increase reference count for this site - this.deref = function () { - this.ref_count--; - } - - this.print = function () { - console.log ("site num: " + this.site_num + " ref_count: " + this.ref_count + " x: " + this.coord.x + " y: " + this.coord.y); - } -} - -function Edge () { - - this.a = 0; // double - this.b = 0; // double - this.c = 0; // double - this.ep = []; - this.ep[0] = new Site(0,0); - this.ep[1] = new Site(0,0); - this.reg = []; - this.reg[0] = new Site(0,0); - this.reg[1] = new Site(0,0); - this.edge_num = 0; -} - -// constructor passes in pointer to Edge and an integer value 'pm' -// NOTE: adopted from original HEcreate() -function Halfedge(e, pm) -{ - this.ELleft = undefined; - this.ELright = undefined; - - this.ELedge = e; - this.ELpm = pm; - - this.vertex = null; // he->vertex = (Site *)NULL; - this.PQnext = null; // he->PQnext = (Halfedge *)NULL; - this.ystar = 0; // double - this.ELref_count = 0; - - // for debug: print info for this halfedge - this.print = function () { - - console.log("vertex is: " + typeof this.vertex + " content: " + this.vertex); - - console.log("ELleft: " + this.ELleft + - " ELright: " + this.ELright + - " ELref_count: " + this.ELref_count); - - if (this.vertex != null) - console.log(" vertex: (" + this.vertex.coord.x + ", " + this.vertex.coord.y + ")"); - } -} - -// Construction of SFVoronoi -function Voronoi() { - - // - // public methods & variables - // - - this.mSites = []; - this.mEdges = []; - this.mVertices = []; - - /* - // convert site id to an index in mSites, or returns (-1) if id is not found - this.get_idx = function (id) { - return ((id2idx.hasOwnProperty(id) === false) ? (-1) : id2idx[id]); - } - */ - - - // - // private - // - - ////////////////////////////////////////////////////////////////////////// - //defs.h - - // command line flags - var triangulate, sorted, plot, debug; // int - var xmin, xmax, ymin, ymax, deltax, deltay; // double - var nsites; // int - var siteidx; // int - var sqrt_nsites; // int - var nvertices; // int - var bottomsite; //Site *bottomsite; - - var nedges; // number of edges (int) - var PQhash = []; // Halfedge *PQhash; - var PQhashsize; // int - var PQcount; // int - var PQmin; // int - - var ELleftend, ELrightend; //Halfedge *ELleftend, *ELrightend; - var ELhashsize; //int - var ELhash = []; //Halfedge **ELhash; - - // special marker to indicate a deleted edge - var DELETED = new Edge(); //Edge* DELETED; - DELETED.a = DELETED.b = DELETED.c = (-2); - - // initialization originally done in sfVoronoi constructor - var le = 0; // int - var re = 1; // int - - // a map from id to index in mSites (sorted) - //var id2idx = new Hash(); - //var id2idx = {}; - - // enclosing neighbor list - var en_list = []; //vector _en_list; - - // - // private methods & variables (originally from VoronoiSFAlgorithm's public methods) - // - - // obtain the bounding box for this Voronoi object - // returns true if the box exists, false if one of the dimensions is empty - //bool getBoundingBox (point2d& min, point2d& max) - function getBoundingBox(min, max) { - min.x = xmin; - min.y = ymin; - max.x = xmax; - max.y = ymax; - - return !(xmin == xmax || ymin == ymax); - } - - // - // private methods & variables (originally from VoronoiSFAlgorithm) - // - - this.recompute = function (sites) { - - // clear data - mSites = []; // a list of sites (sorted by ascending order) - mEdges = []; // a list of computed edges - mVertices = []; // a list of all vertices - - if (sites.length === 0) - return false; - - // init variables, originally in calsvf() - sorted = false; triangulate = false; plot = true; debug = true; - - readsites(sites); - siteidx = 0; - - geominit(); - - if (plot) - plotinit(); - - //console.log('calling Voronoi'); - Voronoi(triangulate); - - return true; - } - - - // - // original protected functions, now into private - // - - //Site* nextone() - function nextone() { - - //console.log("nextone() siteidx: " + siteidx + " nsites: " + nsites); - - // check if next is available - if (siteidx >= nsites) - return null; - - var coord = mSites[siteidx++].coord; - //console.log("site found idx: " + (siteidx-1) + " id: " + mSites[(siteidx-1)].site_num + " (" + coord.x + "," + coord.y + ")"); - - return new Site(coord.x, coord.y); - } - - //void readsites(); - // converting sites to mSites - // NOTE: this is an important step as mSites needs to be sorted (from ascending order) for Voronoi construction - function readsites(sites) { - - // get number of sites first - nsites = sites.length; - - // store initial min-max values - xmin = xmax = sites[0].x; - ymin = ymax = sites[0].y; - //console.log('xmin: ' + xmin + ' xmax: ' + xmax + ' ymin: ' + ymin + ' ymax: ' + ymax); - - var pt; - var site; - - for (var i=0; i < nsites; i++) { - - pt = sites[i]; - site = new Site(pt.x, pt.y); - - // store id directly to site - site.id = pt.id; - //site.site_num = pt.id; - //site.site_num = keys[i]; // use the key (i.e., site ID) as the site numbers - - //console.log('site [' + site.site_num + '] (' + pt.x + ', ' + pt.y + ')'); - - // store onto a new array (to be sorted) - mSites.push(site); - - // check & store min/max values - if (pt.x < xmin) - xmin = pt.x; - else if (pt.x > xmax) - xmax = pt.x; - if (pt.y < ymin) - ymin = pt.y; - else if (pt.y > ymax) - ymax = pt.y; - } - - // order all sites according to coordinate comparisons - mSites.sort(function (a, b) { - return a.coord.compareTo(b.coord); - }); - - /* - // record a map from site id to index in mSites (after sorting) - // this is used to perform other overlap, contain checks - id2idx = {}; - - for (var idx = 0; idx < mSites.length; idx++) { - id2idx[mSites[idx].site_num] = idx; - } - */ - } - - ////////////////////////////////////////////////////////////////////////// - //Geometry.h - - //void sfVoronoi::geominit () - - var geominit = function () { - - nvertices = 0; - nedges = 0; - sqrt_nsites = Math.floor(Math.sqrt(nsites+4)); // NOTE: sqart_nsites is of type integer in C++ - deltay = ymax - ymin; - deltax = xmax - xmin; - //console.log("nsites: " + nsites + " sqrt_nsites: " + sqrt_nsites + " ymax: " + ymax + " ymin: " + ymin + " xmax: " + xmax + " xmin: " + xmin); - } - - var bisect = function (s1, s2) { - - //console.log ("bisecting (%d, %d) (%d, %d)\n", s1.coord.x, s1.coord.y, s2.coord.x, s2.coord.y); - - var dx, dy, adx, ady; // double - var newedge = new Edge(); - - newedge.reg[0] = s1; - newedge.reg[1] = s2; - s1.ref(); - s2.ref(); - newedge.ep[0] = null; - newedge.ep[1] = null; - - dx = s2.coord.x - s1.coord.x; - dy = s2.coord.y - s1.coord.y; - adx = (dx > 0 ? dx : -dx); - ady = (dy > 0 ? dy : -dy); - - newedge.c = s1.coord.x * dx + s1.coord.y * dy + (dx*dx + dy*dy) * 0.5; // double - - if (adx > ady) { - newedge.a = 1.0; - newedge.b = dy/dx; - newedge.c /= dx; - } - else { - newedge.b = 1.0; - newedge.a = dx/dy; - newedge.c /= dy; - } - - newedge.edge_num = nedges++; - out_bisector(newedge); - - return newedge; - } - - var intersect = function (el1, el2) - { - var e1 = el1.ELedge; - var e2 = el2.ELedge; - - if (e1 == null || e2 == null || (e1.reg[1] == e2.reg[1])) - return null; - - var d = e1.a * e2.b - e1.b * e2.a; - - // if difference is close to 0, we assume it's 0 and return it - if (-1.0e-10 < d && d < 1.0e-10) { - //console.log('d is in range, returning null'); - return null; - } - - var e; // Edge *e; - var el; // Halfedge *el; - - var xint = (e1.c*e2.b - e2.c*e1.b)/d; - var yint = (e2.c*e1.a - e1.c*e2.a)/d; - - if (e1.reg[1].coord.compareTo(e2.reg[1].coord) < 0) - { - el = el1; - e = e1; - } - else - { - el = el2; - e = e2; - } - - var right_of_site = (xint >= e.reg[1].coord.x); - - if ((right_of_site && el.ELpm == le) ||(!right_of_site && el.ELpm == re)) - return null; - - var v = new Site(xint, yint); //Site *v; - return v; - } - - function right_of(el, p) - { - // el.ELedge is expected to be valid pointer - var e = el.ELedge; // Edge *e; - var topsite = e.reg[1]; //Site *topsite; - - var right_of_site = (p.x > topsite.coord.x); - - if (right_of_site && el.ELpm == le) - return true; - - if (!right_of_site && el.ELpm == re) - return false; - - var above, fast; // int - var dxp, dyp, dxs, t1, t2, t3, yl; // double - - if (e.a == 1.0) { - - dyp = p.y - topsite.coord.y; - dxp = p.x - topsite.coord.x; - fast = false; - - if ((!right_of_site & (e.b < 0.0)) | (right_of_site & (e.b >= 0.0))) - fast = above = (dyp >= e.b*dxp); - else { - above = p.x + p.y * e.b > e.c; - if (e.b < 0.0) - above = !above; - if (!above) - fast = true; - } - if (!fast) { - - dxs = topsite.coord.x - (e.reg[0]).coord.x; - - // joker: update, skip divide by zero 05.05.27 - // TODO: need to further check what cases could cause divide by 0 - if (dxs != 0) - above = e.b * (dxp*dxp - dyp*dyp) < dxs*dyp*(1.0+2.0*dxp/dxs + e.b*e.b); - else - above = false; - - if (e.b < 0.0) - above = !above; - } - } - //e.b==1.0 - else { - yl = e.c - e.a*p.x; - t1 = p.y - yl; - t2 = p.x - topsite.coord.x; - t3 = yl - topsite.coord.y; - above = t1*t1 > (t2*t2 + t3*t3); - } - - return (el.ELpm == le ? above : !above); - } - - function endpoint(e, lr, s) - { - e.ep[lr] = s; - s.ref(); - - if (e.ep[re-lr] == null) - return; - - out_ep(e); - e.reg[le].deref(); // deref(e.reg[le]); - e.reg[re].deref(); // deref(e.reg[re]); - } - - //void sfVoronoi::makevertex( Site *v ) - function makevertex(v) - { - v.site_num = nvertices++; - //out_vertex(v); - mVertices.push(new point2d(v.coord.x, v.coord.y)); - } - - /* - //void out_vertex ( Site *v ); - function out_vertex(v) { - mVertices.push(new point2d(v.coord.x, v.coord.y)); - } - */ - - - ////////////////////////////////////////////////////////////////////////// - //output.c - var pxmin, pxmax, pymin, pymax, cradius; // double - - function out_bisector(e) - { - //printf ("out_bisector [%f, %f, %f]\n", e.a, e.b, e.c); - //console.log('out_bisector [' + e.a + ', ' + e.b + ', ' + e.c + ']'); - console.log('out_bisector le: ' + le + ' re: ' + re + ' site1: ' + e.reg[le].site_num + ' site2: ' + e.reg[re].site_num); - - var line = new line2d(e.a, e.b, e.c); - - line.bisectingID[0] = e.reg[le].site_num; - line.bisectingID[1] = e.reg[re].site_num; - - // To-do: check if accessing using line.bisectingID[0] is okay (it may be a string instead of a number) - mSites[line.bisectingID[0]].edge_idxlist.push(e.edge_num); - mSites[line.bisectingID[1]].edge_idxlist.push(e.edge_num); - - mEdges.push(line); - } - - function out_ep(e) { - - mEdges[e.edge_num].vertexIndex[0] = (e.ep[le] != null) ? (e.ep[le].site_num) : (-1); - mEdges[e.edge_num].vertexIndex[1] = (e.ep[re] != null) ? (e.ep[re].site_num) : (-1); - - if (!triangulate & plot) { - clip_line(e); - } - - if (!triangulate & !plot) { - //printf("e %d", e.edge_num); - //printf(" %d ", e.ep[le] != ( Site *)NULL ? e.ep[le].site_num : -1); - //printf("%d\n", e.ep[re] != ( Site *)NULL ? e.ep[re].site_num : -1); - } - } - - function plotinit() { - - var dx = xmax - xmin; - var dy = ymax - ymin; - var d = (dx > dy ? dx : dy) * 1.1; - - pxmin = xmin - (d-dx)/2.0; - pxmax = xmax + (d-dx)/2.0; - pymin = ymin - (d-dy)/2.0; - pymax = ymax + (d-dy)/2.0; - - cradius = (pxmax - pxmin)/350.0; - } - - function clip_line(e) { - - var s1, s2; // Site *s1, *s2; - var x1,x2,y1,y2; // double - - if (e.a == 1.0 && e.b >= 0.0) { - s1 = e.ep[1]; - s2 = e.ep[0]; - } - else { - s1 = e.ep[0]; - s2 = e.ep[1]; - } - - if (e.a == 1.0) { - - y1 = pymin; - if (s1 != null && s1.coord.y > pymin) - y1 = s1.coord.y; - - if (y1 > pymax) - return; - - x1 = e.c - e.b * y1; - y2 = pymax; - - if (s2 != null && s2.coord.y < pymax) - y2 = s2.coord.y; - - if (y2 < pymin) - return; - - x2 = e.c - e.b * y2; - - if (((x1> pxmax) & (x2>pxmax)) | ((x1 < pxmin) & (x2 < pxmin))) - return; - - if (x1 > pxmax) { - x1 = pxmax; - y1 = (e.c - x1) / e.b; - } - - if (x1 < pxmin) { - x1 = pxmin; - y1 = (e.c - x1) / e.b; - } - - if (x2 > pxmax) { - x2 = pxmax; - y2 = (e.c - x2) / e.b; - } - - if (x2 < pxmin) { - x2 = pxmin; - y2 = (e.c - x2) / e.b; - } - } - else { - - x1 = pxmin; - if (s1 != null && s1.coord.x > pxmin) - x1 = s1.coord.x; - - if (x1 > pxmax) - return; - - y1 = e.c - e.a * x1; - x2 = pxmax; - - if (s2 != null && s2.coord.x < pxmax) - x2 = s2.coord.x; - - if (x2 < pxmin) - return; - - y2 = e.c - e.a * x2; - - if (((y1 > pymax) & (y2 > pymax)) | ((y1 < pymin) & (y2 < pymin))) - return; - - if (y1> pymax) { - y1 = pymax; - x1 = (e.c - y1) / e.a; - } - - if (y1 < pymin) { - y1 = pymin; - x1 = (e.c - y1) / e.a; - } - - if (y2 > pymax) { - y2 = pymax; - x2 = (e.c - y2) / e.a; - } - - if (y2 < pymin) { - y2 = pymin; - x2 = (e.c - y2) / e.a; - } - } - - mEdges[e.edge_num].seg.p1 = new point2d(x1,y1); - mEdges[e.edge_num].seg.p2 = new point2d(x2,y2); - } - - - ////////////////////////////////////////////////////////////////////////// - //heap.c - - function PQinsert(he, v, offset) { - var last, next; // Halfedge *last, *next; - - he.vertex = v; - - v.ref(); - he.ystar = v.coord.y + offset; - - var buc = PQbucket(he); - last = PQhash[buc]; - - while ((next = last.PQnext) != null && - (he.ystar > next.ystar || (he.ystar == next.ystar && v.coord.x > next.vertex.coord.x))) - last = next; - - he.PQnext = last.PQnext; - last.PQnext = he; - PQcount++; - } - - // void PQdelete(Halfedge *he); - function PQdelete(he) { - - var last; //Halfedge *last; - - if (he.vertex != null) - { - last = PQhash[PQbucket(he)]; - - while (last.PQnext != he) - last = last.PQnext; - - last.PQnext = he.PQnext; - PQcount--; - - he.vertex.deref(); - he.vertex = null; - } - } - - // return the bucket (an integer number) for the halfedge - // int PQbucket(Halfedge *he); - function PQbucket(he) { - - // int - var bucket = Math.floor((he.ystar - ymin) / deltay * PQhashsize); - - // 2012-02-21 syhu added: to check for NaN for bucket - if (bucket < 0 || isNaN(bucket)) - bucket = 0; - - // get last one - if (bucket >= PQhashsize) - bucket = PQhashsize-1; - - // record min - if (bucket < PQmin) - PQmin = bucket; - - //console.log ("*** bucket: " + bucket + " deltay: " + deltay + " ystar: " + he.ystar); - return bucket; - } - - function PQempty() { - return (PQcount == 0); - } - - function PQ_min() { - var answer = new point2d(); // Point - - while (PQhash[PQmin].PQnext == null) - PQmin++; - - answer.x = PQhash[PQmin].PQnext.vertex.coord.x; - answer.y = PQhash[PQmin].PQnext.ystar; - - return answer; - } - - function PQextractmin() { - - //Halfedge *curr; - var curr = PQhash[PQmin].PQnext; - - PQhash[PQmin].PQnext = curr.PQnext; - PQcount--; - - return curr; - } - - function PQinitialize() { - - PQcount = 0; - PQmin = 0; - PQhashsize = 4 * sqrt_nsites; - PQhash = []; //PQhash = new Halfedge[PQhashsize]; - - for (var i=0; i < PQhashsize; i++) { - PQhash[i] = new Halfedge(); - } - } - - ////////////////////////////////////////////////////////////////////////// - //edgelist.c - var ntry = 0, totalsearch = 0; - - function ELinitialize() { - - // need to force "ELhashsize" to be integer - ELhashsize = Math.floor(2 * sqrt_nsites); - - ELhash = []; - - // NOTE: it's important to initialize ELhash with 'null' - for (var i=0; i < ELhashsize; i++) - ELhash.push(null); - - // TODO: init with null, 0 will cause crash - ELleftend = new Halfedge(null, 0); - ELrightend = new Halfedge(null, 0); - - ELleftend.ELleft = null; - ELleftend.ELright = ELrightend; - - ELrightend.ELleft = ELleftend; - ELrightend.ELright = null; - - // set ELleftend and ELrightend to array - ELhash[0] = ELleftend; - ELhash[ELhashsize-1] = ELrightend; - } - - //change arg2 to newH - // void ELinsert (Halfedge *lb, Halfedge* newH); - function ELinsert(lb, newH) { - newH.ELleft = lb; - newH.ELright = lb.ELright; - lb.ELright.ELleft = newH; - lb.ELright = newH; - } - - // get the halfedge in a given bucket - function ELgethash(b) { - - //console.log("ELgethash: b=" + b + " ELhashsize: " + ELhashsize); - if (b < 0 || b >= ELhashsize) { - //console.log("err: ELgethash: b out of range, returning null"); - return null; - } - - var he = ELhash[b]; - - // NOTE: it's important the check is done against DELETED instead of 'null' - // as DELETED is a special marker object - if (he == null || he.ELedge != DELETED) - return he; - - // removing the halfedge node - // Hash table points to deleted half edge. Patch as necessary. - ELhash[b] = null; - - return null; - } - - // find the left boundary of a point p (?) - function ELleftbnd(p) { - - //ntry = 0; - - // Use hash table to get close to desired halfedge - var bucket = Math.floor((p.x - xmin) / deltax * ELhashsize); // int - - //console.log('bucket: ' + bucket + ' ELhashzie: ' + ELhashsize + ' deltax: ' + deltax); - - // syhu: 2012-06-11 add check for NaN - //if (bucket < 0 || isNaN(bucket)) - if (bucket < 0) - bucket = 0; - - if (bucket >= ELhashsize) - bucket = ELhashsize - 1; - - var he = ELgethash(bucket); - - if (he == null) { - - /* - var i=1; // int - while ((he = ELgethash (bucket-i)) == null && - (he = ELgethash (bucket+i)) == null) - i++; - */ - for (var i=1; true; i++) { - if ((he = ELgethash(bucket-i)) != null) - break; - if ((he = ELgethash(bucket+i)) != null) - break; - } - - totalsearch += i; - } - - ntry++; - - // Now search linear list of halfedges for the corect one - // NOTE: he.ELedge must be valid for right_of to process correctly - if (he == ELleftend || (he != ELrightend && right_of(he, p))) { - - do { - // NOTE: ELright is assumed to be a valid object (not possible to be null) - he = he.ELright; - } - while (he != ELrightend && right_of(he, p)); - - he = he.ELleft; - } - else { - - do { - he = he.ELleft; - } - while (he !== ELleftend && !right_of(he,p)); - } - - // Update hash table and reference counts - if (bucket > 0 && bucket < ELhashsize-1) { - if (ELhash[bucket] != null) - ELhash[bucket].ELref_count--; - - ELhash[bucket] = he; - ELhash[bucket].ELref_count++; - } - - //printf ("ELleftbnd: elpm: %d ref_count: %d ystar: %f\n", he.ELpm, he.ELref_count, he.ystar); - return he; - } - - function ELdelete(he) { - he.ELleft.ELright = he.ELright; - he.ELright.ELleft = he.ELleft; - he.ELedge = DELETED; - } - - function ELright(he) { - return he.ELright; - } - - function ELleft(he) { - return he.ELleft; - } - - function leftreg (he) { - - if (he.ELedge == null) - return bottomsite; - - return (he.ELpm == le ? he.ELedge.reg[le] : he.ELedge.reg[re]); - } - - function rightreg (he) { - - if (he.ELedge == null) { - return bottomsite; - } - - return (he.ELpm == le ? he.ELedge.reg[re] : he.ELedge.reg[le]); - } - - ////////////////////////////////////////////////////////////////////////// - //Voronoi.c - //void Voronoi (int triangulate); - - function Voronoi(to_triangulate) { - - //console.log("my function name: " + arguments.callee.name); - - // unused - triangulate = to_triangulate; - - var newsite, bot, top, temp, p; // Site * - var v; //Site *v; - var newintstar = new point2d(0, 0); // Point - - var pm; // int - var lbnd, rbnd, llbnd, rrbnd, bisector; // Halfedge * - var e; // Edge *e; - - PQinitialize(); - bottomsite = nextone(); - ELinitialize(); - - //console.log('get first site...'); - newsite = nextone(); - - while (true) { - - //console.log('still true...'); - if (!PQempty ()) - newintstar = PQ_min(); - - if (newsite != null && - (PQempty () || newsite.coord.compareTo(newintstar) < 0)) { - - //console.log ("new site is smallest\n"); - // new site is smallest - lbnd = ELleftbnd(newsite.coord); - rbnd = ELright(lbnd); - bot = rightreg(lbnd); - - e = bisect(bot, newsite); - bisector = new Halfedge(e, le); // HEcreate(e, le); - - ELinsert(lbnd, bisector); - - //console.log ("find left intersect\n"); - if ((p = intersect(lbnd, bisector)) != null) { - PQdelete(lbnd); - PQinsert(lbnd, p, p.distance(newsite)); - } - - lbnd = bisector; - bisector = new Halfedge(e, re); // HEcreate(e, re); - ELinsert(lbnd, bisector); - - //console.log ("find right intersect\n"); - if ((p = intersect(bisector, rbnd)) != null) - PQinsert(bisector, p, p.distance(newsite)); - - newsite = nextone(); - } - // intersection is smallest - else if (!PQempty()) - { - //console.log ("intersection is smallest\n"); - lbnd = PQextractmin(); - llbnd = ELleft(lbnd); - rbnd = ELright(lbnd); - rrbnd = ELright(rbnd); - bot = leftreg(lbnd); - top = rightreg(rbnd); - v = lbnd.vertex; - - makevertex (v); - - endpoint(lbnd.ELedge, lbnd.ELpm, v); - endpoint(rbnd.ELedge, rbnd.ELpm, v); - - ELdelete(lbnd); - PQdelete(rbnd); - ELdelete(rbnd); - - pm = le; - - if (bot.coord.y > top.coord.y) { - temp = bot; - bot = top; - top = temp; - pm = re; - } - - e = bisect(bot, top); - bisector = new Halfedge(e, pm); - ELinsert(llbnd, bisector); - endpoint(e, re-pm, v); - v.deref(); - - if ((p = intersect(llbnd, bisector)) != null) { - PQdelete(llbnd); - PQinsert(llbnd, p, p.distance(bot)); - } - - if ((p = intersect(bisector, rrbnd)) != null) - PQinsert(bisector, p, p.distance(bot)); - } - else - break; - } - - for (lbnd = ELright(ELleftend); lbnd != ELrightend; lbnd = ELright(lbnd)) { - e = lbnd.ELedge; - out_ep(e); - } - } // end Voronoi -} // end SFVoronoi - -/* -// get sorted site list -Voronoi.prototype.get_sites = function () { - return mSites; -} -*/ - -// produce voronoi given sites & bounding box -Voronoi.prototype.compute = function (sites, bbox) { - - // to measure execution time - var startTime = new Date(); - - // calculate Voronoi - this.recompute(sites); - - // to measure execution time - var stopTime = new Date(); - - // convert cells - var cells = []; - //console.log('mSites.length: ' + mSites.length); - - // store site to cells' site attribute - for (var i=0; i < mSites.length; i++) { - //cells.push(mSites[i].coord); - var cell = { - site: mSites[i].coord, - halfedges: mSites[i].edge_idxlist - } - //console.log('edge_idxlist length: ' + mSites[i].edge_idxlist.length); - cell.site.id = mSites[i].id; - cells.push(cell); - } - - // convert edges - var edges = []; - for (var i=0; i < mEdges.length; i++) { - //if (mEdges[i].seg.is_empty() === false) { - var edge = { - va: mEdges[i].seg.p1, - vb: mEdges[i].seg.p2, - a: mEdges[i].a, - b: mEdges[i].b, - c: mEdges[i].c - } - edges.push(edge); - //} - } - - // prepare return values - var result = { - cells: cells, - edges: edges, - execTime: stopTime.getTime()-startTime.getTime() - } - - return result; -} - -if (typeof module !== "undefined") - module.exports = Voronoi; diff --git a/simulator/example_script.txt b/simulator/example_script.txt new file mode 100644 index 00000000..26d53682 --- /dev/null +++ b/simulator/example_script.txt @@ -0,0 +1,119 @@ +// Instruction Overview for VAST.js simulator scripts +// ___________________________________________________________________ + +// instructions take the form "Command Arg1 Arg2 Ag3...." + +// START NEW MATCHER: +// -------------------------------------------------------------------- +// Command: "newMatcher" +// Arg1: "alias" --> This is the name of the matcher, and how to refer to it in other commands +// Arg2: "isGateway" --> Sets whether the matcher to create is the gateway or not. (only single gateway is currently supported) +// Arg3: "GW_host" --> The address of the GW peer to connect to +// Arg4: "GW_port" --> The port the GW is listening on for other Matcher connections +// Arg5: "VON_port" --> The port we are listening on for other matchers. Will automatically increment if in use. +// Arg6: "client_port" --> The port the matcher listens on for client connections. +// Arg7: "x_ord" --> x ordinate of matcher. Currently only 0 <= x <= 1000 is supported. +// Arg8: "y_ord" --> y ordinate of matcher. Currently only 0 <= y <= 1000 is supported. +// Arg9: "radius" --> The VON peer will always be aware of enclosing neighbours, but will connect to any additional neighbours that fall in this circle. + +// START NEW CLIENT +// -------------------------------------------------------------------- +// Command: "newClient" +// Arg1: "alias" --> This is the name of the client, and how to refer to it in other commands +// Arg2: "GW_host" --> The address of the GW matcher to connect to +// Arg3: "GW_port" --> The port the GW is listening on for client connections +// Arg4: "x_ord" --> x ordinate of client. Currently only 0 <= x <= 1000 is supported. +// Arg5: "y_ord" --> y ordinate of client. Currently only 0 <= y <= 1000 is supported. +// Arg6: "radius" --> Currently unused. + +// SUBSCRIBE +// -------------------------------------------------------------------- +// Command: "subscribe" +// Arg1: "alias" --> The alias of the client to add a subscription for. +// Arg2: "x_ord" --> x ordinate of subscription centre. Currently only 0 <= x <= 1000 is supported. +// Arg3: "y_ord" --> y ordinate of subscription centre. Currently only 0 <= y <= 1000 is supported. +// Arg4: "radius" --> Radius of subscription area. +// Arg5: "channel" --> The channel/topic the subscription is for. + +// PUBLISH +// -------------------------------------------------------------------- +// Command: "publish" +// Arg1: "alias" --> The alias of the client to publish. +// Arg2: "x_ord" --> x ordinate of publication centre. Currently only 0 <= x <= 1000 is supported. +// Arg3: "y_ord" --> y ordinate of publication centre. Currently only 0 <= y <= 1000 is supported. +// Arg4: "radius" --> Radius of publication area. +// Arg5: "channel" --> The channel/topic the publication is for. +// Arg6: "payload" --> The payload of the message. Example: "hello from client 1!". + +// MOVE CLIENT +// -------------------------------------------------------------------- +// Command: "moveClient" +// Arg1: "alias" --> The alias of the client to move. +// Arg2: "x_ord" --> x ordinate of new position. Currently only 0 <= x <= 1000 is supported. +// Arg3: "y_ord" --> y ordinate of new position. Currently only 0 <= y <= 1000 is supported. + +// WAIT BEFORE NEXT INSTRUCTION +// -------------------------------------------------------------------- +// Command: "wait" +// Arg1: "waitTime" --> Time to wait for in milliseconds. + +// END SIMULATION +// -------------------------------------------------------------------- +// Command: "end" --> call after last instruction to end node process. Simulator will run indefinately otherwise. + + +// EXAMPLE INSTRUCTION SCRIPT FOR VAST.js Simulator +//___________________________________________________________________ + +//Start the Gateway matcher +newMatcher GW true localhost 8000 8001 20000 500 500 100 +wait 100 + +//Start other matchers +newMatcher M2 false localhost 8000 8010 20010 167 500 100 +newMatcher M3 false localhost 8000 8020 20020 833 500 100 + +// Start a few clients with localised subscriptions +newClient C1 localhost 20000 300 100 100 +wait 200 +subscribe C1 300 100 100 channel1 + +newClient C2 localhost 20000 200 200 100 +wait 300 +subscribe C2 200 200 100 channel1 + +// start a client with a huge subscription +newClient C3 localhost 20000 500 200 100 +wait 400 +subscribe C3 500 500 500 channel1 + +// add a subscription on a different channel +subscribe C3 500 500 500 channel2 +wait 100 + + +// publish a few messages +publish C1 300 100 10 channel1 "hello from C1!" +wait 100 +publish C2 200 200 100 channel1 "C2 also says hello!" +wait 100 +publish C3 250 250 50 channel1 "C3 sending a message far way" +wait 100 +publish C2 200 200 5 channel2 "C2 publishing on channel2. Only C3 should receive this pub." +wait 100 + +//move a client +moveClient C1 350 500 +wait 1000 +moveClient C1 400 600 + + +publish C2 400 600 10 channel1 "Hi to C1/C3" +publish C2 200 200 10 channel1 "C2/C3 hello" +wait 100 +publish C2 500 500 1000 channel1 "global hello" + + +//End of simulation; wait a bit for any pending publications and control messages +wait 1000 +end \ No newline at end of file diff --git a/simulator/simulator.js b/simulator/simulator.js new file mode 100644 index 00000000..aaa1f1f9 --- /dev/null +++ b/simulator/simulator.js @@ -0,0 +1,380 @@ +// CF Marais December 2021 +// A discrete event simulator for VAST, used for code verification and bug finding + +// imports +const matcher = require('../lib/matcher.js'); +const client = require('../lib/client.js'); + +var log = LOG.newLayer('Simulator_logs', 'Simulator_logs', 'logs_and_events', 5, 5); + +// Data structures to store matchers +// alias --> matcher{}. +var matchers = {}; +var matcherIDs2alias = {}; +var clients = {}; +var clientIDs2alias = {}; + +var instructions = []; + +//importing data from text file +var fs = require('fs'); +const readline = require('readline'); +const { map, data } = require('jquery'); + +var filename = process.argv[2] || "./simulator/example_script.txt"; +if (filename.length > 4 && filename.slice(-4) != ".txt") { + error("Please Provide A Text File"); +} + +// Interpret and execute instruction +async function executeInstruction(instruction, step, success, fail){ + var opts = instruction.opts; + var type = instruction.type; + + switch (type){ + + case 'wait' : { + delay(opts.waitTime, function(){ + success('waited for ' + opts.waitTime + ' milliseconds'); + }); + } + break; + + case 'newMatcher' : { + + if (!matchers.hasOwnProperty(opts.alias)){ + + matchers[opts.alias]= new matcher(opts.x, opts.y, opts.radius, + { + isGateway: opts.isGateway, + GW_host: opts.GW_host, + GW_port: opts.GW_port, + VON_port: opts.VON_port, + client_port: opts.client_port, + alias: opts.alias, + //logLayer: 'Matcher_' + opts.alias, + //logFile: 'Matcher_' + opts.alias, + logDisplayLevel : 3, + logRecordLevel : 4, + eventDisplayLevel : 0, + eventRecordLevel : 5 + }, + function(id){ + matcherIDs2alias[id] = opts.alias; + success('Matcher: ' + opts.alias + ' created with ID: ' + id); + } + ); + } + else{ + fail('Matcher already exists with alias: ' + opts.alias); + } + } + break; + + case 'newClient' : { + if(!clients.hasOwnProperty(opts.alias)){ + + clients[opts.alias] = new client(opts.host, opts.port, opts.alias, opts.x, opts.y, opts.radius, function(id){ + clientIDs2alias[id] = opts.alias; + clients[opts.alias].setAlias = opts.alias; + let m = clients[opts.alias].getMatcherID(); + success('Client ' + opts.alias + ' assigned to matcher: ' + matcherIDs2alias[m]); + }); + } + else{ + fail('client already exists with alias: ' + alias); + } + } + break; + + case 'subscribe' : { + + if(clients.hasOwnProperty(opts.alias)){ + clients[opts.alias].subscribe(opts.x, opts.y, opts.radius, opts.channel); + success(opts.alias + ': added subscription:', opts.x, opts.y, opts.radius, opts.channel); + } + else{ + fail('Invalid client alias for subscription: ' + opts.alias); + } + } + break; + + case 'publish' : { + + if(clients.hasOwnProperty(opts.alias)){ + clients[opts.alias].publish(opts.x, opts.y, opts.radius, opts.payload, opts.channel); + success(opts.alias + ' published:', opts.payload, 'on channel: ' + opts.channel) + } + else{ + fail('client with alias "' + alias + '" does not exist'); + } + } + break; + + case 'moveClient' : { + + if(clients.hasOwnProperty(opts.alias)){ + clients[opts.alias].move(opts.x, opts.y); + success(opts.alias + ' request move to ['+ opts.x + '; ' + opts.y + ']'); + } + else{ + fail('client with alias "' + alias + '" does not exist'); + } + } + break; + + case 'end' : { + log.debug('Ending Simulation'); + process.exit(0); + } + break; + + default: { + fail('instruction at step ' + step + 'is not valid'); + } + } +} + +// A function wrapper used to execute steps synchronously using a promise +var executeInstructionWrapper = function(instruction, step){ + return new Promise(function(resolve, reject){ + + executeInstruction(instruction, step, + function(successResponse){ + resolve(successResponse); + }, + + function(failResponse){ + reject(failResponse); + }); + }); +} + +async function execute(step){ + step = step || 0; + + if (step >= instructions.length){ + log.debug('Reached end of instructions'); + return; + } + + try { + log.debug('Executing instruction ' + step + '. Type: ' + instructions[step].type); + var result = await executeInstructionWrapper(instructions[step], step); + log.debug(result); + } + catch(error){ + log.error(error); + } + execute(step+1); +} + +async function delay(m, callback) { + m = m || 100; + await new Promise(function() { + setTimeout(callback, m); + }); +} + +//function to obtain all the data from a text file +var dataFromTextFiles = async (filename) => { + try { + var dataFromTextFile = []; + const fileStream = fs.createReadStream(filename); + + const rl = readline.createInterface({ + input: fileStream, + crlfDelay: Infinity, + }); + // Note: we use the crlfDelay option to recognize all instances of CR LF + // ('\r\n') in input.txt as a single line break. + + for await (const data of rl) { + var dataLine = []; + var cur = ""; + var isString = 0; + + for (var d of data) { + if (d == '"') { + isString = 1 - isString; + } + + else if (isString == 1) { + cur += d; + } + + else if ( + (d >= "a" && d <= "z") || (d >= "A" && d <= "Z") || + (d >= "0" && d <= "9") || (d == "/")) { + cur += d; + } + + else { + if (cur.length != 0) + dataLine.push(cur); + + cur = ""; + } + } + if (cur.length != 0) + dataLine.push(cur); + + dataFromTextFile.push(dataLine); + } + + return dataFromTextFile; + } catch (e) { + log.error("Error:", e.stack); + } +}; + +var dataFromTextFile = dataFromTextFiles(filename).then((dataFromTextFile) => { + + var i = 1; // line counter + + dataFromTextFile.map((dataFromTextFile) => { + switch (dataFromTextFile[0]) { + + case "wait" :{ + if (dataFromTextFile.length != 2) { + error(`wrong input in line number ${i}`); + } + else { + instructions.push(new instruction(dataFromTextFile[0], + { + waitTime: dataFromTextFile[1] + } + )); + } + i++; + } + break; + + case "newMatcher" :{ + if (dataFromTextFile.length != 10) { + error(`wrong input in line number ${i}`); + } else { + instructions.push( + new instruction(dataFromTextFile[0], { + alias: dataFromTextFile[1], + isGateway: dataFromTextFile[2] == "true" ? true : false, + GW_host: dataFromTextFile[3], + GW_port: Number(dataFromTextFile[4]), + VON_port: Number(dataFromTextFile[5]), + client_port: Number(dataFromTextFile[6]), + x: Number(dataFromTextFile[7]), + y: Number(dataFromTextFile[8]), + radius: Number(dataFromTextFile[9]), + }) + ); + } + i++; + } + break; + + case "newClient" :{ + if (dataFromTextFile.length != 7) { + error(`wrong input in line number ${i}`); + } else { + instructions.push( + new instruction(dataFromTextFile[0], { + alias: dataFromTextFile[1], + host: dataFromTextFile[2], + port: Number(dataFromTextFile[3]), + x: Number(dataFromTextFile[4]), + y: Number(dataFromTextFile[5]), + radius: Number(dataFromTextFile[6]), + }) + ); + } + i++; + } + break; + + case "subscribe" :{ + if (dataFromTextFile.length != 6) { + error(`wrong input in line number ${i}`); + } else { + instructions.push( + new instruction(dataFromTextFile[0], { + alias: dataFromTextFile[1], + x: Number(dataFromTextFile[2]), + y: Number(dataFromTextFile[3]), + radius: Number(dataFromTextFile[4]), + channel: dataFromTextFile[5], + }) + ); + } + i++; + } + break; + + case "publish" :{ + if (dataFromTextFile.length != 7) { + error(`wrong input in line number ${i}`); + } else { + instructions.push( + new instruction(dataFromTextFile[0], { + alias: dataFromTextFile[1], + x: Number(dataFromTextFile[2]), + y: Number(dataFromTextFile[3]), + radius: Number(dataFromTextFile[4]), + channel: dataFromTextFile[5], + payload: dataFromTextFile[6], + }) + ); + } + i++; + } + break; + + case "moveClient" :{ + if (dataFromTextFile.length != 4) { + error(`wrong input in line number ${i}`); + } else { + instructions.push( + new instruction(dataFromTextFile[0], { + alias: dataFromTextFile[1], + x: Number(dataFromTextFile[2]), + y: Number(dataFromTextFile[3]) + }) + ); + } + i++; + } + break; + + // instruction to end simulation + case "end" :{ + instructions.push(new instruction(dataFromTextFile[0])); + return; + } + + default :{ + // NOT a comment or empty line, alert user and end process + if (dataFromTextFile.length > 0 && !dataFromTextFile[0].startsWith('//')){ + error(`Unrecognised Input in line number ${i}`); + } + i++; + break; + } + } + }); + + // start executing once all instructions loaded + execute(); +}); + +var error = function(message){ + log.error(message); + process.exit(); +} + +var instruction = function (type, opts) { + this.type = type; + this.opts = opts; +} + + +dataFromTextFile; + \ No newline at end of file diff --git a/simulator/visualiser.html b/simulator/visualiser.html new file mode 100644 index 00000000..c2404d95 --- /dev/null +++ b/simulator/visualiser.html @@ -0,0 +1,574 @@ + + + + VAST Visualiser + + + + + +
+ + + + + + + + + + + + +
Load Event Log FileLoad Debug Log FilesSelect Debug File to View
+
+
+
+
+ +
+ +
+
+
    +
    +
    +
    + + + + + + + + + + + + + + +
    Time Step Duration [ms]Current TimeTime Controls [10 steps/s]Publication Rendering Lifespan [ms]
    +
    +
    + + + + + + + + + + + + + + diff --git a/socket.io/socket.io.js b/socket.io/socket.io.js deleted file mode 100644 index 082e169c..00000000 --- a/socket.io/socket.io.js +++ /dev/null @@ -1,3862 +0,0 @@ -/*! Socket.IO.js build:0.9.9, development. Copyright(c) 2011 LearnBoost MIT Licensed */ - -var io = ('undefined' === typeof module ? {} : module.exports); -(function() { - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, global) { - - /** - * IO namespace. - * - * @namespace - */ - - var io = exports; - - /** - * Socket.IO version - * - * @api public - */ - - io.version = '0.9.9'; - - /** - * Protocol implemented. - * - * @api public - */ - - io.protocol = 1; - - /** - * Available transports, these will be populated with the available transports - * - * @api public - */ - - io.transports = []; - - /** - * Keep track of jsonp callbacks. - * - * @api private - */ - - io.j = []; - - /** - * Keep track of our io.Sockets - * - * @api private - */ - io.sockets = {}; - - - /** - * Manages connections to hosts. - * - * @param {String} uri - * @Param {Boolean} force creation of new socket (defaults to false) - * @api public - */ - - io.connect = function (host, details) { - var uri = io.util.parseUri(host) - , uuri - , socket; - - if (global && global.location) { - uri.protocol = uri.protocol || global.location.protocol.slice(0, -1); - uri.host = uri.host || (global.document - ? global.document.domain : global.location.hostname); - uri.port = uri.port || global.location.port; - } - - uuri = io.util.uniqueUri(uri); - - var options = { - host: uri.host - , secure: 'https' == uri.protocol - , port: uri.port || ('https' == uri.protocol ? 443 : 80) - , query: uri.query || '' - }; - - io.util.merge(options, details); - - if (options['force new connection'] || !io.sockets[uuri]) { - socket = new io.Socket(options); - } - - if (!options['force new connection'] && socket) { - io.sockets[uuri] = socket; - } - - socket = socket || io.sockets[uuri]; - - // if path is different from '' or / - return socket.of(uri.path.length > 1 ? uri.path : ''); - }; - -})('object' === typeof module ? module.exports : (this.io = {}), this); -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, global) { - - /** - * Utilities namespace. - * - * @namespace - */ - - var util = exports.util = {}; - - /** - * Parses an URI - * - * @author Steven Levithan (MIT license) - * @api public - */ - - var re = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; - - var parts = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', - 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', - 'anchor']; - - util.parseUri = function (str) { - var m = re.exec(str || '') - , uri = {} - , i = 14; - - while (i--) { - uri[parts[i]] = m[i] || ''; - } - - return uri; - }; - - /** - * Produces a unique url that identifies a Socket.IO connection. - * - * @param {Object} uri - * @api public - */ - - util.uniqueUri = function (uri) { - var protocol = uri.protocol - , host = uri.host - , port = uri.port; - - if ('document' in global) { - host = host || document.domain; - port = port || (protocol == 'https' - && document.location.protocol !== 'https:' ? 443 : document.location.port); - } else { - host = host || 'localhost'; - - if (!port && protocol == 'https') { - port = 443; - } - } - - return (protocol || 'http') + '://' + host + ':' + (port || 80); - }; - - /** - * Mergest 2 query strings in to once unique query string - * - * @param {String} base - * @param {String} addition - * @api public - */ - - util.query = function (base, addition) { - var query = util.chunkQuery(base || '') - , components = []; - - util.merge(query, util.chunkQuery(addition || '')); - for (var part in query) { - if (query.hasOwnProperty(part)) { - components.push(part + '=' + query[part]); - } - } - - return components.length ? '?' + components.join('&') : ''; - }; - - /** - * Transforms a querystring in to an object - * - * @param {String} qs - * @api public - */ - - util.chunkQuery = function (qs) { - var query = {} - , params = qs.split('&') - , i = 0 - , l = params.length - , kv; - - for (; i < l; ++i) { - kv = params[i].split('='); - if (kv[0]) { - query[kv[0]] = kv[1]; - } - } - - return query; - }; - - /** - * Executes the given function when the page is loaded. - * - * io.util.load(function () { console.log('page loaded'); }); - * - * @param {Function} fn - * @api public - */ - - var pageLoaded = false; - - util.load = function (fn) { - if ('document' in global && document.readyState === 'complete' || pageLoaded) { - return fn(); - } - - util.on(global, 'load', fn, false); - }; - - /** - * Adds an event. - * - * @api private - */ - - util.on = function (element, event, fn, capture) { - if (element.attachEvent) { - element.attachEvent('on' + event, fn); - } else if (element.addEventListener) { - element.addEventListener(event, fn, capture); - } - }; - - /** - * Generates the correct `XMLHttpRequest` for regular and cross domain requests. - * - * @param {Boolean} [xdomain] Create a request that can be used cross domain. - * @returns {XMLHttpRequest|false} If we can create a XMLHttpRequest. - * @api private - */ - - util.request = function (xdomain) { - - if (xdomain && 'undefined' != typeof XDomainRequest) { - return new XDomainRequest(); - } - - if ('undefined' != typeof XMLHttpRequest && (!xdomain || util.ua.hasCORS)) { - return new XMLHttpRequest(); - } - - if (!xdomain) { - try { - return new window[(['Active'].concat('Object').join('X'))]('Microsoft.XMLHTTP'); - } catch(e) { } - } - - return null; - }; - - /** - * XHR based transport constructor. - * - * @constructor - * @api public - */ - - /** - * Change the internal pageLoaded value. - */ - - if ('undefined' != typeof window) { - util.load(function () { - pageLoaded = true; - }); - } - - /** - * Defers a function to ensure a spinner is not displayed by the browser - * - * @param {Function} fn - * @api public - */ - - util.defer = function (fn) { - if (!util.ua.webkit || 'undefined' != typeof importScripts) { - return fn(); - } - - util.load(function () { - setTimeout(fn, 100); - }); - }; - - /** - * Merges two objects. - * - * @api public - */ - - util.merge = function merge (target, additional, deep, lastseen) { - var seen = lastseen || [] - , depth = typeof deep == 'undefined' ? 2 : deep - , prop; - - for (prop in additional) { - if (additional.hasOwnProperty(prop) && util.indexOf(seen, prop) < 0) { - if (typeof target[prop] !== 'object' || !depth) { - target[prop] = additional[prop]; - seen.push(additional[prop]); - } else { - util.merge(target[prop], additional[prop], depth - 1, seen); - } - } - } - - return target; - }; - - /** - * Merges prototypes from objects - * - * @api public - */ - - util.mixin = function (ctor, ctor2) { - util.merge(ctor.prototype, ctor2.prototype); - }; - - /** - * Shortcut for prototypical and static inheritance. - * - * @api private - */ - - util.inherit = function (ctor, ctor2) { - function f() {}; - f.prototype = ctor2.prototype; - ctor.prototype = new f; - }; - - /** - * Checks if the given object is an Array. - * - * io.util.isArray([]); // true - * io.util.isArray({}); // false - * - * @param Object obj - * @api public - */ - - util.isArray = Array.isArray || function (obj) { - return Object.prototype.toString.call(obj) === '[object Array]'; - }; - - /** - * Intersects values of two arrays into a third - * - * @api public - */ - - util.intersect = function (arr, arr2) { - var ret = [] - , longest = arr.length > arr2.length ? arr : arr2 - , shortest = arr.length > arr2.length ? arr2 : arr; - - for (var i = 0, l = shortest.length; i < l; i++) { - if (~util.indexOf(longest, shortest[i])) - ret.push(shortest[i]); - } - - return ret; - } - - /** - * Array indexOf compatibility. - * - * @see bit.ly/a5Dxa2 - * @api public - */ - - util.indexOf = function (arr, o, i) { - - for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0; - i < j && arr[i] !== o; i++) {} - - return j <= i ? -1 : i; - }; - - /** - * Converts enumerables to array. - * - * @api public - */ - - util.toArray = function (enu) { - var arr = []; - - for (var i = 0, l = enu.length; i < l; i++) - arr.push(enu[i]); - - return arr; - }; - - /** - * UA / engines detection namespace. - * - * @namespace - */ - - util.ua = {}; - - /** - * Whether the UA supports CORS for XHR. - * - * @api public - */ - - util.ua.hasCORS = 'undefined' != typeof XMLHttpRequest && (function () { - try { - var a = new XMLHttpRequest(); - } catch (e) { - return false; - } - - return a.withCredentials != undefined; - })(); - - /** - * Detect webkit. - * - * @api public - */ - - util.ua.webkit = 'undefined' != typeof navigator - && /webkit/i.test(navigator.userAgent); - - /** - * Detect iPad/iPhone/iPod. - * - * @api public - */ - - util.ua.iDevice = 'undefined' != typeof navigator - && /iPad|iPhone|iPod/i.test(navigator.userAgent); - -})('undefined' != typeof io ? io : module.exports, this); - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io) { - - /** - * Expose constructor. - */ - - exports.EventEmitter = EventEmitter; - - /** - * Event emitter constructor. - * - * @api public. - */ - - function EventEmitter () {}; - - /** - * Adds a listener - * - * @api public - */ - - EventEmitter.prototype.on = function (name, fn) { - if (!this.$events) { - this.$events = {}; - } - - if (!this.$events[name]) { - this.$events[name] = fn; - } else if (io.util.isArray(this.$events[name])) { - this.$events[name].push(fn); - } else { - this.$events[name] = [this.$events[name], fn]; - } - - return this; - }; - - EventEmitter.prototype.addListener = EventEmitter.prototype.on; - - /** - * Adds a volatile listener. - * - * @api public - */ - - EventEmitter.prototype.once = function (name, fn) { - var self = this; - - function on () { - self.removeListener(name, on); - fn.apply(this, arguments); - }; - - on.listener = fn; - this.on(name, on); - - return this; - }; - - /** - * Removes a listener. - * - * @api public - */ - - EventEmitter.prototype.removeListener = function (name, fn) { - if (this.$events && this.$events[name]) { - var list = this.$events[name]; - - if (io.util.isArray(list)) { - var pos = -1; - - for (var i = 0, l = list.length; i < l; i++) { - if (list[i] === fn || (list[i].listener && list[i].listener === fn)) { - pos = i; - break; - } - } - - if (pos < 0) { - return this; - } - - list.splice(pos, 1); - - if (!list.length) { - delete this.$events[name]; - } - } else if (list === fn || (list.listener && list.listener === fn)) { - delete this.$events[name]; - } - } - - return this; - }; - - /** - * Removes all listeners for an event. - * - * @api public - */ - - EventEmitter.prototype.removeAllListeners = function (name) { - // TODO: enable this when node 0.5 is stable - //if (name === undefined) { - //this.$events = {}; - //return this; - //} - - if (this.$events && this.$events[name]) { - this.$events[name] = null; - } - - return this; - }; - - /** - * Gets all listeners for a certain event. - * - * @api publci - */ - - EventEmitter.prototype.listeners = function (name) { - if (!this.$events) { - this.$events = {}; - } - - if (!this.$events[name]) { - this.$events[name] = []; - } - - if (!io.util.isArray(this.$events[name])) { - this.$events[name] = [this.$events[name]]; - } - - return this.$events[name]; - }; - - /** - * Emits an event. - * - * @api public - */ - - EventEmitter.prototype.emit = function (name) { - if (!this.$events) { - return false; - } - - var handler = this.$events[name]; - - if (!handler) { - return false; - } - - var args = Array.prototype.slice.call(arguments, 1); - - if ('function' == typeof handler) { - handler.apply(this, args); - } else if (io.util.isArray(handler)) { - var listeners = handler.slice(); - - for (var i = 0, l = listeners.length; i < l; i++) { - listeners[i].apply(this, args); - } - } else { - return false; - } - - return true; - }; - -})( - 'undefined' != typeof io ? io : module.exports - , 'undefined' != typeof io ? io : module.parent.exports -); - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -/** - * Based on JSON2 (http://www.JSON.org/js.html). - */ - -(function (exports, nativeJSON) { - "use strict"; - - // use native JSON if it's available - if (nativeJSON && nativeJSON.parse){ - return exports.JSON = { - parse: nativeJSON.parse - , stringify: nativeJSON.stringify - } - } - - var JSON = exports.JSON = {}; - - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - function date(d, key) { - return isFinite(d.valueOf()) ? - d.getUTCFullYear() + '-' + - f(d.getUTCMonth() + 1) + '-' + - f(d.getUTCDate()) + 'T' + - f(d.getUTCHours()) + ':' + - f(d.getUTCMinutes()) + ':' + - f(d.getUTCSeconds()) + 'Z' : null; - }; - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; - - - function quote(string) { - -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can safely slap some quotes around it. -// Otherwise we must also replace the offending characters with safe escape -// sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' ? c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : '"' + string + '"'; - } - - - function str(key, holder) { - -// Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - -// If the value has a toJSON method, call it to obtain a replacement value. - - if (value instanceof Date) { - value = date(key); - } - -// If we were called with a replacer function, then call the replacer to -// obtain a replacement value. - - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - -// What happens next depends on the value's type. - - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - -// JSON numbers must be finite. Encode non-finite numbers as null. - - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - -// If the value is a boolean or null, convert it to a string. Note: -// typeof null does not produce 'null'. The case is included here in -// the remote chance that this gets fixed someday. - - return String(value); - -// If the type is 'object', we might be dealing with an object or an array or -// null. - - case 'object': - -// Due to a specification blunder in ECMAScript, typeof null is 'object', -// so watch out for that case. - - if (!value) { - return 'null'; - } - -// Make an array to hold the partial results of stringifying this object value. - - gap += indent; - partial = []; - -// Is the value an array? - - if (Object.prototype.toString.apply(value) === '[object Array]') { - -// The value is an array. Stringify every element. Use null as a placeholder -// for non-JSON values. - - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - -// Join all of the elements together, separated with commas, and wrap them in -// brackets. - - v = partial.length === 0 ? '[]' : gap ? - '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : - '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - -// If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - if (typeof rep[i] === 'string') { - k = rep[i]; - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - -// Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - -// Join all of the member texts together, separated with commas, -// and wrap them in braces. - - v = partial.length === 0 ? '{}' : gap ? - '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : - '{' + partial.join(',') + '}'; - gap = mind; - return v; - } - } - -// If the JSON object does not yet have a stringify method, give it one. - - JSON.stringify = function (value, replacer, space) { - -// The stringify method takes a value and an optional replacer, and an optional -// space parameter, and returns a JSON text. The replacer can be a function -// that can replace values, or an array of strings that will select the keys. -// A default replacer method can be provided. Use of the space parameter can -// produce text that is more easily readable. - - var i; - gap = ''; - indent = ''; - -// If the space parameter is a number, make an indent string containing that -// many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - -// If the space parameter is a string, it will be used as the indent string. - - } else if (typeof space === 'string') { - indent = space; - } - -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. - - rep = replacer; - if (replacer && typeof replacer !== 'function' && - (typeof replacer !== 'object' || - typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); - } - -// Make a fake root object containing our value under the key of ''. -// Return the result of stringifying the value. - - return str('', {'': value}); - }; - -// If the JSON object does not yet have a parse method, give it one. - - JSON.parse = function (text, reviver) { - // The parse method takes a text and an optional reviver function, and returns - // a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) { - - // The walk method is used to recursively walk the resulting structure so - // that modifications can be made. - - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - - // Parsing happens in four stages. In the first stage, we replace certain - // Unicode characters with escape sequences. JavaScript handles many characters - // incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function (a) { - return '\\u' + - ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - - // In the second stage, we run the text against regular expressions that look - // for non-JSON patterns. We are especially concerned with '()' and 'new' - // because they can cause invocation, and '=' because it can cause mutation. - // But just to be safe, we want to reject all unexpected forms. - - // We split the second stage into 4 regexp operations in order to work around - // crippling inefficiencies in IE's and Safari's regexp engines. First we - // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we - // replace all simple value tokens with ']' characters. Third, we delete all - // open brackets that follow a colon or comma or that begin the text. Finally, - // we look to see that the remaining characters are only whitespace or ']' or - // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if (/^[\],:{}\s]*$/ - .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') - .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') - .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { - - // In the third stage we use the eval function to compile the text into a - // JavaScript structure. The '{' operator is subject to a syntactic ambiguity - // in JavaScript: it can begin a block or an object literal. We wrap the text - // in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - - // In the optional fourth stage, we recursively walk the new structure, passing - // each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' ? - walk({'': j}, '') : j; - } - - // If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - -})( - 'undefined' != typeof io ? io : module.exports - , typeof JSON !== 'undefined' ? JSON : undefined -); - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io) { - - /** - * Parser namespace. - * - * @namespace - */ - - var parser = exports.parser = {}; - - /** - * Packet types. - */ - - var packets = parser.packets = [ - 'disconnect' - , 'connect' - , 'heartbeat' - , 'message' - , 'json' - , 'event' - , 'ack' - , 'error' - , 'noop' - ]; - - /** - * Errors reasons. - */ - - var reasons = parser.reasons = [ - 'transport not supported' - , 'client not handshaken' - , 'unauthorized' - ]; - - /** - * Errors advice. - */ - - var advice = parser.advice = [ - 'reconnect' - ]; - - /** - * Shortcuts. - */ - - var JSON = io.JSON - , indexOf = io.util.indexOf; - - /** - * Encodes a packet. - * - * @api private - */ - - parser.encodePacket = function (packet) { - var type = indexOf(packets, packet.type) - , id = packet.id || '' - , endpoint = packet.endpoint || '' - , ack = packet.ack - , data = null; - - switch (packet.type) { - case 'error': - var reason = packet.reason ? indexOf(reasons, packet.reason) : '' - , adv = packet.advice ? indexOf(advice, packet.advice) : ''; - - if (reason !== '' || adv !== '') - data = reason + (adv !== '' ? ('+' + adv) : ''); - - break; - - case 'message': - if (packet.data !== '') - data = packet.data; - break; - - case 'event': - var ev = { name: packet.name }; - - if (packet.args && packet.args.length) { - ev.args = packet.args; - } - - data = JSON.stringify(ev); - break; - - case 'json': - data = JSON.stringify(packet.data); - break; - - case 'connect': - if (packet.qs) - data = packet.qs; - break; - - case 'ack': - data = packet.ackId - + (packet.args && packet.args.length - ? '+' + JSON.stringify(packet.args) : ''); - break; - } - - // construct packet with required fragments - var encoded = [ - type - , id + (ack == 'data' ? '+' : '') - , endpoint - ]; - - // data fragment is optional - if (data !== null && data !== undefined) - encoded.push(data); - - return encoded.join(':'); - }; - - /** - * Encodes multiple messages (payload). - * - * @param {Array} messages - * @api private - */ - - parser.encodePayload = function (packets) { - var decoded = ''; - - if (packets.length == 1) - return packets[0]; - - for (var i = 0, l = packets.length; i < l; i++) { - var packet = packets[i]; - decoded += '\ufffd' + packet.length + '\ufffd' + packets[i]; - } - - return decoded; - }; - - /** - * Decodes a packet - * - * @api private - */ - - var regexp = /([^:]+):([0-9]+)?(\+)?:([^:]+)?:?([\s\S]*)?/; - - parser.decodePacket = function (data) { - var pieces = data.match(regexp); - - if (!pieces) return {}; - - var id = pieces[2] || '' - , data = pieces[5] || '' - , packet = { - type: packets[pieces[1]] - , endpoint: pieces[4] || '' - }; - - // whether we need to acknowledge the packet - if (id) { - packet.id = id; - if (pieces[3]) - packet.ack = 'data'; - else - packet.ack = true; - } - - // handle different packet types - switch (packet.type) { - case 'error': - var pieces = data.split('+'); - packet.reason = reasons[pieces[0]] || ''; - packet.advice = advice[pieces[1]] || ''; - break; - - case 'message': - packet.data = data || ''; - break; - - case 'event': - try { - var opts = JSON.parse(data); - packet.name = opts.name; - packet.args = opts.args; - } catch (e) { } - - packet.args = packet.args || []; - break; - - case 'json': - try { - packet.data = JSON.parse(data); - } catch (e) { } - break; - - case 'connect': - packet.qs = data || ''; - break; - - case 'ack': - var pieces = data.match(/^([0-9]+)(\+)?(.*)/); - if (pieces) { - packet.ackId = pieces[1]; - packet.args = []; - - if (pieces[3]) { - try { - packet.args = pieces[3] ? JSON.parse(pieces[3]) : []; - } catch (e) { } - } - } - break; - - case 'disconnect': - case 'heartbeat': - break; - }; - - return packet; - }; - - /** - * Decodes data payload. Detects multiple messages - * - * @return {Array} messages - * @api public - */ - - parser.decodePayload = function (data) { - // IE doesn't like data[i] for unicode chars, charAt works fine - if (data.charAt(0) == '\ufffd') { - var ret = []; - - for (var i = 1, length = ''; i < data.length; i++) { - if (data.charAt(i) == '\ufffd') { - ret.push(parser.decodePacket(data.substr(i + 1).substr(0, length))); - i += Number(length) + 1; - length = ''; - } else { - length += data.charAt(i); - } - } - - return ret; - } else { - return [parser.decodePacket(data)]; - } - }; - -})( - 'undefined' != typeof io ? io : module.exports - , 'undefined' != typeof io ? io : module.parent.exports -); -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io) { - - /** - * Expose constructor. - */ - - exports.Transport = Transport; - - /** - * This is the transport template for all supported transport methods. - * - * @constructor - * @api public - */ - - function Transport (socket, sessid) { - this.socket = socket; - this.sessid = sessid; - }; - - /** - * Apply EventEmitter mixin. - */ - - io.util.mixin(Transport, io.EventEmitter); - - - /** - * Indicates whether heartbeats is enabled for this transport - * - * @api private - */ - - Transport.prototype.heartbeats = function () { - return true; - } - - /** - * Handles the response from the server. When a new response is received - * it will automatically update the timeout, decode the message and - * forwards the response to the onMessage function for further processing. - * - * @param {String} data Response from the server. - * @api private - */ - - Transport.prototype.onData = function (data) { - this.clearCloseTimeout(); - - // If the connection in currently open (or in a reopening state) reset the close - // timeout since we have just received data. This check is necessary so - // that we don't reset the timeout on an explicitly disconnected connection. - if (this.socket.connected || this.socket.connecting || this.socket.reconnecting) { - this.setCloseTimeout(); - } - - if (data !== '') { - // todo: we should only do decodePayload for xhr transports - var msgs = io.parser.decodePayload(data); - - if (msgs && msgs.length) { - for (var i = 0, l = msgs.length; i < l; i++) { - this.onPacket(msgs[i]); - } - } - } - - return this; - }; - - /** - * Handles packets. - * - * @api private - */ - - Transport.prototype.onPacket = function (packet) { - this.socket.setHeartbeatTimeout(); - - if (packet.type == 'heartbeat') { - return this.onHeartbeat(); - } - - if (packet.type == 'connect' && packet.endpoint == '') { - this.onConnect(); - } - - if (packet.type == 'error' && packet.advice == 'reconnect') { - this.isOpen = false; - } - - this.socket.onPacket(packet); - - return this; - }; - - /** - * Sets close timeout - * - * @api private - */ - - Transport.prototype.setCloseTimeout = function () { - if (!this.closeTimeout) { - var self = this; - - this.closeTimeout = setTimeout(function () { - self.onDisconnect(); - }, this.socket.closeTimeout); - } - }; - - /** - * Called when transport disconnects. - * - * @api private - */ - - Transport.prototype.onDisconnect = function () { - if (this.isOpen) this.close(); - this.clearTimeouts(); - this.socket.onDisconnect(); - return this; - }; - - /** - * Called when transport connects - * - * @api private - */ - - Transport.prototype.onConnect = function () { - this.socket.onConnect(); - return this; - } - - /** - * Clears close timeout - * - * @api private - */ - - Transport.prototype.clearCloseTimeout = function () { - if (this.closeTimeout) { - clearTimeout(this.closeTimeout); - this.closeTimeout = null; - } - }; - - /** - * Clear timeouts - * - * @api private - */ - - Transport.prototype.clearTimeouts = function () { - this.clearCloseTimeout(); - - if (this.reopenTimeout) { - clearTimeout(this.reopenTimeout); - } - }; - - /** - * Sends a packet - * - * @param {Object} packet object. - * @api private - */ - - Transport.prototype.packet = function (packet) { - this.send(io.parser.encodePacket(packet)); - }; - - /** - * Send the received heartbeat message back to server. So the server - * knows we are still connected. - * - * @param {String} heartbeat Heartbeat response from the server. - * @api private - */ - - Transport.prototype.onHeartbeat = function (heartbeat) { - this.packet({ type: 'heartbeat' }); - }; - - /** - * Called when the transport opens. - * - * @api private - */ - - Transport.prototype.onOpen = function () { - this.isOpen = true; - this.clearCloseTimeout(); - this.socket.onOpen(); - }; - - /** - * Notifies the base when the connection with the Socket.IO server - * has been disconnected. - * - * @api private - */ - - Transport.prototype.onClose = function () { - var self = this; - - /* FIXME: reopen delay causing a infinit loop - this.reopenTimeout = setTimeout(function () { - self.open(); - }, this.socket.options['reopen delay']);*/ - - this.isOpen = false; - this.socket.onClose(); - this.onDisconnect(); - }; - - /** - * Generates a connection url based on the Socket.IO URL Protocol. - * See for more details. - * - * @returns {String} Connection url - * @api private - */ - - Transport.prototype.prepareUrl = function () { - var options = this.socket.options; - - return this.scheme() + '://' - + options.host + ':' + options.port + '/' - + options.resource + '/' + io.protocol - + '/' + this.name + '/' + this.sessid; - }; - - /** - * Checks if the transport is ready to start a connection. - * - * @param {Socket} socket The socket instance that needs a transport - * @param {Function} fn The callback - * @api private - */ - - Transport.prototype.ready = function (socket, fn) { - fn.call(this); - }; -})( - 'undefined' != typeof io ? io : module.exports - , 'undefined' != typeof io ? io : module.parent.exports -); -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io, global) { - - /** - * Expose constructor. - */ - - exports.Socket = Socket; - - /** - * Create a new `Socket.IO client` which can establish a persistent - * connection with a Socket.IO enabled server. - * - * @api public - */ - - function Socket (options) { - this.options = { - port: 80 - , secure: false - , document: 'document' in global ? document : false - , resource: 'socket.io' - , transports: io.transports - , 'connect timeout': 10000 - , 'try multiple transports': true - , 'reconnect': true - , 'reconnection delay': 500 - , 'reconnection limit': Infinity - , 'reopen delay': 3000 - , 'max reconnection attempts': 10 - , 'sync disconnect on unload': true - , 'auto connect': true - , 'flash policy port': 10843 - , 'manualFlush': false - }; - - io.util.merge(this.options, options); - - this.connected = false; - this.open = false; - this.connecting = false; - this.reconnecting = false; - this.namespaces = {}; - this.buffer = []; - this.doBuffer = false; - - if (this.options['sync disconnect on unload'] && - (!this.isXDomain() || io.util.ua.hasCORS)) { - var self = this; - io.util.on(global, 'beforeunload', function () { - self.disconnectSync(); - }, false); - } - - if (this.options['auto connect']) { - this.connect(); - } -}; - - /** - * Apply EventEmitter mixin. - */ - - io.util.mixin(Socket, io.EventEmitter); - - /** - * Returns a namespace listener/emitter for this socket - * - * @api public - */ - - Socket.prototype.of = function (name) { - if (!this.namespaces[name]) { - this.namespaces[name] = new io.SocketNamespace(this, name); - - if (name !== '') { - this.namespaces[name].packet({ type: 'connect' }); - } - } - - return this.namespaces[name]; - }; - - /** - * Emits the given event to the Socket and all namespaces - * - * @api private - */ - - Socket.prototype.publish = function () { - this.emit.apply(this, arguments); - - var nsp; - - for (var i in this.namespaces) { - if (this.namespaces.hasOwnProperty(i)) { - nsp = this.of(i); - nsp.$emit.apply(nsp, arguments); - } - } - }; - - /** - * Performs the handshake - * - * @api private - */ - - function empty () { }; - - Socket.prototype.handshake = function (fn) { - var self = this - , options = this.options; - - function complete (data) { - if (data instanceof Error) { - self.connecting = false; - self.onError(data.message); - } else { - fn.apply(null, data.split(':')); - } - }; - - var url = [ - 'http' + (options.secure ? 's' : '') + ':/' - , options.host + ':' + options.port - , options.resource - , io.protocol - , io.util.query(this.options.query, 't=' + +new Date) - ].join('/'); - - if (this.isXDomain() && !io.util.ua.hasCORS) { - var insertAt = document.getElementsByTagName('script')[0] - , script = document.createElement('script'); - - script.src = url + '&jsonp=' + io.j.length; - insertAt.parentNode.insertBefore(script, insertAt); - - io.j.push(function (data) { - complete(data); - script.parentNode.removeChild(script); - }); - } else { - var xhr = io.util.request(); - - xhr.open('GET', url, true); - xhr.withCredentials = true; - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - xhr.onreadystatechange = empty; - - if (xhr.status == 200) { - complete(xhr.responseText); - } else if (xhr.status == 403) { - self.onError(xhr.responseText); - } else { - self.connecting = false; - !self.reconnecting && self.onError(xhr.responseText); - } - } - }; - xhr.send(null); - } - }; - - /** - * Find an available transport based on the options supplied in the constructor. - * - * @api private - */ - - Socket.prototype.getTransport = function (override) { - var transports = override || this.transports, match; - - for (var i = 0, transport; transport = transports[i]; i++) { - if (io.Transport[transport] - && io.Transport[transport].check(this) - && (!this.isXDomain() || io.Transport[transport].xdomainCheck(this))) { - return new io.Transport[transport](this, this.sessionid); - } - } - - return null; - }; - - /** - * Connects to the server. - * - * @param {Function} [fn] Callback. - * @returns {io.Socket} - * @api public - */ - - Socket.prototype.connect = function (fn) { - if (this.connecting) { - return this; - } - - var self = this; - self.connecting = true; - - this.handshake(function (sid, heartbeat, close, transports) { - self.sessionid = sid; - self.closeTimeout = close * 1000; - self.heartbeatTimeout = heartbeat * 1000; - if(!self.transports) - self.transports = self.origTransports = (transports ? io.util.intersect( - transports.split(',') - , self.options.transports - ) : self.options.transports); - - self.setHeartbeatTimeout(); - - function connect (transports){ - if (self.transport) self.transport.clearTimeouts(); - - self.transport = self.getTransport(transports); - if (!self.transport) return self.publish('connect_failed'); - - // once the transport is ready - self.transport.ready(self, function () { - self.connecting = true; - self.publish('connecting', self.transport.name); - self.transport.open(); - - if (self.options['connect timeout']) { - self.connectTimeoutTimer = setTimeout(function () { - if (!self.connected) { - self.connecting = false; - - if (self.options['try multiple transports']) { - var remaining = self.transports; - - while (remaining.length > 0 && remaining.splice(0,1)[0] != - self.transport.name) {} - - if (remaining.length){ - connect(remaining); - } else { - self.publish('connect_failed'); - } - } - } - }, self.options['connect timeout']); - } - }); - } - - connect(self.transports); - - self.once('connect', function (){ - clearTimeout(self.connectTimeoutTimer); - - fn && typeof fn == 'function' && fn(); - }); - }); - - return this; - }; - - /** - * Clears and sets a new heartbeat timeout using the value given by the - * server during the handshake. - * - * @api private - */ - - Socket.prototype.setHeartbeatTimeout = function () { - clearTimeout(this.heartbeatTimeoutTimer); - if(this.transport && !this.transport.heartbeats()) return; - - var self = this; - this.heartbeatTimeoutTimer = setTimeout(function () { - self.transport.onClose(); - }, this.heartbeatTimeout); - }; - - /** - * Sends a message. - * - * @param {Object} data packet. - * @returns {io.Socket} - * @api public - */ - - Socket.prototype.packet = function (data) { - if (this.connected && !this.doBuffer) { - this.transport.packet(data); - } else { - this.buffer.push(data); - } - - return this; - }; - - /** - * Sets buffer state - * - * @api private - */ - - Socket.prototype.setBuffer = function (v) { - this.doBuffer = v; - - if (!v && this.connected && this.buffer.length) { - if (!this.options['manualFlush']) { - this.flushBuffer(); - } - } - }; - - /** - * Flushes the buffer data over the wire. - * To be invoked manually when 'manualFlush' is set to true. - * - * @api public - */ - - Socket.prototype.flushBuffer = function() { - this.transport.payload(this.buffer); - this.buffer = []; - }; - - - /** - * Disconnect the established connect. - * - * @returns {io.Socket} - * @api public - */ - - Socket.prototype.disconnect = function () { - if (this.connected || this.connecting) { - if (this.open) { - this.of('').packet({ type: 'disconnect' }); - } - - // handle disconnection immediately - this.onDisconnect('booted'); - } - - return this; - }; - - /** - * Disconnects the socket with a sync XHR. - * - * @api private - */ - - Socket.prototype.disconnectSync = function () { - // ensure disconnection - var xhr = io.util.request(); - var uri = [ - 'http' + (this.options.secure ? 's' : '') + ':/' - , this.options.host + ':' + this.options.port - , this.options.resource - , io.protocol - , '' - , this.sessionid - ].join('/') + '/?disconnect=1'; - - xhr.open('GET', uri, false); - xhr.send(null); - - // handle disconnection immediately - this.onDisconnect('booted'); - }; - - /** - * Check if we need to use cross domain enabled transports. Cross domain would - * be a different port or different domain name. - * - * @returns {Boolean} - * @api private - */ - - Socket.prototype.isXDomain = function () { - - var port = global.location.port || - ('https:' == global.location.protocol ? 443 : 80); - - return this.options.host !== global.location.hostname - || this.options.port != port; - }; - - /** - * Called upon handshake. - * - * @api private - */ - - Socket.prototype.onConnect = function () { - if (!this.connected) { - this.connected = true; - this.connecting = false; - if (!this.doBuffer) { - // make sure to flush the buffer - this.setBuffer(false); - } - this.emit('connect'); - } - }; - - /** - * Called when the transport opens - * - * @api private - */ - - Socket.prototype.onOpen = function () { - this.open = true; - }; - - /** - * Called when the transport closes. - * - * @api private - */ - - Socket.prototype.onClose = function () { - this.open = false; - clearTimeout(this.heartbeatTimeoutTimer); - }; - - /** - * Called when the transport first opens a connection - * - * @param text - */ - - Socket.prototype.onPacket = function (packet) { - this.of(packet.endpoint).onPacket(packet); - }; - - /** - * Handles an error. - * - * @api private - */ - - Socket.prototype.onError = function (err) { - if (err && err.advice) { - if (err.advice === 'reconnect' && (this.connected || this.connecting)) { - this.disconnect(); - if (this.options.reconnect) { - this.reconnect(); - } - } - } - - this.publish('error', err && err.reason ? err.reason : err); - }; - - /** - * Called when the transport disconnects. - * - * @api private - */ - - Socket.prototype.onDisconnect = function (reason) { - var wasConnected = this.connected - , wasConnecting = this.connecting; - - this.connected = false; - this.connecting = false; - this.open = false; - - if (wasConnected || wasConnecting) { - this.transport.close(); - this.transport.clearTimeouts(); - if (wasConnected) { - this.publish('disconnect', reason); - - if ('booted' != reason && this.options.reconnect && !this.reconnecting) { - this.reconnect(); - } - } - } - }; - - /** - * Called upon reconnection. - * - * @api private - */ - - Socket.prototype.reconnect = function () { - this.reconnecting = true; - this.reconnectionAttempts = 0; - this.reconnectionDelay = this.options['reconnection delay']; - - var self = this - , maxAttempts = this.options['max reconnection attempts'] - , tryMultiple = this.options['try multiple transports'] - , limit = this.options['reconnection limit']; - - function reset () { - if (self.connected) { - for (var i in self.namespaces) { - if (self.namespaces.hasOwnProperty(i) && '' !== i) { - self.namespaces[i].packet({ type: 'connect' }); - } - } - self.publish('reconnect', self.transport.name, self.reconnectionAttempts); - } - - clearTimeout(self.reconnectionTimer); - - self.removeListener('connect_failed', maybeReconnect); - self.removeListener('connect', maybeReconnect); - - self.reconnecting = false; - - delete self.reconnectionAttempts; - delete self.reconnectionDelay; - delete self.reconnectionTimer; - delete self.redoTransports; - - self.options['try multiple transports'] = tryMultiple; - }; - - function maybeReconnect () { - if (!self.reconnecting) { - return; - } - - if (self.connected) { - return reset(); - }; - - if (self.connecting && self.reconnecting) { - return self.reconnectionTimer = setTimeout(maybeReconnect, 1000); - } - - if (self.reconnectionAttempts++ >= maxAttempts) { - if (!self.redoTransports) { - self.on('connect_failed', maybeReconnect); - self.options['try multiple transports'] = true; - self.transports = self.origTransports; - self.transport = self.getTransport(); - self.redoTransports = true; - self.connect(); - } else { - self.publish('reconnect_failed'); - reset(); - } - } else { - if (self.reconnectionDelay < limit) { - self.reconnectionDelay *= 2; // exponential back off - } - - self.connect(); - self.publish('reconnecting', self.reconnectionDelay, self.reconnectionAttempts); - self.reconnectionTimer = setTimeout(maybeReconnect, self.reconnectionDelay); - } - }; - - this.options['try multiple transports'] = false; - this.reconnectionTimer = setTimeout(maybeReconnect, this.reconnectionDelay); - - this.on('connect', maybeReconnect); - }; - -})( - 'undefined' != typeof io ? io : module.exports - , 'undefined' != typeof io ? io : module.parent.exports - , this -); -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io) { - - /** - * Expose constructor. - */ - - exports.SocketNamespace = SocketNamespace; - - /** - * Socket namespace constructor. - * - * @constructor - * @api public - */ - - function SocketNamespace (socket, name) { - this.socket = socket; - this.name = name || ''; - this.flags = {}; - this.json = new Flag(this, 'json'); - this.ackPackets = 0; - this.acks = {}; - }; - - /** - * Apply EventEmitter mixin. - */ - - io.util.mixin(SocketNamespace, io.EventEmitter); - - /** - * Copies emit since we override it - * - * @api private - */ - - SocketNamespace.prototype.$emit = io.EventEmitter.prototype.emit; - - /** - * Creates a new namespace, by proxying the request to the socket. This - * allows us to use the synax as we do on the server. - * - * @api public - */ - - SocketNamespace.prototype.of = function () { - return this.socket.of.apply(this.socket, arguments); - }; - - /** - * Sends a packet. - * - * @api private - */ - - SocketNamespace.prototype.packet = function (packet) { - packet.endpoint = this.name; - this.socket.packet(packet); - this.flags = {}; - return this; - }; - - /** - * Sends a message - * - * @api public - */ - - SocketNamespace.prototype.send = function (data, fn) { - var packet = { - type: this.flags.json ? 'json' : 'message' - , data: data - }; - - if ('function' == typeof fn) { - packet.id = ++this.ackPackets; - packet.ack = true; - this.acks[packet.id] = fn; - } - - return this.packet(packet); - }; - - /** - * Emits an event - * - * @api public - */ - - SocketNamespace.prototype.emit = function (name) { - var args = Array.prototype.slice.call(arguments, 1) - , lastArg = args[args.length - 1] - , packet = { - type: 'event' - , name: name - }; - - if ('function' == typeof lastArg) { - packet.id = ++this.ackPackets; - packet.ack = 'data'; - this.acks[packet.id] = lastArg; - args = args.slice(0, args.length - 1); - } - - packet.args = args; - - return this.packet(packet); - }; - - /** - * Disconnects the namespace - * - * @api private - */ - - SocketNamespace.prototype.disconnect = function () { - if (this.name === '') { - this.socket.disconnect(); - } else { - this.packet({ type: 'disconnect' }); - this.$emit('disconnect'); - } - - return this; - }; - - /** - * Handles a packet - * - * @api private - */ - - SocketNamespace.prototype.onPacket = function (packet) { - var self = this; - - function ack () { - self.packet({ - type: 'ack' - , args: io.util.toArray(arguments) - , ackId: packet.id - }); - }; - - switch (packet.type) { - case 'connect': - this.$emit('connect'); - break; - - case 'disconnect': - if (this.name === '') { - this.socket.onDisconnect(packet.reason || 'booted'); - } else { - this.$emit('disconnect', packet.reason); - } - break; - - case 'message': - case 'json': - var params = ['message', packet.data]; - - if (packet.ack == 'data') { - params.push(ack); - } else if (packet.ack) { - this.packet({ type: 'ack', ackId: packet.id }); - } - - this.$emit.apply(this, params); - break; - - case 'event': - var params = [packet.name].concat(packet.args); - - if (packet.ack == 'data') - params.push(ack); - - this.$emit.apply(this, params); - break; - - case 'ack': - if (this.acks[packet.ackId]) { - this.acks[packet.ackId].apply(this, packet.args); - delete this.acks[packet.ackId]; - } - break; - - case 'error': - if (packet.advice){ - this.socket.onError(packet); - } else { - if (packet.reason == 'unauthorized') { - this.$emit('connect_failed', packet.reason); - } else { - this.$emit('error', packet.reason); - } - } - break; - } - }; - - /** - * Flag interface. - * - * @api private - */ - - function Flag (nsp, name) { - this.namespace = nsp; - this.name = name; - }; - - /** - * Send a message - * - * @api public - */ - - Flag.prototype.send = function () { - this.namespace.flags[this.name] = true; - this.namespace.send.apply(this.namespace, arguments); - }; - - /** - * Emit an event - * - * @api public - */ - - Flag.prototype.emit = function () { - this.namespace.flags[this.name] = true; - this.namespace.emit.apply(this.namespace, arguments); - }; - -})( - 'undefined' != typeof io ? io : module.exports - , 'undefined' != typeof io ? io : module.parent.exports -); - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io, global) { - - /** - * Expose constructor. - */ - - exports.websocket = WS; - - /** - * The WebSocket transport uses the HTML5 WebSocket API to establish an - * persistent connection with the Socket.IO server. This transport will also - * be inherited by the FlashSocket fallback as it provides a API compatible - * polyfill for the WebSockets. - * - * @constructor - * @extends {io.Transport} - * @api public - */ - - function WS (socket) { - io.Transport.apply(this, arguments); - }; - - /** - * Inherits from Transport. - */ - - io.util.inherit(WS, io.Transport); - - /** - * Transport name - * - * @api public - */ - - WS.prototype.name = 'websocket'; - - /** - * Initializes a new `WebSocket` connection with the Socket.IO server. We attach - * all the appropriate listeners to handle the responses from the server. - * - * @returns {Transport} - * @api public - */ - - WS.prototype.open = function () { - var query = io.util.query(this.socket.options.query) - , self = this - , Socket - - - if (!Socket) { - Socket = global.MozWebSocket || global.WebSocket; - } - - this.websocket = new Socket(this.prepareUrl() + query); - - this.websocket.onopen = function () { - self.onOpen(); - self.socket.setBuffer(false); - }; - this.websocket.onmessage = function (ev) { - self.onData(ev.data); - }; - this.websocket.onclose = function () { - self.onClose(); - self.socket.setBuffer(true); - }; - this.websocket.onerror = function (e) { - self.onError(e); - }; - - return this; - }; - - /** - * Send a message to the Socket.IO server. The message will automatically be - * encoded in the correct message format. - * - * @returns {Transport} - * @api public - */ - - // Do to a bug in the current IDevices browser, we need to wrap the send in a - // setTimeout, when they resume from sleeping the browser will crash if - // we don't allow the browser time to detect the socket has been closed - if (io.util.ua.iDevice) { - WS.prototype.send = function (data) { - var self = this; - setTimeout(function() { - self.websocket.send(data); - },0); - return this; - }; - } else { - WS.prototype.send = function (data) { - this.websocket.send(data); - return this; - }; - } - - /** - * Payload - * - * @api private - */ - - WS.prototype.payload = function (arr) { - for (var i = 0, l = arr.length; i < l; i++) { - this.packet(arr[i]); - } - return this; - }; - - /** - * Disconnect the established `WebSocket` connection. - * - * @returns {Transport} - * @api public - */ - - WS.prototype.close = function () { - this.websocket.close(); - return this; - }; - - /** - * Handle the errors that `WebSocket` might be giving when we - * are attempting to connect or send messages. - * - * @param {Error} e The error. - * @api private - */ - - WS.prototype.onError = function (e) { - this.socket.onError(e); - }; - - /** - * Returns the appropriate scheme for the URI generation. - * - * @api private - */ - WS.prototype.scheme = function () { - return this.socket.options.secure ? 'wss' : 'ws'; - }; - - /** - * Checks if the browser has support for native `WebSockets` and that - * it's not the polyfill created for the FlashSocket transport. - * - * @return {Boolean} - * @api public - */ - - WS.check = function () { - return ('WebSocket' in global && !('__addTask' in WebSocket)) - || 'MozWebSocket' in global; - }; - - /** - * Check if the `WebSocket` transport support cross domain communications. - * - * @returns {Boolean} - * @api public - */ - - WS.xdomainCheck = function () { - return true; - }; - - /** - * Add the transport to your public io.transports array. - * - * @api private - */ - - io.transports.push('websocket'); - -})( - 'undefined' != typeof io ? io.Transport : module.exports - , 'undefined' != typeof io ? io : module.parent.exports - , this -); - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io) { - - /** - * Expose constructor. - */ - - exports.flashsocket = Flashsocket; - - /** - * The FlashSocket transport. This is a API wrapper for the HTML5 WebSocket - * specification. It uses a .swf file to communicate with the server. If you want - * to serve the .swf file from a other server than where the Socket.IO script is - * coming from you need to use the insecure version of the .swf. More information - * about this can be found on the github page. - * - * @constructor - * @extends {io.Transport.websocket} - * @api public - */ - - function Flashsocket () { - io.Transport.websocket.apply(this, arguments); - }; - - /** - * Inherits from Transport. - */ - - io.util.inherit(Flashsocket, io.Transport.websocket); - - /** - * Transport name - * - * @api public - */ - - Flashsocket.prototype.name = 'flashsocket'; - - /** - * Disconnect the established `FlashSocket` connection. This is done by adding a - * new task to the FlashSocket. The rest will be handled off by the `WebSocket` - * transport. - * - * @returns {Transport} - * @api public - */ - - Flashsocket.prototype.open = function () { - var self = this - , args = arguments; - - WebSocket.__addTask(function () { - io.Transport.websocket.prototype.open.apply(self, args); - }); - return this; - }; - - /** - * Sends a message to the Socket.IO server. This is done by adding a new - * task to the FlashSocket. The rest will be handled off by the `WebSocket` - * transport. - * - * @returns {Transport} - * @api public - */ - - Flashsocket.prototype.send = function () { - var self = this, args = arguments; - WebSocket.__addTask(function () { - io.Transport.websocket.prototype.send.apply(self, args); - }); - return this; - }; - - /** - * Disconnects the established `FlashSocket` connection. - * - * @returns {Transport} - * @api public - */ - - Flashsocket.prototype.close = function () { - WebSocket.__tasks.length = 0; - io.Transport.websocket.prototype.close.call(this); - return this; - }; - - /** - * The WebSocket fall back needs to append the flash container to the body - * element, so we need to make sure we have access to it. Or defer the call - * until we are sure there is a body element. - * - * @param {Socket} socket The socket instance that needs a transport - * @param {Function} fn The callback - * @api private - */ - - Flashsocket.prototype.ready = function (socket, fn) { - function init () { - var options = socket.options - , port = options['flash policy port'] - , path = [ - 'http' + (options.secure ? 's' : '') + ':/' - , options.host + ':' + options.port - , options.resource - , 'static/flashsocket' - , 'WebSocketMain' + (socket.isXDomain() ? 'Insecure' : '') + '.swf' - ]; - - // Only start downloading the swf file when the checked that this browser - // actually supports it - if (!Flashsocket.loaded) { - if (typeof WEB_SOCKET_SWF_LOCATION === 'undefined') { - // Set the correct file based on the XDomain settings - WEB_SOCKET_SWF_LOCATION = path.join('/'); - } - - if (port !== 843) { - WebSocket.loadFlashPolicyFile('xmlsocket://' + options.host + ':' + port); - } - - WebSocket.__initialize(); - Flashsocket.loaded = true; - } - - fn.call(self); - } - - var self = this; - if (document.body) return init(); - - io.util.load(init); - }; - - /** - * Check if the FlashSocket transport is supported as it requires that the Adobe - * Flash Player plug-in version `10.0.0` or greater is installed. And also check if - * the polyfill is correctly loaded. - * - * @returns {Boolean} - * @api public - */ - - Flashsocket.check = function () { - if ( - typeof WebSocket == 'undefined' - || !('__initialize' in WebSocket) || !swfobject - ) return false; - - return swfobject.getFlashPlayerVersion().major >= 10; - }; - - /** - * Check if the FlashSocket transport can be used as cross domain / cross origin - * transport. Because we can't see which type (secure or insecure) of .swf is used - * we will just return true. - * - * @returns {Boolean} - * @api public - */ - - Flashsocket.xdomainCheck = function () { - return true; - }; - - /** - * Disable AUTO_INITIALIZATION - */ - - if (typeof window != 'undefined') { - WEB_SOCKET_DISABLE_AUTO_INITIALIZATION = true; - } - - /** - * Add the transport to your public io.transports array. - * - * @api private - */ - - io.transports.push('flashsocket'); -})( - 'undefined' != typeof io ? io.Transport : module.exports - , 'undefined' != typeof io ? io : module.parent.exports -); -/* SWFObject v2.2 - is released under the MIT License -*/ -if ('undefined' != typeof window) { -var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O[(['Active'].concat('Object').join('X'))]!=D){try{var ad=new window[(['Active'].concat('Object').join('X'))](W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab -// License: New BSD License -// Reference: http://dev.w3.org/html5/websockets/ -// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol - -(function() { - - if ('undefined' == typeof window || window.WebSocket) return; - - var console = window.console; - if (!console || !console.log || !console.error) { - console = {log: function(){ }, error: function(){ }}; - } - - if (!swfobject.hasFlashPlayerVersion("10.0.0")) { - console.error("Flash Player >= 10.0.0 is required."); - return; - } - if (location.protocol == "file:") { - console.error( - "WARNING: web-socket-js doesn't work in file:///... URL " + - "unless you set Flash Security Settings properly. " + - "Open the page via Web server i.e. http://..."); - } - - /** - * This class represents a faux web socket. - * @param {string} url - * @param {array or string} protocols - * @param {string} proxyHost - * @param {int} proxyPort - * @param {string} headers - */ - WebSocket = function(url, protocols, proxyHost, proxyPort, headers) { - var self = this; - self.__id = WebSocket.__nextId++; - WebSocket.__instances[self.__id] = self; - self.readyState = WebSocket.CONNECTING; - self.bufferedAmount = 0; - self.__events = {}; - if (!protocols) { - protocols = []; - } else if (typeof protocols == "string") { - protocols = [protocols]; - } - // Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc. - // Otherwise, when onopen fires immediately, onopen is called before it is set. - setTimeout(function() { - WebSocket.__addTask(function() { - WebSocket.__flash.create( - self.__id, url, protocols, proxyHost || null, proxyPort || 0, headers || null); - }); - }, 0); - }; - - /** - * Send data to the web socket. - * @param {string} data The data to send to the socket. - * @return {boolean} True for success, false for failure. - */ - WebSocket.prototype.send = function(data) { - if (this.readyState == WebSocket.CONNECTING) { - throw "INVALID_STATE_ERR: Web Socket connection has not been established"; - } - // We use encodeURIComponent() here, because FABridge doesn't work if - // the argument includes some characters. We don't use escape() here - // because of this: - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#escape_and_unescape_Functions - // But it looks decodeURIComponent(encodeURIComponent(s)) doesn't - // preserve all Unicode characters either e.g. "\uffff" in Firefox. - // Note by wtritch: Hopefully this will not be necessary using ExternalInterface. Will require - // additional testing. - var result = WebSocket.__flash.send(this.__id, encodeURIComponent(data)); - if (result < 0) { // success - return true; - } else { - this.bufferedAmount += result; - return false; - } - }; - - /** - * Close this web socket gracefully. - */ - WebSocket.prototype.close = function() { - if (this.readyState == WebSocket.CLOSED || this.readyState == WebSocket.CLOSING) { - return; - } - this.readyState = WebSocket.CLOSING; - WebSocket.__flash.close(this.__id); - }; - - /** - * Implementation of {@link DOM 2 EventTarget Interface} - * - * @param {string} type - * @param {function} listener - * @param {boolean} useCapture - * @return void - */ - WebSocket.prototype.addEventListener = function(type, listener, useCapture) { - if (!(type in this.__events)) { - this.__events[type] = []; - } - this.__events[type].push(listener); - }; - - /** - * Implementation of {@link DOM 2 EventTarget Interface} - * - * @param {string} type - * @param {function} listener - * @param {boolean} useCapture - * @return void - */ - WebSocket.prototype.removeEventListener = function(type, listener, useCapture) { - if (!(type in this.__events)) return; - var events = this.__events[type]; - for (var i = events.length - 1; i >= 0; --i) { - if (events[i] === listener) { - events.splice(i, 1); - break; - } - } - }; - - /** - * Implementation of {@link DOM 2 EventTarget Interface} - * - * @param {Event} event - * @return void - */ - WebSocket.prototype.dispatchEvent = function(event) { - var events = this.__events[event.type] || []; - for (var i = 0; i < events.length; ++i) { - events[i](event); - } - var handler = this["on" + event.type]; - if (handler) handler(event); - }; - - /** - * Handles an event from Flash. - * @param {Object} flashEvent - */ - WebSocket.prototype.__handleEvent = function(flashEvent) { - if ("readyState" in flashEvent) { - this.readyState = flashEvent.readyState; - } - if ("protocol" in flashEvent) { - this.protocol = flashEvent.protocol; - } - - var jsEvent; - if (flashEvent.type == "open" || flashEvent.type == "error") { - jsEvent = this.__createSimpleEvent(flashEvent.type); - } else if (flashEvent.type == "close") { - // TODO implement jsEvent.wasClean - jsEvent = this.__createSimpleEvent("close"); - } else if (flashEvent.type == "message") { - var data = decodeURIComponent(flashEvent.message); - jsEvent = this.__createMessageEvent("message", data); - } else { - throw "unknown event type: " + flashEvent.type; - } - - this.dispatchEvent(jsEvent); - }; - - WebSocket.prototype.__createSimpleEvent = function(type) { - if (document.createEvent && window.Event) { - var event = document.createEvent("Event"); - event.initEvent(type, false, false); - return event; - } else { - return {type: type, bubbles: false, cancelable: false}; - } - }; - - WebSocket.prototype.__createMessageEvent = function(type, data) { - if (document.createEvent && window.MessageEvent && !window.opera) { - var event = document.createEvent("MessageEvent"); - event.initMessageEvent("message", false, false, data, null, null, window, null); - return event; - } else { - // IE and Opera, the latter one truncates the data parameter after any 0x00 bytes. - return {type: type, data: data, bubbles: false, cancelable: false}; - } - }; - - /** - * Define the WebSocket readyState enumeration. - */ - WebSocket.CONNECTING = 0; - WebSocket.OPEN = 1; - WebSocket.CLOSING = 2; - WebSocket.CLOSED = 3; - - WebSocket.__flash = null; - WebSocket.__instances = {}; - WebSocket.__tasks = []; - WebSocket.__nextId = 0; - - /** - * Load a new flash security policy file. - * @param {string} url - */ - WebSocket.loadFlashPolicyFile = function(url){ - WebSocket.__addTask(function() { - WebSocket.__flash.loadManualPolicyFile(url); - }); - }; - - /** - * Loads WebSocketMain.swf and creates WebSocketMain object in Flash. - */ - WebSocket.__initialize = function() { - if (WebSocket.__flash) return; - - if (WebSocket.__swfLocation) { - // For backword compatibility. - window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation; - } - if (!window.WEB_SOCKET_SWF_LOCATION) { - console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf"); - return; - } - var container = document.createElement("div"); - container.id = "webSocketContainer"; - // Hides Flash box. We cannot use display: none or visibility: hidden because it prevents - // Flash from loading at least in IE. So we move it out of the screen at (-100, -100). - // But this even doesn't work with Flash Lite (e.g. in Droid Incredible). So with Flash - // Lite, we put it at (0, 0). This shows 1x1 box visible at left-top corner but this is - // the best we can do as far as we know now. - container.style.position = "absolute"; - if (WebSocket.__isFlashLite()) { - container.style.left = "0px"; - container.style.top = "0px"; - } else { - container.style.left = "-100px"; - container.style.top = "-100px"; - } - var holder = document.createElement("div"); - holder.id = "webSocketFlash"; - container.appendChild(holder); - document.body.appendChild(container); - // See this article for hasPriority: - // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html - swfobject.embedSWF( - WEB_SOCKET_SWF_LOCATION, - "webSocketFlash", - "1" /* width */, - "1" /* height */, - "10.0.0" /* SWF version */, - null, - null, - {hasPriority: true, swliveconnect : true, allowScriptAccess: "always"}, - null, - function(e) { - if (!e.success) { - console.error("[WebSocket] swfobject.embedSWF failed"); - } - }); - }; - - /** - * Called by Flash to notify JS that it's fully loaded and ready - * for communication. - */ - WebSocket.__onFlashInitialized = function() { - // We need to set a timeout here to avoid round-trip calls - // to flash during the initialization process. - setTimeout(function() { - WebSocket.__flash = document.getElementById("webSocketFlash"); - WebSocket.__flash.setCallerUrl(location.href); - WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG); - for (var i = 0; i < WebSocket.__tasks.length; ++i) { - WebSocket.__tasks[i](); - } - WebSocket.__tasks = []; - }, 0); - }; - - /** - * Called by Flash to notify WebSockets events are fired. - */ - WebSocket.__onFlashEvent = function() { - setTimeout(function() { - try { - // Gets events using receiveEvents() instead of getting it from event object - // of Flash event. This is to make sure to keep message order. - // It seems sometimes Flash events don't arrive in the same order as they are sent. - var events = WebSocket.__flash.receiveEvents(); - for (var i = 0; i < events.length; ++i) { - WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]); - } - } catch (e) { - console.error(e); - } - }, 0); - return true; - }; - - // Called by Flash. - WebSocket.__log = function(message) { - console.log(decodeURIComponent(message)); - }; - - // Called by Flash. - WebSocket.__error = function(message) { - console.error(decodeURIComponent(message)); - }; - - WebSocket.__addTask = function(task) { - if (WebSocket.__flash) { - task(); - } else { - WebSocket.__tasks.push(task); - } - }; - - /** - * Test if the browser is running flash lite. - * @return {boolean} True if flash lite is running, false otherwise. - */ - WebSocket.__isFlashLite = function() { - if (!window.navigator || !window.navigator.mimeTypes) { - return false; - } - var mimeType = window.navigator.mimeTypes["application/x-shockwave-flash"]; - if (!mimeType || !mimeType.enabledPlugin || !mimeType.enabledPlugin.filename) { - return false; - } - return mimeType.enabledPlugin.filename.match(/flashlite/i) ? true : false; - }; - - if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) { - if (window.addEventListener) { - window.addEventListener("load", function(){ - WebSocket.__initialize(); - }, false); - } else { - window.attachEvent("onload", function(){ - WebSocket.__initialize(); - }); - } - } - -})(); - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io, global) { - - /** - * Expose constructor. - * - * @api public - */ - - exports.XHR = XHR; - - /** - * XHR constructor - * - * @costructor - * @api public - */ - - function XHR (socket) { - if (!socket) return; - - io.Transport.apply(this, arguments); - this.sendBuffer = []; - }; - - /** - * Inherits from Transport. - */ - - io.util.inherit(XHR, io.Transport); - - /** - * Establish a connection - * - * @returns {Transport} - * @api public - */ - - XHR.prototype.open = function () { - this.socket.setBuffer(false); - this.onOpen(); - this.get(); - - // we need to make sure the request succeeds since we have no indication - // whether the request opened or not until it succeeded. - this.setCloseTimeout(); - - return this; - }; - - /** - * Check if we need to send data to the Socket.IO server, if we have data in our - * buffer we encode it and forward it to the `post` method. - * - * @api private - */ - - XHR.prototype.payload = function (payload) { - var msgs = []; - - for (var i = 0, l = payload.length; i < l; i++) { - msgs.push(io.parser.encodePacket(payload[i])); - } - - this.send(io.parser.encodePayload(msgs)); - }; - - /** - * Send data to the Socket.IO server. - * - * @param data The message - * @returns {Transport} - * @api public - */ - - XHR.prototype.send = function (data) { - this.post(data); - return this; - }; - - /** - * Posts a encoded message to the Socket.IO server. - * - * @param {String} data A encoded message. - * @api private - */ - - function empty () { }; - - XHR.prototype.post = function (data) { - var self = this; - this.socket.setBuffer(true); - - function stateChange () { - if (this.readyState == 4) { - this.onreadystatechange = empty; - self.posting = false; - - if (this.status == 200){ - self.socket.setBuffer(false); - } else { - self.onClose(); - } - } - } - - function onload () { - this.onload = empty; - self.socket.setBuffer(false); - }; - - this.sendXHR = this.request('POST'); - - if (global.XDomainRequest && this.sendXHR instanceof XDomainRequest) { - this.sendXHR.onload = this.sendXHR.onerror = onload; - } else { - this.sendXHR.onreadystatechange = stateChange; - } - - this.sendXHR.send(data); - }; - - /** - * Disconnects the established `XHR` connection. - * - * @returns {Transport} - * @api public - */ - - XHR.prototype.close = function () { - this.onClose(); - return this; - }; - - /** - * Generates a configured XHR request - * - * @param {String} url The url that needs to be requested. - * @param {String} method The method the request should use. - * @returns {XMLHttpRequest} - * @api private - */ - - XHR.prototype.request = function (method) { - var req = io.util.request(this.socket.isXDomain()) - , query = io.util.query(this.socket.options.query, 't=' + +new Date); - - req.open(method || 'GET', this.prepareUrl() + query, true); - - if (method == 'POST') { - try { - if (req.setRequestHeader) { - req.setRequestHeader('Content-type', 'text/plain;charset=UTF-8'); - } else { - // XDomainRequest - req.contentType = 'text/plain'; - } - } catch (e) {} - } - - return req; - }; - - /** - * Returns the scheme to use for the transport URLs. - * - * @api private - */ - - XHR.prototype.scheme = function () { - return this.socket.options.secure ? 'https' : 'http'; - }; - - /** - * Check if the XHR transports are supported - * - * @param {Boolean} xdomain Check if we support cross domain requests. - * @returns {Boolean} - * @api public - */ - - XHR.check = function (socket, xdomain) { - try { - var request = io.util.request(xdomain), - usesXDomReq = (global.XDomainRequest && request instanceof XDomainRequest), - socketProtocol = (socket && socket.options && socket.options.secure ? 'https:' : 'http:'), - isXProtocol = (socketProtocol != global.location.protocol); - if (request && !(usesXDomReq && isXProtocol)) { - return true; - } - } catch(e) {} - - return false; - }; - - /** - * Check if the XHR transport supports cross domain requests. - * - * @returns {Boolean} - * @api public - */ - - XHR.xdomainCheck = function (socket) { - return XHR.check(socket, true); - }; - -})( - 'undefined' != typeof io ? io.Transport : module.exports - , 'undefined' != typeof io ? io : module.parent.exports - , this -); -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io) { - - /** - * Expose constructor. - */ - - exports.htmlfile = HTMLFile; - - /** - * The HTMLFile transport creates a `forever iframe` based transport - * for Internet Explorer. Regular forever iframe implementations will - * continuously trigger the browsers buzy indicators. If the forever iframe - * is created inside a `htmlfile` these indicators will not be trigged. - * - * @constructor - * @extends {io.Transport.XHR} - * @api public - */ - - function HTMLFile (socket) { - io.Transport.XHR.apply(this, arguments); - }; - - /** - * Inherits from XHR transport. - */ - - io.util.inherit(HTMLFile, io.Transport.XHR); - - /** - * Transport name - * - * @api public - */ - - HTMLFile.prototype.name = 'htmlfile'; - - /** - * Creates a new Ac...eX `htmlfile` with a forever loading iframe - * that can be used to listen to messages. Inside the generated - * `htmlfile` a reference will be made to the HTMLFile transport. - * - * @api private - */ - - HTMLFile.prototype.get = function () { - this.doc = new window[(['Active'].concat('Object').join('X'))]('htmlfile'); - this.doc.open(); - this.doc.write(''); - this.doc.close(); - this.doc.parentWindow.s = this; - - var iframeC = this.doc.createElement('div'); - iframeC.className = 'socketio'; - - this.doc.body.appendChild(iframeC); - this.iframe = this.doc.createElement('iframe'); - - iframeC.appendChild(this.iframe); - - var self = this - , query = io.util.query(this.socket.options.query, 't='+ +new Date); - - this.iframe.src = this.prepareUrl() + query; - - io.util.on(window, 'unload', function () { - self.destroy(); - }); - }; - - /** - * The Socket.IO server will write script tags inside the forever - * iframe, this function will be used as callback for the incoming - * information. - * - * @param {String} data The message - * @param {document} doc Reference to the context - * @api private - */ - - HTMLFile.prototype._ = function (data, doc) { - this.onData(data); - try { - var script = doc.getElementsByTagName('script')[0]; - script.parentNode.removeChild(script); - } catch (e) { } - }; - - /** - * Destroy the established connection, iframe and `htmlfile`. - * And calls the `CollectGarbage` function of Internet Explorer - * to release the memory. - * - * @api private - */ - - HTMLFile.prototype.destroy = function () { - if (this.iframe){ - try { - this.iframe.src = 'about:blank'; - } catch(e){} - - this.doc = null; - this.iframe.parentNode.removeChild(this.iframe); - this.iframe = null; - - CollectGarbage(); - } - }; - - /** - * Disconnects the established connection. - * - * @returns {Transport} Chaining. - * @api public - */ - - HTMLFile.prototype.close = function () { - this.destroy(); - return io.Transport.XHR.prototype.close.call(this); - }; - - /** - * Checks if the browser supports this transport. The browser - * must have an `Ac...eXObject` implementation. - * - * @return {Boolean} - * @api public - */ - - HTMLFile.check = function (socket) { - if (typeof window != "undefined" && (['Active'].concat('Object').join('X')) in window){ - try { - var a = new window[(['Active'].concat('Object').join('X'))]('htmlfile'); - return a && io.Transport.XHR.check(socket); - } catch(e){} - } - return false; - }; - - /** - * Check if cross domain requests are supported. - * - * @returns {Boolean} - * @api public - */ - - HTMLFile.xdomainCheck = function () { - // we can probably do handling for sub-domains, we should - // test that it's cross domain but a subdomain here - return false; - }; - - /** - * Add the transport to your public io.transports array. - * - * @api private - */ - - io.transports.push('htmlfile'); - -})( - 'undefined' != typeof io ? io.Transport : module.exports - , 'undefined' != typeof io ? io : module.parent.exports -); - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io, global) { - - /** - * Expose constructor. - */ - - exports['xhr-polling'] = XHRPolling; - - /** - * The XHR-polling transport uses long polling XHR requests to create a - * "persistent" connection with the server. - * - * @constructor - * @api public - */ - - function XHRPolling () { - io.Transport.XHR.apply(this, arguments); - }; - - /** - * Inherits from XHR transport. - */ - - io.util.inherit(XHRPolling, io.Transport.XHR); - - /** - * Merge the properties from XHR transport - */ - - io.util.merge(XHRPolling, io.Transport.XHR); - - /** - * Transport name - * - * @api public - */ - - XHRPolling.prototype.name = 'xhr-polling'; - - /** - * Indicates whether heartbeats is enabled for this transport - * - * @api private - */ - - XHRPolling.prototype.heartbeats = function () { - return false; - }; - - /** - * Establish a connection, for iPhone and Android this will be done once the page - * is loaded. - * - * @returns {Transport} Chaining. - * @api public - */ - - XHRPolling.prototype.open = function () { - var self = this; - - io.Transport.XHR.prototype.open.call(self); - return false; - }; - - /** - * Starts a XHR request to wait for incoming messages. - * - * @api private - */ - - function empty () {}; - - XHRPolling.prototype.get = function () { - if (!this.isOpen) return; - - var self = this; - - function stateChange () { - if (this.readyState == 4) { - this.onreadystatechange = empty; - - if (this.status == 200) { - self.onData(this.responseText); - self.get(); - } else { - self.onClose(); - } - } - }; - - function onload () { - this.onload = empty; - this.onerror = empty; - self.onData(this.responseText); - self.get(); - }; - - function onerror () { - self.onClose(); - }; - - this.xhr = this.request(); - - if (global.XDomainRequest && this.xhr instanceof XDomainRequest) { - this.xhr.onload = onload; - this.xhr.onerror = onerror; - } else { - this.xhr.onreadystatechange = stateChange; - } - - this.xhr.send(null); - }; - - /** - * Handle the unclean close behavior. - * - * @api private - */ - - XHRPolling.prototype.onClose = function () { - io.Transport.XHR.prototype.onClose.call(this); - - if (this.xhr) { - this.xhr.onreadystatechange = this.xhr.onload = this.xhr.onerror = empty; - try { - this.xhr.abort(); - } catch(e){} - this.xhr = null; - } - }; - - /** - * Webkit based browsers show a infinit spinner when you start a XHR request - * before the browsers onload event is called so we need to defer opening of - * the transport until the onload event is called. Wrapping the cb in our - * defer method solve this. - * - * @param {Socket} socket The socket instance that needs a transport - * @param {Function} fn The callback - * @api private - */ - - XHRPolling.prototype.ready = function (socket, fn) { - var self = this; - - io.util.defer(function () { - fn.call(self); - }); - }; - - /** - * Add the transport to your public io.transports array. - * - * @api private - */ - - io.transports.push('xhr-polling'); - -})( - 'undefined' != typeof io ? io.Transport : module.exports - , 'undefined' != typeof io ? io : module.parent.exports - , this -); - -/** - * socket.io - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (exports, io, global) { - /** - * There is a way to hide the loading indicator in Firefox. If you create and - * remove a iframe it will stop showing the current loading indicator. - * Unfortunately we can't feature detect that and UA sniffing is evil. - * - * @api private - */ - - var indicator = global.document && "MozAppearance" in - global.document.documentElement.style; - - /** - * Expose constructor. - */ - - exports['jsonp-polling'] = JSONPPolling; - - /** - * The JSONP transport creates an persistent connection by dynamically - * inserting a script tag in the page. This script tag will receive the - * information of the Socket.IO server. When new information is received - * it creates a new script tag for the new data stream. - * - * @constructor - * @extends {io.Transport.xhr-polling} - * @api public - */ - - function JSONPPolling (socket) { - io.Transport['xhr-polling'].apply(this, arguments); - - this.index = io.j.length; - - var self = this; - - io.j.push(function (msg) { - self._(msg); - }); - }; - - /** - * Inherits from XHR polling transport. - */ - - io.util.inherit(JSONPPolling, io.Transport['xhr-polling']); - - /** - * Transport name - * - * @api public - */ - - JSONPPolling.prototype.name = 'jsonp-polling'; - - /** - * Posts a encoded message to the Socket.IO server using an iframe. - * The iframe is used because script tags can create POST based requests. - * The iframe is positioned outside of the view so the user does not - * notice it's existence. - * - * @param {String} data A encoded message. - * @api private - */ - - JSONPPolling.prototype.post = function (data) { - var self = this - , query = io.util.query( - this.socket.options.query - , 't='+ (+new Date) + '&i=' + this.index - ); - - if (!this.form) { - var form = document.createElement('form') - , area = document.createElement('textarea') - , id = this.iframeId = 'socketio_iframe_' + this.index - , iframe; - - form.className = 'socketio'; - form.style.position = 'absolute'; - form.style.top = '0px'; - form.style.left = '0px'; - form.style.display = 'none'; - form.target = id; - form.method = 'POST'; - form.setAttribute('accept-charset', 'utf-8'); - area.name = 'd'; - form.appendChild(area); - document.body.appendChild(form); - - this.form = form; - this.area = area; - } - - this.form.action = this.prepareUrl() + query; - - function complete () { - initIframe(); - self.socket.setBuffer(false); - }; - - function initIframe () { - if (self.iframe) { - self.form.removeChild(self.iframe); - } - - try { - // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) - iframe = document.createElement('