<commit_before>/*
 * Authors: Isaac Zylstra and Victor Norman @ Calvin College, Grand Rapids, MI.
 * Contact: vtn2@calvin.edu
 */

(function(ext) {

    //The variable that will hold the json to be read from
    var jsonObject = null;

    //The scale applied to the kinect data to make it map to the canvas better.
    var xScale = 240;
    var yScale = 180;
    var zScale = 200;

    //The status of the kinect
    var status = 0;

    //alert letting the user know what needs to be done before loading the extension.
    alert("BEFORE CLICKING OK: Make sure the kinect is connected and your JSON websocket server has started");

    console.log("connecting to server ..");

    // create a new websocket and connect
    window.ws = new WebSocket('ws://localhost:8181/');

    // when data is comming from the server, this method is called
    ws.onmessage = function (evt) {
        jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };

    // Cleanup function when the extension is unloaded
    ext._shutdown = function()
    {
    window.ws.close();
    };

    // Reports status of kinect
    ext._getStatus = function() {
        if(status == 0)
        {
        return {status: 0, msg: 'Kinect is not connected to Scratch'};
        }
        if(status == 1)
        {
            return {status: 1, msg: 'Kinect is connected, but is not detecting any bodies'};
        }
        if(status == 2)
        {
            return {status: 2, msg: 'Kinect is sending body data'};
        }
    };

        // Block and block menu descriptions
    var descriptor = {
        blocks: [
            ['r', '%m.b %m.j %m.c', 'joints', 'Body 1', 'Head', 'x'],
            ['r', 'Body ID %n %m.j %m.c', 'jointsID', '0', 'Head', 'x'],
            ['b', '%m.b %m.d Handstate is %m.h', 'handstate', 'Body 1', 'Left', 'Closed'],
            ['b', 'Body ID %n %m.d Handstate is %m.h', 'handstateID', '0', 'Left', 'Closed'],
            ['r', '%m.b %m.d Handstate', 'handdebug', 'Body 1', 'Left'], //Comment out of final version.
            ['r', '%m.b id', 'bodyid', 'Body 1'],
            ['b', '%m.b tracked', 'tracked', 'Body 1'],
            ['b', 'connected', 'connected'],
            ['', 'Basic body check', 'basic_body_check'], //Comment out of final version.
            ['', 'Restart local connection', 'restart'],
            ['', 'connect to %s', 'ipconnect', '0.0.0.0'],
            ['', 'Close connection', 'closeconn'], //Comment out of final version.
            ['', 'console.log %n', 'write'], //Comment out of final version.
            ['', 'bad only %n', 'writeB'] //Comment out of final version.
        ],

        menus: {
	    j: ['Left Ankle', 'Right Ankle', 'Left Elbow', 'Right Elbow', 'Left Foot', 'Right Foot', 'Left Hand', 'Right Hand', 'Left Hand Tip', 'Right Hand Tip', 'Head', 'Left Hip', 'Right Hip', 'Left Knee', 'Right Knee', 'Neck', 'Left Shoulder', 'Right Shoulder', 'Spine Base', 'Spine Middle', 'Spine Shoulder', 'Left Thumb', 'Right Thumb', 'Left Wrist', 'Right Wrist'],
        b: ['Body 1', 'Body 2', 'Body 3', 'Body 4', 'Body 5', 'Body 6'],
        h: ['Unknown', 'Not Tracked', 'Open', 'Closed', 'Lasso'],
        c: ['x', 'y', 'z'],
        d: ['Left', 'Right']
    }
    };

    //restarts the local connection
    ext.restart = function() {
        window.ws.close();
        console.log("connecting to local server ..");
        window.ws = new WebSocket('ws://localhost:8181/');

        // when data is comming from the server, this method is called
        ws.onmessage = function (evt) {
            jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };
    };

    //s: a string containing the ip the user wishes to connect to.
    //Creates a remote connection to s.
    ext.ipconnect = function(string) {
        window.ws.close();
        console.log("connecting to "+string+' ..');
        window.ws = new WebSocket('ws://'+string+':8181/');

        // when data is comming from the server, this method is called
        ws.onmessage = function (evt) {
            jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
        };

        // when the connection is established, this method is called
        ws.onopen = function () {
        console.log('.. connection open');
        };

        // when the connection is closed, this method is called
        ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
        };
    }

    //Closes the current connection
    ext.closeconn = function()
    {
        window.ws.close();
    }

    //m: the number to be written to the console
    //Outputs numeric content to console
    ext.write = function(number){
        console.log(number);
    };

    //m: input to be compared to 0
    //Writes "bad" in console if the input is 0
    ext.writeB = function(number){
        if(number == 0)
        {
            console.log("bad");
        }
    };

    //Checks the body 1 head x coordinate
    //Good for check if any data is getting in from the kinect
    ext.basic_body_check = function() {
        console.log(jsonObject.bodies[0].joints[3].x*xScale);
    };

    //m: the body chosen (Body 1-6)
    //Gives the id of the selected body
    ext.bodyid = function(body)
    {
        switch(body){
            case 'Body 1': return jsonObject.bodies[0].id;
            case 'Body 2': return jsonObject.bodies[1].id;
            case 'Body 3': return jsonObject.bodies[2].id;
            case 'Body 4': return jsonObject.bodies[3].id;
            case 'Body 5': return jsonObject.bodies[4].id;
            case 'Body 6': return jsonObject.bodies[5].id;
        }
    }

        //True if scratch is receiving the kinect (but not necessarily data)
    ext.connected = function()
    {
        if(status == 0){
            return false;
        }

        if(status == 1 || 2){
            return true;
        }
    };

    //m: the body chosen (Body 1-6)
    //True if scratch is receiving the chosen body data
    ext.tracked = function(body)
    {
        var i = -1;
        switch(body){
            case 'Body 1': i = 0;
                break;
            case 'Body 2': i = 1;
                break;
            case 'Body 3': i = 2;
                break;
            case 'Body 4': i = 3;
                break;
            case 'Body 5': i = 4;
                break;
            case 'Body 6': i = 5;
                break;
        }

        return jsonObject.bodies[i].id != 0;
    };

    //l: the body chosen (Body 1-6)
    //d: which handstate (left or right)
    //Outputs the left handstate of the selected body
    ext.handdebug = function(body,direction)
    {
        var i;
        switch(body){
            case 'Body 1': i=0;
                break;
            case 'Body 2': i=1;
                break;
            case 'Body 3': i=2;
                break;
            case 'Body 4': i=3;
                break;
            case 'Body 5': i=4;
                break;
            case 'Body 6': i=5;
                break;
        }

        switch(direction)
        {
            case 'Left': return jsonObject.bodies[i].lhandstate;
            case 'Right': return jsonObject.bodies[i].rhandstate;
        }
    }

    //l: The selected body (Body 1-6)
    //d: Which handstate (left or right)
    //n: The selected handstate (Unknown, Not Tracked, Open, Closed, Lasso)
    //Returns true if the selected bodies left handstate is the same as block selected one.
    ext.handstate = function(body,direction,handstate)
    {
        var i;
        var j;
        switch(body){
            case 'Body 1': i=0;
                break;
            case 'Body 2': i=1;
                break;
            case 'Body 3': i=2;
                break;
            case 'Body 4': i=3;
                break;
            case 'Body 5': i=4;
                break;
            case 'Body 6': i=5;
                break;
        }

        switch(handstate)
        {
            case 'Unknown': j = 0;
                break;
            case 'Not Tracked': j = 1;
                break;
            case 'Open': j = 2;
                break;
            case 'Closed': j = 3;
                break;
            case 'Lasso': j = 4;
                break;
        }

        switch(direction)
        {
            case 'Left': return jsonObject.bodies[i].lhandstate == j;
            case 'Right': return jsonObject.bodies[i].rhandstate == j;
        }
    }

    //l: The selected body (Body 1-6)
    //d: Which handstate (left or right)
    //n: The selected handstate (Unknown, Not Tracked, Open, Closed, Lasso)
    //Returns true if the selected bodies left handstate is the same as block selected one.
        ext.handstateID = function(bodyID,direction,handstate)
    {
        var k;
        var j;

                    switch(handstate)
        {
            case 'Unknown': k = 0;
                break;
            case 'Not Tracked': k = 1;
                break;
            case 'Open': k = 2;
                break;
            case 'Closed': k = 3;
                break;
            case 'Lasso': k = 4;
                break;
        }

        for(i = 0; i < 6; i++)
        {
            if(bodyID == jsonObject.bodies[i].id)
            {
                j = i;
            }
        }

        switch(direction)
        {
            case 'Left': return jsonObject.bodies[j].lhandstate == k;
            case 'Right': return jsonObject.bodies[j].rhandstate == k;
        }
    }

    //l: The body chosen (Body 1-6).
    //k1: The joint chosen (All joint the kinect v2 tracks).
    //x: The chosen coordinate (x, y, or z).
    //Gets the coordinate chosen from the joint chosen from the body chosen
    ext.joints = function(body,joint,coordinate)
    {
        var a = -1;
        var b = -1;

        switch(joint){
            case 'Left Ankle': a=14;
                break;
            case 'Right Ankle': a=18;
                break;
            case 'Left Elbow': a=5;
                break;
            case 'Right Elbow': a=9;
                break;
            case 'Left Foot': a=15;
                break;
            case 'Right Foot': a=19;
                break;
            case 'Left Hand': a=7;
                break;
            case 'Right Hand': a=11;
                break;
            case 'Left Hand Tip': a=21;
                break;
            case 'Right Hand Tip': a=23;
                break;
            case 'Head': a=3;
                break;
            case 'Left Hip': a=12;
                break;
            case 'Right Hip': a=16;
                break;
            case 'Left Knee': a=13;
                break;
            case 'Right Knee': a=17;
                break;
            case 'Neck': a=2;
                break;
            case 'Left Shoulder': a=4;
                break;
            case 'Right Shoulder': a=8;
                break;
            case 'Spine Base': a=0;
                break;
            case 'Spine Middle': a=1;
                break;
            case 'Spine Shoulder': a=20;
                break;
            case 'Left Thumb': a=22;
                break;
            case 'Right Thumb': a=24;
                break;
            case 'Left Wrist': a=6;
                break;
            case 'Right Wrist': a=10;
                break;
        }

        switch(body){
            case 'Body 1': b=0;
                break;
            case 'Body 2': b=1;
                break;
            case 'Body 3': b=2;
                break;
            case 'Body 4': b=3;
                break;
            case 'Body 5': b=4;
                break;
            case 'Body 6': b=5;
                break;
        }

        switch(coordinate){
            case 'x': return jsonObject.bodies[b].joints[a].x*xScale;
            case 'y': return jsonObject.bodies[b].joints[a].y*yScale;
            case 'z': return jsonObject.bodies[b].joints[a].z*zScale;
        }
    }

    //bodyID: The body chosen (Body 1-6).
    //k1: The joint chosen (All joint the kinect v2 tracks).
    //x: The chosen coordinate (x, y, or z).
    //Gets the coordinate chosen from the joint chosen from the body chosen
    ext.jointsID = function(bodyID,joint,coordinate)
    {
        var a = -1;
        var b = -1;

        switch(joint){
            case 'Left Ankle': a=14;
                break;
            case 'Right Ankle': a=18;
                break;
            case 'Left Elbow': a=5;
                break;
            case 'Right Elbow': a=9;
                break;
            case 'Left Foot': a=15;
                break;
            case 'Right Foot': a=19;
                break;
            case 'Left Hand': a=7;
                break;
            case 'Right Hand': a=11;
                break;
            case 'Left Hand Tip': a=21;
                break;
            case 'Right Hand Tip': a=23;
                break;
            case 'Head': a=3;
                break;
            case 'Left Hip': a=12;
                break;
            case 'Right Hip': a=16;
                break;
            case 'Left Knee': a=13;
                break;
            case 'Right Knee': a=17;
                break;
            case 'Neck': a=2;
                break;
            case 'Left Shoulder': a=4;
                break;
            case 'Right Shoulder': a=8;
                break;
            case 'Spine Base': a=0;
                break;
            case 'Spine Middle': a=1;
                break;
            case 'Spine Shoulder': a=20;
                break;
            case 'Left Thumb': a=22;
                break;
            case 'Right Thumb': a=24;
                break;
            case 'Left Wrist': a=6;
                break;
            case 'Right Wrist': a=10;
                break;
        }

        for(i = 0; i < 6; i++)
        {
            if(bodyID == jsonObject.bodies[i].id)
            {
                b = i;
            }
        }

        switch(coordinate){
            case 'x': return jsonObject.bodies[b].joints[a].x*xScale;
            case 'y': return jsonObject.bodies[b].joints[a].y*yScale;
            case 'z': return jsonObject.bodies[b].joints[a].z*zScale;
        }
    }

    // Register the extension
    ScratchExtensions.register('SkelScratch', descriptor, ext);
})({});<commit_msg>Revert "Revert "Rename local connection block and function""<commit_after>/*
 * Authors: Isaac Zylstra and Victor Norman @ Calvin College, Grand Rapids, MI.
 * Contact: vtn2@calvin.edu
 */

(function(ext) {

    //The variable that will hold the json to be read from
    var jsonObject = null;

    //The scale applied to the kinect data to make it map to the canvas better.
    var xScale = 240;
    var yScale = 180;
    var zScale = 200;

    //The status of the kinect
    var status = 0;

    //alert letting the user know what needs to be done before loading the extension.
    alert("BEFORE CLICKING OK: Make sure the kinect is connected and your JSON websocket server has started");

    console.log("connecting to server ..");

    // create a new websocket and connect
    window.ws = new WebSocket('ws://localhost:8181/');

    // when data is comming from the server, this method is called
    ws.onmessage = function (evt) {
        jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };

    // Cleanup function when the extension is unloaded
    ext._shutdown = function()
    {
    window.ws.close();
    };

    // Reports status of kinect
    ext._getStatus = function() {
        if(status == 0)
        {
        return {status: 0, msg: 'Kinect is not connected to Scratch'};
        }
        if(status == 1)
        {
            return {status: 1, msg: 'Kinect is connected, but is not detecting any bodies'};
        }
        if(status == 2)
        {
            return {status: 2, msg: 'Kinect is sending body data'};
        }
    };

        // Block and block menu descriptions
    var descriptor = {
        blocks: [
            ['r', '%m.b %m.j %m.c', 'joints', 'Body 1', 'Head', 'x'],
            ['r', 'Body ID %n %m.j %m.c', 'jointsID', '0', 'Head', 'x'],
            ['b', '%m.b %m.d Handstate is %m.h', 'handstate', 'Body 1', 'Left', 'Closed'],
            ['b', 'Body ID %n %m.d Handstate is %m.h', 'handstateID', '0', 'Left', 'Closed'],
            ['r', '%m.b %m.d Handstate', 'handdebug', 'Body 1', 'Left'], //Comment out of final version.
            ['r', '%m.b id', 'bodyid', 'Body 1'],
            ['b', '%m.b tracked', 'tracked', 'Body 1'],
            ['b', 'connected', 'connected'],
            ['', 'Basic body check', 'basic_body_check'], //Comment out of final version.
            ['', 'Start new local connection', 'local'],
            ['', 'connect to %s', 'ipconnect', '0.0.0.0'],
            ['', 'Close connection', 'closeconn'], //Comment out of final version.
            ['', 'console.log %n', 'write'], //Comment out of final version.
            ['', 'bad only %n', 'writeB'] //Comment out of final version.
        ],

        menus: {
	    j: ['Left Ankle', 'Right Ankle', 'Left Elbow', 'Right Elbow', 'Left Foot', 'Right Foot', 'Left Hand', 'Right Hand', 'Left Hand Tip', 'Right Hand Tip', 'Head', 'Left Hip', 'Right Hip', 'Left Knee', 'Right Knee', 'Neck', 'Left Shoulder', 'Right Shoulder', 'Spine Base', 'Spine Middle', 'Spine Shoulder', 'Left Thumb', 'Right Thumb', 'Left Wrist', 'Right Wrist'],
        b: ['Body 1', 'Body 2', 'Body 3', 'Body 4', 'Body 5', 'Body 6'],
        h: ['Unknown', 'Not Tracked', 'Open', 'Closed', 'Lasso'],
        c: ['x', 'y', 'z'],
        d: ['Left', 'Right']
    }
    };

    //restarts the local connection
    ext.local = function() {
        window.ws.close();
        console.log("connecting to local server ..");
        window.ws = new WebSocket('ws://localhost:8181/');

        // when data is comming from the server, this method is called
        ws.onmessage = function (evt) {
            jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };
    };

    //s: a string containing the ip the user wishes to connect to.
    //Creates a remote connection to s.
    ext.ipconnect = function(string) {
        window.ws.close();
        console.log("connecting to "+string+' ..');
        window.ws = new WebSocket('ws://'+string+':8181/');

        // when data is comming from the server, this method is called
        ws.onmessage = function (evt) {
            jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
        };

        // when the connection is established, this method is called
        ws.onopen = function () {
        console.log('.. connection open');
        };

        // when the connection is closed, this method is called
        ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
        };
    }

    //Closes the current connection
    ext.closeconn = function()
    {
        window.ws.close();
    }

    //m: the number to be written to the console
    //Outputs numeric content to console
    ext.write = function(number){
        console.log(number);
    };

    //m: input to be compared to 0
    //Writes "bad" in console if the input is 0
    ext.writeB = function(number){
        if(number == 0)
        {
            console.log("bad");
        }
    };

    //Checks the body 1 head x coordinate
    //Good for check if any data is getting in from the kinect
    ext.basic_body_check = function() {
        console.log(jsonObject.bodies[0].joints[3].x*xScale);
    };

    //m: the body chosen (Body 1-6)
    //Gives the id of the selected body
    ext.bodyid = function(body)
    {
        switch(body){
            case 'Body 1': return jsonObject.bodies[0].id;
            case 'Body 2': return jsonObject.bodies[1].id;
            case 'Body 3': return jsonObject.bodies[2].id;
            case 'Body 4': return jsonObject.bodies[3].id;
            case 'Body 5': return jsonObject.bodies[4].id;
            case 'Body 6': return jsonObject.bodies[5].id;
        }
    }

        //True if scratch is receiving the kinect (but not necessarily data)
    ext.connected = function()
    {
        if(status == 0){
            return false;
        }

        if(status == 1 || 2){
            return true;
        }
    };

    //m: the body chosen (Body 1-6)
    //True if scratch is receiving the chosen body data
    ext.tracked = function(body)
    {
        var i = -1;
        switch(body){
            case 'Body 1': i = 0;
                break;
            case 'Body 2': i = 1;
                break;
            case 'Body 3': i = 2;
                break;
            case 'Body 4': i = 3;
                break;
            case 'Body 5': i = 4;
                break;
            case 'Body 6': i = 5;
                break;
        }

        return jsonObject.bodies[i].id != 0;
    };

    //l: the body chosen (Body 1-6)
    //d: which handstate (left or right)
    //Outputs the left handstate of the selected body
    ext.handdebug = function(body,direction)
    {
        var i;
        switch(body){
            case 'Body 1': i=0;
                break;
            case 'Body 2': i=1;
                break;
            case 'Body 3': i=2;
                break;
            case 'Body 4': i=3;
                break;
            case 'Body 5': i=4;
                break;
            case 'Body 6': i=5;
                break;
        }

        switch(direction)
        {
            case 'Left': return jsonObject.bodies[i].lhandstate;
            case 'Right': return jsonObject.bodies[i].rhandstate;
        }
    }

    //l: The selected body (Body 1-6)
    //d: Which handstate (left or right)
    //n: The selected handstate (Unknown, Not Tracked, Open, Closed, Lasso)
    //Returns true if the selected bodies left handstate is the same as block selected one.
    ext.handstate = function(body,direction,handstate)
    {
        var i;
        var j;
        switch(body){
            case 'Body 1': i=0;
                break;
            case 'Body 2': i=1;
                break;
            case 'Body 3': i=2;
                break;
            case 'Body 4': i=3;
                break;
            case 'Body 5': i=4;
                break;
            case 'Body 6': i=5;
                break;
        }

        switch(handstate)
        {
            case 'Unknown': j = 0;
                break;
            case 'Not Tracked': j = 1;
                break;
            case 'Open': j = 2;
                break;
            case 'Closed': j = 3;
                break;
            case 'Lasso': j = 4;
                break;
        }

        switch(direction)
        {
            case 'Left': return jsonObject.bodies[i].lhandstate == j;
            case 'Right': return jsonObject.bodies[i].rhandstate == j;
        }
    }

    //l: The selected body (Body 1-6)
    //d: Which handstate (left or right)
    //n: The selected handstate (Unknown, Not Tracked, Open, Closed, Lasso)
    //Returns true if the selected bodies left handstate is the same as block selected one.
        ext.handstateID = function(bodyID,direction,handstate)
    {
        var k;
        var j;

                    switch(handstate)
        {
            case 'Unknown': k = 0;
                break;
            case 'Not Tracked': k = 1;
                break;
            case 'Open': k = 2;
                break;
            case 'Closed': k = 3;
                break;
            case 'Lasso': k = 4;
                break;
        }

        for(i = 0; i < 6; i++)
        {
            if(bodyID == jsonObject.bodies[i].id)
            {
                j = i;
            }
        }

        switch(direction)
        {
            case 'Left': return jsonObject.bodies[j].lhandstate == k;
            case 'Right': return jsonObject.bodies[j].rhandstate == k;
        }
    }

    //l: The body chosen (Body 1-6).
    //k1: The joint chosen (All joint the kinect v2 tracks).
    //x: The chosen coordinate (x, y, or z).
    //Gets the coordinate chosen from the joint chosen from the body chosen
    ext.joints = function(body,joint,coordinate)
    {
        var a = -1;
        var b = -1;

        switch(joint){
            case 'Left Ankle': a=14;
                break;
            case 'Right Ankle': a=18;
                break;
            case 'Left Elbow': a=5;
                break;
            case 'Right Elbow': a=9;
                break;
            case 'Left Foot': a=15;
                break;
            case 'Right Foot': a=19;
                break;
            case 'Left Hand': a=7;
                break;
            case 'Right Hand': a=11;
                break;
            case 'Left Hand Tip': a=21;
                break;
            case 'Right Hand Tip': a=23;
                break;
            case 'Head': a=3;
                break;
            case 'Left Hip': a=12;
                break;
            case 'Right Hip': a=16;
                break;
            case 'Left Knee': a=13;
                break;
            case 'Right Knee': a=17;
                break;
            case 'Neck': a=2;
                break;
            case 'Left Shoulder': a=4;
                break;
            case 'Right Shoulder': a=8;
                break;
            case 'Spine Base': a=0;
                break;
            case 'Spine Middle': a=1;
                break;
            case 'Spine Shoulder': a=20;
                break;
            case 'Left Thumb': a=22;
                break;
            case 'Right Thumb': a=24;
                break;
            case 'Left Wrist': a=6;
                break;
            case 'Right Wrist': a=10;
                break;
        }

        switch(body){
            case 'Body 1': b=0;
                break;
            case 'Body 2': b=1;
                break;
            case 'Body 3': b=2;
                break;
            case 'Body 4': b=3;
                break;
            case 'Body 5': b=4;
                break;
            case 'Body 6': b=5;
                break;
        }

        switch(coordinate){
            case 'x': return jsonObject.bodies[b].joints[a].x*xScale;
            case 'y': return jsonObject.bodies[b].joints[a].y*yScale;
            case 'z': return jsonObject.bodies[b].joints[a].z*zScale;
        }
    }

    //bodyID: The body chosen (Body 1-6).
    //k1: The joint chosen (All joint the kinect v2 tracks).
    //x: The chosen coordinate (x, y, or z).
    //Gets the coordinate chosen from the joint chosen from the body chosen
    ext.jointsID = function(bodyID,joint,coordinate)
    {
        var a = -1;
        var b = -1;

        switch(joint){
            case 'Left Ankle': a=14;
                break;
            case 'Right Ankle': a=18;
                break;
            case 'Left Elbow': a=5;
                break;
            case 'Right Elbow': a=9;
                break;
            case 'Left Foot': a=15;
                break;
            case 'Right Foot': a=19;
                break;
            case 'Left Hand': a=7;
                break;
            case 'Right Hand': a=11;
                break;
            case 'Left Hand Tip': a=21;
                break;
            case 'Right Hand Tip': a=23;
                break;
            case 'Head': a=3;
                break;
            case 'Left Hip': a=12;
                break;
            case 'Right Hip': a=16;
                break;
            case 'Left Knee': a=13;
                break;
            case 'Right Knee': a=17;
                break;
            case 'Neck': a=2;
                break;
            case 'Left Shoulder': a=4;
                break;
            case 'Right Shoulder': a=8;
                break;
            case 'Spine Base': a=0;
                break;
            case 'Spine Middle': a=1;
                break;
            case 'Spine Shoulder': a=20;
                break;
            case 'Left Thumb': a=22;
                break;
            case 'Right Thumb': a=24;
                break;
            case 'Left Wrist': a=6;
                break;
            case 'Right Wrist': a=10;
                break;
        }

        for(i = 0; i < 6; i++)
        {
            if(bodyID == jsonObject.bodies[i].id)
            {
                b = i;
            }
        }

        switch(coordinate){
            case 'x': return jsonObject.bodies[b].joints[a].x*xScale;
            case 'y': return jsonObject.bodies[b].joints[a].y*yScale;
            case 'z': return jsonObject.bodies[b].joints[a].z*zScale;
        }
    }

    // Register the extension
    ScratchExtensions.register('SkelScratch', descriptor, ext);
})({});<|endoftext|>


<commit_before>/* eslint-env browser */
import {getPreferredLanguages} from './Languages.js';
// Keep this as the last import for Rollup
import JsonRefs from 'json-refs/browser/json-refs-standalone-min.js';

const getCurrDir = () =>
    window.location.href.replace(/(index\.html)?#.*$/, '');

export const getMetaProp = function getMetaProp (lang, metadataObj, properties, allowObjects) {
    let prop;
    properties = typeof properties === 'string' ? [properties] : properties;
    lang.some((lan) => {
        const p = properties.slice(0);
        let strings = metadataObj['localization-strings'][lan];
        while (strings && p.length) {
            strings = strings[p.shift()];
        }
        // Todo: Fix this allowance for allowObjects (as it does not properly
        //        fallback if an object is returned from a language because
        //        that language is missing content and is only thus returning
        //        an object)
        prop = (allowObjects || typeof strings === 'string')
            ? strings
            : undefined;
        return prop;
    });
    return prop;
};

// Use the following to dynamically add specific file schema in place of
//    generic table schema if validating against files.jsonschema
//  filesSchema.properties.groups.items.properties.files.items.properties.
//      file.anyOf.splice(1, 1, {$ref: schemaFile});
// Todo: Allow use of dbs and fileGroup together in base directories?
export const getMetadata = async (file, property, basePath) => {
    try {
        return (await JsonRefs
            .resolveRefsAt(
                (basePath || getCurrDir()) + file + (property ? '#/' + property : ''),
                {
                    loaderOptions: {
                        processContent (res, callback) {
                            callback(undefined, JSON.parse( // eslint-disable-line standard/no-callback-literal
                                res.text ||
                                // `.metadata` not a recognized extension, so
                                //    convert to string for JSON in Node
                                res.body.toString()
                            ));
                        }
                    }
                }
            )).resolved;
    } catch (err) {
        throw err;
    }
};

export const getFieldNameAndValueAliases = function ({
    field, schemaItems, metadataObj, getFieldAliasOrName, lang
}) {
    const fieldSchemaIndex = schemaItems.findIndex((item) =>
        item.title === field
    );
    const fieldSchema = schemaItems[fieldSchemaIndex];

    const ret = {
        fieldName: getFieldAliasOrName(field)
    };

    const fieldInfo = metadataObj.fields[field];
    let fieldValueAliasMap = fieldInfo && fieldInfo['fieldvalue-aliases'];
    if (fieldValueAliasMap) {
        if (fieldValueAliasMap.localeKey) {
            fieldValueAliasMap = getMetaProp(
                lang,
                metadataObj,
                fieldValueAliasMap.localeKey.split('/'),
                true
            );
        }
        ret.aliases = [];
        // Todo: We could use `prefer_alias` but algorithm below may cover
        //    needed cases
        if (fieldSchema.enum && fieldSchema.enum.length) {
            fieldSchema.enum.forEach((enm) => {
                ret.aliases.push(
                    getMetaProp(lang, metadataObj, ['fieldvalue', field, enm], true)
                );
                if (enm in fieldValueAliasMap &&
                    // Todo: We could allow numbers here too, but crowds
                    //         pull-down
                    typeof fieldValueAliasMap[enm] === 'string') {
                    ret.aliases.push(...fieldValueAliasMap[enm]);
                }
            });
        } else {
            // Todo: We might iterate over all values (in case some not
            //         included in fv map)
            // Todo: Check `fieldSchema` for integer or string type
            Object.entries(fieldValueAliasMap).forEach(([key, aliases]) => {
                // We'll preserve the numbers since probably more useful if
                //   stored with data (as opposed to enums)
                if (!Array.isArray(aliases)) {
                    aliases = Object.values(aliases);
                }
                // We'll assume the longest version is best for auto-complete
                ret.aliases.push(
                    ...(
                        aliases.filter((v) =>
                            aliases.every((x) =>
                                x === v || !(
                                    x.toLowerCase().startsWith(v.toLowerCase())
                                )
                            )
                        ).map((v) => v + ' (' + key + ')')
                    )
                );
            });
        }
        ret.fieldValueAliasMap = JSON.parse(JSON.stringify(fieldValueAliasMap));
        // ret.aliases.sort();
    }
    ret.fieldSchema = fieldSchema;
    ret.fieldSchemaIndex = fieldSchemaIndex;
    ret.preferAlias = fieldInfo.prefer_alias;
    ret.lang = fieldInfo.lang;
    return ret;
};

export const getBrowseFieldData = function ({
    metadataObj, schemaItems, getFieldAliasOrName, lang, callback
}) {
    metadataObj.table.browse_fields.forEach((browseFieldSetObject, i) => {
        if (typeof browseFieldSetObject === 'string') {
            browseFieldSetObject = {set: [browseFieldSetObject]};
        }
        if (!browseFieldSetObject.name) {
            browseFieldSetObject.name = browseFieldSetObject.set.join(',');
        }

        const setName = browseFieldSetObject.name;
        const fieldSets = browseFieldSetObject.set;
        const {presort} = browseFieldSetObject;
        // Todo: Deal with ['td', [['h3', [ld(browseFieldObject.name)]]]]
        //          as kind of fieldset

        const browseFields = fieldSets.map((field) =>
            getFieldNameAndValueAliases({
                lang,
                field, schemaItems, metadataObj,
                getFieldAliasOrName
            })
        );
        callback({setName, browseFields, i, presort}); // eslint-disable-line standard/no-callback-literal
    });
};

// Todo: Incorporate other methods into this class
export class Metadata {
    constructor ({metadataObj}) {
        this.metadataObj = metadataObj;
    }

    getFieldLang (field) {
        const {metadataObj} = this;
        const fields = metadataObj && metadataObj.fields;
        return fields && fields[field] && fields[field].lang;
    }

    getFieldMatchesLocale ({
        namespace, preferredLocale, schemaItems,
        pluginsForWork
    }) {
        const {metadataObj} = this;
        return (field) => {
            const preferredLanguages = getPreferredLanguages({
                namespace, preferredLocale
            });
            if (pluginsForWork.isPluginField({namespace, field})) {
                let [, , targetLanguage] = pluginsForWork.getPluginFieldParts({namespace, field});
                if (targetLanguage === '{locale}') {
                    targetLanguage = preferredLocale;
                }
                return !targetLanguage ||
                    preferredLanguages.includes(targetLanguage);
            }
            const metaLang = this.getFieldLang(field);
            const localeStrings = metadataObj &&
                metadataObj['localization-strings'];

            // If this is a localized field (e.g., enum), we don't want
            //  to avoid as may be translated (should check though)
            const hasFieldValue = localeStrings &&
                Object.keys(localeStrings).some(lng => {
                    const fv = localeStrings[lng] &&
                        localeStrings[lng].fieldvalue;
                    return fv && fv[field];
                });

            return hasFieldValue ||
                (metaLang && preferredLanguages.includes(metaLang)) ||
                schemaItems.some(item =>
                    item.title === field && item.type !== 'string'
                );
        };
    }
};
<commit_msg>- Todo<commit_after>/* eslint-env browser */
import {getPreferredLanguages} from './Languages.js';
// Keep this as the last import for Rollup
import JsonRefs from 'json-refs/browser/json-refs-standalone-min.js';

const getCurrDir = () =>
    window.location.href.replace(/(index\.html)?#.*$/, '');

export const getMetaProp = function getMetaProp (lang, metadataObj, properties, allowObjects) {
    let prop;
    properties = typeof properties === 'string' ? [properties] : properties;
    lang.some((lan) => {
        const p = properties.slice(0);
        let strings = metadataObj['localization-strings'][lan];
        while (strings && p.length) {
            strings = strings[p.shift()];
        }
        // Todo: Fix this allowance for allowObjects (as it does not properly
        //        fallback if an object is returned from a language because
        //        that language is missing content and is only thus returning
        //        an object)
        prop = (allowObjects || typeof strings === 'string')
            ? strings
            : undefined;
        return prop;
    });
    return prop;
};

// Use the following to dynamically add specific file schema in place of
//    generic table schema if validating against files.jsonschema
//  filesSchema.properties.groups.items.properties.files.items.properties.
//      file.anyOf.splice(1, 1, {$ref: schemaFile});
// Todo: Allow use of dbs and fileGroup together in base directories?
export const getMetadata = async (file, property, basePath) => {
    try {
        return (await JsonRefs
            .resolveRefsAt(
                (basePath || getCurrDir()) + file + (property ? '#/' + property : ''),
                {
                    loaderOptions: {
                        processContent (res, callback) {
                            callback(undefined, JSON.parse( // eslint-disable-line standard/no-callback-literal
                                res.text ||
                                // `.metadata` not a recognized extension, so
                                //    convert to string for JSON in Node
                                res.body.toString()
                            ));
                        }
                    }
                }
            )).resolved;
    } catch (err) {
        throw err;
    }
};

export const getFieldNameAndValueAliases = function ({
    field, schemaItems, metadataObj, getFieldAliasOrName, lang
}) {
    const fieldSchemaIndex = schemaItems.findIndex((item) =>
        item.title === field
    );
    const fieldSchema = schemaItems[fieldSchemaIndex];

    const ret = {
        fieldName: getFieldAliasOrName(field)
    };

    const fieldInfo = metadataObj.fields[field];
    let fieldValueAliasMap = fieldInfo && fieldInfo['fieldvalue-aliases'];
    if (fieldValueAliasMap) {
        if (fieldValueAliasMap.localeKey) {
            fieldValueAliasMap = getMetaProp(
                lang,
                metadataObj,
                fieldValueAliasMap.localeKey.split('/'),
                true
            );
        }
        ret.aliases = [];
        // Todo: We could use `prefer_alias` but algorithm below may cover
        //    needed cases
        if (fieldSchema.enum && fieldSchema.enum.length) {
            fieldSchema.enum.forEach((enm) => {
                ret.aliases.push(
                    getMetaProp(lang, metadataObj, ['fieldvalue', field, enm], true)
                );
                if (enm in fieldValueAliasMap &&
                    // Todo: We could allow numbers here too, but crowds
                    //         pull-down
                    typeof fieldValueAliasMap[enm] === 'string') {
                    ret.aliases.push(...fieldValueAliasMap[enm]);
                }
            });
        } else {
            // Todo: We might iterate over all values (in case some not
            //         included in fv map)
            // Todo: Check `fieldSchema` for integer or string type
            Object.entries(fieldValueAliasMap).forEach(([key, aliases]) => {
                // We'll preserve the numbers since probably more useful if
                //   stored with data (as opposed to enums)
                if (!Array.isArray(aliases)) {
                    aliases = Object.values(aliases);
                }
                // We'll assume the longest version is best for auto-complete
                ret.aliases.push(
                    ...(
                        aliases.filter((v) =>
                            aliases.every((x) =>
                                x === v || !(
                                    x.toLowerCase().startsWith(v.toLowerCase())
                                )
                            )
                        ).map((v) => v + ' (' + key + ')') // Todo: i18nize
                    )
                );
            });
        }
        ret.fieldValueAliasMap = JSON.parse(JSON.stringify(fieldValueAliasMap));
        // ret.aliases.sort();
    }
    ret.fieldSchema = fieldSchema;
    ret.fieldSchemaIndex = fieldSchemaIndex;
    ret.preferAlias = fieldInfo.prefer_alias;
    ret.lang = fieldInfo.lang;
    return ret;
};

export const getBrowseFieldData = function ({
    metadataObj, schemaItems, getFieldAliasOrName, lang, callback
}) {
    metadataObj.table.browse_fields.forEach((browseFieldSetObject, i) => {
        if (typeof browseFieldSetObject === 'string') {
            browseFieldSetObject = {set: [browseFieldSetObject]};
        }
        if (!browseFieldSetObject.name) {
            browseFieldSetObject.name = browseFieldSetObject.set.join(',');
        }

        const setName = browseFieldSetObject.name;
        const fieldSets = browseFieldSetObject.set;
        const {presort} = browseFieldSetObject;
        // Todo: Deal with ['td', [['h3', [ld(browseFieldObject.name)]]]]
        //          as kind of fieldset

        const browseFields = fieldSets.map((field) =>
            getFieldNameAndValueAliases({
                lang,
                field, schemaItems, metadataObj,
                getFieldAliasOrName
            })
        );
        callback({setName, browseFields, i, presort}); // eslint-disable-line standard/no-callback-literal
    });
};

// Todo: Incorporate other methods into this class
export class Metadata {
    constructor ({metadataObj}) {
        this.metadataObj = metadataObj;
    }

    getFieldLang (field) {
        const {metadataObj} = this;
        const fields = metadataObj && metadataObj.fields;
        return fields && fields[field] && fields[field].lang;
    }

    getFieldMatchesLocale ({
        namespace, preferredLocale, schemaItems,
        pluginsForWork
    }) {
        const {metadataObj} = this;
        return (field) => {
            const preferredLanguages = getPreferredLanguages({
                namespace, preferredLocale
            });
            if (pluginsForWork.isPluginField({namespace, field})) {
                let [, , targetLanguage] = pluginsForWork.getPluginFieldParts({namespace, field});
                if (targetLanguage === '{locale}') {
                    targetLanguage = preferredLocale;
                }
                return !targetLanguage ||
                    preferredLanguages.includes(targetLanguage);
            }
            const metaLang = this.getFieldLang(field);
            const localeStrings = metadataObj &&
                metadataObj['localization-strings'];

            // If this is a localized field (e.g., enum), we don't want
            //  to avoid as may be translated (should check though)
            const hasFieldValue = localeStrings &&
                Object.keys(localeStrings).some(lng => {
                    const fv = localeStrings[lng] &&
                        localeStrings[lng].fieldvalue;
                    return fv && fv[field];
                });

            return hasFieldValue ||
                (metaLang && preferredLanguages.includes(metaLang)) ||
                schemaItems.some(item =>
                    item.title === field && item.type !== 'string'
                );
        };
    }
};
<|endoftext|>


<commit_before>'use strict'

import test from 'ava'

import openModal from '../reducers/open-modal'

test('open modal', t => {
  const state = [{name: "Add Summoners", open: false}, {name: "Add Location", open: false}]
  const index = 0
  const action = {type: 'OPEN_SUMMONERS_MODAL', index}
  const data = openModal(state, action)

  t.is(data[index].open, true)
})
<commit_msg>Single Quotes<commit_after>'use strict'

import test from 'ava'

import openModal from '../reducers/open-modal'

test('open modal', t => {
  const state = [{name: 'Add Summoners', open: false}, {name: 'Add Location', open: false}]
  const index = 0
  const action = {type: 'OPEN_SUMMONERS_MODAL', index}
  const data = openModal(state, action)

  t.is(data[index].open, true)
})
<|endoftext|>


<commit_before>// @flow
import 'raf/polyfill'
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import nock from 'nock'
import { api } from 'neon-js'

configure({ adapter: new Adapter() })

beforeAll(() => {
  api.setSwitchFreeze(true)
  nock.disableNetConnect()
})

afterAll(() => {
  api.setSwitchFreeze(false)
  nock.cleanAll()
})
<commit_msg>updates setupTests.js<commit_after>// @flow
import 'raf/polyfill'
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import nock from 'nock'
import { api } from 'neon-js'

configure({ adapter: new Adapter() })

beforeAll(() => {
  api.setSwitchFreeze(true)
})

afterAll(() => {
  api.setSwitchFreeze(false)
  nock.cleanAll()
})
<|endoftext|>


<commit_before>'use babel'
/** @jsx etch.dom */

import etch from 'etch'

export default class Collapser {
  constructor (props, children) {
    this.props = props
    this.children = children

    this.collapsed = false
    this.toggleCollapsed = this.toggleCollapsed.bind(this)

    etch.initialize(this)
    Collapser.instances.add(this)
  }

  update (props, children) {
    this.props = props
    this.children = children
    etch.update(this)
  }

  render () {
    const {header, ...others} = this.props
    const fullHeader = (

        {this.renderTriangle()}
        {header}

    )
    const contents = (

        {this.children}

    )

    return (

{fullHeader}{contents}

    )
  }

  renderTriangle () {
    return (

        {this.collapsed ? '\u25B6\uFE0E' : '\u25BC'}

    )
  }

  toggleCollapsed (e) {
    e.stopPropagation()
    this.collapsed = !this.collapsed
    etch.update(this)
  }

  collapse () {
    this.collapsed = true
    etch.update(this)
  }

  uncollapse () {
    this.collapsed = false
    etch.update(this)
  }

  destroy () {
    Collapser.instances.delete(this)
    etch.destroy(this)
  }
}

Collapser.instances = new Set()

Collapser.collapseAll = () => {
  Collapser.instances.forEach(c => c.collapse())
}

Collapser.uncollapseAll = () => {
  Collapser.instances.forEach(c => c.uncollapse())
}
<commit_msg>Only collapse test when clicking test title<commit_after>'use babel'
/** @jsx etch.dom */

import etch from 'etch'

export default class Collapser {
  constructor (props, children) {
    this.props = props
    this.children = children

    this.collapsed = false
    this.toggleCollapsed = this.toggleCollapsed.bind(this)

    etch.initialize(this)
    Collapser.instances.add(this)
  }

  update (props, children) {
    this.props = props
    this.children = children
    etch.update(this)
  }

  render () {
    const {header, ...others} = this.props
    const fullHeader = (

        {this.renderTriangle()}
        {header}

    )
    const contents = (

        {this.children}

    )

    return (

{fullHeader}{contents}

    )
  }

  renderTriangle () {
    return (

        {this.collapsed ? '\u25B6\uFE0E' : '\u25BC'}

    )
  }

  toggleCollapsed (e) {
    e.stopPropagation()
    this.collapsed = !this.collapsed
    etch.update(this)
  }

  collapse () {
    this.collapsed = true
    etch.update(this)
  }

  uncollapse () {
    this.collapsed = false
    etch.update(this)
  }

  destroy () {
    Collapser.instances.delete(this)
    etch.destroy(this)
  }
}

Collapser.instances = new Set()

Collapser.collapseAll = () => {
  Collapser.instances.forEach(c => c.collapse())
}

Collapser.uncollapseAll = () => {
  Collapser.instances.forEach(c => c.uncollapse())
}
<|endoftext|>


<commit_before>"use strict"
let Chart = {
  a: 'array',
  b: 'boolean',
  C: 'object-serializable',
  d: 'double',
  i: 'integer',                               // Done
  N: 'null',
  o: 'deprecated way to encode objects',
  O: 'object + class',
  r: 'reference',
  R: 'pointer reference',
  s: 'string'                                 // Done
}
let Assert = require('assert')
let Regex = {
  i: /i:(.*?);/
}
class Serialize{
  static serialize(){

  }
  static unserialize(Item){
    Assert.equal(typeof Item, 'string', "Serialize.unserialize expects parameter one to be string")
    return Serialize.__unserializeItem(Item)
  }
  static __unserializeItem(Item){
    let Type = Item.substr(0, 1)
    let Length
    let Value
    if(Type === 'i'){
      Value = Regex.i.exec(Item)
      Assert(Value, "Syntax Error")
      return {
        Index: Value.index + Value[0].length - 1, // Length is 1-based
        Value: parseInt(Value[1])
      }
    } else if(Type === 's'){
      Length = parseInt(Item.substr(2, 1))
      Assert(Length === Length, "Syntax Error") // NaN !== NaN
      Item = Item.substr(4, Length + 2)
      return {
        Index: Length + Length.toString().length + 5,
        Value: Item.substr(1, Item.length - 2).replace(/\\"/g, '"') // 2 quotes
      }
    }
    return Type
  }
}
<commit_msg>:new: Implement Boolean Parsing<commit_after>"use strict"
let Chart = {
  a: 'array',
  b: 'boolean',                               // Done
  C: 'object-serializable',
  d: 'double',
  i: 'integer',                               // Done
  N: 'null',
  o: 'deprecated way to encode objects',
  O: 'object + class',
  r: 'reference',
  R: 'pointer reference',
  s: 'string'                                 // Done
}
let Assert = require('assert')
let Regex = {
  i: /i:(.*?);/
}
class Serialize{
  static serialize(){

  }
  static unserialize(Item){
    Assert.equal(typeof Item, 'string', "Serialize.unserialize expects parameter one to be string")
    return Serialize.__unserializeItem(Item)
  }
  static __unserializeItem(Item){
    let Type = Item.substr(0, 1)
    let Length
    let Value
    if(Type === 'i'){
      Value = Regex.i.exec(Item)
      Assert(Value, "Syntax Error")
      return {
        Index: Value.index + Value[0].length - 1, // Length is 1-based
        Value: parseInt(Value[1])
      }
    } else if(Type === 's'){
      Length = parseInt(Item.substr(2, 1))
      Assert(Length === Length, "Syntax Error") // NaN !== NaN
      Item = Item.substr(4, Length + 2)
      return {
        Index: Length + Length.toString().length + 5,
        Value: Item.substr(1, Item.length - 2).replace(/\\"/g, '"') // 2 quotes
      }
    } else if(Type === 'b'){
      return {
        Value: Boolean(Item.substr(2, 1)),
        Index: 3
      }
    }
    return Type
  }
}

<|endoftext|>


<commit_before>// require external libs
import {bilibiliVideoInfoProvider,bilibiliBangumiVideoInfoProvider} from './bilibiliVideoInfoProvider';
import {sleep, parseSafe, parseTime, mySendMessage, parseXmlSafe, fetchretry, storageSet, storageGet, storageRemove, storageClear} from './utils';
import commentSenderQuery from './commentSenderQuery';
import bilibiliVideoProvider from './bilibiliVideoProvider';
import xml2ass from './xml2ass';

// shortcuts
Element.prototype.find=Element.prototype.querySelectorAll;
Element.prototype.attr=Element.prototype.getAttribute;
Element.prototype.on=Element.prototype.addEventListener;
Element.prototype.off=Element.prototype.removeEventListener;
Element.prototype.data=function(str){return this.dataset[str];};
Element.prototype.html=function(str){return str ? (this.innerHTML = str) : this.innerHTML;};
Element.prototype.hide=function(){this.style.display = 'none';};
Element.prototype.show=function(){this.style.display = '';};
Element.prototype.addClass=function(){return this.classList.add(...arguments);};
Element.prototype.removeClass=function(){return this.classList.remove(...arguments);};
Element.prototype.toggleClass=function(){return this.classList.toggle(...arguments);};
Element.prototype.hasClass=function(){return this.classList.contains(...arguments);};
Element.prototype.replaceClass=function(){return this.classList.replace(...arguments);};
NodeList.prototype.map = HTMLCollection.prototype.map = Array.prototype.map;
NodeList.prototype.filter = HTMLCollection.prototype.filter = Array.prototype.filter;
NodeList.prototype.reduce = HTMLCollection.prototype.reduce = Array.prototype.reduce;
NodeList.prototype.reduceRight = HTMLCollection.prototype.reduceRight = Array.prototype.reduceRight;
NodeList.prototype.every = HTMLCollection.prototype.every = Array.prototype.every;
NodeList.prototype.some = HTMLCollection.prototype.some = Array.prototype.some;
var _$ = document.querySelector;
var _$$ = document.querySelectorAll;

//main func
(async function() {
var mainData={};
	let url = location.href;
	let avid, page, epid, cid, videoInfo, videoLink, options;
	let _options = storageGet();
	//get video info
	switch(location.hostname){
		case 'www.bilibili.com':
			let _avid = url.match(/bilibili.com\/video\/av([0-9]+)/);
			if (!_avid) return console.log('cannot match avid');
			avid = url.match(/bilibili.com\/video\/av([0-9]+)/)[1];
			let _page = url.match(/bilibili.com\/video\/av[0-9]+\/index_([0-9]+).html/);
			page = _page ? _page[1] : 1;
			videoInfo = await bilibiliVideoInfoProvider(avid, page);
			break;
		case 'bangumi.bilibili.com':
			let hash = location.hash;
			epid = hash.length > 1 && hash.match(/^\#[0-9]+$/) && hash.substr(1);
			let _epid = url.match(/bangumi.bilibili.com\/anime\/v\/([0-9]+)/);
			if (!epid && _epid) epid = _epid[1];
			if (!epid) return console.log('cannot match epid');
			videoInfo = await bilibiliBangumiVideoInfoProvider(epid);
			avid = videoInfo.avid;
			page = Number(videoInfo.page);
			break;
		default:
			return;
	}
	cid = videoInfo.list[page-1].cid;
	if (!(avid && page && cid && videoInfo)) return console.warn('something went wrong, exiting.');
	// preload video links
	let _videoLink = bilibiliVideoProvider(cid, avid, page);
	let comment = {};
	// preload comments
	comment.url = `${location.protocol}//comment.bilibili.com/${cid}.xml`;
	comment._text = fetchretry(comment.url);
	options = await _options;
})();<commit_msg>[content] begin to add ui<commit_after>// require external libs
import {bilibiliVideoInfoProvider,bilibiliBangumiVideoInfoProvider} from './bilibiliVideoInfoProvider';
import {sleep, parseSafe, parseTime, mySendMessage, parseXmlSafe, fetchretry, storageSet, storageGet, storageRemove, storageClear} from './utils';
import commentSenderQuery from './commentSenderQuery';
import bilibiliVideoProvider from './bilibiliVideoProvider';
import xml2ass from './xml2ass';

// shortcuts
Element.prototype.find=Element.prototype.querySelectorAll;
Element.prototype.attr=Element.prototype.getAttribute;
Element.prototype.on=Element.prototype.addEventListener;
Element.prototype.off=Element.prototype.removeEventListener;
Element.prototype.data=function(str){return this.dataset[str];};
Element.prototype.text=function(){return this.innerText;};
Element.prototype.html=function(str){return str ? (this.innerHTML = str) : this.innerHTML;};
Element.prototype.hide=function(){this.style.display = 'none';};
Element.prototype.show=function(){this.style.display = '';};
Element.prototype.addClass=function(){return this.classList.add(...arguments);};
Element.prototype.removeClass=function(){return this.classList.remove(...arguments);};
Element.prototype.toggleClass=function(){return this.classList.toggle(...arguments);};
Element.prototype.hasClass=function(){return this.classList.contains(...arguments);};
Element.prototype.replaceClass=function(){return this.classList.replace(...arguments);};
NodeList.prototype.map = HTMLCollection.prototype.map = Array.prototype.map;
NodeList.prototype.filter = HTMLCollection.prototype.filter = Array.prototype.filter;
NodeList.prototype.reduce = HTMLCollection.prototype.reduce = Array.prototype.reduce;
NodeList.prototype.reduceRight = HTMLCollection.prototype.reduceRight = Array.prototype.reduceRight;
NodeList.prototype.every = HTMLCollection.prototype.every = Array.prototype.every;
NodeList.prototype.some = HTMLCollection.prototype.some = Array.prototype.some;
const _$ = e =>document.querySelector(e);
const _$$ = e => document.querySelectorAll(e);
const $h = html => {
	let elem = document.createElement('div');
	elem.outerHTML = html;
	return elem;
};

//main func
(async function() {
var mainData={};
	const url = location.href;
	let avid, page, epid, cid, videoInfo, videoLink, options, isBangumi, genPage;
	const _options = storageGet();
	//get video info
	switch(location.hostname){
		case 'www.bilibili.com':
			const _avid = url.match(/bilibili.com\/video\/av([0-9]+)/);
			if (!_avid) return console.log('cannot match avid');
			avid = url.match(/bilibili.com\/video\/av([0-9]+)/)[1];
			const _page = url.match(/bilibili.com\/video\/av[0-9]+\/index_([0-9]+).html/);
			page = _page ? _page[1] : 1;
			videoInfo = await bilibiliVideoInfoProvider(avid, page);
			break;
		case 'bangumi.bilibili.com':
			const hash = location.hash;
			epid = hash.length > 1 && hash.match(/^\#[0-9]+$/) && hash.substr(1);
			const _epid = url.match(/bangumi.bilibili.com\/anime\/v\/([0-9]+)/);
			if (!epid && _epid) epid = _epid[1];
			if (!epid) return console.log('cannot match epid');
			videoInfo = await bilibiliBangumiVideoInfoProvider(epid);
			avid = videoInfo.avid;
			page = Number(videoInfo.page);
			isBangumi = true;
			break;
		default:
			return;
	}
	cid = videoInfo.list[page-1].cid;
	if (!(avid && page && cid && videoInfo)) return console.warn('something went wrong, exiting.');
	// preload video links
	const _videoLink = bilibiliVideoProvider(cid, avid, page);
	let comment = {};
	// preload comments
	comment.url = `${location.protocol}//comment.bilibili.com/${cid}.xml`;
	comment._text = fetchretry(comment.url);
	let videoPic = _$('img.cover_image').attr('src');
	options = await _options;
	if (!_$('.b-page-body')) genPage = decodeURIComponent(__GetCookie('redirectUrl'));
	if (_$('.b-page-body .z-msg') > 0 && _$('.b-page-body .z-msg').text().indexOf('版权') > -1) genPage =1;
	let biliHelper = $h(isBangumi && !genPage ? "
哔哩哔哩助手

哔哩哔哩助手 " + options.version + "设置

" : "

助手扩展菜单

哔哩哔哩助手 " + options.version + "设置

");
	biliHelper.helperBlock.find('.t').onclick=()=>biliHelper.helperBlock.toggleClass('active');
	biliHelper.blockInfo = biliHelper.find('.info');
	biliHelper.mainBlock = biliHelper.find('.main');
	biliHelper.mainBlock.infoSection = $h('

视频信息

aid: ' + avid + 'pg: ' + page + '

');
	biliHelper.mainBlock.append(biliHelper.mainBlock.infoSection);
	biliHelper.mainBlock.ondblclick=e=>e.shiftKey && biliHelper.mainBlock.infoSection.toggleClass('hidden');
	if (genPage && genPage.match && genPage.match('http')) {
	    biliHelper.mainBlock.redirectSection = $h('

生成页选项

前往原始跳转页

');
	    biliHelper.mainBlock.append(biliHelper.mainBlock.redirectSection);
	}
	biliHelper.mainBlock.speedSection = $h('

视频播放控制

镜像视频
视频播放速度<input id="bilibili_helper_html5_video_speed" type="number" class="b-input" placeholder="1.0" value=1.0>
旋转视频<input id="bilibili_helper_html5_video_rotate" type="number" class="b-input" placeholder="0" value=0>

');
	biliHelper.mainBlock.append(biliHelper.mainBlock.speedSection);
	biliHelper.mainBlock.speedSection.input = biliHelper.mainBlock.speedSection.find('input#bilibili_helper_html5_video_speed.b-input');
	biliHelper.mainBlock.speedSection.input.step = 0.1;
	biliHelper.mainBlock.speedSection.res = biliHelper.mainBlock.speedSection.find('#bilibili_helper_html5_video_res');
	biliHelper.mainBlock.speedSection.mirror = biliHelper.mainBlock.speedSection.find('#bilibili_helper_html5_video_mirror');
	biliHelper.mainBlock.speedSection.rotate = biliHelper.mainBlock.speedSection.find('#bilibili_helper_html5_video_rotate');
	biliHelper.mainBlock.speedSection.rotate.step = 90;
	biliHelper.mainBlock.switcherSection = $h('

播放器切换

');
	biliHelper.mainBlock.switcherSection.button = $h('原始播放器原始HTML5Mac 客户端SWF 播放器Iframe 播放器HTML5 (超清)HTML5 (高清)HTML5 (低清)');
	biliHelper.mainBlock.switcherSection.button.onclick = e =>playerSwitcher[e.target.attr('type')]();
	biliHelper.mainBlock.switcherSection.find('p').append(biliHelper.mainBlock.switcherSection.button);
	if (biliHelper.redirectUrl) {
	    biliHelper.mainBlock.switcherSection.find('a[type="original"]').addClass('hidden');
	    biliHelper.mainBlock.switcherSection.find('a[type="swf"],a[type="iframe"]').removeClass('hidden');
	}
	if (localStorage.getItem('bilimac_player_type')) {
	    biliHelper.mainBlock.switcherSection.find('a[type="bilimac"]').removeClass('hidden');
	}
	biliHelper.mainBlock.append(biliHelper.mainBlock.switcherSection);
	biliHelper.mainBlock.downloaderSection = $h('

视频下载

视频地址获取中，请稍等…

');
	biliHelper.mainBlock.append(biliHelper.mainBlock.downloaderSection);
	biliHelper.mainBlock.querySection = $h('

弹幕发送者查询

正在加载全部弹幕, 请稍等…

');
	biliHelper.mainBlock.append(biliHelper.mainBlock.querySection);
	(isBangumi && !genPage ? $('.v1-bangumi-info-operate .v1-app-btn') : $('.player-wrapper .arc-toolbar')).append(biliHelper.helperBlock);

})();<|endoftext|>


<commit_before>define([
	'backbone'
],
function( Backbone ) {
    'use strict';

	/* Return a collection class definition */
	return Backbone.Collection.extend({
		url: "http://localhost:3000/spots",

		initialize: function() {
			console.log("initialize a Spots collection");
		}
	});
});
<commit_msg>As we'll consume an API that is JSON API compliant (http://jsonapi.org/), we have to get the proper key from the response.<commit_after>define([
	'backbone',
	'models/spot'
],
function( Backbone, Spot ) {
    'use strict';

	/* Return a collection class definition */
	return Backbone.Collection.extend({
		model: Spot,
		url: "http://localhost:3000/spots",

		initialize: function() {
			console.log("initialize a Spots collection");
		},

		parse: function(response) {
			return response.spots;
		}
	});
});
<|endoftext|>


<commit_before>(function () {
'use strict';
var module = angular.module('fim.base');

module.controller('GoodsCtrl', function($location, $q, $scope, modals, $routeParams, nxt, db, plugins, requests, $timeout,
  ActivityProvider, MessagesProvider, BlocksProvider, AliasProvider, NamespacedAliasProvider, AssetsProvider, CurrencyProvider, AccountProvider,
  BuyOrderProvider, SellOrderProvider, AccountPostProvider, AccountForgerProvider, AccountLessorsProvider,
  dateParser, dateFilter, accountsService, PaymentsProvider, $rootScope, serverService, shoppingCartService, GoodsProvider, GoodsPostProvider) {

		$scope.id_rs          = $routeParams.id_rs;
		$scope.paramTimestamp = 0; //nxt.util.convertToEpochTimestamp(Date.now()) + (24 * 60 * 60);
    $scope.filter         = {};

		var api = nxt.get($scope.id_rs);
		// console.log(api);

		$scope.shoppingCart = shoppingCartService.get();
		// console.log($scope.shoppingCart);

		// var getAllGoodsargs = {
		// 	requestType: 'getDGSGoods',
		// 	seller: $scope.id_rs
		// }
		// api.engine.socket().callAPIFunction(getAllGoodsargs).then(function(data) {
		// 	console.log(data);
		// 	$scope.allGoods = data.goods;
		// 	console.log($scope.allGoods.goods);
		// })

		$scope.deleteGood = function(good) {
			var deleteGoodArgs = {
				requestType: 'dgsDelisting',
				goods: good.goods
			}
        plugins.get('transaction').get('dgsDelisting').execute($scope.id_rs, deleteGoodArgs);
		}

		$scope.details = function(goodsDetails) {
			// console.log(goodsDetails);
			$location.path('/accounts/'+$scope.id_rs+'/goods/'+goodsDetails.goods+'/details');
		}

		$scope.add = function() {
			var args = {
        requestType: 'dgsListing'
      }
	    plugins.get('transaction').get('dgsListing').execute($scope.id_rs, args).then(function(addedGoods) {
        $scope.isAdded = addedGoods;
        $scope.priceNQT = nxt.util.convertToNQT(addedGoods.priceNXT);
      })
		}

	  $scope.showGoods = new GoodsProvider(api, $scope, $scope.id_rs);
  	$scope.showGoods.reload();

  	$scope.provider = new GoodsPostProvider(api, $scope, 5, $scope.id_rs);
    $scope.provider.reload();

    $scope.$watch('showGoods', function(s, data) {
      console.log("goods:", data);
    });

    //     if ($scope.showTransactionFilter) {
    //   $scope.filter.all = true;
    //   $scope.filter.payments = true;
    //   $scope.filter.messages = true;
    //   $scope.filter.aliases = true;
    //   $scope.filter.namespacedAliases = true;
    //   $scope.filter.polls = true;
    //   $scope.filter.accountInfo = true;
    //   $scope.filter.announceHub = true;
    //   $scope.filter.goodsStore = true;
    //   $scope.filter.balanceLeasing = true;
    //   $scope.filter.trades = true;
    //   $scope.filter.assetIssued = true;
    //   $scope.filter.assetTransfer = true;
    //   $scope.filter.assetOrder = true;
    //   $scope.filter.currencyIssued = true;
    //   $scope.filter.currencyTransfer = true;
    //   $scope.filter.currencyOther = true;

    //   $scope.filterAllChanged = function () {
    //     $scope.$evalAsync(function () {
    //       var on = $scope.filter.all;
    //       $scope.filter.payments = on;
    //       $scope.filter.messages = on;
    //       $scope.filter.aliases = on;
    //       $scope.filter.namespacedAliases = on;
    //       $scope.filter.polls = on;
    //       $scope.filter.accountInfo = on;
    //       $scope.filter.announceHub = on;
    //       $scope.filter.goodsStore = on;
    //       $scope.filter.balanceLeasing = on;
    //       $scope.filter.trades = on;
    //       $scope.filter.assetIssued = on;
    //       $scope.filter.assetTransfer = on;
    //       $scope.filter.assetOrder = on;
    //       $scope.filter.currencyIssued = on;
    //       $scope.filter.currencyTransfer = on;
    //       $scope.filter.currencyOther = on;

    //       $scope.filterChanged();
    //     });
    //   }

    //   $scope.filterChanged = function () {
    //     $scope.provider.applyFilter($scope.filter);
    //   }
    // }

	});
})();<commit_msg>delete Goods implemented<commit_after>(function () {
'use strict';
var module = angular.module('fim.base');

module.controller('GoodsCtrl', function($location, $q, $scope, modals, $routeParams, nxt, db, plugins, requests, $timeout,
  ActivityProvider, MessagesProvider, BlocksProvider, AliasProvider, NamespacedAliasProvider, AssetsProvider, CurrencyProvider, AccountProvider,
  BuyOrderProvider, SellOrderProvider, AccountPostProvider, AccountForgerProvider, AccountLessorsProvider,
  dateParser, dateFilter, accountsService, PaymentsProvider, $rootScope, serverService, shoppingCartService, GoodsProvider, GoodsPostProvider) {

		$scope.id_rs          = $routeParams.id_rs;
		$scope.paramTimestamp = 0; //nxt.util.convertToEpochTimestamp(Date.now()) + (24 * 60 * 60);
    $scope.filter         = {};

		var api = nxt.get($scope.id_rs);
		// console.log(api);

		$scope.shoppingCart = shoppingCartService.get();
		// console.log($scope.shoppingCart);

		// var getAllGoodsargs = {
		// 	requestType: 'getDGSGoods',
		// 	seller: $scope.id_rs
		// }
		// api.engine.socket().callAPIFunction(getAllGoodsargs).then(function(data) {
		// 	console.log(data);
		// 	$scope.allGoods = data.goods;
		// 	console.log($scope.allGoods.goods);
		// })

		$scope.deleteGood = function(good) {
			var deleteGoodArgs = {
				requestType: 'dgsDelisting',
				goods: good.goods
			}
        plugins.get('transaction').get('dgsDelisting').execute($scope.id_rs, deleteGoodArgs).then(function(deletedGood) {
          $scope.showGoods.allGoods.splice(deletedGood, 1);
        })
		}

		$scope.details = function(goodsDetails) {
			// console.log(goodsDetails);
			$location.path('/accounts/'+$scope.id_rs+'/goods/'+goodsDetails.goods+'/details');
		}

		$scope.add = function() {
			var args = {
        requestType: 'dgsListing'
      }
	    plugins.get('transaction').get('dgsListing').execute($scope.id_rs, args).then(function(addedGoods) {
        $scope.isAdded = addedGoods;
        $scope.priceNQT = nxt.util.convertToNQT(addedGoods.priceNXT);
      })
		}

	  $scope.showGoods = new GoodsProvider(api, $scope, $scope.id_rs);
  	$scope.showGoods.reload();

  	$scope.provider = new GoodsPostProvider(api, $scope, 5, $scope.id_rs);
    $scope.provider.reload();

    $scope.$watch('showGoods', function(s, data) {
      console.log("goods:", data);
    });

    //     if ($scope.showTransactionFilter) {
    //   $scope.filter.all = true;
    //   $scope.filter.payments = true;
    //   $scope.filter.messages = true;
    //   $scope.filter.aliases = true;
    //   $scope.filter.namespacedAliases = true;
    //   $scope.filter.polls = true;
    //   $scope.filter.accountInfo = true;
    //   $scope.filter.announceHub = true;
    //   $scope.filter.goodsStore = true;
    //   $scope.filter.balanceLeasing = true;
    //   $scope.filter.trades = true;
    //   $scope.filter.assetIssued = true;
    //   $scope.filter.assetTransfer = true;
    //   $scope.filter.assetOrder = true;
    //   $scope.filter.currencyIssued = true;
    //   $scope.filter.currencyTransfer = true;
    //   $scope.filter.currencyOther = true;

    //   $scope.filterAllChanged = function () {
    //     $scope.$evalAsync(function () {
    //       var on = $scope.filter.all;
    //       $scope.filter.payments = on;
    //       $scope.filter.messages = on;
    //       $scope.filter.aliases = on;
    //       $scope.filter.namespacedAliases = on;
    //       $scope.filter.polls = on;
    //       $scope.filter.accountInfo = on;
    //       $scope.filter.announceHub = on;
    //       $scope.filter.goodsStore = on;
    //       $scope.filter.balanceLeasing = on;
    //       $scope.filter.trades = on;
    //       $scope.filter.assetIssued = on;
    //       $scope.filter.assetTransfer = on;
    //       $scope.filter.assetOrder = on;
    //       $scope.filter.currencyIssued = on;
    //       $scope.filter.currencyTransfer = on;
    //       $scope.filter.currencyOther = on;

    //       $scope.filterChanged();
    //     });
    //   }

    //   $scope.filterChanged = function () {
    //     $scope.provider.applyFilter($scope.filter);
    //   }
    // }

	});
})();<|endoftext|>


<commit_before>/**
 * Prepros
 * (c) Subash Pathak
 * sbshpthk@gmail.com
 * License: MIT
 */

/*jshint browser: true, node: true*/
/*global prepros, $, angular*/

prepros.factory("compiler", function (projectsManager, fileTypes, notification, $filter, $rootScope, liveServer) {

	"use strict";

	var fs = require('fs-extra'),
        path = require('path');

	//function to compile
	function compile(fid) {

		var file = projectsManager.getFileById(fid);

        var ext =  path.extname(file.input).toLowerCase();

        //Replace file.output placeholders with real paths
        var cfg = projectsManager.getProjectConfig(file.pid);

        //Remove angular hash maps so that the change in file here won't affect files in project
        var f = $.parseJSON(angular.toJson(file));

        //Sass compiler requires project path for config.rb file
        if(ext === '.scss' || ext === '.sass') {

            f.projectPath = projectsManager.getProjectById(file.pid).path;
        }

        f.output = $filter('interpolatePath')(file.output, cfg);

        if (fs.existsSync(f.input)) {

            fileTypes.compile(f, function(data){

                $rootScope.$apply(function(){
                    notification.success('Compilation Successful', 'Successfully compiled ' + f.name, data);
                });

                if(projectsManager.getProjectById(f.pid).config.liveRefresh) {
                    liveServer.refresh(f.output);
                }

            }, function(data){

                $rootScope.$apply(function(){
                    notification.error('Compilation Failed', 'Failed to compile ' + f.name, data);
                });

            });
        }
	}

	return{
		compile      : compile
	};

});

<commit_msg>managed compile queue closes #143<commit_after>/**
 * Prepros
 * (c) Subash Pathak
 * sbshpthk@gmail.com
 * License: MIT
 */

/*jshint browser: true, node: true*/
/*global prepros, $, angular, _*/

prepros.factory("compiler", function (projectsManager, fileTypes, notification, $filter, $rootScope, liveServer) {

	"use strict";

	var fs = require('fs-extra'),
        path = require('path');

    var compileQueue = [];

	//function to compile
	function compile(fid) {

        if(!_.contains(compileQueue, fid)) {

            compileQueue.push(fid);

            var file = projectsManager.getFileById(fid);

            var ext =  path.extname(file.input).toLowerCase();

            //Replace file.output placeholders with real paths
            var cfg = projectsManager.getProjectConfig(file.pid);

            //Remove angular hash maps so that the change in file here won't affect files in project
            var f = $.parseJSON(angular.toJson(file));

            //Sass compiler requires project path for config.rb file
            if(ext === '.scss' || ext === '.sass') {

                f.projectPath = projectsManager.getProjectById(file.pid).path;
            }

            f.output = $filter('interpolatePath')(file.output, cfg);

            if (fs.existsSync(f.input)) {

                fileTypes.compile(f, function(data){

                    compileQueue = _.without(compileQueue, fid);

                    $rootScope.$apply(function(){

                        notification.success('Compilation Successful', 'Successfully compiled ' + f.name, data);

                    });

                    if(projectsManager.getProjectById(f.pid).config.liveRefresh) {
                        liveServer.refresh(f.output);
                    }

                }, function(data){

                    compileQueue = _.without(compileQueue, fid);

                    $rootScope.$apply(function(){
                        notification.error('Compilation Failed', 'Failed to compile ' + f.name, data);
                    });

                });
            }
        }
	}

	return{
		compile      : compile
	};

});

<|endoftext|>


<commit_before>function passLoginToNative() {
    // MARK: Use info from cookie for speed
    var message = {};
    var uniqueId = GetCookie('uniqueVisitorId') || guid();
    var userNameForLogin = GetCookie('USER_NAME') || GetCookie('USER_NAME_FT') || '';
    var userIdForLoginUser = GetCookie('USER_ID') || '';
    var ccode = GetCookie('ccode') || '';
    message = {
        'username': userNameForLogin,
        'userId': userIdForLoginUser,
        'uniqueVisitorId': uniqueId,
        'ccode': ccode
    };
    // MARK: Get subscription: standard/premium
    var paywall = GetCookie('paywall') || '';
    var paywallExpire = GetCookie('paywall_expire') || '';
    if (paywall !== '') {
        message.paywall = paywall;
    }
    if (paywallExpire !== '') {
        message.paywallExpire = paywallExpire;
    }
    try {
       webkit.messageHandlers.user.postMessage(message);
    } catch (ignore) {
    }
    // MARK: If the user is not logged in, no need to go on checking API
    if (userIdForLoginUser === '') {
        return;
    }
    // MARK: Valid the info with a network request
    var xhr = new XMLHttpRequest();
    xhr.open('GET', '/index.php/jsapi/paywall');
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.onload = function() {
        if (xhr.status === 200) {
            var userInfo = JSON.parse(xhr.responseText);
            window.htmlClass = document.documentElement.className;
            window.htmlClass = window.htmlClass.replace(/\ is\-subscriber/g, '').replace(/\ is\-premium/g, '').replace(/\ is\-standard/g, '');
            if (userInfo.paywall === 0) {
                if (userInfo.premium === 1) {
                    message.paywall = 'premium';
                    window.htmlClass += ' is-subscriber is-premium';
                } else {
                    message.paywall = 'standard';
                    window.htmlClass += ' is-subscriber is-standard';
                }
                message.paywallExpire = userInfo.expire || '';
                document.documentElement.className = window.htmlClass;
            } else {
                message.paywall = '';
                message.paywallExpire = '';
            }
            message.ccode = userInfo.campaign_code || '';
            message.duration = userInfo.latest_duration || '';
            message.source = userInfo.source || '';
            try {
               webkit.messageHandlers.user.postMessage(message);
            } catch (ignore) {

            }
            //var mainDomain = document.domain.replace(/^[^.]+/g, '');
            console.log ('save User expire: ' + userInfo.expire);
            SetCookie('paywall_expire',userInfo.expire,86400*100,'/');
            SetCookie('paywall',message.paywall,86400*100,'/');
            console.log ('get User expire: ' + GetCookie('paywall_expire'));
        }
    };
    xhr.send();
}

// MARK: This will throw error if not in iOS WKWebview
try {
    passLoginToNative();
} catch(ignore) {

}
<commit_msg>source for paywall<commit_after>function passLoginToNative() {
    // MARK: Use info from cookie for speed
    var message = {};
    var uniqueId = GetCookie('uniqueVisitorId') || guid();
    var userNameForLogin = GetCookie('USER_NAME') || GetCookie('USER_NAME_FT') || '';
    var userIdForLoginUser = GetCookie('USER_ID') || '';
    var paywallSource = GetCookie('paywall_source') || '';
    var ccode = GetCookie('ccode') || '';
    message = {
        username: userNameForLogin,
        userId: userIdForLoginUser,
        uniqueVisitorId: uniqueId,
        ccode: ccode,
        source: paywallSource
    };
    // MARK: Get subscription: standard/premium
    var paywall = GetCookie('paywall') || '';
    var paywallExpire = GetCookie('paywall_expire') || '';
    if (paywall !== '') {
        message.paywall = paywall;
    }
    if (paywallExpire !== '') {
        message.paywallExpire = paywallExpire;
    }
    try {
       webkit.messageHandlers.user.postMessage(message);
    } catch (ignore) {
    }
    // MARK: If the user is not logged in, no need to go on checking API
    if (userIdForLoginUser === '') {
        return;
    }
    // MARK: Valid the info with a network request
    var xhr = new XMLHttpRequest();
    xhr.open('GET', '/index.php/jsapi/paywall');
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.onload = function() {
        if (xhr.status === 200) {
            var userInfo = JSON.parse(xhr.responseText);
            window.htmlClass = document.documentElement.className;
            window.htmlClass = window.htmlClass.replace(/\ is\-subscriber/g, '').replace(/\ is\-premium/g, '').replace(/\ is\-standard/g, '');
            if (userInfo.paywall === 0) {
                if (userInfo.premium === 1) {
                    message.paywall = 'premium';
                    window.htmlClass += ' is-subscriber is-premium';
                } else {
                    message.paywall = 'standard';
                    window.htmlClass += ' is-subscriber is-standard';
                }
                message.paywallExpire = userInfo.expire || '';
                document.documentElement.className = window.htmlClass;
            } else {
                message.paywall = '';
                message.paywallExpire = '';
            }
            message.ccode = userInfo.campaign_code || '';
            message.duration = userInfo.latest_duration || '';
            message.source = userInfo.source || '';
            try {
               webkit.messageHandlers.user.postMessage(message);
            } catch (ignore) {

            }
            //var mainDomain = document.domain.replace(/^[^.]+/g, '');
            console.log ('save User expire: ' + userInfo.expire);
            SetCookie('paywall_expire',userInfo.expire,86400*100,'/');
            SetCookie('paywall',message.paywall,86400*100,'/');
            SetCookie('paywall_source',message.source,86400*100,'/');
            console.log ('get User expire: ' + GetCookie('paywall_expire'));
        }
    };
    xhr.send();
}

// MARK: This will throw error if not in iOS WKWebview
try {
    passLoginToNative();
} catch(ignore) {

}
<|endoftext|>