<commit_before>
module.exports = function () {
	var myparser = {},
        language,
        data= { name:"", type:"", comment:"", disjoinWith:[], subClassOf:[], equivalent:[], superClasses:[]};;

    myparser.set_language=function(l){

        language=l;
    }

myparser.start= function(){

}

    myparser.findClassIndex=function(id){

        var objindex=0;
        for(var i=0; i< parsed.class.length; i++){

            if (parsed.class[i].id==id)
                objindex=i;

        }
        return objindex;
}
     myparser.findPropertyIndex=function(id){

        var objindex=0;
        for(var i=0; i< parsed.property.length; i++){

            if (parsed.property[i].id==id)
                objindex=i;

        }
        return objindex;
}

    myparser.insert =function(data){

    }

    myparser.edit =function(data){

    }

    myparser.delete =function(id){

    }
    myparser.findName=function(id){
        data.name= parsed.classAttribute[myparser.findClassIndex(id)].label[language];
        if (typeof data.name=='undefined')
            data.name= parsed.classAttribute[myparser.findClassIndex(id)].label["IRI-based"];
    }
    myparser.findComment=function(id){
        data.comment=parsed.classAttribute[myparser.findClassIndex(id)].comment[language];
            if(typeof data.comment=='undefined')
                data.comment="";
    }
    myparser.findType=function(id){
        data.type= parsed.class[myparser.findClassIndex(id)].type;
    }
    myparser.findDisjointWith=function(id){
        for(var i=0; i<parsed.propertyAttribute.length;i++)
            {

                if (parsed.propertyAttribute[i].domain==id && parsed.property[i].type=="owl:disjointWith"){
                    var element={name:"", internalindex:"", id:"", equivalentTo: ""};
                    element.id= parsed.propertyAttribute[i].range;
                    element.internalindex= i;
                    element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label[language];
                    if (typeof element.name=='undefined')
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
                    element.equivalentTo=myparser.findEquivalentClasses(element.id);
                    data.disjoinWith.push(element);

                }
            }
    }
    myparser.findSubclasses=function(id){
        if (typeof parsed.classAttribute[myparser.findClassIndex(id)].subClasses != 'undefined')
            {

                for(var i=0; i<parsed.classAttribute[myparser.findClassIndex(id)].subClasses.length;i++)
                {   var element={name:"", internalindex:"", id:"", equivalentTo: ""};
                    element.id= parsed.classAttribute[myparser.findClassIndex(id)].subClasses[i];
                    element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label[language];
                    if (typeof element.name=='undefined')
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
                 element.equivalentTo=myparser.findEquivalentClasses(element.id);
                 data.subClassOf.push(element);

                }

            }
    }
    myparser.findSuperclasses=function(id){
    if (typeof parsed.classAttribute[myparser.findClassIndex(id)].superClasses != 'undefined')
            {

                for(var i=0; i<parsed.classAttribute[myparser.findClassIndex(id)].superClasses.length;i++)
                {   var element={name:"", internalindex:"", id:"", equivalentTo: ""};
                    element.id= parsed.classAttribute[myparser.findClassIndex(id)].superClasses[i];
                    element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label[language];
                    if (typeof element.name=='undefined')
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
                 element.equivalentTo=myparser.findEquivalentClasses(element.id);
                 data.superClasses.push(element);

                }

            }}
    myparser.findEquivalentClasses=function(id){
        if (typeof parsed.classAttribute[myparser.findClassIndex(id)].equivalent != 'undefined'){
             var equivalents= parsed.classAttribute[myparser.findClassIndex(id)].equivalent;
             var ind=myparser.findClassIndex(id);
             var element={name:"", internalindex:"", id:"", equivalentTo: ""};//oggetto equivalent
             for(var i=0; i<equivalents.length;i++)
                {

                        element.id= equivalents[""+i].id();
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label[language];
                        if (typeof element.name=='undefined')
                            element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
                        data.equivalent.push(element);

                }
            return element;
            }
    }
    myparser.read=function(id){
        myparser.findName(id);
        myparser.findComment(id);
        myparser.findType(id);
        myparser.findDisjointWith(id);
        myparser.findEquivalentClasses(id);
        myparser.findSubclasses(id);
        myparser.findSuperclasses(id);
        return data;
    }

return myparser;
}

       // console.log(node.id);<commit_msg>Revert "my parser modularization"<commit_after>
module.exports = function () {
	var myparser = {},
        language;

    myparser.set_language=function(l){

        language=l;
    }

myparser.start= function(){

}

    myparser.findClassIndex=function(id){

        var objindex=0;
        for(var i=0; i< parsed.class.length; i++){

            if (parsed.class[i].id==id)
                objindex=i;

        }
        return objindex;
}
     myparser.findPropertyIndex=function(id){

        var objindex=0;
        for(var i=0; i< parsed.property.length; i++){

            if (parsed.property[i].id==id)
                objindex=i;

        }
        return objindex;
}

    myparser.insert =function(data){

    }

    myparser.edit =function(data){

    }

    myparser.delete =function(id){

    }

    myparser.read=function(id){

        var index= myparser.findClassIndex(id);
        var data= { name:"", type:"", comment:"", disjoinWith:[], subClassOf:[], equivalent:[], superClasses:[]};
        //var element={name:"", internalindex:"", id:"", equivalentTo: ""};
        data.name= parsed.classAttribute[index].label[language];
        if (typeof data.name=='undefined')
<<<<<<< HEAD
            data.name= parsed.classAttribute[myparser.findClassIndex(id)].label["IRI-based"];
    }
    myparser.findComment=function(id){
        data.comment=parsed.classAttribute[myparser.findClassIndex(id)].comment[language];
=======
            data.name= parsed.classAttribute[index].label["IRI-based"];
        data.type= parsed.class[index].type;
        if (typeof parsed.classAttribute[index].comment != 'undefined'){
            data.comment=parsed.classAttribute[index].comment[language];
>>>>>>> parent of 6b3cb69... my parser modularization
            if(typeof data.comment=='undefined')
                data.comment="";
        }
        //disjoint
        for(var i=0; i<parsed.propertyAttribute.length;i++)
            {

                if (parsed.propertyAttribute[i].domain==id && parsed.property[i].type=="owl:disjointWith"){
                    var element={name:"", internalindex:"", id:"", equivalentTo: ""};
                    element.id= parsed.propertyAttribute[i].range;
                    element.internalindex= i;
                    element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label[language];
                    if (typeof element.name=='undefined')
<<<<<<< HEAD
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
                    element.equivalentTo=myparser.findEquivalentClasses(element.id);
=======
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
>>>>>>> parent of 6b3cb69... my parser modularization
                    data.disjoinWith.push(element);

                }
            }
<<<<<<< HEAD
    }
    myparser.findSubclasses=function(id){
        if (typeof parsed.classAttribute[myparser.findClassIndex(id)].subClasses != 'undefined')
=======
        //superclass
        if (typeof parsed.classAttribute[myparser.findClassIndex(id)].superClasses != 'undefined')
>>>>>>> parent of 6b3cb69... my parser modularization
            {

                for(var i=0; i<parsed.classAttribute[myparser.findClassIndex(id)].superClasses.length;i++)
                {   var element={name:"", internalindex:"", id:"", equivalentTo: ""};
                    element.id= parsed.classAttribute[myparser.findClassIndex(id)].superClasses[i];
                    element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label[language];
                    if (typeof element.name=='undefined')
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
<<<<<<< HEAD
                 element.equivalentTo=myparser.findEquivalentClasses(element.id);
                 data.subClassOf.push(element);
=======
                    data.superClasses.push(element);
>>>>>>> parent of 6b3cb69... my parser modularization

                }

            }
        //subclass
        if (typeof parsed.classAttribute[myparser.findClassIndex(id)].subClasses != 'undefined')
            {

                for(var i=0; i<parsed.classAttribute[myparser.findClassIndex(id)].subClasses.length;i++)
                {   var element={name:"", internalindex:"", id:"", equivalentTo: ""};
                    element.id= parsed.classAttribute[myparser.findClassIndex(id)].subClasses[i];
                    element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label[language];
                    if (typeof element.name=='undefined')
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
<<<<<<< HEAD
                 element.equivalentTo=myparser.findEquivalentClasses(element.id);
                 data.superClasses.push(element);
=======
                    data.subClassOf.push(element);
>>>>>>> parent of 6b3cb69... my parser modularization

                }

            }

        //equivalent --- tratta come un oggetto;
         if (typeof parsed.classAttribute[myparser.findClassIndex(id)].equivalent != 'undefined'){
             var equivalents= parsed.classAttribute[myparser.findClassIndex(id)].equivalent;
             var ind=myparser.findClassIndex(id);
<<<<<<< HEAD
             var element={name:"", internalindex:"", id:"", equivalentTo: ""};//oggetto equivalent
             for(var i=0; i<equivalents.length;i++)
                {

                        element.id= equivalents[""+i].id();
=======
            for(var i=0; i<equivalents.length;i++)
                {       var element={name:"", internalindex:"", id:"", equivalentTo: ""};//oggetto equivalent
                        element.id= equivalents[i].id();
>>>>>>> parent of 6b3cb69... my parser modularization
                        element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label[language];
                        if (typeof element.name=='undefined')
                            element.name= parsed.classAttribute[myparser.findClassIndex(element.id)].label["IRI-based"];
                        data.equivalent.push(element);

                }
            }

    return data;
    }

return myparser;
}

       // console.log(node.id);<|endoftext|>


<commit_before>'use strict';

var fetch  = require('node-fetch');
var path   = require('path');
var config = require(path.resolve('./config/config'));

exports.notifier = function (serviceName, type) {
  var notifyBChost = config.notification.host;
  var port = config.notification.port || null;
  var host = notifyBChost.match(/http/) ? notifyBChost : 'http://' + notifyBChost,
    port = port,
    serviceName = serviceName,
    type = type,
    url = port ? host + ':' + port : host;

  return {
    subscribe : function (channelId) {
      // console.log ('subscribing ',channelId, url + '/api/subscriptions/');
      // console.log (JSON.stringify({
      //       serviceName: serviceName,
      //       channel: type,
      //       userChannelId: channelId,
      //       state: 'confirmed'
      //     }));
      return fetch(url + '/api/subscriptions/', {
        method: 'post',
        body: JSON.stringify({
            serviceName: serviceName,
            channel: type,
            userChannelId: channelId,
            state: 'confirmed'
          }),
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json'}
        })
        .then(function(res) {
          return res.json();
        });
    },
    subscribeUpdate : function (subscriptionId, channelId) {
      return fetch(url + '/api/subscriptions/' + subscriptionId, {
        method: 'patch',
        body: JSON.stringify({
            userChannelId: channelId
          }),
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json'}
        })
        .then(function(res) {
          return res.json();
        });
    },
    unsubscribe : function (subscriptionId) {
      return fetch(url + '/api/subscriptions/' + subscriptionId, {
        method: 'delete',
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json'}
        })
        .then(function(res) {
          return res.json();
        });
    },
    notify : function (messageObj) {
      return fetch(url + '/api/notifications/', {
        method: 'post',
        body: JSON.stringify({
          'serviceName': serviceName,
          'message': messageObj,
          'channel': type,
          'isBroadcast': true
        }),
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      })
      .then(function(res) {
        return res.json();
      });
    }

  }
};
<commit_msg>some output for debugging<commit_after>'use strict';

var fetch  = require('node-fetch');
var path   = require('path');
var config = require(path.resolve('./config/config'));

exports.notifier = function (serviceName, type) {
  var notifyBChost = config.notification.host;
  var port = config.notification.port || null;
  var host = notifyBChost.match(/http/) ? notifyBChost : 'http://' + notifyBChost,
    port = port,
    serviceName = serviceName,
    type = type,
    url = port ? host + ':' + port : host;

  return {
    subscribe : function (channelId) {
      console.log ('subscribe ',channelId, url);
      return fetch(url + '/api/subscriptions/', {
        method: 'post',
        body: JSON.stringify({
            serviceName: serviceName,
            channel: type,
            userChannelId: channelId,
            state: 'confirmed'
          }),
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json'}
        })
        .then(function(res) {
          return res.json();
        });
    },
    subscribeUpdate : function (subscriptionId, channelId) {
      console.log ('subscribeUpdate ',subscriptionId, channelId, url);
      return fetch(url + '/api/subscriptions/' + subscriptionId, {
        method: 'patch',
        body: JSON.stringify({
            userChannelId: channelId
          }),
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json'}
        })
        .then(function(res) {
          return res.json();
        });
    },
    unsubscribe : function (subscriptionId) {
      console.log ('unsubscribe ',subscriptionId, url);
      return fetch(url + '/api/subscriptions/' + subscriptionId, {
        method: 'delete',
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json'}
        })
        .then(function(res) {
          return res.json();
        });
    },
    notify : function (messageObj) {
      console.log ('notify ',messageObj, url);
      return fetch(url + '/api/notifications/', {
        method: 'post',
        body: JSON.stringify({
          'serviceName': serviceName,
          'message': messageObj,
          'channel': type,
          'isBroadcast': true
        }),
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      })
      .then(function(res) {
        return res.json();
      });
    }

  }
};
<|endoftext|>


<commit_before>const Config                    = use("config");
const Controllers               = use('core/controllers');
const Factories                 = use('core/factories');

const OpenApi = {

    generate() {
        return Object.values(this.sections).reduce((obj, section) => {
            return Object.assign(obj, section.apply(this, arguments));
        }, {});
    },

    sections: {
        _version:    (meta) => {return {"swagger": "2.0"}},

        _info:       (meta) => {return {"info": {
                                            "title": meta.title,
                                            "description": meta.description,
                                            "version": meta.version,
                                        }
        }},
        _host:       (meta) => {return {"host": Config.server.url.replace(/https?:\/\//,"")}},
        _basePath:   (meta) => {return {"basePath": "/" + Config.router.urlPrefix.slice(0, -1)}},
        _schemes:    (meta) => {return {"schemes": ["https"]}},
        _tags:       (meta) => {return {"tags": [...Controllers.get()].map(([tag]) => {return {"name": tag}} ).sort((a,b) => a.name.toLowerCase() < b.name.toLowerCase()? -1 : 1)}},
        _definitions:(meta) => {return {"definitions": OpenApi._definitions()}},
        _paths:      (meta) => {return {"paths": OpenApi._paths()}},
        _securityDef:(meta) => {return {"securityDefinitions": {
                                                "Permission": {
                                                    "description": "Provides access to private API's",
                                                    "type": "oauth2",
                                                    "authorizationUrl": "https://dev.friskyradio.com/auth",
                                                    "flow": "implicit",
                                                    "scopes": OpenApi._permissionScopes
                                                },
                                                "Root permission": {
                                                    "description": "Provides root access to private API's",
                                                    "type": "oauth2",
                                                    "authorizationUrl": "https://dev.friskyradio.com/auth",
                                                    "flow": "implicit",
                                                    "scopes": OpenApi._permissionRootScopes
                                                }
                                            }
                                        }}
    },

    _models() {
        return [...Controllers.get()].map(([tag, route]) => {
            try {
                return Factories(tag);
            }catch(e){
                return null;
            }
        }).filter(model => model);
    },

    _definitions() {
        const models = this._models();
        return models.reduce((definition, model) => {
            definition[model.__model__.name] = {
                "type": "object",
                "xml": {
                    "name": model.__model__.name
                },
                "required": [],
                "properties": {}
            };

            Object.entries(model.__model__.prototype.scheme).forEach(([propertyName, property]) => {
                if([...property._outputModifications].some(modificatorFunction => modificatorFunction.name === "hidden")){
                    return null;
                }

                definition[model.__model__.name].properties[propertyName] = this._propertyType(property);

                if([...property._validators].some(validatorFunction => validatorFunction.name === "required")){
                    definition[model.__model__.name].required.push(propertyName);
                }
            });

            if(!definition[model.__model__.name].required.length) {
                delete definition[model.__model__.name].required;
            }

            return definition;
        }, {});
    },

    _propertyType(property) {
        const types = {
            "none": (property) => { return {
                "type": "undefined",
                "format": "undefined",
                "example": "undefined"
            }},
            "NumberProperty": (property) => { return {
                "type": "number",
                "example": property.documentationExampleValue || 42
            }},
            "StringProperty": (property) => { return {
                "type": "string",
                "example": property.documentationExampleValue || "string literal"
            }},
            "ObjectProperty": (property) => { return {
                "type": "object",
                "example": property.documentationExampleValue || {}
            }},
            "DateProperty": (property) => { return {
                "type": "string",
                "format": "Date ISO 8601",
                "example": property.documentationExampleValue || "2018-07-30T16:52:00.192Z"
            }},
            "EnumProperty": (property) => { return {
                "type": "string",
                "enum": property.valuesList,
                "example": property.documentationExampleValue || property.valuesList[0]
            }},
            "SetProperty": (property) => { return {
                "type": "array",
                "items": {
                    "type": "string",
                    "enum": property.valuesList
                },
                "example": property.documentationExampleValue || [property.valuesList[0], property.valuesList[1]]
            }},
            "ModelProperty": (property) => { return {
                "$ref": `#/definitions/${property.modelName}`
                // "example": {
                //     id: 42,
                //     link: `${property.modelName.toLowerCase()}/42`
                // }
            }}
        };

        if(types[property.constructor.name]){
            return types[property.constructor.name](property);
        } else {
            return types["none"];
        }
    },

    _paths() {
        const paths = {};

        [...Controllers.get()].forEach(([controllerName, apis]) => {
            apis.reduce((paths, route) => {
                let argIndex = 0;
                let collection = true;
                let path;

                let uri = "/" + (route.pattern.toString().split("(?:\\?")[0].replace(Config.router.urlPrefix.replace(/\//g, "\\/"), "").match(/\w+|\(\\d\+\)/g) || ["/"]).map((section, index, map)=> {
                    if(section === "(\\d+)" && index === map.length - 1) {
                        collection = false;
                    }

                    return section === "(\\d+)" ? "{" + route.arguments.required[argIndex++].name + (Config.router.primaryKeyPattern === "\\d+" ? "Id" : "Uuid") + "}" : section;
                }).join('/');

                if(!paths[uri]) {
                    paths[uri] = {};
                }
                if(paths[uri][route.method.toLowerCase()]) {
                    uri += (route.arguments.optional.length? " [? " + route.arguments.optional.map(arg => arg.name).join("=, ") + "=]" : "");
                    paths[uri] = {};
                }

                path = paths[uri][route.method.toLowerCase()] = {
                    "tags": [
                        controllerName
                    ],
                    "deprecated": !!route.annotations.deprecated,
                    "consumes": ["application/json"],
                    "produces": ["application/json"],
                    "summary": route.annotations.summary? toCapitalCase(route.annotations.summary) :
                        ({"GET": "Get", "POST": "Create", "PUT": "Update", "DELETE": "Remove", "OPTIONS": "Ping"}[route.method] + ` ${controllerName} instance`),
                    "operationId": route.method + uri + route.arguments.optional.map(arg => toCapitalCase(arg.name)).join(""),
                    "parameters": [],
                    "responses": {}
                };
                route.arguments.required.forEach(arg => {
                    path["parameters"].push({
                        "name": arg.name + (Config.router.primaryKeyPattern === "\\d+" ? "Id" : "Uuid"),
                        "in": "path",
                        "required": true,
                        "type": Config.router.primaryKeyPattern === "\\d+" ? "integer" : "uid"
                    });
                });
                route.arguments.optional.forEach(arg => {
                    path["parameters"].push({
                        "name": arg.name,
                        "in": "query",
                        "required": false,
                        "type": "string"
                    });
                });

                path["responses"]["200"] = {
                    "description": `Success`,
                };

                if (this._models().map(model => model.__model__.name).includes(controllerName)) {

                    if (route.method === "GET") {
                        path["responses"]["200"] = collection?
                            {
                                "description": `Collection of ${controllerName} instances, empty array if not found`,
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": `#/definitions/${controllerName}`
                                    }
                                }
                            }
                            :
                            {
                                "description": `Instance of ${controllerName} model`,
                                "schema": {
                                    "$ref": `#/definitions/${controllerName}`
                                }
                            };
                        if (!collection) {
                            path["responses"]["404"] = {
                                "description": `Instance of ${controllerName} model was not found.`,
                            };
                        }
                    }

                    if (route.method === "POST") {
                        path["parameters"].push({
                            "name": "model",
                            "in": "body",
                            "description": `Instance of ${controllerName} model`,
                            "required": true,
                            "schema": {
                                "$ref": `#/definitions/${controllerName}`
                            }
                        });

                        path["responses"]["201"] = {
                            "description": `Created instance of ${controllerName} model`,
                            "schema": {
                                "$ref": `#/definitions/${controllerName}`
                            }
                        };
                    }

                    if (route.method === "PUT") {
                        path["parameters"].push({
                            "name": "model",
                            "in": "body",
                            "description": `Instance of ${controllerName} model`,
                            "required": true,
                            "schema": {
                                "$ref": `#/definitions/${controllerName}`
                            }
                        });

                        path["responses"]["200"] = {
                            "description": `Updated instance of ${controllerName} model`,
                            "schema": {
                                "$ref": `#/definitions/${controllerName}`
                            }
                        };
                    }

                    if (route.method === "DELETE") {
                        path["responses"]["204"] = {
                            "description": `Instance of ${controllerName} model successfuly removed`,
                        };
                    }

                }

                if (route.permission) {
                    path["responses"]["401"] = {
                        "description": `Authorization token is missing or invalid`,
                    };
                    path["responses"]["403"] = {
                        "description": `Request is authenticated but doesn't have required permissions`,
                    };

                    path["security"] = [
                        {"Permission": [route.permission] }
                    ];

                    this._permissionScopes[route.permission] = `Permission to ${route.permission.split(".")[1]} ${route.permission.split(".")[0]}`;

                    if(route.annotations.rootownerpermissions) {
                        path["security"].push(
                            {"Root permission": [route.annotations.rootownerpermissions] }
                        );
                        this._permissionRootScopes[route.annotations.rootownerpermissions] = `Root access to ${route.annotations.rootownerpermissions.split(".")[0]}`;
                    }

                }

                if(!path["parameters"].length){
                    delete paths[uri][route.method.toLowerCase()].parameters;
                }

                return paths;
            }, paths);
        });

        console.log(paths);
        return paths;
    },

    _permissionScopes: {},
    _permissionRootScopes: {},

};

function toCapitalCase(str) {
    return str[0].toUpperCase() + str.slice(1);
}

module.exports = OpenApi;<commit_msg>Remove logging :)<commit_after>const Config                    = use("config");
const Controllers               = use('core/controllers');
const Factories                 = use('core/factories');

const OpenApi = {

    generate() {
        return Object.values(this.sections).reduce((obj, section) => {
            return Object.assign(obj, section.apply(this, arguments));
        }, {});
    },

    sections: {
        _version:    (meta) => {return {"swagger": "2.0"}},

        _info:       (meta) => {return {"info": {
                                            "title": meta.title,
                                            "description": meta.description,
                                            "version": meta.version,
                                        }
        }},
        _host:       (meta) => {return {"host": Config.server.url.replace(/https?:\/\//,"")}},
        _basePath:   (meta) => {return {"basePath": "/" + Config.router.urlPrefix.slice(0, -1)}},
        _schemes:    (meta) => {return {"schemes": ["https"]}},
        _tags:       (meta) => {return {"tags": [...Controllers.get()].map(([tag]) => {return {"name": tag}} ).sort((a,b) => a.name.toLowerCase() < b.name.toLowerCase()? -1 : 1)}},
        _definitions:(meta) => {return {"definitions": OpenApi._definitions()}},
        _paths:      (meta) => {return {"paths": OpenApi._paths()}},
        _securityDef:(meta) => {return {"securityDefinitions": {
                                                "Permission": {
                                                    "description": "Provides access to private API's",
                                                    "type": "oauth2",
                                                    "authorizationUrl": "https://dev.friskyradio.com/auth",
                                                    "flow": "implicit",
                                                    "scopes": OpenApi._permissionScopes
                                                },
                                                "Root permission": {
                                                    "description": "Provides root access to private API's",
                                                    "type": "oauth2",
                                                    "authorizationUrl": "https://dev.friskyradio.com/auth",
                                                    "flow": "implicit",
                                                    "scopes": OpenApi._permissionRootScopes
                                                }
                                            }
                                        }}
    },

    _models() {
        return [...Controllers.get()].map(([tag, route]) => {
            try {
                return Factories(tag);
            }catch(e){
                return null;
            }
        }).filter(model => model);
    },

    _definitions() {
        const models = this._models();
        return models.reduce((definition, model) => {
            definition[model.__model__.name] = {
                "type": "object",
                "xml": {
                    "name": model.__model__.name
                },
                "required": [],
                "properties": {}
            };

            Object.entries(model.__model__.prototype.scheme).forEach(([propertyName, property]) => {
                if([...property._outputModifications].some(modificatorFunction => modificatorFunction.name === "hidden")){
                    return null;
                }

                definition[model.__model__.name].properties[propertyName] = this._propertyType(property);

                if([...property._validators].some(validatorFunction => validatorFunction.name === "required")){
                    definition[model.__model__.name].required.push(propertyName);
                }
            });

            if(!definition[model.__model__.name].required.length) {
                delete definition[model.__model__.name].required;
            }

            return definition;
        }, {});
    },

    _propertyType(property) {
        const types = {
            "none": (property) => { return {
                "type": "undefined",
                "format": "undefined",
                "example": "undefined"
            }},
            "NumberProperty": (property) => { return {
                "type": "number",
                "example": property.documentationExampleValue || 42
            }},
            "StringProperty": (property) => { return {
                "type": "string",
                "example": property.documentationExampleValue || "string literal"
            }},
            "ObjectProperty": (property) => { return {
                "type": "object",
                "example": property.documentationExampleValue || {}
            }},
            "DateProperty": (property) => { return {
                "type": "string",
                "format": "Date ISO 8601",
                "example": property.documentationExampleValue || "2018-07-30T16:52:00.192Z"
            }},
            "EnumProperty": (property) => { return {
                "type": "string",
                "enum": property.valuesList,
                "example": property.documentationExampleValue || property.valuesList[0]
            }},
            "SetProperty": (property) => { return {
                "type": "array",
                "items": {
                    "type": "string",
                    "enum": property.valuesList
                },
                "example": property.documentationExampleValue || [property.valuesList[0], property.valuesList[1]]
            }},
            "ModelProperty": (property) => { return {
                "$ref": `#/definitions/${property.modelName}`
                // "example": {
                //     id: 42,
                //     link: `${property.modelName.toLowerCase()}/42`
                // }
            }}
        };

        if(types[property.constructor.name]){
            return types[property.constructor.name](property);
        } else {
            return types["none"];
        }
    },

    _paths() {
        const paths = {};

        [...Controllers.get()].forEach(([controllerName, apis]) => {
            apis.reduce((paths, route) => {
                let argIndex = 0;
                let collection = true;
                let path;

                let uri = "/" + (route.pattern.toString().split("(?:\\?")[0].replace(Config.router.urlPrefix.replace(/\//g, "\\/"), "").match(/\w+|\(\\d\+\)/g) || ["/"]).map((section, index, map)=> {
                    if(section === "(\\d+)" && index === map.length - 1) {
                        collection = false;
                    }

                    return section === "(\\d+)" ? "{" + route.arguments.required[argIndex++].name + (Config.router.primaryKeyPattern === "\\d+" ? "Id" : "Uuid") + "}" : section;
                }).join('/');

                if(!paths[uri]) {
                    paths[uri] = {};
                }
                if(paths[uri][route.method.toLowerCase()]) {
                    uri += (route.arguments.optional.length? " [? " + route.arguments.optional.map(arg => arg.name).join("=, ") + "=]" : "");
                    paths[uri] = {};
                }

                path = paths[uri][route.method.toLowerCase()] = {
                    "tags": [
                        controllerName
                    ],
                    "deprecated": !!route.annotations.deprecated,
                    "consumes": ["application/json"],
                    "produces": ["application/json"],
                    "summary": route.annotations.summary? toCapitalCase(route.annotations.summary) :
                        ({"GET": "Get", "POST": "Create", "PUT": "Update", "DELETE": "Remove", "OPTIONS": "Ping"}[route.method] + ` ${controllerName} instance`),
                    "operationId": route.method + uri + route.arguments.optional.map(arg => toCapitalCase(arg.name)).join(""),
                    "parameters": [],
                    "responses": {}
                };
                route.arguments.required.forEach(arg => {
                    path["parameters"].push({
                        "name": arg.name + (Config.router.primaryKeyPattern === "\\d+" ? "Id" : "Uuid"),
                        "in": "path",
                        "required": true,
                        "type": Config.router.primaryKeyPattern === "\\d+" ? "integer" : "uid"
                    });
                });
                route.arguments.optional.forEach(arg => {
                    path["parameters"].push({
                        "name": arg.name,
                        "in": "query",
                        "required": false,
                        "type": "string"
                    });
                });

                path["responses"]["200"] = {
                    "description": `Success`,
                };

                if (this._models().map(model => model.__model__.name).includes(controllerName)) {

                    if (route.method === "GET") {
                        path["responses"]["200"] = collection?
                            {
                                "description": `Collection of ${controllerName} instances, empty array if not found`,
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": `#/definitions/${controllerName}`
                                    }
                                }
                            }
                            :
                            {
                                "description": `Instance of ${controllerName} model`,
                                "schema": {
                                    "$ref": `#/definitions/${controllerName}`
                                }
                            };
                        if (!collection) {
                            path["responses"]["404"] = {
                                "description": `Instance of ${controllerName} model was not found.`,
                            };
                        }
                    }

                    if (route.method === "POST") {
                        path["parameters"].push({
                            "name": "model",
                            "in": "body",
                            "description": `Instance of ${controllerName} model`,
                            "required": true,
                            "schema": {
                                "$ref": `#/definitions/${controllerName}`
                            }
                        });

                        path["responses"]["201"] = {
                            "description": `Created instance of ${controllerName} model`,
                            "schema": {
                                "$ref": `#/definitions/${controllerName}`
                            }
                        };
                    }

                    if (route.method === "PUT") {
                        path["parameters"].push({
                            "name": "model",
                            "in": "body",
                            "description": `Instance of ${controllerName} model`,
                            "required": true,
                            "schema": {
                                "$ref": `#/definitions/${controllerName}`
                            }
                        });

                        path["responses"]["200"] = {
                            "description": `Updated instance of ${controllerName} model`,
                            "schema": {
                                "$ref": `#/definitions/${controllerName}`
                            }
                        };
                    }

                    if (route.method === "DELETE") {
                        path["responses"]["204"] = {
                            "description": `Instance of ${controllerName} model successfuly removed`,
                        };
                    }

                }

                if (route.permission) {
                    path["responses"]["401"] = {
                        "description": `Authorization token is missing or invalid`,
                    };
                    path["responses"]["403"] = {
                        "description": `Request is authenticated but doesn't have required permissions`,
                    };

                    path["security"] = [
                        {"Permission": [route.permission] }
                    ];

                    this._permissionScopes[route.permission] = `Permission to ${route.permission.split(".")[1]} ${route.permission.split(".")[0]}`;

                    if(route.annotations.rootownerpermissions) {
                        path["security"].push(
                            {"Root permission": [route.annotations.rootownerpermissions] }
                        );
                        this._permissionRootScopes[route.annotations.rootownerpermissions] = `Root access to ${route.annotations.rootownerpermissions.split(".")[0]}`;
                    }

                }

                if(!path["parameters"].length){
                    delete paths[uri][route.method.toLowerCase()].parameters;
                }

                return paths;
            }, paths);
        });
        return paths;
    },

    _permissionScopes: {},
    _permissionRootScopes: {},

};

function toCapitalCase(str) {
    return str[0].toUpperCase() + str.slice(1);
}

module.exports = OpenApi;<|endoftext|>


<commit_before>import WidgetsBase from './widgets.base';
import WidgetsHandle from './widgets.handle';

import {Vector3} from 'three';

/**
 * @module widgets/handle
 *
 */

export default class WidgetsRoi extends WidgetsBase {
    constructor(targetMesh, controls, camera, container) {
        super();

        this._targetMesh = targetMesh;
        this._controls = controls;
        this._camera = camera;
        this._container = container;

        this._active = true;
        this._init = false;

        this._worldPosition = new Vector3();
        if (this._targetMesh !== null) {
            this._worldPosition = this._targetMesh.position;
        }

        // mesh stuff
        this._material = null;
        this._geometry = null;
        this._mesh = null;

        // dom stuff
        this._lines = [];
        this._area = null;

        // add handles
        this._handles = [];

        // first handle
        let firstHandle = new WidgetsHandle(this._targetMesh, this._controls, this._camera, this._container);
        firstHandle.worldPosition = this._worldPosition;
        firstHandle.hovered = true;
        this.add(firstHandle);

        this._handles.push(firstHandle);

        // Create ruler
        this.create();

        this.onMove = this.onMove.bind(this);
        this.addEventListeners();

        this._orientation = null;
        this._slice = null;
    }

    addEventListeners() {
        this._container.addEventListener('mousewheel', this.onMove);
        this._container.addEventListener('DOMMouseScroll', this.onMove);
    }

    onMove(evt) {
        this._dragged = true;
        let numHandles = this._handles.length;

        if (this.active && !this._init) {
            let lastHandle = this._handles[numHandles-1];
            lastHandle.hovered = false;
            lastHandle.active = false;
            lastHandle.tracking = false;

            let nextHandle = new WidgetsHandle(this._targetMesh, this._controls, this._camera, this._container);
            nextHandle.worldPosition = this._worldPosition;
            nextHandle.hovered = true;
            nextHandle.active = true;
            nextHandle.tracking = true;
            this.add(nextHandle);

            this._handles.push(nextHandle);

            let newLine = document.createElement('div');
            newLine.setAttribute('class', 'widgets handle line');
            newLine.style.position = 'absolute';
            newLine.style.transformOrigin = '0 100%';
            newLine.style.marginTop = '-1px';
            newLine.style.height = '2px';
            newLine.style.width = '3px';
            newLine.style.backgroundColor = '#F9F9F9';

            this._lines.push(newLine);
            this._container.appendChild(newLine);
        }

        let hovered = false;

        for (let index in this._handles) {
            this._handles[index].onMove(evt);
            hovered = hovered || this._handles[index].hovered;
        }

        this._hovered = hovered;

        if (this.active && numHandles > 2) {
            this.pushPopHandle();
        }

        this.update();
    }

    onStart(evt) {
        this._dragged = false;

        let active = false;

        for (let index in this._handles) {
            this._handles[index].onStart(evt);
            active = active || this._handles[index].active;
        }

        this._active = active;
        this.update();
    }

    onEnd(evt) {
        // First Handle
        let active = false;
        for (let index in this._handles.slice(0, this._handles.length-2)) {
            this._handles[index].onEnd(evt);
            active = active || this._handles[index].active;
        }

        // Second Handle
        if (this._dragged || !this._handles[this._handles.length-1].tracking) {
            this._handles[this._handles.length-1].tracking = false;
            this._handles[this._handles.length-1].onEnd(evt);
        } else {
            this._handles[this._handles.length-1].tracking = false;
        }

        active = active || this._handles[this._handles.length-1].active;
        // State of ruler widget
        this._active = active;

        if (this._lines.length < this._handles.length) {
            let newLine = document.createElement('div');
            newLine.setAttribute('class', 'widgets handle line');
            newLine.style.position = 'absolute';
            newLine.style.transformOrigin = '0 100%';
            newLine.style.marginTop = '-1px';
            newLine.style.height = '2px';
            newLine.style.width = '3px';
            newLine.style.backgroundColor = '#F9F9F9';

            this._lines.push(newLine);
            this._container.appendChild(newLine);
        }

        this._init = true;
        this.updateMesh();
        this.update();
    }

    create() {
        this.createDOM();
    }

    hideDOM() {
        for (let index in this._handles) {
            this._handles[index].hideDOM();
        }

        for (let index in this._lines) {
            this._lines[index].style.display = 'none';
        }
    }

    showDOM() {
        for (let index in this._handles) {
            this._handles[index].showDOM();
        }

        for (let index in this._lines) {
            this._lines[index].style.display = '';
        }
    }

    hideMesh() {
        this.visible = false;
    }

    showMesh() {
        this.visible = true;
    }

    show() {
        this.showDOM();
        this.showMesh();
    }

    hide() {
        this.hideDOM();
        this.hideMesh();
    }

    update() {
        this.updateColor();

        for (let index in this._handles) {
            this._handles[index].update();
        }

        // mesh stuff
        this.updateMeshColor();
        this.updateMeshPosition();

        // DOM stuff
        this.updateDOMPosition();
        this.updateDOMColor();
    }

    updateMesh() {
        // geometry

        var points = [];
        for (let index in this._handles) {
            points.push(this._handles[index].worldPosition);
        }

        var center = AMI.SliceGeometry.centerOfMass(points);
        var side1 = new THREE.Vector3(0, 0, 0);
        var side2 = new THREE.Vector3(0, 0, 0);
        side1.subVectors(points[0], center);
        side2.subVectors(points[1], center);
        var direction = new THREE.Vector3(0, 0, 0);
        direction.crossVectors(side1, side2);

        let reference = center;
        // direction from first point to reference
        let referenceDirection = new THREE.Vector3(
            points[0].x - reference.x,
            points[0].y - reference.y,
            points[0].z - reference.z
        ).normalize();

        let base = new THREE.Vector3(0, 0, 0)
            .crossVectors(referenceDirection, direction)
            .normalize();

        let orderedpoints = [];

        // other lines // if inter, return location + angle
        for (let j = 0; j < points.length; j++) {
            let point = new THREE.Vector3(
                points[j].x,
                points[j].y,
                points[j].z);
            point.direction = new THREE.Vector3(
                points[j].x - reference.x,
                points[j].y - reference.y,
                points[j].z - reference.z).normalize();

            let x = referenceDirection.dot(point.direction);
            let y = base.dot(point.direction);
            point.xy = {x, y};

            let theta = Math.atan2(y, x) * (180 / Math.PI);
            point.angle = theta;

            orderedpoints.push(point);
        }

        let sliceShape = AMI.SliceGeometry.shape(orderedpoints);

        var shape  = new THREE.Shape(orderedpoints);

        this._geometry = new THREE.ShapeGeometry(sliceShape);

        this._geometry.vertices = orderedpoints;
        this._geometry.verticesNeedUpdate = true;
        this._geometry.elementsNeedUpdate = true;

        this._mesh = new THREE.Mesh(this._geometry, new THREE.MeshBasicMaterial({color: 0x00ff00}));

        this._mesh.visible = true;
        // add it!
        this.add(this._mesh);
    }

    updateMeshColor() {
        if (this._material) {
            this._material.color.set(this._color);
        }
    }

    updateMeshPosition() {
        if (this._geometry) {
            this._geometry.verticesNeedUpdate = true;
        }
    }

    createDOM() {
        // add line!
        this._line = document.createElement('div');
        this._line.setAttribute('class', 'widgets handle line');
        this._line.style.position = 'absolute';
        this._line.style.transformOrigin = '0 100%';
        this._line.style.marginTop = '-1px';
        this._line.style.height = '2px';
        this._line.style.width = '3px';
        this._container.appendChild(this._line);

        this.updateDOMColor();
    }

    isPointOnLine(pointA, pointB, pointToCheck) {
        let c = new Vector3();
        c.crossVectors(pointA.clone().sub(pointToCheck), pointB.clone().sub(pointToCheck));
        return !c.length();
    }

    pushPopHandle() {
        let handle0 = this._handles[this._handles.length-3];
        let handle1 = this._handles[this._handles.length-2];
        let newhandle = this._handles[this._handles.length-1];

        let isOnLine = this.isPointOnLine(handle0.worldPosition, handle1.worldPosition, newhandle.worldPosition);

        let w0 = handle0;
        let w1 = newhandle;

        var interpointdist = Math.sqrt((w0.x-w1.x)*(w0.x-w1.x) + (w0.y-w1.y)*(w0.y-w1.y) + (w0.z-w1.z)*(w0.z-w1.z));

        if (isOnLine || interpointdist < 3) {
            handle1._dom.style.display = 'none';
            this.remove(handle1);

            this._handles[this._handles.length-2] = newhandle;
            this._handles.pop();

            let tempLine = this._lines.pop();
            tempLine.style.display = 'none';
            this._container.removeChild(tempLine);
        }

        return isOnLine;
    }

    updateLineDOM(lineIndex, handle0Index, handle1Index) {
        // update rulers lines and text!
        let x1 = this._handles[handle0Index].screenPosition.x;
        let y1 = this._handles[handle0Index].screenPosition.y;
        let x2 = this._handles[handle1Index].screenPosition.x;
        let y2 = this._handles[handle1Index].screenPosition.y;

        let x0 = x2;
        let y0 = y2;

        if (y1 >= y2) {
            y0 = y2 - 30;
        } else {
            y0 = y2 + 30;
        }

        let length = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        let angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;

        let posY = y1 - this._container.offsetHeight;

        // update line
        let transform = `translate3D(${x1}px, ${posY}px, 0)`;
        transform += ` rotate(${angle}deg)`;

        this._lines[lineIndex].style.transform = transform;
        this._lines[lineIndex].style.width = length + 'px';
    }

    updateDOMPosition() {
        if (this._handles.length >= 2) {
            for (let index in this._lines) {
                this.updateLineDOM(index, index, parseInt(index) + 1 == this._handles.length ? 0 : parseInt(index) + 1);
            }
        }
    }

    updateDOMColor() {
        if (this._handles.length >= 2) {
            for (let index in this._lines) {
                this._lines[index].style.backgroundColor = `${this._color}`;
            }
        }
    }

    getPointInBetweenByPerc(pointA, pointB, percentage) {
        let dir = pointB.clone().sub(pointA);
        let len = dir.length();
        dir = dir.normalize().multiplyScalar(len*percentage);
        return pointA.clone().add(dir);
    }

    get worldPosition() {
        return this._worldPosition;
    }

    set worldPosition(worldPosition) {
        this._worldPosition = worldPosition;

        for (let index in this._handles) {
            this._handles[index]._worldPosition = this._worldPosition;
        }

        this.update();
    }
}
<commit_msg>Update widgets.roi.js<commit_after>import WidgetsBase from './widgets.base';
import WidgetsHandle from './widgets.handle';

import {Vector3} from 'three';

/**
 * @module widgets/handle
 *
 */

export default class WidgetsRoi extends WidgetsBase {
    constructor(targetMesh, controls, camera, container) {
        super();

        this._targetMesh = targetMesh;
        this._controls = controls;
        this._camera = camera;
        this._container = container;

        this._active = true;
        this._init = false;

        this._worldPosition = new Vector3();
        if (this._targetMesh !== null) {
            this._worldPosition = this._targetMesh.position;
        }

        // mesh stuff
        this._material = null;
        this._geometry = null;
        this._mesh = null;

        // dom stuff
        this._lines = [];
        this._area = null;

        // add handles
        this._handles = [];

        // first handle
        let firstHandle = new WidgetsHandle(this._targetMesh, this._controls, this._camera, this._container);
        firstHandle.worldPosition = this._worldPosition;
        firstHandle.hovered = true;
        this.add(firstHandle);

        this._handles.push(firstHandle);

        // Create ruler
        this.create();

        this.onMove = this.onMove.bind(this);
        this.addEventListeners();

        this._orientation = null;
        this._slice = null;
    }

    addEventListeners() {
        this._container.addEventListener('mousewheel', this.onMove);
        this._container.addEventListener('DOMMouseScroll', this.onMove);
    }

    onMove(evt) {
        this._dragged = true;
        let numHandles = this._handles.length;

        if (this.active && !this._init) {
            let lastHandle = this._handles[numHandles-1];
            lastHandle.hovered = false;
            lastHandle.active = false;
            lastHandle.tracking = false;

            let nextHandle = new WidgetsHandle(this._targetMesh, this._controls, this._camera, this._container);
            nextHandle.worldPosition = this._worldPosition;
            nextHandle.hovered = true;
            nextHandle.active = true;
            nextHandle.tracking = true;
            this.add(nextHandle);

            this._handles.push(nextHandle);

            let newLine = document.createElement('div');
            newLine.setAttribute('class', 'widgets handle line');
            newLine.style.position = 'absolute';
            newLine.style.transformOrigin = '0 100%';
            newLine.style.marginTop = '-1px';
            newLine.style.height = '2px';
            newLine.style.width = '3px';
            newLine.style.backgroundColor = '#F9F9F9';

            this._lines.push(newLine);
            this._container.appendChild(newLine);
        }

        let hovered = false;

        for (let index in this._handles) {
            this._handles[index].onMove(evt);
            hovered = hovered || this._handles[index].hovered;
        }

        this._hovered = hovered;

        if (this.active && numHandles > 2) {
            this.pushPopHandle();
        }

        this.update();
    }

    onStart(evt) {
        this._dragged = false;

        let active = false;

        for (let index in this._handles) {
            this._handles[index].onStart(evt);
            active = active || this._handles[index].active;
        }

        this._active = active;
        this.update();
    }

    onEnd(evt) {
        // First Handle
        let active = false;
        for (let index in this._handles.slice(0, this._handles.length-2)) {
            this._handles[index].onEnd(evt);
            active = active || this._handles[index].active;
        }

        // Second Handle
        if (this._dragged || !this._handles[this._handles.length-1].tracking) {
            this._handles[this._handles.length-1].tracking = false;
            this._handles[this._handles.length-1].onEnd(evt);
        } else {
            this._handles[this._handles.length-1].tracking = false;
        }

        active = active || this._handles[this._handles.length-1].active;
        // State of ruler widget
        this._active = active;

        if (this._lines.length < this._handles.length) {
            let newLine = document.createElement('div');
            newLine.setAttribute('class', 'widgets handle line');
            newLine.style.position = 'absolute';
            newLine.style.transformOrigin = '0 100%';
            newLine.style.marginTop = '-1px';
            newLine.style.height = '2px';
            newLine.style.width = '3px';
            newLine.style.backgroundColor = '#F9F9F9';

            this._lines.push(newLine);
            this._container.appendChild(newLine);
        }

        this._init = true;
        this.updateMesh();
        this.update();
    }

    create() {
        this.createDOM();
    }

    hideDOM() {
        for (let index in this._handles) {
            this._handles[index].hideDOM();
        }

        for (let index in this._lines) {
            this._lines[index].style.display = 'none';
        }
    }

    showDOM() {
        for (let index in this._handles) {
            this._handles[index].showDOM();
        }

        for (let index in this._lines) {
            this._lines[index].style.display = '';
        }
    }

    hideMesh() {
        this.visible = false;
    }

    showMesh() {
        this.visible = true;
    }

    show() {
        this.showDOM();
        this.showMesh();
    }

    hide() {
        this.hideDOM();
        this.hideMesh();
    }

    update() {
        this.updateColor();

        for (let index in this._handles) {
            this._handles[index].update();
        }

        // mesh stuff
        this.updateMeshColor();
        this.updateMeshPosition();

        // DOM stuff
        this.updateDOMPosition();
        this.updateDOMColor();
    }

    updateMesh() {
        // geometry

        var points = [];
        for (let index in this._handles) {
            points.push(this._handles[index].worldPosition);
        }

        var center = AMI.SliceGeometry.centerOfMass(points);
        var side1 = new THREE.Vector3(0, 0, 0);
        var side2 = new THREE.Vector3(0, 0, 0);
        side1.subVectors(points[0], center);
        side2.subVectors(points[1], center);
        var direction = new THREE.Vector3(0, 0, 0);
        direction.crossVectors(side1, side2);

        let reference = center;
        // direction from first point to reference
        let referenceDirection = new THREE.Vector3(
            points[0].x - reference.x,
            points[0].y - reference.y,
            points[0].z - reference.z
        ).normalize();

        let base = new THREE.Vector3(0, 0, 0)
            .crossVectors(referenceDirection, direction)
            .normalize();

        let orderedpoints = [];

        // other lines // if inter, return location + angle
        for (let j = 0; j < points.length; j++) {
            let point = new THREE.Vector3(
                points[j].x,
                points[j].y,
                points[j].z);
            point.direction = new THREE.Vector3(
                points[j].x - reference.x,
                points[j].y - reference.y,
                points[j].z - reference.z).normalize();

            let x = referenceDirection.dot(point.direction);
            let y = base.dot(point.direction);
            point.xy = {x, y};

            let theta = Math.atan2(y, x) * (180 / Math.PI);
            point.angle = theta;

            orderedpoints.push(point);
        }

        let sliceShape = AMI.SliceGeometry.shape(orderedpoints);

        var shape = new THREE.Shape(orderedpoints);

        this._geometry = new THREE.ShapeGeometry(sliceShape);

        this._geometry.vertices = orderedpoints;
        this._geometry.verticesNeedUpdate = true;
        this._geometry.elementsNeedUpdate = true;

        this._mesh = new THREE.Mesh(this._geometry, new THREE.MeshBasicMaterial({color: 0x00ff00}));

        this._mesh.visible = true;
        // add it!
        this.add(this._mesh);
    }

    updateMeshColor() {
        if (this._material) {
            this._material.color.set(this._color);
        }
    }

    updateMeshPosition() {
        if (this._geometry) {
            this._geometry.verticesNeedUpdate = true;
        }
    }

    createDOM() {
        // add line!
        this._line = document.createElement('div');
        this._line.setAttribute('class', 'widgets handle line');
        this._line.style.position = 'absolute';
        this._line.style.transformOrigin = '0 100%';
        this._line.style.marginTop = '-1px';
        this._line.style.height = '2px';
        this._line.style.width = '3px';
        this._container.appendChild(this._line);

        this.updateDOMColor();
    }

    isPointOnLine(pointA, pointB, pointToCheck) {
        let c = new Vector3();
        c.crossVectors(pointA.clone().sub(pointToCheck), pointB.clone().sub(pointToCheck));
        return !c.length();
    }

    pushPopHandle() {
        let handle0 = this._handles[this._handles.length-3];
        let handle1 = this._handles[this._handles.length-2];
        let newhandle = this._handles[this._handles.length-1];

        let isOnLine = this.isPointOnLine(handle0.worldPosition, handle1.worldPosition, newhandle.worldPosition);

        let w0 = handle0;
        let w1 = newhandle;

        var interpointdist = Math.sqrt((w0.x-w1.x)*(w0.x-w1.x) + (w0.y-w1.y)*(w0.y-w1.y) + (w0.z-w1.z)*(w0.z-w1.z));

        if (isOnLine || interpointdist < 3) {
            handle1._dom.style.display = 'none';
            this.remove(handle1);

            this._handles[this._handles.length-2] = newhandle;
            this._handles.pop();

            let tempLine = this._lines.pop();
            tempLine.style.display = 'none';
            this._container.removeChild(tempLine);
        }

        return isOnLine;
    }

    updateLineDOM(lineIndex, handle0Index, handle1Index) {
        // update rulers lines and text!
        let x1 = this._handles[handle0Index].screenPosition.x;
        let y1 = this._handles[handle0Index].screenPosition.y;
        let x2 = this._handles[handle1Index].screenPosition.x;
        let y2 = this._handles[handle1Index].screenPosition.y;

        let x0 = x2;
        let y0 = y2;

        if (y1 >= y2) {
            y0 = y2 - 30;
        } else {
            y0 = y2 + 30;
        }

        let length = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        let angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;

        let posY = y1 - this._container.offsetHeight;

        // update line
        let transform = `translate3D(${x1}px, ${posY}px, 0)`;
        transform += ` rotate(${angle}deg)`;

        this._lines[lineIndex].style.transform = transform;
        this._lines[lineIndex].style.width = length + 'px';
    }

    updateDOMPosition() {
        if (this._handles.length >= 2) {
            for (let index in this._lines) {
                this.updateLineDOM(index, index, parseInt(index) + 1 == this._handles.length ? 0 : parseInt(index) + 1);
            }
        }
    }

    updateDOMColor() {
        if (this._handles.length >= 2) {
            for (let index in this._lines) {
                this._lines[index].style.backgroundColor = `${this._color}`;
            }
        }
    }

    getPointInBetweenByPerc(pointA, pointB, percentage) {
        let dir = pointB.clone().sub(pointA);
        let len = dir.length();
        dir = dir.normalize().multiplyScalar(len*percentage);
        return pointA.clone().add(dir);
    }

    get worldPosition() {
        return this._worldPosition;
    }

    set worldPosition(worldPosition) {
        this._worldPosition = worldPosition;

        for (let index in this._handles) {
            this._handles[index]._worldPosition = this._worldPosition;
        }

        this.update();
    }
}
<|endoftext|>


<commit_before>odoo.define("mozaik_membership_payment.payment_form", function (require) {
    "use strict";

    var core = require("web.core");

    var _t = core._t;

    var paymentForm = require("payment.payment_form");
    paymentForm.include({
        // Warning: This is a copy of the odoo method (no way to overload it) search on ACS
        payEvent: function (ev) {
            ev.preventDefault();
            var form = this.el;
            var checked_radio = this.$('input[type="radio"]:checked');
            var self = this;
            if (ev.type === "submit") {
                var button = $(ev.target).find('*[type="submit"]')[0];
            } else {
                var button = ev.target;
            }

            // First we check that the user has selected a payment method
            if (checked_radio.length === 1) {
                checked_radio = checked_radio[0];

                // We retrieve all the input inside the acquirer form and 'serialize' them to an indexed array
                var acquirer_id = this.getAcquirerIdFromRadio(checked_radio);
                var acquirer_form = false;
                if (this.isNewPaymentRadio(checked_radio)) {
                    acquirer_form = this.$("#o_payment_add_token_acq_" + acquirer_id);
                } else {
                    acquirer_form = this.$("#o_payment_form_acq_" + acquirer_id);
                }
                var inputs_form = $("input", acquirer_form);
                var ds = $('input[name="data_set"]', acquirer_form)[0];

                // If the user is adding a new payment
                if (this.isNewPaymentRadio(checked_radio)) {
                    if (this.options.partnerId === undefined) {
                        console.warn(
                            "payment_form: unset partner_id when adding new token; things could go wrong"
                        );
                    }
                    var form_data = this.getFormData(inputs_form);
                    var wrong_input = false;

                    inputs_form.toArray().forEach(function (element) {
                        // Skip the check of non visible inputs
                        if ($(element).attr("type") == "hidden") {
                            return true;
                        }
                        $(element)
                            .closest("div.form-group")
                            .removeClass("o_has_error")
                            .find(".form-control, .custom-select")
                            .removeClass("is-invalid");
                        $(element).siblings(".o_invalid_field").remove();
                        // Force check of forms validity (useful for Firefox that refill forms automatically on f5)
                        $(element).trigger("focusout");
                        if (element.dataset.isRequired && element.value.length === 0) {
                            $(element)
                                .closest("div.form-group")
                                .addClass("o_has_error")
                                .find(".form-control, .custom-select")
                                .addClass("is-invalid");
                            $(element)
                                .closest("div.form-group")
                                .append(
                                    '
' +
                                        _.str.escapeHTML("The value is invalid.") +
                                        "
"
                                );
                            wrong_input = true;
                        } else if (
                            $(element).closest("div.form-group").hasClass("o_has_error")
                        ) {
                            wrong_input = true;
                            $(element)
                                .closest("div.form-group")
                                .append(
                                    '
' +
                                        _.str.escapeHTML("The value is invalid.") +
                                        "
"
                                );
                        }
                    });

                    if (wrong_input) {
                        return;
                    }

                    this.disableButton(button);
                    // Do the call to the route stored in the 'data_set' input of the acquirer form, the data must be called 'create-route'
                    return this._rpc({
                        route: ds.dataset.createRoute,
                        params: form_data,
                    })
                        .then(function (data) {
                            // If the server has returned true
                            if (data.result) {
                                // And it need a 3DS authentication
                                if (data["3d_secure"] !== false) {
                                    // Then we display the 3DS page to the user
                                    $("body").html(data["3d_secure"]);
                                } else {
                                    checked_radio.value = data.id; // Set the radio value to the new card id
                                    form.submit();
                                    return new Promise(function () {});
                                }
                            }
                            // If the server has returned false, we display an error
                            else if (data.error) {
                                self.displayError("", data.error);
                            } else {
                                // If the server doesn't provide an error message
                                self.displayError(
                                    _t("Server Error"),
                                    _t(
                                        "e.g. Your credit card details are wrong. Please verify."
                                    )
                                );
                            }
                            // Here we remove the 'processing' icon from the 'add a new payment' button
                            self.enableButton(button);
                        })
                        .guardedCatch(function (error) {
                            error.event.preventDefault();
                            // If the rpc fails, pretty obvious
                            self.enableButton(button);

                            self.displayError(
                                _t("Server Error"),
                                _t(
                                    "We are not able to add your payment method at the moment."
                                ) + self._parseError(error)
                            );
                        });
                }
                // If the user is going to pay with a form payment, then
                else if (this.isFormPaymentRadio(checked_radio)) {
                    this.disableButton(button);
                    var $tx_url = this.$el.find('input[name="prepare_tx_url"]');
                    // If there's a prepare tx url set
                    if ($tx_url.length === 1) {
                        // If the user wants to save his credit card info
                        var form_save_token = acquirer_form
                            .find('input[name="o_payment_form_save_token"]')
                            .prop("checked");
                        // Then we call the route to prepare the transaction
                        return this._rpc({
                            route: $tx_url[0].value,
                            params: {
                                acquirer_id: parseInt(acquirer_id),
                                save_token: form_save_token,
                                access_token: self.options.accessToken,
                                success_url: self.options.successUrl,
                                error_url: self.options.errorUrl,
                                callback_method: self.options.callbackMethod,
                                order_id: self.options.orderId,
                                invoice_id: self.options.invoiceId,
                                membership_id: self.options.membershipId, // ACS: added membership_id
                                membership_request_id: self.options.membershipRequestId, // ACS: added membership_request_id
                            },
                        })
                            .then(function (result) {
                                if (result) {
                                    // If the server sent us the html form, we create a form element
                                    var newForm = document.createElement("form");
                                    newForm.setAttribute(
                                        "method",
                                        self._get_redirect_form_method()
                                    );
                                    newForm.setAttribute(
                                        "provider",
                                        checked_radio.dataset.provider
                                    );
                                    newForm.hidden = true; // Hide it
                                    newForm.innerHTML = result; // Put the html sent by the server inside the form
                                    var action_url = $(newForm)
                                        .find('input[name="data_set"]')
                                        .data("actionUrl");
                                    newForm.setAttribute("action", action_url); // Set the action url
                                    $(document.getElementsByTagName("body")[0]).append(
                                        newForm
                                    ); // Append the form to the body
                                    $(newForm).find("input[data-remove-me]").remove(); // Remove all the input that should be removed
                                    if (action_url) {
                                        newForm.submit(); // And finally submit the form
                                        return new Promise(function () {});
                                    }
                                } else {
                                    self.displayError(
                                        _t("Server Error"),
                                        _t(
                                            "We are not able to redirect you to the payment form."
                                        )
                                    );
                                    self.enableButton(button);
                                }
                            })
                            .guardedCatch(function (error) {
                                error.event.preventDefault();
                                self.displayError(
                                    _t("Server Error"),
                                    _t(
                                        "We are not able to redirect you to the payment form."
                                    ) +
                                        " " +
                                        self._parseError(error)
                                );
                                self.enableButton(button);
                            });
                    }
                    // We append the form to the body and send it.
                    this.displayError(
                        _t("Cannot setup the payment"),
                        _t("We're unable to process your payment.")
                    );
                    self.enableButton(button);
                } else {
                    // If the user is using an old payment then we just submit the form
                    this.disableButton(button);
                    form.submit();
                    return new Promise(function () {});
                }
            } else {
                this.displayError(
                    _t("No payment method selected"),
                    _t("Please select a payment method.")
                );
                this.enableButton(button);
            }
        },
    });
});
<commit_msg>lint: disable eslint in payment_form.js<commit_after>/* eslint-disable */
odoo.define("mozaik_membership_payment.payment_form", function (require) {
    "use strict";

    var core = require("web.core");

    var _t = core._t;

    var paymentForm = require("payment.payment_form");
    paymentForm.include({
        // Warning: This is a copy of the odoo method (no way to overload it) search on ACS
        payEvent: function (ev) {
            ev.preventDefault();
            var form = this.el;
            var checked_radio = this.$('input[type="radio"]:checked');
            var self = this;
            if (ev.type === "submit") {
                var button = $(ev.target).find('*[type="submit"]')[0];
            } else {
                var button = ev.target;
            }

            // First we check that the user has selected a payment method
            if (checked_radio.length === 1) {
                checked_radio = checked_radio[0];

                // We retrieve all the input inside the acquirer form and 'serialize' them to an indexed array
                var acquirer_id = this.getAcquirerIdFromRadio(checked_radio);
                var acquirer_form = false;
                if (this.isNewPaymentRadio(checked_radio)) {
                    acquirer_form = this.$("#o_payment_add_token_acq_" + acquirer_id);
                } else {
                    acquirer_form = this.$("#o_payment_form_acq_" + acquirer_id);
                }
                var inputs_form = $("input", acquirer_form);
                var ds = $('input[name="data_set"]', acquirer_form)[0];

                // If the user is adding a new payment
                if (this.isNewPaymentRadio(checked_radio)) {
                    if (this.options.partnerId === undefined) {
                        console.warn(
                            "payment_form: unset partner_id when adding new token; things could go wrong"
                        );
                    }
                    var form_data = this.getFormData(inputs_form);
                    var wrong_input = false;

                    inputs_form.toArray().forEach(function (element) {
                        // Skip the check of non visible inputs
                        if ($(element).attr("type") == "hidden") {
                            return true;
                        }
                        $(element)
                            .closest("div.form-group")
                            .removeClass("o_has_error")
                            .find(".form-control, .custom-select")
                            .removeClass("is-invalid");
                        $(element).siblings(".o_invalid_field").remove();
                        // Force check of forms validity (useful for Firefox that refill forms automatically on f5)
                        $(element).trigger("focusout");
                        if (element.dataset.isRequired && element.value.length === 0) {
                            $(element)
                                .closest("div.form-group")
                                .addClass("o_has_error")
                                .find(".form-control, .custom-select")
                                .addClass("is-invalid");
                            $(element)
                                .closest("div.form-group")
                                .append(
                                    '
' +
                                        _.str.escapeHTML("The value is invalid.") +
                                        "
"
                                );
                            wrong_input = true;
                        } else if (
                            $(element).closest("div.form-group").hasClass("o_has_error")
                        ) {
                            wrong_input = true;
                            $(element)
                                .closest("div.form-group")
                                .append(
                                    '
' +
                                        _.str.escapeHTML("The value is invalid.") +
                                        "
"
                                );
                        }
                    });

                    if (wrong_input) {
                        return;
                    }

                    this.disableButton(button);
                    // Do the call to the route stored in the 'data_set' input of the acquirer form, the data must be called 'create-route'
                    return this._rpc({
                        route: ds.dataset.createRoute,
                        params: form_data,
                    })
                        .then(function (data) {
                            // If the server has returned true
                            if (data.result) {
                                // And it need a 3DS authentication
                                if (data["3d_secure"] !== false) {
                                    // Then we display the 3DS page to the user
                                    $("body").html(data["3d_secure"]);
                                } else {
                                    checked_radio.value = data.id; // Set the radio value to the new card id
                                    form.submit();
                                    return new Promise(function () {});
                                }
                            }
                            // If the server has returned false, we display an error
                            else if (data.error) {
                                self.displayError("", data.error);
                            } else {
                                // If the server doesn't provide an error message
                                self.displayError(
                                    _t("Server Error"),
                                    _t(
                                        "e.g. Your credit card details are wrong. Please verify."
                                    )
                                );
                            }
                            // Here we remove the 'processing' icon from the 'add a new payment' button
                            self.enableButton(button);
                        })
                        .guardedCatch(function (error) {
                            error.event.preventDefault();
                            // If the rpc fails, pretty obvious
                            self.enableButton(button);

                            self.displayError(
                                _t("Server Error"),
                                _t(
                                    "We are not able to add your payment method at the moment."
                                ) + self._parseError(error)
                            );
                        });
                }
                // If the user is going to pay with a form payment, then
                else if (this.isFormPaymentRadio(checked_radio)) {
                    this.disableButton(button);
                    var $tx_url = this.$el.find('input[name="prepare_tx_url"]');
                    // If there's a prepare tx url set
                    if ($tx_url.length === 1) {
                        // If the user wants to save his credit card info
                        var form_save_token = acquirer_form
                            .find('input[name="o_payment_form_save_token"]')
                            .prop("checked");
                        // Then we call the route to prepare the transaction
                        return this._rpc({
                            route: $tx_url[0].value,
                            params: {
                                acquirer_id: parseInt(acquirer_id),
                                save_token: form_save_token,
                                access_token: self.options.accessToken,
                                success_url: self.options.successUrl,
                                error_url: self.options.errorUrl,
                                callback_method: self.options.callbackMethod,
                                order_id: self.options.orderId,
                                invoice_id: self.options.invoiceId,
                                membership_id: self.options.membershipId, // ACS: added membership_id
                                membership_request_id: self.options.membershipRequestId, // ACS: added membership_request_id
                            },
                        })
                            .then(function (result) {
                                if (result) {
                                    // If the server sent us the html form, we create a form element
                                    var newForm = document.createElement("form");
                                    newForm.setAttribute(
                                        "method",
                                        self._get_redirect_form_method()
                                    );
                                    newForm.setAttribute(
                                        "provider",
                                        checked_radio.dataset.provider
                                    );
                                    newForm.hidden = true; // Hide it
                                    newForm.innerHTML = result; // Put the html sent by the server inside the form
                                    var action_url = $(newForm)
                                        .find('input[name="data_set"]')
                                        .data("actionUrl");
                                    newForm.setAttribute("action", action_url); // Set the action url
                                    $(document.getElementsByTagName("body")[0]).append(
                                        newForm
                                    ); // Append the form to the body
                                    $(newForm).find("input[data-remove-me]").remove(); // Remove all the input that should be removed
                                    if (action_url) {
                                        newForm.submit(); // And finally submit the form
                                        return new Promise(function () {});
                                    }
                                } else {
                                    self.displayError(
                                        _t("Server Error"),
                                        _t(
                                            "We are not able to redirect you to the payment form."
                                        )
                                    );
                                    self.enableButton(button);
                                }
                            })
                            .guardedCatch(function (error) {
                                error.event.preventDefault();
                                self.displayError(
                                    _t("Server Error"),
                                    _t(
                                        "We are not able to redirect you to the payment form."
                                    ) +
                                        " " +
                                        self._parseError(error)
                                );
                                self.enableButton(button);
                            });
                    }
                    // We append the form to the body and send it.
                    this.displayError(
                        _t("Cannot setup the payment"),
                        _t("We're unable to process your payment.")
                    );
                    self.enableButton(button);
                } else {
                    // If the user is using an old payment then we just submit the form
                    this.disableButton(button);
                    form.submit();
                    return new Promise(function () {});
                }
            } else {
                this.displayError(
                    _t("No payment method selected"),
                    _t("Please select a payment method.")
                );
                this.enableButton(button);
            }
        },
    });
});
<|endoftext|>


<commit_before>//Nightclub by SilverTactic (Siiilver) and panpawn
if (!global.nightclubs) global.nightclubs = {};
var nightclubs = global.nightclubs;

function getColor () {
	var color = '#';
	for (var i = 0; i < 6; i++) {
		color += 'ABCDE'[Math.floor(Math.random() * 5)];
	}
	return color;
}

function colorify (message) {
	var total = '';
	for (var i = 0; i < message.length; i++) {
		if (message[i] === ' ') {
			total += ' ';
			continue;
		}
		total += '' + message[i] + '';
	}
	return total;
}

function formatHTML (message) {
	var escapes = ['&', '<', '>', '>', '"', ''', '/'];
	if (!message) return '';
	var total = '';
	for (var i = 0; i < message.length; i++) {
		if (message[i] === '&') {
			var sub = message.substr(i);
			var part = sub.substr(0, sub.indexOf(';') + 1);
			if (escapes.indexOf(part) > -1) {
				i += part.length - 1;
				total += '' + part + '';
				continue;
			}
		}
		if (message[i] == '<') {
			var sub = message.substr(i).match(/<(span|b|a|i|code|s)[^]+<\/(span|b|a|i|code|s)>/);
			if (sub) {
				if (/<(a|b|i|s)>/.test(sub[0].substr(0, 3))) {
					total += sub[0].substr(0, 3) + colorify(sub[0].substr(3, sub[0].length - 7)) + sub[0].substr(sub[0].length - 4);
				} else total += sub[0];
				i += sub[0].length - 1;
				continue;
			}
		}
		total += '' + message[i].escapeHTML() + '';
	}
	return total;
}

function formatMessage (message) {
	message = message.replace(/\_\_([^ ](?:[^]*?[^ ])?)\_\_(?![^]*?<\/a)/g, '$1') //italics
		.replace(/\*\*([^ ](?:[^]*?[^ ])?)\*\*/g, '$1') //bold
		.replace(/\~\~([^ ](?:[^]*?[^ ])?)\~\~/g, '<s>$1</s>') //strikethrough
		.replace(/\`\`([^ ](?:[^]*?[^ ])?)\`\`/g, '$1') //code
		//urls
		.replace(/(https?\:\/\/[a-z0-9-.]+(\/([^\s]*[^\s?.,])?)?|[a-z0-9]([a-z0-9-\.]*[a-z0-9])?\.(com|org|net|edu|tk|us)((\/([^\s]*[^\s?.,])?)?|\b))/ig, '$1')
		.replace(/<a href="([a-z]*[^a-z:])/g, '<a href="http://$1')
		.replace(/(\bgoogle ?\[([^\]<]+)\])/ig, '$1')
		.replace(/(\bgl ?\[([^\]<]+)\])/ig, '$1')
		.replace(/(\bwiki ?\[([^\]<]+)\])/ig, '$1')
		.replace(/\[\[([^< ]([^<`]*?[^< ])?)\]\]/ig, '$1')
		.replace(/spoiler:([^]+)/i, 'spoiler: $1');
	return formatHTML(message);
}

function nightclubify (message) {
	var rank = '', rankIndex = (toId(message[0]) ? 0 : 1);
	if (rankIndex) rank = message[0];
	var user = message.substring(rankIndex, (~message.indexOf('|') ? message.indexOf('|') : message.length));
	if (!toId(user)) return '|c:|' + (~~(Date.now() / 1000)) + '|' + message;
	message = (~message.indexOf('|') ? message.substring(message.indexOf('|') + 1) : '');
	return '|raw|
' +
		'' + rank + '' +
		'<button name = "parseCommand" value = "/user ' + user + '" style = "outline: none; cursor: pointer; font-size: inherit; text-shadow: inherit; font-family: inherit; background: none; padding: 0px; border: none; display: inline-block; color: ' + Gold.hashColor(toId(user)) + ';">' + user + ':</button>' +
		' ' + formatMessage(Tools.escapeHTML(message)) + '
';
}

Rooms.Room.prototype.add = function (message) {
	if (typeof message !== 'string') throw new Error("Deprecated message type");
	this.logEntry(message);
	if (this.logTimes && message.substr(0, 3) === '|c|') {
		if (nightclubs[this.id]) message = nightclubify(message.substr(3));
		else message = '|c:|' + (~~(Date.now() / 1000)) + '|' + message.substr(3);
	} else if (nightclubs[this.id]) {
		var style = '|raw|
';
		if (message.match(/^\|html\||^\|raw\|/m) && !message.match(/\|\~\|/m)) {
			message = style + message.replace(/^\|html\||^\|raw\|/m, '') + '
';
		}
		else if (!message.match(/^\|[a-z]+\|/) && !message.match(/^\|\|/)) message = style + message + '
';
	}
	this.log.push(message);
	return this;
};

Users.Connection.prototype.sendTo = function (roomid, data) {
	if (roomid && nightclubs[roomid.id]) {
		var style = '|html|
';
		if (data.match(/^\|html\||^\|raw\|/m) && !data.match(/\|\~\|/m)) {
			if (data.split('\n').length > 1) {
				style = '|html|
';
				var parts = data.split('\n');
				if (parts[parts.length - 1].match(/^\|html\||^\|raw\|/m)) parts[parts.length - 1] = style + parts[parts.length - 1].replace(/^\|html\||^\|raw\|/m, '') + '
';
				data = parts.join('\n');
			} else data = style + data.replace(/^\|html\||^\|raw\|/m, '') + '
';
		}
		else if (!data.match(/^\|[a-z]+\|/) && !data.match(/^\|\|/)) data = style + data + '
';
	}
	if (roomid && roomid.id) roomid = roomid.id;
	if (roomid && roomid !== 'lobby') data = '>' + roomid + '\n' + data;
	Sockets.socketSend(this.worker, this.socketid, data);
	Monitor.countNetworkUse(data.length);
};
var cmds = {
	'': function (target, room, user) {
		if (nightclubs[room.id]) return this.parse('/nightclub off');
		this.parse('/nightclub on');
	},
	on: function (target, room, user) {
		if (!this.can('declare', null, room)) return this.sendReply('You must be ranked % or higher to toggle this room\'s nightclub mode.');
		if (nightclubs[room.id]) return this.sendReply('This room\'s already in nightclub mode!');

		this.privateModCommand("(" + user.name + " has turned nightclub mode on in this room.)");
		nightclubs[room.id] = true;
		room.add('' + colorify('LET\'S GET FITZY! NIGHTCLUB MODE: ON!') + '');
	},
	off: function (target, room, user) {
		if (!this.can('declare', null, room)) return this.sendReply('You must be ranked % or higher to toggle this room\'s nightclub mode.');
		if (!nightclubs[room.id]) return this.sendReply('This room isn\'t in nightclub mode yet...');

		this.privateModCommand("(" + user.name + " has turned nightclub mode off in this room.)");
		room.add('' + colorify('Sizzle down now... Nightclub mode: OFF!') + '');
		delete nightclubs[room.id];
	}
};
exports.commands = {
	nc: 'nightclub',
	nightclub: cmds,
	dayclub: cmds.off
};
<commit_msg>Delete nightclub.js<commit_after><|endoftext|>