<commit_before>// A function that builds the __new__ method for the factory function
__BRYTHON__.$__new__ = function(factory){
    return function(cls){
        /*
        if(cls===undefined){
            throw __BRYTHON__.builtins.TypeError(factory.$dict.__name__+'.__new__(): not enough arguments')
        }
        */
        var res = factory.apply(null,[])
        res.__class__ = cls.$dict
        var init_func = null
        try{init_func = __BRYTHON__.builtins.getattr(res,'__init__')}
        catch(err){}
        if(init_func!==null){
            var args = [], pos=0
            for(var i=1, _len_i = arguments.length; i < _len_i;i++){args[pos++]=arguments[i]}
            init_func.apply(null,args)
            res.__initialized__ = true
        }
        return res
    }
}

__BRYTHON__.builtins.object = (function($B){

var _b_=$B.builtins

// class object for the built-in class 'object'
var $ObjectDict = {
    //__class__:$type, : not here, added in py_type.js after $type is defined
    // __bases__ : set to an empty tuple in py_list.js after tuple is defined
    __name__:'object',
    $native:true
}

// Function for comparison operators
// In a<b, if b defines __gt__, use b.__gt__(a)
var reverse_func = {'__lt__':'__gt__',
    '__gt__':'__lt__',
    '__le__': '__ge__',
    '__ge__': '__le__'
}
var $ObjectNI = function(name,op){
    return function(self, other){
        var klass = $B.get_class(other),
            other_comp = _b_.getattr(klass, reverse_func[name])
        if(other_comp.__func__===$ObjectDict[reverse_func[name]]){
            throw _b_.TypeError('unorderable types: object() '+op+
                ' '+ _b_.str($B.get_class(other).__name__)+'()')
        }else{
            return other_comp(other, self)
        }
    }
}

// Name of special methods : if they are not found as attributes, try
// the "reflected" attribute on the argument
// For instance, for "getattr(x,'__mul__')", if object x has no attribute
// "__mul__", try a function using the attribute "__rmul__" of its
// first argument

var opnames = ['add','sub','mul','truediv','floordiv','mod','pow',
    'lshift','rshift','and','xor','or']
var opsigns = ['+','-','*','/','//','%','**','<<','>>','&','^', '|']

$ObjectDict.__delattr__ = function(self,attr){
    _b_.getattr(self, attr) // raises AttributeError if necessary
    delete self[attr];
    return _b_.None
}

$ObjectDict.__dir__ = function(self) {
    var objects = [self],
        pos=1,
        klass = self.__class__ || $B.get_class(self)
    objects[pos++] = klass
    var mro = klass.__mro__
    for (var i=0, _len_i = mro.length; i < _len_i; i++) {
        objects[pos++]=mro[i]
    }

    var res = [], pos=0
    for (var i=0, _len_i = objects.length; i < _len_i; i++) {
        for(var attr in objects[i]){
            //if(attr.charAt(0)=='$' && attr.substr(0,2)!=='$$'){
            if(attr.charAt(0)=='$' && attr.charAt(1) != '$') {
                // exclude internal attributes set by Brython
                continue
            }
            if(!isNaN(parseInt(attr.charAt(0)))){
                // Exclude numerical attributes
                // '0', '1' are in attributes of string 'ab'
                continue
            }
            if(attr=='__mro__'){continue}
            res[pos++]=attr
        }
    }
    res = _b_.list(_b_.set(res))
    _b_.list.$dict.sort(res)
    return res
}

$ObjectDict.__eq__ = function(self,other){
    // equality test defaults to identity of objects
    //test_issue_1393
    var _class=$B.get_class(self)
    if (_class.$native || _class.__name__ == 'function') {
       var _class1=$B.get_class(other)
       if (!_class1.$native && _class1.__name__ != 'function') {
          return _b_.getattr(other, '__eq__')(self)
       }
    }
    return self===other
}

$ObjectDict.__format__ = function(){
    var $ = $B.args('__format__', 2, {self:null, spec:null},
        ['self', 'spec'], arguments, {}, null, null)
    if($.spec!==''){throw _b_.TypeError("non-empty format string passed to object.__format__")}
    return _b_.getattr($.self, '__repr__')()
}

$ObjectDict.__ge__ = $ObjectNI('__ge__','>=')

$ObjectDict.__getattribute__ = function(obj,attr){

    var klass = obj.__class__ || $B.get_class(obj)
    if(attr==='__class__'){
        return klass.$factory
    }
    var res = obj[attr]

    if(res===undefined){
        // search in classes hierarchy, following method resolution order
        function check(obj, kl, attr){
            if(kl.$methods){
                var method = kl.$methods[attr]
                if(method!==undefined){
                    return method(obj)
                }
            }
            var v=kl[attr]
            if(v!==undefined){
                return v
            }else if(attr=='__str__' && kl['__repr__']!==undefined){
                // If the class doesn't define __str__ but defines __repr__,
                // use __repr__
                return kl['__repr__']
            }
        }
        res = check(obj, klass, attr)
        if(res===undefined){
            var mro = klass.__mro__
            for(var i=0, _len_i = mro.length; i < _len_i;i++){
                res = check(obj, mro[i], attr)
                if(res!==undefined){break}
            }
        }
    }else{
        if(res.__set__===undefined){
            // For non-data descriptors, the attribute found in object
            // dictionary takes precedence
            return res
        }
    }

    if(res!==undefined){

        if(res.__class__===_b_.property.$dict){
            return res.__get__(res, obj, klass)
        }

        var get = res.__get__
        if(get===undefined && res.__class__){
            var get = res.__class__.__get__
            for(var i=0;i<res.__class__.__mro__.length && get===undefined; i++){
                get = res.__class__.__mro__[i].__get__
            }
        }
        var __get__ = get === undefined ? null : _b_.getattr(res,'__get__',null)

        // For descriptors, attribute resolution is done by applying __get__
        if(__get__!==null){
            try{return __get__.apply(null, [obj, klass])}
            catch(err){
                console.log('error in get.apply', err)
                console.log(__get__+'')
                throw err
            }
        }

        if(typeof res=='object'){
            if(__get__ && (typeof __get__=='function')){
                get_func = function(x,y){return __get__.apply(x,[y,klass])}
            }
        }

        if(__get__===null && (typeof res=='function')){
            __get__ = function(x){return x}
        }
        if(__get__!==null){ // descriptor
            res.__name__ = attr
            // __new__ is a static method
            if(attr == '__new__'){res.$type = 'staticmethod'}
            var res1 = __get__.apply(null, [res, obj, klass])
            if(typeof res1 == 'function'){
                // If attribute is a class then return it unchanged
                //
                // Example :
                // ===============
                // class A:
                //    def __init__(self,x):
                //        self.x = x
                //
                // class B:
                //    foo = A
                //    def __init__(self):
                //        self.info = self.foo(18)
                //
                // B()
                // ===============
                // In class B, when we call self.foo(18), self.foo is the
                // class A, its method __init__ must be called without B's
                // self as first argument

                if(res1.__class__ === $B.$factory) return res

                // Same thing if the attribute is a method of an instance
                // =================
                // class myRepr:
                //     def repr(self, a):
                //         return a
                //
                // class myclass:
                //     _repr=myRepr()
                //     repr= _repr.repr
                //
                //     def myfunc(self):
                //         return self.repr('test')
                // =================
                // In function myfunc, self.repr is an instance of MyRepr,
                // it must be used as is, not transformed into a method

                else if(res1.__class__===$B.$MethodDict){
                    return res
                }

                // instance method object
                return $B.make_method(attr, klass, res)(obj)

            }else{
                // result of __get__ is not a function
                return res1
            }
        }
        // attribute is not a descriptor : return it unchanged
        return res
    }else{
        // search __getattr__
        var _ga = obj['__getattr__']
        if(_ga===undefined){
            _ga = klass['__getattr__']
            if(_ga===undefined){
                var mro = klass.__mro__
                for(var i=0, len=mro.length; i < len;i++){
                    _ga = mro[i]['__getattr__']
                    if(_ga!==undefined){
                        break
                    }
                }
            }
        }
        if(_ga!==undefined){
            try{return _ga(obj,attr)}
            catch(err){}
        }
        // for special methods such as __mul__, look for __rmul__ on operand
        if(attr.substr(0,2)=='__' && attr.substr(attr.length-2)=='__'){
            var attr1 = attr.substr(2,attr.length-4) // stripped of __
            var rank = opnames.indexOf(attr1)
            if(rank > -1){
                var rop = '__r'+opnames[rank]+'__' // name of reflected operator
                var func = function(){
                    try{
                        // Operands must be of different types
                        if($B.get_class(arguments[0])===klass){throw Error('')}
                        return _b_.getattr(arguments[0],rop)(obj)
                    }catch(err){
                        var msg = "unsupported operand types for "+
                            opsigns[rank]+": '"+ klass.__name__+"' and '"+
                            $B.get_class(arguments[0]).__name__+"'"
                        throw _b_.TypeError(msg)
                    }
                }
                func.$infos = {__name__ : klass.__name__+'.'+attr}
                return func
            }
        }
        //throw AttributeError('object '+obj.__class__.__name__+" has no attribute '"+attr+"'")
    }
}

$ObjectDict.__gt__ = $ObjectNI('__gt__','>')

$ObjectDict.__hash__ = function (self) {
    var hash = self.__hashvalue__
    if(hash!==undefined){return hash}
    return self.__hashvalue__=$B.$py_next_hash--;
}

$ObjectDict.__init__ = function(){
    if(arguments.length == 1) {  // only self
        return _b_.None  // all is good ... return None
    } else if(arguments.length == 2) {  // at most "self" and kwargs
        kw = arguments[1]
        if(kw.$nat !== undefined && kw.kw !== undefined) { // kwargs is well formed
            if(Object.keys(kw.kw).length == 0) {  // no items in kwargs
                return _b_.None  // all is good ... return None
            }
        }
    }
    // *args expansion has elements or **kwargs is not empty
    throw _b_.TypeError("object() takes no parameters")
}

$ObjectDict.__le__ = $ObjectNI('__le__','<=')

$ObjectDict.__lt__ = $ObjectNI('__lt__','<')

$ObjectDict.__mro__ = []

$ObjectDict.__new__ = function(cls){
    if(cls===undefined){throw _b_.TypeError('object.__new__(): not enough arguments')}
    return {__class__ : cls.$dict}
}

$ObjectDict.__ne__ = function(self,other){
    return !_b_.getattr(self, '__eq__')(other)
}

$ObjectDict.__repr__ = function(self){
    if(self===object) return "<class 'object'>"
    if(self.__class__===$B.$factory) return "<class '"+self.$dict.__name__+"'>"
    if(self.__class__===$B.$type && self.__name__=='classXXX') return "<class '"+self.__name__+"'>"
    if(self.__class__.__module__!==undefined){
        return "<"+self.__class__.__module__+"."+self.__class__.__name__+" object>"
    }else{
        return "<"+self.__class__.__name__+" object>"
    }
}

$ObjectDict.__setattr__ = function(self,attr,val){
    if(val===undefined){ // setting an attribute to 'object' type is not allowed
        throw _b_.TypeError("can't set attributes of built-in/extension type 'object'")
    }else if(self.__class__===$ObjectDict){
        // setting an attribute to object() is not allowed
        if($ObjectDict[attr]===undefined){
            throw _b_.AttributeError("'object' object has no attribute '"+attr+"'")
        }else{
            throw _b_.AttributeError("'object' object attribute '"+attr+"' is read-only")
        }
    }
    self[attr] = val
    return _b_.None
}
$ObjectDict.__setattr__.__str__ = function(){return 'method object.setattr'}

$ObjectDict.__str__ = $ObjectDict.__repr__

$ObjectDict.__subclasshook__ = function(){return _b_.NotImplemented}

// constructor of the built-in class 'object'
function object(){return {__class__:$ObjectDict}}

object.$dict = $ObjectDict
// object.__class__ = $factory : this is done in py_types
$ObjectDict.$factory = object
object.__repr__ = object.__str__ = function(){return "<class 'object'>"}

$B.make_class = function(class_obj){
    // class_obj has at least an attribute "name", and possibly an attribute
    // init

    function A(){
        var res = {__class__:A.$dict}
        if(class_obj.init){
            class_obj.init.apply(null,
                [res].concat(Array.prototype.slice.call(arguments)))
        }
        return res
    }

    A.__class__ = $B.$factory

    A.$dict = {
        __class__: $B.type,
        __name__: class_obj.name
    }
    A.$dict.__mro__ = [object.$dict]

    return A
}

return object

})(__BRYTHON__)
<commit_msg>Fix bug in object() : didn't raise an exception with "object(x=0)"<commit_after>// A function that builds the __new__ method for the factory function
__BRYTHON__.$__new__ = function(factory){
    return function(cls){
        /*
        if(cls===undefined){
            throw __BRYTHON__.builtins.TypeError(factory.$dict.__name__+'.__new__(): not enough arguments')
        }
        */
        var res = factory.apply(null,[])
        res.__class__ = cls.$dict
        var init_func = null
        try{init_func = __BRYTHON__.builtins.getattr(res,'__init__')}
        catch(err){}
        if(init_func!==null){
            var args = [], pos=0
            for(var i=1, _len_i = arguments.length; i < _len_i;i++){args[pos++]=arguments[i]}
            init_func.apply(null,args)
            res.__initialized__ = true
        }
        return res
    }
}

__BRYTHON__.builtins.object = (function($B){

var _b_=$B.builtins

// class object for the built-in class 'object'
var $ObjectDict = {
    //__class__:$type, : not here, added in py_type.js after $type is defined
    // __bases__ : set to an empty tuple in py_list.js after tuple is defined
    __name__:'object',
    $native:true
}

// Function for comparison operators
// In a<b, if b defines __gt__, use b.__gt__(a)
var reverse_func = {'__lt__':'__gt__',
    '__gt__':'__lt__',
    '__le__': '__ge__',
    '__ge__': '__le__'
}
var $ObjectNI = function(name,op){
    return function(self, other){
        var klass = $B.get_class(other),
            other_comp = _b_.getattr(klass, reverse_func[name])
        if(other_comp.__func__===$ObjectDict[reverse_func[name]]){
            throw _b_.TypeError('unorderable types: object() '+op+
                ' '+ _b_.str($B.get_class(other).__name__)+'()')
        }else{
            return other_comp(other, self)
        }
    }
}

// Name of special methods : if they are not found as attributes, try
// the "reflected" attribute on the argument
// For instance, for "getattr(x,'__mul__')", if object x has no attribute
// "__mul__", try a function using the attribute "__rmul__" of its
// first argument

var opnames = ['add','sub','mul','truediv','floordiv','mod','pow',
    'lshift','rshift','and','xor','or']
var opsigns = ['+','-','*','/','//','%','**','<<','>>','&','^', '|']

$ObjectDict.__delattr__ = function(self,attr){
    _b_.getattr(self, attr) // raises AttributeError if necessary
    delete self[attr];
    return _b_.None
}

$ObjectDict.__dir__ = function(self) {
    var objects = [self],
        pos=1,
        klass = self.__class__ || $B.get_class(self)
    objects[pos++] = klass
    var mro = klass.__mro__
    for (var i=0, _len_i = mro.length; i < _len_i; i++) {
        objects[pos++]=mro[i]
    }

    var res = [], pos=0
    for (var i=0, _len_i = objects.length; i < _len_i; i++) {
        for(var attr in objects[i]){
            //if(attr.charAt(0)=='$' && attr.substr(0,2)!=='$$'){
            if(attr.charAt(0)=='$' && attr.charAt(1) != '$') {
                // exclude internal attributes set by Brython
                continue
            }
            if(!isNaN(parseInt(attr.charAt(0)))){
                // Exclude numerical attributes
                // '0', '1' are in attributes of string 'ab'
                continue
            }
            if(attr=='__mro__'){continue}
            res[pos++]=attr
        }
    }
    res = _b_.list(_b_.set(res))
    _b_.list.$dict.sort(res)
    return res
}

$ObjectDict.__eq__ = function(self,other){
    // equality test defaults to identity of objects
    //test_issue_1393
    var _class=$B.get_class(self)
    if (_class.$native || _class.__name__ == 'function') {
       var _class1=$B.get_class(other)
       if (!_class1.$native && _class1.__name__ != 'function') {
          return _b_.getattr(other, '__eq__')(self)
       }
    }
    return self===other
}

$ObjectDict.__format__ = function(){
    var $ = $B.args('__format__', 2, {self:null, spec:null},
        ['self', 'spec'], arguments, {}, null, null)
    if($.spec!==''){throw _b_.TypeError("non-empty format string passed to object.__format__")}
    return _b_.getattr($.self, '__repr__')()
}

$ObjectDict.__ge__ = $ObjectNI('__ge__','>=')

$ObjectDict.__getattribute__ = function(obj,attr){

    var klass = obj.__class__ || $B.get_class(obj)
    if(attr==='__class__'){
        return klass.$factory
    }
    var res = obj[attr]

    if(res===undefined){
        // search in classes hierarchy, following method resolution order
        function check(obj, kl, attr){
            if(kl.$methods){
                var method = kl.$methods[attr]
                if(method!==undefined){
                    return method(obj)
                }
            }
            var v=kl[attr]
            if(v!==undefined){
                return v
            }else if(attr=='__str__' && kl['__repr__']!==undefined){
                // If the class doesn't define __str__ but defines __repr__,
                // use __repr__
                return kl['__repr__']
            }
        }
        res = check(obj, klass, attr)
        if(res===undefined){
            var mro = klass.__mro__
            for(var i=0, _len_i = mro.length; i < _len_i;i++){
                res = check(obj, mro[i], attr)
                if(res!==undefined){break}
            }
        }
    }else{
        if(res.__set__===undefined){
            // For non-data descriptors, the attribute found in object
            // dictionary takes precedence
            return res
        }
    }

    if(res!==undefined){

        if(res.__class__===_b_.property.$dict){
            return res.__get__(res, obj, klass)
        }

        var get = res.__get__
        if(get===undefined && res.__class__){
            var get = res.__class__.__get__
            for(var i=0;i<res.__class__.__mro__.length && get===undefined; i++){
                get = res.__class__.__mro__[i].__get__
            }
        }
        var __get__ = get === undefined ? null : _b_.getattr(res,'__get__',null)

        // For descriptors, attribute resolution is done by applying __get__
        if(__get__!==null){
            try{return __get__.apply(null, [obj, klass])}
            catch(err){
                console.log('error in get.apply', err)
                console.log(__get__+'')
                throw err
            }
        }

        if(typeof res=='object'){
            if(__get__ && (typeof __get__=='function')){
                get_func = function(x,y){return __get__.apply(x,[y,klass])}
            }
        }

        if(__get__===null && (typeof res=='function')){
            __get__ = function(x){return x}
        }
        if(__get__!==null){ // descriptor
            res.__name__ = attr
            // __new__ is a static method
            if(attr == '__new__'){res.$type = 'staticmethod'}
            var res1 = __get__.apply(null, [res, obj, klass])
            if(typeof res1 == 'function'){
                // If attribute is a class then return it unchanged
                //
                // Example :
                // ===============
                // class A:
                //    def __init__(self,x):
                //        self.x = x
                //
                // class B:
                //    foo = A
                //    def __init__(self):
                //        self.info = self.foo(18)
                //
                // B()
                // ===============
                // In class B, when we call self.foo(18), self.foo is the
                // class A, its method __init__ must be called without B's
                // self as first argument

                if(res1.__class__ === $B.$factory) return res

                // Same thing if the attribute is a method of an instance
                // =================
                // class myRepr:
                //     def repr(self, a):
                //         return a
                //
                // class myclass:
                //     _repr=myRepr()
                //     repr= _repr.repr
                //
                //     def myfunc(self):
                //         return self.repr('test')
                // =================
                // In function myfunc, self.repr is an instance of MyRepr,
                // it must be used as is, not transformed into a method

                else if(res1.__class__===$B.$MethodDict){
                    return res
                }

                // instance method object
                return $B.make_method(attr, klass, res)(obj)

            }else{
                // result of __get__ is not a function
                return res1
            }
        }
        // attribute is not a descriptor : return it unchanged
        return res
    }else{
        // search __getattr__
        var _ga = obj['__getattr__']
        if(_ga===undefined){
            _ga = klass['__getattr__']
            if(_ga===undefined){
                var mro = klass.__mro__
                for(var i=0, len=mro.length; i < len;i++){
                    _ga = mro[i]['__getattr__']
                    if(_ga!==undefined){
                        break
                    }
                }
            }
        }
        if(_ga!==undefined){
            try{return _ga(obj,attr)}
            catch(err){}
        }
        // for special methods such as __mul__, look for __rmul__ on operand
        if(attr.substr(0,2)=='__' && attr.substr(attr.length-2)=='__'){
            var attr1 = attr.substr(2,attr.length-4) // stripped of __
            var rank = opnames.indexOf(attr1)
            if(rank > -1){
                var rop = '__r'+opnames[rank]+'__' // name of reflected operator
                var func = function(){
                    try{
                        // Operands must be of different types
                        if($B.get_class(arguments[0])===klass){throw Error('')}
                        return _b_.getattr(arguments[0],rop)(obj)
                    }catch(err){
                        var msg = "unsupported operand types for "+
                            opsigns[rank]+": '"+ klass.__name__+"' and '"+
                            $B.get_class(arguments[0]).__name__+"'"
                        throw _b_.TypeError(msg)
                    }
                }
                func.$infos = {__name__ : klass.__name__+'.'+attr}
                return func
            }
        }
        //throw AttributeError('object '+obj.__class__.__name__+" has no attribute '"+attr+"'")
    }
}

$ObjectDict.__gt__ = $ObjectNI('__gt__','>')

$ObjectDict.__hash__ = function (self) {
    var hash = self.__hashvalue__
    if(hash!==undefined){return hash}
    return self.__hashvalue__=$B.$py_next_hash--;
}

$ObjectDict.__init__ = function(){
    if(arguments.length == 1) {  // only self
        return _b_.None  // all is good ... return None
    } else if(arguments.length == 2) {  // at most "self" and kwargs
        kw = arguments[1]
        if(kw.$nat !== undefined && kw.kw !== undefined) { // kwargs is well formed
            if(Object.keys(kw.kw).length == 0) {  // no items in kwargs
                return _b_.None  // all is good ... return None
            }
        }
    }
    // *args expansion has elements or **kwargs is not empty
    throw _b_.TypeError("object() takes no parameters")
}

$ObjectDict.__le__ = $ObjectNI('__le__','<=')

$ObjectDict.__lt__ = $ObjectNI('__lt__','<')

$ObjectDict.__mro__ = []

$ObjectDict.__new__ = function(cls){
    if(cls===undefined){throw _b_.TypeError('object.__new__(): not enough arguments')}
    return {__class__ : cls.$dict}
}

$ObjectDict.__ne__ = function(self,other){
    return !_b_.getattr(self, '__eq__')(other)
}

$ObjectDict.__repr__ = function(self){
    if(self===object) return "<class 'object'>"
    if(self.__class__===$B.$factory) return "<class '"+self.$dict.__name__+"'>"
    if(self.__class__===$B.$type && self.__name__=='classXXX') return "<class '"+self.__name__+"'>"
    if(self.__class__.__module__!==undefined){
        return "<"+self.__class__.__module__+"."+self.__class__.__name__+" object>"
    }else{
        return "<"+self.__class__.__name__+" object>"
    }
}

$ObjectDict.__setattr__ = function(self,attr,val){
    if(val===undefined){ // setting an attribute to 'object' type is not allowed
        throw _b_.TypeError("can't set attributes of built-in/extension type 'object'")
    }else if(self.__class__===$ObjectDict){
        // setting an attribute to object() is not allowed
        if($ObjectDict[attr]===undefined){
            throw _b_.AttributeError("'object' object has no attribute '"+attr+"'")
        }else{
            throw _b_.AttributeError("'object' object attribute '"+attr+"' is read-only")
        }
    }
    self[attr] = val
    return _b_.None
}
$ObjectDict.__setattr__.__str__ = function(){return 'method object.setattr'}

$ObjectDict.__str__ = $ObjectDict.__repr__

$ObjectDict.__subclasshook__ = function(){return _b_.NotImplemented}

// constructor of the built-in class 'object'
function object(){
    var res = {__class__:$ObjectDict},
        args = [res].concat(Array.prototype.slice.call(arguments))
    $ObjectDict.__init__.apply(null, args)
    return res
}

object.$dict = $ObjectDict
// object.__class__ = $factory : this is done in py_types
$ObjectDict.$factory = object
object.__repr__ = object.__str__ = function(){return "<class 'object'>"}

$B.make_class = function(class_obj){
    // class_obj has at least an attribute "name", and possibly an attribute
    // init

    function A(){
        var res = {__class__:A.$dict}
        if(class_obj.init){
            class_obj.init.apply(null,
                [res].concat(Array.prototype.slice.call(arguments)))
        }
        return res
    }

    A.__class__ = $B.$factory

    A.$dict = {
        __class__: $B.type,
        __name__: class_obj.name
    }
    A.$dict.__mro__ = [object.$dict]

    return A
}

return object

})(__BRYTHON__)
<|endoftext|>


<commit_before>var fs = require('fs');
var uuid = require('uuid');
var path = require('path');

/*

  var state = {
    users:{
      user1:{
        projects:{
          56:{
            name:'test',
            containers:{
              test:{

              },
              bimserver:{

              }
            }
          }
        }
      }
    }
  }

*/

module.exports = function(opts){

  var state = {
    users:{}
  }

  var file = opts.datafile || path.join(__dirname, 'jencadata.json')
  if(!fs.existsSync(file)){
    save_data()
  }

  function save_data(){
    if(opts.memory) return
    fs.writeFileSync(file, state, 'utf8', (err) => {
      if (err) throw err;
    })
  }

  function ensure_user(id){
    if(!state.users[id]){
      state.users[id] = {
        projects:{}
      }
    }
    return state.users[id]
  }

  function create_project(userid, data, done){
    var id = uuid.v1()
    var user = ensure_user(userid)
    user.projects[id] = data
    data.id = id
    if(!data.containers) data.containers = [];
    data.containers.forEach(function(container){
      container.id = uuid.v1()
      container.host = data.project_host
    })
    save_data()
    done(null, data)
  }

  function project_running(userid, data, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]
    var project = user.projects[data.id]
    project.containers = data.containers
    save_data()
    done(null, project)
  }

  function get_project(userid, projectid, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]
    var project = user.projects[projectid]
    done(null, project)
  }

  function list_projects(userid, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]

    var projects = Object.keys(user.projects).map(function(projectid){
      return user.projects[projectid]
    })
    done(null, projects)
  }

  function delete_project(userid, projectid, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]
    delete(user.projects[projectid])
    done()
  }

  function save_project(userid, projectid, data, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]
    var project = user.projects[projectid]
    Object.keys(data).forEach(function(prop){
      project[prop] = data[prop]
    })
    save_data()
    done(null, project)
  }

  function get_state(){
    return state
  }

  return {
    create_project:create_project,
    project_running:project_running,
    get_project:get_project,
    list_projects:list_projects,
    delete_project:delete_project,
    save_project:save_project,
    get_state:get_state
  }
}<commit_msg>added state reset method on jsonfile storage module<commit_after>var fs = require('fs');
var uuid = require('uuid');
var path = require('path');

/*

  var state = {
    users:{
      user1:{
        projects:{
          56:{
            name:'test',
            containers:{
              test:{

              },
              bimserver:{

              }
            }
          }
        }
      }
    }
  }

*/

module.exports = function(opts){

  var state = {}

  var file = opts.datafile || path.join(__dirname, 'jencadata.json')
  if(!fs.existsSync(file)){
    save_data()
  }
  reset_state()

  function reset_state(){
    state = {
      users:{}
    }
  }

  function save_data(){
    if(opts.memory) return
    fs.writeFileSync(file, state, 'utf8', (err) => {
      if (err) throw err;
    })
  }

  function ensure_user(id){
    if(!state.users[id]){
      state.users[id] = {
        projects:{}
      }
    }
    return state.users[id]
  }

  function create_project(userid, data, done){
    var id = uuid.v1()
    var user = ensure_user(userid)
    user.projects[id] = data
    data.id = id
    if(!data.containers) data.containers = [];
    data.containers.forEach(function(container){
      container.id = uuid.v1()
      container.host = data.project_host
    })
    save_data()
    done(null, data)
  }

  function project_running(userid, data, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]
    var project = user.projects[data.id]
    project.containers = data.containers
    save_data()
    done(null, project)
  }

  function get_project(userid, projectid, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }

    if(!state.users[userid].projects[projectid]){
      done('there is no project with id: ' + projectid)
      return
    }

    var user = state.users[userid]
    var project = user.projects[projectid]
    done(null, project)
  }

  function list_projects(userid, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]

    var projects = Object.keys(user.projects).map(function(projectid){
      return user.projects[projectid]
    })
    done(null, projects)
  }

  function delete_project(userid, projectid, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]
    delete(user.projects[projectid])
    done()
  }

  function save_project(userid, projectid, data, done){
    if(!state.users[userid]){
      done('there is no user with id: ' + userid)
      return
    }
    var user = state.users[userid]
    var project = user.projects[projectid]
    Object.keys(data).forEach(function(prop){
      project[prop] = data[prop]
    })
    save_data()
    done(null, project)
  }

  function get_state(){
    return state
  }

  return {
    create_project:create_project,
    project_running:project_running,
    get_project:get_project,
    list_projects:list_projects,
    delete_project:delete_project,
    save_project:save_project,
    get_state:get_state,

    reset_state:reset_state
  }
}<|endoftext|>


<commit_before>/**
 * @name OnlineFriendCount
 * @author Zerthox
 * @version 1.5.0
 * @description Add the old online friend count back to guild list. Because nostalgia.
 * @authorLink https://github.com/Zerthox
 * @donate https://paypal.me/zerthox
 * @website https://github.com/Zerthox/BetterDiscord-Plugins
 * @source https://github.com/Zerthox/BetterDiscord-Plugins/blob/master/v1/OnlineFriendCount.plugin.js
 * @updateUrl https://raw.githubusercontent.com/Zerthox/BetterDiscord-Plugins/master/v1/OnlineFriendCount.plugin.js
 */

/* @cc_on
    @if (@_jscript)
        var name = WScript.ScriptName.split(".")[0];
        var shell = WScript.CreateObject("WScript.Shell");
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        shell.Popup("Do NOT run random scripts from the internet with the Windows Script Host!\n\nYou are supposed to move this file to your BandagedBD/BetterDiscord plugins folder.", 0, name + ": Warning!", 0x1030);
        var pluginsPath = shell.expandEnvironmentStrings("%appdata%\\BetterDiscord\\plugins");
        if (!fso.FolderExists(pluginsPath)) {
            if (shell.Popup("Unable to find the BetterDiscord plugins folder on your computer.\nOpen the download page of BandagedBD/BetterDiscord?", 0, name + ": BetterDiscord installation not found", 0x14) === 6) {
                shell.Exec("explorer \"https://github.com/rauenzi/betterdiscordapp/releases\"");
            }
        } else if (WScript.ScriptFullName === pluginsPath + "\\" + WScript.ScriptName) {
            shell.Popup("This plugin is already in the correct folder.\nNavigate to the \"Plugins\" settings tab in Discord and enable it there.", 0, name, 0x40);
        } else {
            shell.Exec("explorer " + pluginsPath);
        }
        WScript.Quit();
    @else
@*/

const {React, ReactDOM} = BdApi;
const Flux = BdApi.findModuleByProps("connectStores");

function qReact(node, query) {
    let match = false;

    try {
        match = query(node);
    } catch (err) {
        console.debug("Suppressed error in qReact query:\n", err);
    }

    if (match) {
        return node;
    } else if (node && node.props && node.props.children) {
        for (const child of [node.props.children].flat()) {
            const result = qReact(child, query);

            if (result) {
                return result;
            }
        }
    }

    return null;
}

const Module = {
    Constants: BdApi.findModuleByProps("Permissions"),
    Status: BdApi.findModuleByProps("getState", "getStatus"),
    Relationships: BdApi.findModuleByProps("isFriend", "getRelationshipCount")
};
const Component = {
    HomeButton: BdApi.findModule((m) => m.default && m.default.toString().includes("showDMsOnly")),
    Link: BdApi.findModuleByProps("NavLink").Link
};
const Selector = {
    guilds: BdApi.findModuleByProps("guilds", "base"),
    list: BdApi.findModuleByProps("listItem"),
    friendsOnline: "friendsOnline-2JkivW"
};
const Styles = `/*! OnlineFriendCount v1.5.0 styles */
.friendsOnline-2JkivW {
    color: rgba(255, 255, 255, 0.3);
    text-align: center;
    text-transform: uppercase;
    font-size: 10px;
    font-weight: 500;
    line-height: 1.3;
    width: 70px;
    word-wrap: normal;
    white-space: nowrap;
    cursor: pointer;
}
.friendsOnline-2JkivW:hover {
    color: rgba(255, 255, 255, 0.5);
}`;

function OnlineCount({online}) {
    return React.createElement(
        "div",
        {
            className: Selector.list.listItem
        },
        React.createElement(
            Component.Link,
            {
                to: {
                    pathname: "/channels/@me"
                }
            },
            React.createElement(
                "div",
                {
                    className: Selector.friendsOnline
                },
                online,
                " Online"
            )
        )
    );
}

const OnlineCountContainer = Flux.connectStores([Module.Status, Module.Relationships], () => {
    const {RelationshipTypes, StatusTypes} = Module.Constants;
    const relationships = Module.Relationships.getRelationships();
    const filtered = Object.entries(relationships).filter(
        ([id, type]) => type === RelationshipTypes.FRIEND && Module.Status.getStatus(id) !== StatusTypes.OFFLINE
    );
    return {
        online: filtered.length
    };
})(OnlineCount);

class Plugin {
    start() {
        this.injectCSS(Styles);
        this.createPatch(Component.HomeButton, "default", {
            instead: ({methodArguments: [props], originalMethod}) => {
                return React.createElement(
                    React.Fragment,
                    null,
                    originalMethod(props),
                    React.createElement(OnlineCountContainer, null)
                );
            }
        });
        this.triggerRerender();
    }

    stop() {
        this.triggerRerender();
    }

    findGuildsOwner() {
        const node = document.getElementsByClassName(Selector.guilds.guilds)[0];
        let fiber = BdApi.getInternalInstance(node);

        if (!fiber) {
            return null;
        }

        while (fiber) {
            if (fiber.stateNode instanceof React.Component) {
                return fiber;
            }

            fiber = fiber.return;
        }

        return null;
    }

    triggerRerender() {
        const fiber = this.findGuildsOwner();

        if (fiber) {
            fiber.stateNode.forceUpdate();
            this.log("Successfully triggered Guilds rerender");
        } else {
            this.warn("Unable to trigger Guilds rerender");
        }
    }
}

module.exports = class Wrapper extends Plugin {
    getName() {
        return "OnlineFriendCount";
    }

    getVersion() {
        return "1.5.0";
    }

    getAuthor() {
        return "Zerthox";
    }

    getDescription() {
        return "Add the old online friend count back to guild list. Because nostalgia.";
    }

    log(...msgs) {
        console.log(
            `%c[${this.getName()}] %c(v${this.getVersion()})`,
            "color: #3a71c1; font-weight: 700;",
            "color: #666; font-size: .8em;",
            ...msgs
        );
    }

    warn(...msgs) {
        console.warn(
            `%c[${this.getName()}] %c(v${this.getVersion()})`,
            "color: #3a71c1; font-weight: 700;",
            "color: #666; font-size: .8em;",
            ...msgs
        );
    }

    error(...msgs) {
        console.error(
            `%c[${this.getName()}] %c(v${this.getVersion()})`,
            "color: #3a71c1; font-weight: 700;",
            "color: #666; font-size: .8em;",
            ...msgs
        );
    }

    constructor(...args) {
        super(...args);
        this._Patches = [];

        if (this.defaults) {
            this.settings = {...this.defaults, ...this.loadData("settings")};
        }
    }

    start() {
        this.log("Enabled");
        super.start();
    }

    stop() {
        while (this._Patches.length > 0) {
            this._Patches.pop()();
        }

        this.log("Unpatched all");

        if (document.getElementById(this.getName())) {
            BdApi.clearCSS(this.getName());
        }

        super.stop();
        this.log("Disabled");
    }

    saveData(id, value) {
        return BdApi.saveData(this.getName(), id, value);
    }

    loadData(id, fallback = null) {
        const data = BdApi.loadData(this.getName(), id);
        return data !== undefined && data !== null ? data : fallback;
    }

    injectCSS(css) {
        const el = document.getElementById(this.getName());

        if (!el) {
            BdApi.injectCSS(this.getName(), css);
        } else {
            el.innerHTML += "\n\n/* --- */\n\n" + css;
        }
    }

    createPatch(target, method, options) {
        options.silent = true;

        this._Patches.push(BdApi.monkeyPatch(target, method, options));

        const name =
            options.name ||
            target.displayName ||
            target.name ||
            target.constructor.displayName ||
            target.constructor.name ||
            "Unknown";
        this.log(
            `Patched ${method} of ${name} ${
                options.type === "component" || target instanceof React.Component ? "component" : "module"
            }`
        );
    }

    async forceUpdate(...classes) {
        this.forceUpdateElements(...classes.map((e) => Array.from(document.getElementsByClassName(e))).flat());
    }

    async forceUpdateElements(...elements) {
        for (const el of elements) {
            try {
                let fiber = BdApi.getInternalInstance(el);

                if (fiber) {
                    while (!fiber.stateNode || !fiber.stateNode.forceUpdate) {
                        fiber = fiber.return;
                    }

                    fiber.stateNode.forceUpdate();
                }
            } catch (e) {
                this.warn(
                    `Failed to force update "${
                        el.id ? `#${el.id}` : el.className ? `.${el.className}` : el.tagName
                    }" state node`
                );
                console.error(e);
            }
        }
    }
};

if (Plugin.prototype.getSettings) {
    const Flex = BdApi.findModuleByDisplayName("Flex");
    const Button = BdApi.findModuleByProps("Link", "Hovers");
    const Form = BdApi.findModuleByProps("FormItem", "FormSection", "FormDivider");
    const Margins = BdApi.findModuleByProps("marginLarge");

    class Settings extends React.Component {
        constructor(...args) {
            super(...args);
            this.state = this.props.current;
        }

        render() {
            const {name, defaults, children: Child} = this.props;
            return React.createElement(
                Form.FormSection,
                null,
                React.createElement(Child, {
                    update: (changed) => this.update({...this.state, ...changed}),
                    ...this.state
                }),
                React.createElement(Form.FormDivider, {
                    className: [Margins.marginTop20, Margins.marginBottom20].join(" ")
                }),
                React.createElement(
                    Flex,
                    {
                        justify: Flex.Justify.END
                    },
                    React.createElement(
                        Button,
                        {
                            size: Button.Sizes.SMALL,
                            onClick: () =>
                                BdApi.showConfirmationModal(name, "Reset all settings?", {
                                    onConfirm: () => this.update(defaults)
                                })
                        },
                        "Reset"
                    )
                )
            );
        }

        update(settings) {
            this.setState(settings);
            this.props.onChange(settings);
        }
    }

    module.exports.prototype.getSettingsPanel = function () {
        return React.createElement(
            Settings,
            {
                name: this.getName(),
                current: this.settings,
                defaults: this.defaults,
                onChange: (settings) => {
                    this.settings = settings;

                    if (this.update instanceof Function) {
                        this.update();
                    }

                    this.saveData("settings", settings);
                }
            },
            this.getSettings()
        );
    };
}

/* @end@*/
<commit_msg>use Discord's color variables<commit_after>/**
 * @name OnlineFriendCount
 * @author Zerthox
 * @version 1.5.0
 * @description Add the old online friend count back to guild list. Because nostalgia.
 * @authorLink https://github.com/Zerthox
 * @donate https://paypal.me/zerthox
 * @website https://github.com/Zerthox/BetterDiscord-Plugins
 * @source https://github.com/Zerthox/BetterDiscord-Plugins/blob/master/v1/OnlineFriendCount.plugin.js
 * @updateUrl https://raw.githubusercontent.com/Zerthox/BetterDiscord-Plugins/master/v1/OnlineFriendCount.plugin.js
 */

/* @cc_on
    @if (@_jscript)
        var name = WScript.ScriptName.split(".")[0];
        var shell = WScript.CreateObject("WScript.Shell");
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        shell.Popup("Do NOT run random scripts from the internet with the Windows Script Host!\n\nYou are supposed to move this file to your BandagedBD/BetterDiscord plugins folder.", 0, name + ": Warning!", 0x1030);
        var pluginsPath = shell.expandEnvironmentStrings("%appdata%\\BetterDiscord\\plugins");
        if (!fso.FolderExists(pluginsPath)) {
            if (shell.Popup("Unable to find the BetterDiscord plugins folder on your computer.\nOpen the download page of BandagedBD/BetterDiscord?", 0, name + ": BetterDiscord installation not found", 0x14) === 6) {
                shell.Exec("explorer \"https://github.com/rauenzi/betterdiscordapp/releases\"");
            }
        } else if (WScript.ScriptFullName === pluginsPath + "\\" + WScript.ScriptName) {
            shell.Popup("This plugin is already in the correct folder.\nNavigate to the \"Plugins\" settings tab in Discord and enable it there.", 0, name, 0x40);
        } else {
            shell.Exec("explorer " + pluginsPath);
        }
        WScript.Quit();
    @else
@*/

const {React, ReactDOM} = BdApi;
const Flux = BdApi.findModuleByProps("connectStores");

function qReact(node, query) {
    let match = false;

    try {
        match = query(node);
    } catch (err) {
        console.debug("Suppressed error in qReact query:\n", err);
    }

    if (match) {
        return node;
    } else if (node && node.props && node.props.children) {
        for (const child of [node.props.children].flat()) {
            const result = qReact(child, query);

            if (result) {
                return result;
            }
        }
    }

    return null;
}

const Module = {
    Constants: BdApi.findModuleByProps("Permissions"),
    Status: BdApi.findModuleByProps("getState", "getStatus"),
    Relationships: BdApi.findModuleByProps("isFriend", "getRelationshipCount")
};
const Component = {
    HomeButton: BdApi.findModule((m) => m.default && m.default.toString().includes("showDMsOnly")),
    Link: BdApi.findModuleByProps("NavLink").Link
};
const Selector = {
    guilds: BdApi.findModuleByProps("guilds", "base"),
    list: BdApi.findModuleByProps("listItem"),
    friendsOnline: "friendsOnline-2JkivW"
};
const Styles = `/*! OnlineFriendCount v1.5.0 styles */
.friendsOnline-2JkivW {
    color: var(--interactive-normal);
    text-align: center;
    text-transform: uppercase;
    font-size: 10px;
    font-weight: 500;
    line-height: 1.3;
    width: 70px;
    word-wrap: normal;
    white-space: nowrap;
    cursor: pointer;
}
.friendsOnline-2JkivW:hover {
    color: var(--interactive-hover);
}`;

function OnlineCount({online}) {
    return React.createElement(
        "div",
        {
            className: Selector.list.listItem
        },
        React.createElement(
            Component.Link,
            {
                to: {
                    pathname: "/channels/@me"
                }
            },
            React.createElement(
                "div",
                {
                    className: Selector.friendsOnline
                },
                online,
                " Online"
            )
        )
    );
}

const OnlineCountContainer = Flux.connectStores([Module.Status, Module.Relationships], () => {
    const {RelationshipTypes, StatusTypes} = Module.Constants;
    const relationships = Module.Relationships.getRelationships();
    const filtered = Object.entries(relationships).filter(
        ([id, type]) => type === RelationshipTypes.FRIEND && Module.Status.getStatus(id) !== StatusTypes.OFFLINE
    );
    return {
        online: filtered.length
    };
})(OnlineCount);

class Plugin {
    start() {
        this.injectCSS(Styles);
        this.createPatch(Component.HomeButton, "default", {
            instead: ({methodArguments: [props], originalMethod}) => {
                return React.createElement(
                    React.Fragment,
                    null,
                    originalMethod(props),
                    React.createElement(OnlineCountContainer, null)
                );
            }
        });
        this.triggerRerender();
    }

    stop() {
        this.triggerRerender();
    }

    findGuildsOwner() {
        const node = document.getElementsByClassName(Selector.guilds.guilds)[0];
        let fiber = BdApi.getInternalInstance(node);

        if (!fiber) {
            return null;
        }

        while (fiber) {
            if (fiber.stateNode instanceof React.Component) {
                return fiber;
            }

            fiber = fiber.return;
        }

        return null;
    }

    triggerRerender() {
        const fiber = this.findGuildsOwner();

        if (fiber) {
            fiber.stateNode.forceUpdate();
            this.log("Successfully triggered Guilds rerender");
        } else {
            this.warn("Unable to trigger Guilds rerender");
        }
    }
}

module.exports = class Wrapper extends Plugin {
    getName() {
        return "OnlineFriendCount";
    }

    getVersion() {
        return "1.5.0";
    }

    getAuthor() {
        return "Zerthox";
    }

    getDescription() {
        return "Add the old online friend count back to guild list. Because nostalgia.";
    }

    log(...msgs) {
        console.log(
            `%c[${this.getName()}] %c(v${this.getVersion()})`,
            "color: #3a71c1; font-weight: 700;",
            "color: #666; font-size: .8em;",
            ...msgs
        );
    }

    warn(...msgs) {
        console.warn(
            `%c[${this.getName()}] %c(v${this.getVersion()})`,
            "color: #3a71c1; font-weight: 700;",
            "color: #666; font-size: .8em;",
            ...msgs
        );
    }

    error(...msgs) {
        console.error(
            `%c[${this.getName()}] %c(v${this.getVersion()})`,
            "color: #3a71c1; font-weight: 700;",
            "color: #666; font-size: .8em;",
            ...msgs
        );
    }

    constructor(...args) {
        super(...args);
        this._Patches = [];

        if (this.defaults) {
            this.settings = {...this.defaults, ...this.loadData("settings")};
        }
    }

    start() {
        this.log("Enabled");
        super.start();
    }

    stop() {
        while (this._Patches.length > 0) {
            this._Patches.pop()();
        }

        this.log("Unpatched all");

        if (document.getElementById(this.getName())) {
            BdApi.clearCSS(this.getName());
        }

        super.stop();
        this.log("Disabled");
    }

    saveData(id, value) {
        return BdApi.saveData(this.getName(), id, value);
    }

    loadData(id, fallback = null) {
        const data = BdApi.loadData(this.getName(), id);
        return data !== undefined && data !== null ? data : fallback;
    }

    injectCSS(css) {
        const el = document.getElementById(this.getName());

        if (!el) {
            BdApi.injectCSS(this.getName(), css);
        } else {
            el.innerHTML += "\n\n/* --- */\n\n" + css;
        }
    }

    createPatch(target, method, options) {
        options.silent = true;

        this._Patches.push(BdApi.monkeyPatch(target, method, options));

        const name =
            options.name ||
            target.displayName ||
            target.name ||
            target.constructor.displayName ||
            target.constructor.name ||
            "Unknown";
        this.log(
            `Patched ${method} of ${name} ${
                options.type === "component" || target instanceof React.Component ? "component" : "module"
            }`
        );
    }

    async forceUpdate(...classes) {
        this.forceUpdateElements(...classes.map((e) => Array.from(document.getElementsByClassName(e))).flat());
    }

    async forceUpdateElements(...elements) {
        for (const el of elements) {
            try {
                let fiber = BdApi.getInternalInstance(el);

                if (fiber) {
                    while (!fiber.stateNode || !fiber.stateNode.forceUpdate) {
                        fiber = fiber.return;
                    }

                    fiber.stateNode.forceUpdate();
                }
            } catch (e) {
                this.warn(
                    `Failed to force update "${
                        el.id ? `#${el.id}` : el.className ? `.${el.className}` : el.tagName
                    }" state node`
                );
                console.error(e);
            }
        }
    }
};

if (Plugin.prototype.getSettings) {
    const Flex = BdApi.findModuleByDisplayName("Flex");
    const Button = BdApi.findModuleByProps("Link", "Hovers");
    const Form = BdApi.findModuleByProps("FormItem", "FormSection", "FormDivider");
    const Margins = BdApi.findModuleByProps("marginLarge");

    class Settings extends React.Component {
        constructor(...args) {
            super(...args);
            this.state = this.props.current;
        }

        render() {
            const {name, defaults, children: Child} = this.props;
            return React.createElement(
                Form.FormSection,
                null,
                React.createElement(Child, {
                    update: (changed) => this.update({...this.state, ...changed}),
                    ...this.state
                }),
                React.createElement(Form.FormDivider, {
                    className: [Margins.marginTop20, Margins.marginBottom20].join(" ")
                }),
                React.createElement(
                    Flex,
                    {
                        justify: Flex.Justify.END
                    },
                    React.createElement(
                        Button,
                        {
                            size: Button.Sizes.SMALL,
                            onClick: () =>
                                BdApi.showConfirmationModal(name, "Reset all settings?", {
                                    onConfirm: () => this.update(defaults)
                                })
                        },
                        "Reset"
                    )
                )
            );
        }

        update(settings) {
            this.setState(settings);
            this.props.onChange(settings);
        }
    }

    module.exports.prototype.getSettingsPanel = function () {
        return React.createElement(
            Settings,
            {
                name: this.getName(),
                current: this.settings,
                defaults: this.defaults,
                onChange: (settings) => {
                    this.settings = settings;

                    if (this.update instanceof Function) {
                        this.update();
                    }

                    this.saveData("settings", settings);
                }
            },
            this.getSettings()
        );
    };
}

/* @end@*/
<|endoftext|>


<commit_before>define([
	"dojo/_base/declare", "dijit/layout/BorderContainer", "dojo/on",
	"dojo/dom-class", "dijit/layout/ContentPane", "dojo/dom-construct",
	"../PageGrid", "../formatter", "../../WorkspaceManager", "dojo/_base/lang",
	"dojo/dom-attr","../WorkspaceExplorerView", "dijit/Dialog"
], function(declare, BorderContainer, on,
			domClass, ContentPane, domConstruct,
			Grid, formatter, WorkspaceManager, lang,
			domAttr, WorkspaceExplorerView, Dialog){
	return declare([BorderContainer], {
		"baseClass": "ExperimentViewer",
		"disabled": false,
		"query": null,
		data: null,
		containerType: "job_result",
		_resultType: null,
		_jobOut: {
			"start_time": {"label": "Start time", "format": formatter.epochDate},
			"elapsed_time": {"label": "Run time", "format": formatter.runTime},
			"end_time": {"label": "End time", "format": formatter.epochDate},
			"parameters": {"label": "Parameters", "format": function(d){ return '
' + JSON.stringify(d,null,2) + "
"}}
		},
		_jobOrder: ["start_time", "end_time", "elapsed_time", "parameters"],
		_appLabel: "",
		_resultMetaTypes: {},
		_autoLabels: {},
		_setDataAttr: function(data){
			this.data = data;
			//console.log("[JobResult] data: ", data);
			this._hiddenPath = data.path + "." + data.name;
			// console.log("[JobResult] Output Files: ", this.data.autoMeta.output_files);
			var _self = this;

			// check to see if there's a hidden .folder with the actual data
			WorkspaceManager.getObject(this._hiddenPath, true).otherwise(function(err) {
				new Dialog({
					content: "No output from this job was found in the '."+_self.data.name+"' folder. "
								  +"If you moved the job result file from another location, please ensure you "
									+"have also moved the accomanying folder to this location.",
					title: "Error Loading Job Result",
					style: "width: 300px !important;"
				}).show();
			});

			// get the contents directly from the hidden folder, since metadata may be stale after a move
			WorkspaceManager.getFolderContents(this._hiddenPath, true, true)
				.then(function(objs){
					//console.log("[JobResult] objects: ", objs);
						_self._resultObjects = objs;
						_self.setupResultType();
						_self.refresh();
				});

		},
		isSummaryView: function(){
			return false;
		},
		setupResultType: function(){
			// console.log("[JobResult] setupResultType()");
			if(this.data.autoMeta.app.id){
				this._resultType = this.data.autoMeta.app.id;
				// console.log("[JobResult] _resultType:",this._resultType);
			}
			if(this._resultType == "GenomeAssembly"){
				this._appLabel = "Genome Assembly";
			}
			else{
				this._appLabel = this._resultType;
			}
		},
		getExtraMetaDataForHeader: function(job_output){
			return job_output;
		},
		refresh: function(){
			// console.log("[JobResult] refresh()");
			if(this.data){
				var jobHeader = '

';
				if(this.data.autoMeta && this.data.autoMeta.app){
					jobHeader = jobHeader + this._appLabel + " ";
				}
				jobHeader = jobHeader + "Job Result" + '
';
				//this.viewer.set('content',jobHeader);

				var output = [];
				output.push(jobHeader + '

');
				var job_output = [];

				// add extra metadata header lines
				job_output = this.getExtraMetaDataForHeader(job_output)

				this._jobOrder.forEach(function(prop){
					/*if (prop=="output_files") { return; }
					if (prop=="app") { return; }
					if (prop=="job_output") { return; }
					if (prop=="hostname") { return; }*/
					if(!this.data.autoMeta[prop]){
						return;
					}

					if(this._jobOut.hasOwnProperty(prop)){
						//this._jobOut[prop]["value"]=this.data.autoMeta[prop];
						var tableLabel = this._jobOut[prop].hasOwnProperty("label") ? this._jobOut[prop]["label"] : prop;
						var tableValue = this._jobOut[prop].hasOwnProperty("format") ? this._jobOut[prop]["format"](this.data.autoMeta[prop]) : this.data.autoMeta[prop];
						job_output.push('
' + this._jobOut[prop]["label"] + '	' + tableValue + "
");
					}
				}, this);
			}

			output.push.apply(output, job_output);
			output.push("

");

			if(this.data.userMeta){
				Object.keys(this.data.userMeta).forEach(function(prop){
					output.push("
" + prop + ": " + this.data.userMeta[prop] + "
");
				}, this);
			}

			output.push("
");
			this.viewHeader.set("content", output.join(""));
			this.resize();
		},
		startup: function(){
			if(this._started){
				return;
			}
			this.inherited(arguments);
			this.viewHeader = new ContentPane({content: "Loading data from "+this.data.name+" job file.  If you have moved your job result, please ensure you have also moved the ."+this.data.name+" folder to this directory as well.", region: "top", style:"width:90%;height:40%;"});
			//this.viewer= new ContentPane({content: "", region: "center"});
			this.viewer = new WorkspaceExplorerView({region: "center", path: this._hiddenPath});
			// console.log("[JobResult] WSV: ", this.viewer);
			this.addChild(this.viewHeader);
			this.addChild(this.viewer);

			this.on("i:click", function(evt){
				var rel = domAttr.get(evt.target, 'rel');
				if(rel){
					WorkspaceManager.downloadFile(rel);
				}else{
					console.warn("link not found: ", rel);
				}
			});
		}
	});
});
<commit_msg>added job id to the job header table and parsed the ustrings so they look like regular json. also added stubs for a collapsable title pane for the parameters<commit_after>define([
	"dojo/_base/declare", "dijit/layout/BorderContainer", "dojo/on",
	"dojo/dom-class", "dijit/layout/ContentPane", "dojo/dom-construct",
	"../PageGrid", "../formatter", "../../WorkspaceManager", "dojo/_base/lang",
	"dojo/dom-attr", /*"dijit/TitlePane",*/ "../WorkspaceExplorerView", "dijit/Dialog"
], function(declare, BorderContainer, on,
			domClass, ContentPane, domConstruct,
			Grid, formatter, WorkspaceManager, lang,
			domAttr, WorkspaceExplorerView, Dialog
		/*,TitlePane*/){
	return declare([BorderContainer], {
		"baseClass": "ExperimentViewer",
		"disabled": false,
		"query": null,
		data: null,
		//params: null,
		containerType: "job_result",
		_resultType: null,
		_jobOut: {
			"id": {"label": "Job ID"},
			"start_time": {"label": "Start time", "format": formatter.epochDate},
			"end_time": {"label": "End time", "format": formatter.epochDate},
			"elapsed_time": {"label": "Run time", "format": formatter.runTime},
			"parameters": {"label": "Parameters", "format": function(d){
				if(d.hasOwnProperty('ustring')){
				    d['ustring'] = JSON.parse(d['ustring'])
				}
				return '
' + JSON.stringify(d,null,2) + "
"
			}}
		},
		_jobOrder: ["id", "start_time", "end_time", "elapsed_time", "parameters"],
		_appLabel: "",
		_resultMetaTypes: {},
		_autoLabels: {},
		_setDataAttr: function(data){
			this.data = data;
			//console.log("[JobResult] data: ", data);
			this._hiddenPath = data.path + "." + data.name;
			// console.log("[JobResult] Output Files: ", this.data.autoMeta.output_files);
			var _self = this;

			// check to see if there's a hidden .folder with the actual data
			WorkspaceManager.getObject(this._hiddenPath, true).otherwise(function(err) {
				new Dialog({
					content: "No output from this job was found in the '."+_self.data.name+"' folder. "
								  +"If you moved the job result file from another location, please ensure you "
									+"have also moved the accomanying folder to this location.",
					title: "Error Loading Job Result",
					style: "width: 300px !important;"
				}).show();
			});

			// get the contents directly from the hidden folder, since metadata may be stale after a move
			WorkspaceManager.getFolderContents(this._hiddenPath, true, true)
				.then(function(objs){
					//console.log("[JobResult] objects: ", objs);
						_self._resultObjects = objs;
						_self.setupResultType();
						_self.refresh();
				});

		},
		isSummaryView: function(){
			return false;
		},
		setupResultType: function(){
			// console.log("[JobResult] setupResultType()");
			if(this.data.autoMeta.app.id){
				this._resultType = this.data.autoMeta.app.id;
				// console.log("[JobResult] _resultType:",this._resultType);
			}
			if(this._resultType == "GenomeAssembly"){
				this._appLabel = "Genome Assembly";
			}
			else{
				this._appLabel = this._resultType;
			}
		},
		getExtraMetaDataForHeader: function(job_output){
			return job_output;
		},
		refresh: function(){
			// console.log("[JobResult] refresh()");
			if(this.data){
				var jobHeader = '

';
				if(this.data.autoMeta && this.data.autoMeta.app){
					jobHeader = jobHeader + this._appLabel + " ";
				}
				jobHeader = jobHeader + "Job Result" + '
';
				//this.viewer.set('content',jobHeader);

				var output = [];
				output.push(jobHeader + '

');
				var job_output = [];

				// add extra metadata header lines
				job_output = this.getExtraMetaDataForHeader(job_output)

				this._jobOrder.forEach(function(prop){
					/*if (prop=="output_files") { return; }
					if (prop=="app") { return; }
					if (prop=="job_output") { return; }
					if (prop=="hostname") { return; }*/
					if(!this.data.autoMeta[prop]){
						return;
					}

					if(this._jobOut.hasOwnProperty(prop)){
						//this._jobOut[prop]["value"]=this.data.autoMeta[prop];
						var tableLabel = this._jobOut[prop].hasOwnProperty("label") ? this._jobOut[prop]["label"] : prop;
						var tableValue = this._jobOut[prop].hasOwnProperty("format") ? this._jobOut[prop]["format"](this.data.autoMeta[prop]) : this.data.autoMeta[prop];
						// if(prop == 'parameters') {
						// 	this.params = new TitlePane({
						// 		title: "Parameters",
						// 		style: "margin-bottom:5px;",
						// 		open: false,
						// 		content: tableValue
						// 	});
						// 	job_output.push('

');
						//} else {
							job_output.push('
' + this._jobOut[prop]["label"] + '	' + tableValue + "
");
						//}
					}
				}, this);
			}

			output.push.apply(output, job_output);
			output.push("

");

			if(this.data.userMeta){
				Object.keys(this.data.userMeta).forEach(function(prop){
					output.push("
" + prop + ": " + this.data.userMeta[prop] + "
");
				}, this);
			}

			output.push("
");
			this.viewHeader.set("content", output.join(""));
			//domConstruct.place(this.params.domNode, "param-div");
			//domConstruct.byId("param-div").appendChild(this.params.domNode);
			this.resize();
		},
		startup: function(){
			if(this._started){
				return;
			}
			this.inherited(arguments);
			this.viewHeader = new ContentPane({content: "Loading data from "+this.data.name+" job file.  If you have moved your job result, please ensure you have also moved the ."+this.data.name+" folder to this directory as well.", region: "top", style:"width:90%;height:30%;"});
			//this.viewer= new ContentPane({content: "", region: "center"});
			this.viewer = new WorkspaceExplorerView({region: "center", path: this._hiddenPath});
			// console.log("[JobResult] WSV: ", this.viewer);
			this.addChild(this.viewHeader);
			this.addChild(this.viewer);

			this.on("i:click", function(evt){
				var rel = domAttr.get(evt.target, 'rel');
				if(rel){
					WorkspaceManager.downloadFile(rel);
				}else{
					console.warn("link not found: ", rel);
				}
			});
		}
	});
});
<|endoftext|>


<commit_before>'use strict';

/* global cw, shp */
L.Shapefile = L.GeoJSON.extend({
  options: {
    importUrl: 'shp.js'
  },

  initialize: function(file, options) {
    L.Util.setOptions(this, options);
    if (typeof cw !== 'undefined') {
      /*eslint-disable no-new-func*/
      if (!options.isArrayBufer) {
        this.worker = cw(new Function('data', 'cb', 'importScripts("' + this.options.importUrl + '");shp(data).then(cb);'));
      } else {
        this.worker = cw(new Function('data', 'importScripts("' + this.options.importUrl + '"); return shp.parseZip(data);'));
      }
      /*eslint-enable no-new-func*/
    }
    L.GeoJSON.prototype.initialize.call(this, {
      features: []
    }, options);
    this.addFileData(file);
  },

  addFileData: function(file) {
    var self = this;
    this.fire('data:loading');
    if (typeof file !== 'string' && !('byteLength' in file)) {
      var data = this.addData(file);
      this.fire('data:loaded');
      return data;
    }
    if (!this.worker) {
      shp(file).then(function(data) {
        self.addData(data);
        self.fire('data:loaded');
      });
      return this;
    }
    var promise;
    if (this.options.isArrayBufer) {
      promise = this.worker.data(file, [file]);
    } else {
      promise = this.worker.data(cw.makeUrl(file));
    }

    promise.then(function(data) {
      self.addData(data);
      self.fire('data:loaded');
      self.worker.close();
    });
    return this;
  }
});

L.shapefile = function(a, b, c) {
  return new L.Shapefile(a, b, c);
};
<commit_msg>Add error event<commit_after>'use strict';

/* global cw, shp, L */
L.Shapefile = L.GeoJSON.extend({
  options: {
    importUrl: 'shp.js'
  },

  initialize: function(file, options) {
    L.Util.setOptions(this, options);
    if (typeof cw !== 'undefined') {
      /*eslint-disable no-new-func*/
      if (!options.isArrayBufer) {
        this.worker = cw(new Function('data', 'cb', 'importScripts("' + this.options.importUrl + '");shp(data).then(cb);'));
      } else {
        this.worker = cw(new Function('data', 'importScripts("' + this.options.importUrl + '"); return shp.parseZip(data);'));
      }
      /*eslint-enable no-new-func*/
    }
    L.GeoJSON.prototype.initialize.call(this, {
      features: []
    }, options);
    this.addFileData(file);
  },

  addFileData: function(file) {
    var self = this;
    this.fire('data:loading');
    if (typeof file !== 'string' && !('byteLength' in file)) {
      var data = this.addData(file);
      this.fire('data:loaded');
      return data;
    }
    if (!this.worker) {
      shp(file).then(function(data) {
        self.addData(data);
        self.fire('data:loaded');
      }, function(e) {
        self.fire('data:error', e);
      });
      return this;
    }
    var promise;
    if (this.options.isArrayBufer) {
      promise = this.worker.data(file, [file]);
    } else {
      promise = this.worker.data(cw.makeUrl(file));
    }

    promise.then(function(data) {
      self.addData(data);
      self.fire('data:loaded');
      self.worker.close();
    }, function(e) {
      self.fire('data:error', e);
    });
    return this;
  }
});

L.shapefile = function(a, b, c) {
  return new L.Shapefile(a, b, c);
};
<|endoftext|>


<commit_before>class AuthCommunicationService {

  constructor($http) {
    "ngInject";
    this.$http = $http;
  }

  login(email,password) {
    return this.$http.post("/api/auth/",{ email,password })
      .then((res) => res.data);
  }

  update() {
    return this.$http.get("/api/auth/status/")
      .then((res) => res.data);
  }

  logout() {
    let email = "",password = "";
    return this.$http.post("/api/auth/logout/",{ email, password });
  }
}

export default AuthCommunicationService;
<commit_msg>removed username and password from logout<commit_after>class AuthCommunicationService {

  constructor($http) {
    "ngInject";
    this.$http = $http;
  }

  login(email,password) {
    return this.$http.post("/api/auth/",{ email,password })
      .then((res) => res.data);
  }

  update() {
    return this.$http.get("/api/auth/status/")
      .then((res) => res.data);
  }

  logout() {
    return this.$http.post("/api/auth/logout/");
  }
}

export default AuthCommunicationService;
<|endoftext|>


<commit_before>//helper function
function inArray(needle, haystack) {
    var length = haystack.length;
    for (var i = 0; i < length; i++) {
        if (haystack[i].onData == needle) return true;
        if (haystack[i].table == needle) return true;
    }
    return false;
}
// transitions and animations
Vue.transition('fade', {
    enterClass: 'fadeInRight',
    leaveClass: 'fadeOutLeft'
});
Vue.transition('actions', {
    enterClass: 'fadeInRight',
    leaveClass: 'zoomOutUp'
});
var vm = new Vue({
    el: 'body',
    data: {
        //Booleans
        show: false,
        submit: false,
        error: false,
        OneToManyBool: false,
        more: false,
        OpenClose: false,
        //error message
        errorMsg: '',
        // Type select
        select: ['String', 'date', 'longText', 'integer', 'biginteger', 'boolean', 'float'],
        selected: '0',
        // rows counts
        rows: 0,
        // your base Url
        baseUrl: baseURL,
        // Tables
        OneToMany: scaffoldList,
        attributes: [],
        OneToManyRows: 0,
        table: '',
        OneToManyData: [],
    },
    methods: {
        // add row
        increment: function() {
            this.error = false;
            this.rows += 1;
        },
        //delete row
        decrement: function() {
            if (this.rows == 0 && this.OneToManyRows == 0) {
                this.errorMsg = 'Can not remove the line!!'
                this.error = true;
            } else {
                if (this.OneToManyRows != 0) {
                    this.OneToManyData.$remove(this.OneToManyRows);
                    this.OneToManyRows -= 1;
                    return;
                }
                this.rows -= 1;
            }
        },
        // add relation
        addOneToMany: function() {
            this.OneToManyBool = true;
            if (this.OpenClose) {
                var onData = $('#on').val();
                var table = $('#tbl').val();
                if (!onData || inArray(table, this.OneToManyData)) {
                    this.errorMsg = "Whoops, Error!!";
                    this.error = true
                    return;
                }
                this.OneToManyData.push({
                    id: this.OneToManyRows,
                    table: this.table,
                    onData: onData
                });
                this.OneToManyRows += 1;
            }
            this.error = false;
        },
        // get attributes
        getAttr: function(index) {
            console.log(index);
            this.selected = $('#tbl').val();
            console.log(this.baseUrl + '/scaffold/getAttributes/' + this.selected);
            $.getJSON(this.baseUrl + '/scaffold/getAttributes/' + this.selected, function(response) {
                this.attributes = response
                this.table = this.selected;
                this.OpenClose = true;
            }.bind(this)).error(function(response) {
                vm.errorMsg = 'Field not founds or the table does not migrated';
                vm.error = true
            });
        },
        // switch
        lastStep: function() {
            this.submit = false;
            this.more = false;
            this.OneToManyBool = false;
        },
        //switch
        lastOne: function() {
            this.submit = !this.submit;
            this.OneToManyBool = false;
        },
        //romove relation
        removeRelation: function(item) {
            this.OneToManyData.$remove(item);
        }
    }
})
<commit_msg>remove main.js<commit_after><|endoftext|>


<commit_before>import GroupMenuModule from "./groupMenu";

const { module } = angular.mock;

describe("GroupMenu", () => {
  beforeEach(module(GroupMenuModule));

  let $log;
  beforeEach(inject(($injector) => {
    $log = $injector.get("$log");
    $log.reset();
  }));
  afterEach(() => {
    $log.assertEmpty();
  });

  describe("Module", () => {
    it("is named groupMenu", () => {
      expect(GroupMenuModule).to.equal("groupMenu");
    });
  });

  describe("Controller", () => {
    let $componentController, $mdDialog, $state, $q, $rootScope;
    beforeEach(inject(($injector) => {
      $componentController = $injector.get("$componentController");
      $mdDialog = $injector.get("$mdDialog");
      $state = $injector.get("$state");
      $q = $injector.get("$q");
      $rootScope = $injector.get("$rootScope");
      sinon.stub($mdDialog, "show");
      sinon.stub($state, "go");
    }));

    it("opens join group dialog", () => {
      let $ctrl = $componentController("groupMenu", {});
      $mdDialog.show.returns($q((resolve) => {
        resolve(1337);
      }));
      $ctrl.openJoinGroupDialog();
      $rootScope.$apply();
      expect($state.go).to.have.been.calledWith( "group", { groupId: 1337 } );
    });
  });
});
<commit_msg>test: groupMenu<commit_after>import GroupMenuModule from "./groupMenu";

const { module } = angular.mock;

describe("GroupMenu", () => {
  beforeEach(module(GroupMenuModule));

  let $log;
  beforeEach(inject(($injector) => {
    $log = $injector.get("$log");
    $log.reset();
  }));
  afterEach(() => {
    $log.assertEmpty();
  });

  describe("Module", () => {
    it("is named groupMenu", () => {
      expect(GroupMenuModule).to.equal("groupMenu");
    });
  });

  describe("Controller", () => {
    let $componentController, $mdDialog, $state, $q, $rootScope, CurrentGroup, GroupService;
    beforeEach(inject(($injector) => {
      $componentController = $injector.get("$componentController");
      $mdDialog = $injector.get("$mdDialog");
      $state = $injector.get("$state");
      $q = $injector.get("$q");
      GroupService = $injector.get("GroupService");
      CurrentGroup = $injector.get("CurrentGroup");
      $rootScope = $injector.get("$rootScope");
      sinon.stub($mdDialog, "show");
      sinon.stub($state, "go");
      sinon.stub(GroupService, "listMy");
    }));

    it("opens join group dialog", () => {
      let $ctrl = $componentController("groupMenu", {});
      $mdDialog.show.returns($q((resolve) => {
        resolve(1337);
      }));
      $ctrl.openJoinGroupDialog();
      $rootScope.$apply();
      expect($state.go).to.have.been.calledWith( "group", { groupId: 1337 } );
    });

    it("goes to group", () => {
      let $ctrl = $componentController("groupMenu", {});
      CurrentGroup.set({ id: 84 });
      $ctrl.groupButton();
      expect($state.go).to.have.been.calledWith("group", { groupId: 84 });
    });

    it("goes to home", () => {
      let $ctrl = $componentController("groupMenu", {});
      $ctrl.groupButton();
      expect($state.go).to.have.been.calledWith("home");
    });

    it("gets data on init", () => {
      let $ctrl = $componentController("groupMenu", {});
      GroupService.listMy.returns($q((resolve) => {
        resolve([{ id: 85 }]);
      }));
      $ctrl.$onInit();
      $rootScope.$apply();
      expect(GroupService.listMy).to.have.been.called;
      expect($ctrl.groups[0]).to.deep.equal({ id: 85 });
    });
  });
});
<|endoftext|>


<commit_before>define(['jquery', 'backbone'], function($, Backbone){
    var View = Backbone.View.extend({
        el: '#mmx-topics',
        initialize: function(options){
            var me = this;
            me.options = options;
            me.options.eventPubSub.bind('initMMXProjecttopics', function(model){
                me.model = model;
                $('#mmx-new-topic-input').val('');
                me.getTopics(function(){
                    me.render();
                });
                me.modal = $('#mmx-publishtopic-modal');
                $('#mmx-publishtopic-btn').click(function(){
                    me.publishTopic();
                });
            });
        },
        events : {
            'click #mmx-new-topic-btn': 'createTopic',
            'click #mmx-topic-list table tbody td .topic-delete-btn': 'deleteTopic',
            'click #mmx-topic-list table tbody td .topic-publish-btn': 'showPublishModal'
        },
        getTopics: function(cb){
            var me = this;
            AJAX('apps/'+me.model.attributes.id+'/topics', 'GET', 'application/json', null, function(res, status, xhr){
                me.topics = res;
                cb();
            }, function(xhr, status, thrownError){
                alert(xhr.responseText);
            });
        },
        render: function(){
            this.$el.find('#mmx-topic-list').html(_.template($('#MessagingTopicsListView').html(), {
                col : this.topics
            }));
        },
        createTopic: function(){
            var me = this;
            var input = $('#mmx-new-topic-input');
            if(!$.trim(input.val()).length) return alert('Topic Name is a required field.');
            AJAX('apps/'+me.model.attributes.id+'/topics', 'POST', 'application/json', {
                name : input.val()
            }, function(res, status, xhr){
                input.val('');
                me.topics.push(res);
                me.render();
            }, function(xhr, status, thrownError){
                alert(xhr.responseText);
            });
        },
        deleteTopic: function(e){
            var me = this;
            Alerts.Confirm.display({
                title   : 'Confirm Topic Deletion',
                content : 'Please verify that you wish to delete this topic.'
            }, function(){
                var row = $(e.currentTarget).closest('tr');
                AJAX('apps/'+me.model.attributes.id+'/topics/'+encodeURIComponent(row.attr('did')), 'DELETE', 'application/json', null, function(res, status, xhr){
                    utils.removeByAttr(me.topics, 'id', row.attr('did'));
                    row.hide('slow', function(){
                        row.remove();
                    });
                }, function(xhr, status, thrownError){
                    alert(xhr.responseText);
                });
            });
        },
        showPublishModal: function(e){
            var tid = $(e.currentTarget).closest('tr').attr('did');
            this.activeTopic = utils.getByAttr(this.topics, 'id', tid)[0];
            this.modal.find('span.mmx-topic-name-placeholder').text(this.activeTopic.name);
            this.modal.modal('show');
        },
        publishTopic: function(){
            var me = this;
            var msg = this.modal.find('textarea');
            AJAX('apps/'+me.model.attributes.id+'/topics/'+encodeURIComponent(this.activeTopic.id)+'/publish', 'POST', 'application/json', {
                payload : msg.val()
            }, function(res, status, xhr){
                msg.val('');
                alert('message sent');
            }, function(xhr, status, thrownError){
                alert(xhr.responseText);
            });
        }
    });
    return View;
});<commit_msg>fix multiple topic post bug<commit_after>define(['jquery', 'backbone'], function($, Backbone){
    var View = Backbone.View.extend({
        el: '#mmx-topics',
        initialize: function(options){
            var me = this;
            me.options = options;
            me.options.eventPubSub.bind('initMMXProjecttopics', function(model){
                me.model = model;
                $('#mmx-new-topic-input').val('');
                me.getTopics(function(){
                    me.render();
                });
            });
            me.modal = $('#mmx-publishtopic-modal');
            $('#mmx-publishtopic-btn').click(function(){
                me.publishTopic();
            });
        },
        events : {
            'click #mmx-new-topic-btn': 'createTopic',
            'click #mmx-topic-list table tbody td .topic-delete-btn': 'deleteTopic',
            'click #mmx-topic-list table tbody td .topic-publish-btn': 'showPublishModal'
        },
        getTopics: function(cb){
            var me = this;
            AJAX('apps/'+me.model.attributes.id+'/topics', 'GET', 'application/json', null, function(res, status, xhr){
                me.topics = res;
                cb();
            }, function(xhr, status, thrownError){
                alert(xhr.responseText);
            });
        },
        render: function(){
            this.$el.find('#mmx-topic-list').html(_.template($('#MessagingTopicsListView').html(), {
                col : this.topics
            }));
        },
        createTopic: function(){
            var me = this;
            var input = $('#mmx-new-topic-input');
            if(!$.trim(input.val()).length) return alert('Topic Name is a required field.');
            AJAX('apps/'+me.model.attributes.id+'/topics', 'POST', 'application/json', {
                name : input.val()
            }, function(res, status, xhr){
                input.val('');
                me.topics.push(res);
                me.render();
            }, function(xhr, status, thrownError){
                alert(xhr.responseText);
            });
        },
        deleteTopic: function(e){
            var me = this;
            Alerts.Confirm.display({
                title   : 'Confirm Topic Deletion',
                content : 'Please verify that you wish to delete this topic.'
            }, function(){
                var row = $(e.currentTarget).closest('tr');
                AJAX('apps/'+me.model.attributes.id+'/topics/'+encodeURIComponent(row.attr('did')), 'DELETE', 'application/json', null, function(res, status, xhr){
                    utils.removeByAttr(me.topics, 'id', row.attr('did'));
                    row.hide('slow', function(){
                        row.remove();
                    });
                }, function(xhr, status, thrownError){
                    alert(xhr.responseText);
                });
            });
        },
        showPublishModal: function(e){
            var tid = $(e.currentTarget).closest('tr').attr('did');
            this.activeTopic = utils.getByAttr(this.topics, 'id', tid)[0];
            this.modal.find('span.mmx-topic-name-placeholder').text(this.activeTopic.name);
            this.modal.modal('show');
        },
        publishTopic: function(){
            var me = this;
            var msg = this.modal.find('textarea');
            AJAX('apps/'+me.model.attributes.id+'/topics/'+encodeURIComponent(this.activeTopic.id)+'/publish', 'POST', 'application/json', {
                payload : msg.val()
            }, function(res, status, xhr){
                msg.val('');
                alert('message sent');
            }, function(xhr, status, thrownError){
                alert(xhr.responseText);
            });
        }
    });
    return View;
});<|endoftext|>


<commit_before>import React from 'react';
import { action } from '@storybook/addon-actions';
import { Store, State } from '@sambego/storybook-state';
import { storiesOf } from '@storybook/react';
import { checkA11y } from 'storybook-addon-a11y';
import { withKnobs, boolean } from "@storybook/addon-knobs/react";
import { withInfo } from '@storybook/addon-info';
import { Box, Button, DataGrid, Heading4, IconMenu, MenuItem, Link, Section, StatusBullet, TextTiny, Tooltip } from '../components';
import rows from '../static/data/datagrid';

const TooltippedStatusBullet = Tooltip(StatusBullet);

const store = new Store({
  comparableId: 1,
});

const handleButtonClick = () => {
  store.set({ comparableId: store.get('comparableId') + 1 });
  action('onClick - refresh data - set comparableId to other value')();
};

storiesOf('DataGrids', module)
  .addDecorator((story, context) => withInfo('common info')(story)(context))
  .addDecorator(checkA11y)
  .addDecorator(withKnobs)
  .add('Basic', () => (
    <Box>

        <Button onClick={handleButtonClick} label="Refresh data" level="primary" />

      <State store={store}>
        <DataGrid selectable={boolean('Selectable', false)} comparableId={1}>
          <DataGrid.HeaderRow>
            <DataGrid.HeaderCell flex="min-width" />
            <DataGrid.HeaderCell border="right" onClick={action('onClick: column sort')} sorted="asc">Invoice</DataGrid.HeaderCell>
            <DataGrid.HeaderCell onClick={action('onClick: column sort')} align="right">Amount</DataGrid.HeaderCell>
            <DataGrid.HeaderCell flex="2" onClick={action('onClick: column sort')}>Customer</DataGrid.HeaderCell>
            <DataGrid.HeaderCell onClick={action('onClick: column sort')}>Due date</DataGrid.HeaderCell>
            <DataGrid.HeaderCell flex="min-width"/>
          </DataGrid.HeaderRow>
          {
            rows.map((row, index) => {
              return (
                <DataGrid.BodyRow key={index}>
                  <DataGrid.Cell align="center" flex="min-width">
                    <TooltippedStatusBullet
                      color={row.column1}
                      tooltip={<TextTiny>Overdue</TextTiny>}
                      tooltipColor={row.column1}
                      tooltipSize="small"
                      size="large"
                    />
                  </DataGrid.Cell>
                  <DataGrid.Cell border="right"><Link href="#" inherit={false}>{row.column5}</Link> </DataGrid.Cell>
                  <DataGrid.Cell align="right" strong> {`€ ${row.column3}`}</DataGrid.Cell>
                  <DataGrid.Cell flex="2"> {row.column2}</DataGrid.Cell>
                  <DataGrid.Cell soft>{row.column4}</DataGrid.Cell>
                  <DataGrid.Cell align="right" flex="min-width">
                    <IconMenu position="top-right">
                      <MenuItem>Remove row</MenuItem>
                    </IconMenu>
                  </DataGrid.Cell>
                </DataGrid.BodyRow>
              );
            })
          }
          <DataGrid.FooterRow backgroundColor="neutral">
            <DataGrid.Cell flex="min-width"/>
            <DataGrid.Cell align="right" border="right" soft>
              <Heading4>Total Excl Btw</Heading4>
            </DataGrid.Cell>
            <DataGrid.Cell align="right" strong>
              € 13460.52
            </DataGrid.Cell>
            <DataGrid.Cell flex="2"/>
            <DataGrid.Cell/>
            <DataGrid.Cell flex="min-width"/>
          </DataGrid.FooterRow>

          <DataGrid.FooterRow backgroundColor="neutral">
            <DataGrid.Cell flex="min-width"/>
            <DataGrid.Cell align="right" border="right" soft>
              <Heading4>+ VAT</Heading4>
            </DataGrid.Cell>
            <DataGrid.Cell align="right" strong>
              € 2826.71
            </DataGrid.Cell>
            <DataGrid.Cell flex="2"/>
            <DataGrid.Cell/>
            <DataGrid.Cell flex="min-width"/>
          </DataGrid.FooterRow>

          <DataGrid.FooterRow backgroundColor="neutral">
            <DataGrid.Cell flex="min-width"/>
            <DataGrid.Cell align="right" border="right" soft>
              <Heading4>Total Incl Btw</Heading4>
            </DataGrid.Cell>
            <DataGrid.Cell align="right" strong backgroundColor="white" border="around">
              € 16287.23
            </DataGrid.Cell>
            <DataGrid.Cell flex="2"/>
            <DataGrid.Cell/>
            <DataGrid.Cell flex="min-width"/>
          </DataGrid.FooterRow>
        </DataGrid>
      </State>
    </Box>
  ));
<commit_msg>Storybook: updated stories<commit_after>import React from 'react';
import { action } from '@storybook/addon-actions';
import { Store, State } from '@sambego/storybook-state';
import { storiesOf } from '@storybook/react';
import { checkA11y } from 'storybook-addon-a11y';
import { withKnobs, boolean, number } from "@storybook/addon-knobs/react";
import { withInfo } from '@storybook/addon-info';
import { Box, Button, DataGrid, Heading4, IconMenu, MenuItem, Link, Section, StatusBullet, TextTiny, Tooltip } from '../components';
import rows from '../static/data/datagrid';

const TooltippedStatusBullet = Tooltip(StatusBullet);

const store = new Store({
  comparableId: 1,
});

const handleButtonClick = () => {
  store.set({ comparableId: store.get('comparableId') + 1 });
  action('onClick - refresh data - set comparableId to other value')();
};

storiesOf('DataGrids', module)
  .addDecorator((story, context) => withInfo('common info')(story)(context))
  .addDecorator(checkA11y)
  .addDecorator(withKnobs)
  .add('Basic', () => (
    <Box>

        <Button onClick={handleButtonClick} label="Refresh data" level="primary" />

      <State store={store}>
        <DataGrid
          selectable={boolean('Selectable', true)}
          stickyFromLeft={number('Sticky from left', 3)}
          stickyFromRight={number('Sticky from right', 1)}
          comparableId={1}
        >
          <DataGrid.HeaderRow>
            <DataGrid.HeaderCell flex="min-width" />
            <DataGrid.HeaderCell onClick={action('onClick: column sort')} sorted="asc">Invoice</DataGrid.HeaderCell>
            <DataGrid.HeaderCell onClick={action('onClick: column sort')} align="right">Amount</DataGrid.HeaderCell>
            <DataGrid.HeaderCell flex="2" onClick={action('onClick: column sort')}>Customer</DataGrid.HeaderCell>
            <DataGrid.HeaderCell onClick={action('onClick: column sort')}>Due date</DataGrid.HeaderCell>
            <DataGrid.HeaderCell flex="min-width"/>
          </DataGrid.HeaderRow>
          {
            rows.map((row, index) => {
              return (
                <DataGrid.BodyRow key={index}>
                  <DataGrid.Cell align="center" flex="min-width">
                    <TooltippedStatusBullet
                      color={row.column1}
                      tooltip={<TextTiny>Overdue</TextTiny>}
                      tooltipColor={row.column1}
                      tooltipSize="small"
                      size="large"
                    />
                  </DataGrid.Cell>
                  <DataGrid.Cell><Link href="#" inherit={false}>{row.column5}</Link> </DataGrid.Cell>
                  <DataGrid.Cell align="right" strong> {`€ ${row.column3}`}</DataGrid.Cell>
                  <DataGrid.Cell flex="2">{row.column2}</DataGrid.Cell>
                  <DataGrid.Cell soft>{row.column4}</DataGrid.Cell>
                  <DataGrid.Cell align="right" flex="min-width">
                    <IconMenu position="top-right">
                      <MenuItem onClick={action('onClick: delete row')}>Remove row</MenuItem>
                    </IconMenu>
                  </DataGrid.Cell>
                </DataGrid.BodyRow>
              );
            })
          }
          <DataGrid.FooterRow backgroundColor="neutral">
            <DataGrid.Cell flex="min-width"/>
            <DataGrid.Cell align="right" soft>
              <Heading4>Total Excl Btw</Heading4>
            </DataGrid.Cell>
            <DataGrid.Cell align="right" strong>
              € 13460.52
            </DataGrid.Cell>
            <DataGrid.Cell flex="2"/>
            <DataGrid.Cell/>
            <DataGrid.Cell flex="min-width"/>
          </DataGrid.FooterRow>

          <DataGrid.FooterRow backgroundColor="neutral">
            <DataGrid.Cell flex="min-width"/>
            <DataGrid.Cell align="right" soft>
              <Heading4>+ VAT</Heading4>
            </DataGrid.Cell>
            <DataGrid.Cell align="right" strong>
              € 2826.71
            </DataGrid.Cell>
            <DataGrid.Cell flex="2"/>
            <DataGrid.Cell/>
            <DataGrid.Cell flex="min-width"/>
          </DataGrid.FooterRow>

          <DataGrid.FooterRow backgroundColor="neutral">
            <DataGrid.Cell flex="min-width"/>
            <DataGrid.Cell align="right" soft>
              <Heading4>Total Incl Btw</Heading4>
            </DataGrid.Cell>
            <DataGrid.Cell align="right" strong backgroundColor="white" border="around">
              € 16287.23
            </DataGrid.Cell>
            <DataGrid.Cell flex="2"/>
            <DataGrid.Cell/>
            <DataGrid.Cell flex="min-width"/>
          </DataGrid.FooterRow>
        </DataGrid>
      </State>
    </Box>
  ));
<|endoftext|>


<commit_before>define({
    ru: {
        'Allowed values:'             : 'Допустимые значения:',
        'Compare all with predecessor': 'Сравнить всё с предыдущей версией',
        'compare changes to:'         : 'сравнить с:',
        'compared to'                 : 'в сравнении с',
        'Default value:'              : 'По умолчанию:',
        'Description'                 : 'Описание',
        'Field'                       : 'Название',
        'General'                     : 'Общая информация',
        'Generated with'              : 'Сгенерировано с помощью',
        'Name'                        : 'Название',
        'No response values.'         : 'Нет значений для ответа.',
        'optional'                    : 'необязательный',
        'Parameter'                   : 'Параметры',
        'Permission:'                 : 'Доступ:',
        'Response'                    : 'Ответ',
        'Send'                        : 'Отправить',
        'Send a Sample Request'       : 'Отправить тестовый запрос',
        'show up to version:'         : 'показать версию:',
        'Size range:'                 : 'Ограничения:',
        'Type'                        : 'Тип',
        'url'                         : 'url'
    }
});
<commit_msg>Update Russian translation.<commit_after>define({
    ru: {
        'Allowed values:'             : 'Допустимые значения:',
        'Compare all with predecessor': 'Сравнить с предыдущей версией',
        'compare changes to:'         : 'сравнить с:',
        'compared to'                 : 'в сравнении с',
        'Default value:'              : 'По умолчанию:',
        'Description'                 : 'Описание',
        'Field'                       : 'Название',
        'General'                     : 'Общая информация',
        'Generated with'              : 'Сгенерировано с помощью',
        'Name'                        : 'Название',
        'No response values.'         : 'Нет значений для ответа.',
        'optional'                    : 'необязательный',
        'Parameter'                   : 'Параметр',
        'Permission:'                 : 'Разрешено:',
        'Response'                    : 'Ответ',
        'Send'                        : 'Отправить',
        'Send a Sample Request'       : 'Отправить тестовый запрос',
        'show up to version:'         : 'показать версию:',
        'Size range:'                 : 'Ограничения:',
        'Type'                        : 'Тип',
        'url'                         : 'URL'
    }
});
<|endoftext|>