start to parse variable data blocks, tests are yet missing, coding tables and especially encoder functions not completex
This commit is contained in:
		@@ -1,31 +1,95 @@
 | 
				
			|||||||
export namespace MeterbusLibCodeTables {
 | 
					import {MeterbusLibUtils} from './utils'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export namespace MeterbusLibCodeTables { 
 | 
				
			||||||
    export const MEDIUM_CODE : string[] =
 | 
					    export const MEDIUM_CODE : string[] =
 | 
				
			||||||
            ['Other', 
 | 
					            [
 | 
				
			||||||
               'Oil', 
 | 
					                'Other', 
 | 
				
			||||||
               'Electrity', 
 | 
					                'Oil', 
 | 
				
			||||||
               'Gas', 
 | 
					                'Electrity', 
 | 
				
			||||||
               'Heat (Volume measured at return temperature: outlet',
 | 
					                'Gas', 
 | 
				
			||||||
               'Steam', 
 | 
					                'Heat (Volume measured at return temperature: outlet',
 | 
				
			||||||
               'Hot Water', 
 | 
					                'Steam', 
 | 
				
			||||||
               'Water', 
 | 
					                'Hot  Water', 
 | 
				
			||||||
               'Heat Cost Allocator', 
 | 
					                'Water', 
 | 
				
			||||||
               'Compressed Air',
 | 
					                'Heat Cost Allocator', 
 | 
				
			||||||
               'Cooling Load Meter (Volume measured at return temperature: outlet', 
 | 
					                'Compressed Air',
 | 
				
			||||||
               'Cooling Load Meter (Volume measured at flow temperature: inlet',
 | 
					                'Cooling Load Meter (Volume measured at return temperature: outlet', 
 | 
				
			||||||
               'Heat (Volume measured at flow temperature: inlet)', 
 | 
					                'Cooling Load Meter (Volume measured at flow temperature: inlet',
 | 
				
			||||||
               'Heat / Cooling Load Meter',
 | 
					                'Heat (Volume measured at flow temperature: inlet)', 
 | 
				
			||||||
               'Bus / System', 
 | 
					                'Heat / Cooling Load Meter',
 | 
				
			||||||
               'Unknown Medium',
 | 
					                'Bus / System', 
 | 
				
			||||||
               'Reserved (10)',
 | 
					                'Unknown Medium',
 | 
				
			||||||
               'Reserved (11)',
 | 
					                'Reserved (10)',
 | 
				
			||||||
               'Reserved (12)',
 | 
					                'Reserved (11)',
 | 
				
			||||||
               'Reserved (13)',
 | 
					                'Reserved (12)',
 | 
				
			||||||
               'Reserved (14)',
 | 
					                'Reserved (13)',
 | 
				
			||||||
               'Reserved (15)',
 | 
					                'Reserved (14)',
 | 
				
			||||||
               'Cold Water',
 | 
					                'Reserved (15)',
 | 
				
			||||||
               'Dual Water',
 | 
					                'Cold Water',
 | 
				
			||||||
               'Pressure',
 | 
					                'Dual Water',
 | 
				
			||||||
               'A/D Converter',
 | 
					                'Pressure',
 | 
				
			||||||
 | 
					                'A/D Converter',
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export const DIF_FUNCTION_FIELD : string[] =
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                'Instantaneous value',
 | 
				
			||||||
 | 
					                'Maximum value',
 | 
				
			||||||
 | 
					                'Minimum value',
 | 
				
			||||||
 | 
					                'Value during error state'
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export class DCFt { 
 | 
				
			||||||
 | 
					        name : string
 | 
				
			||||||
 | 
					        length : number
 | 
				
			||||||
 | 
					        encoder : (v: number[]) => any
 | 
				
			||||||
 | 
					        constructor(n : string, l : number, e : (v: number[]) => any) {
 | 
				
			||||||
 | 
					            this.name = n
 | 
				
			||||||
 | 
					            this.length = l
 | 
				
			||||||
 | 
					            this.encoder = e
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export const DIF_CODING_FIELD : DCFt[] =
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                new DCFt('No Data',                   0, (x)=>{ return x}),
 | 
				
			||||||
 | 
					                new DCFt('8 Bit Integer',             1, (x)=>{ return x[0]}),
 | 
				
			||||||
 | 
					                new DCFt('16 Bit Integer',            2, (x)=>{ return (x[1] << 8) + x[0]}),
 | 
				
			||||||
 | 
					                new DCFt('24 Bit Integer',            3, (x)=>{ return (x[2] << 16) + (x[1] << 8) + x[0]}),
 | 
				
			||||||
 | 
					                new DCFt('32 Bit Integer',            4, (x)=>{ return (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]}),
 | 
				
			||||||
 | 
					                new DCFt('32 Bit Real',               4, (x)=>{ return x}), // FIXME
 | 
				
			||||||
 | 
					                new DCFt('48 Bit Integer',            6, (x)=>{ return (x[5] << 40) + (x[4] << 32) + (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]}),       
 | 
				
			||||||
 | 
					                new DCFt('64 Bit Integer',            8, (x)=>{ return (x[7] << 56) + (x[6] << 48) + (x[5] << 40) + (x[4] << 32) + (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]}),
 | 
				
			||||||
 | 
					                new DCFt('Selection for Readout',     0, (x)=>{ return x}),
 | 
				
			||||||
 | 
					                new DCFt('2 Digit BCD',               1, (x)=>{ return MeterbusLibUtils.bcd(x)}),
 | 
				
			||||||
 | 
					                new DCFt('4 Digit BCD',               2, (x)=>{ return MeterbusLibUtils.bcd(x)}),
 | 
				
			||||||
 | 
					                new DCFt('6 Digit BCD',               3, (x)=>{ return MeterbusLibUtils.bcd(x)}),
 | 
				
			||||||
 | 
					                new DCFt('8 Digit BCD',               4, (x)=>{ return MeterbusLibUtils.bcd(x)}),
 | 
				
			||||||
 | 
					                new DCFt('variable length',          -1, (x)=>{ return x}),
 | 
				
			||||||
 | 
					                new DCFt('12 Digit BCD',              6, (x)=>{ return MeterbusLibUtils.bcd(x)}),
 | 
				
			||||||
 | 
					                new DCFt('Special Function',          0, (x)=>{ return x})
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*            
 | 
				
			||||||
 | 
					                    DATA_FIELD_CODES = (
 | 
				
			||||||
 | 
					                            ('No Data',                   0, None),
 | 
				
			||||||
 | 
					                            ('8 Bit Integer',             1, lambda x: x[0]),
 | 
				
			||||||
 | 
					                            ('16 Bit Integer',            2, lambda x: (x[1] << 8) + x[0]),
 | 
				
			||||||
 | 
					                            ('24 Bit Integer',            3, lambda x: (x[2] << 16) + (x[1] << 8) + x[0]),
 | 
				
			||||||
 | 
					                            ('32 Bit Integer',            4, lambda x: (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]),
 | 
				
			||||||
 | 
					                            ('32 Bit Real',               4, lambda x: struct.unpack('f', str(bytearray(x)))[0]),
 | 
				
			||||||
 | 
					                            ('48 Bit Integer',            6, lambda x: (x[5] << 40) + (x[4] << 32) + (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]),       
 | 
				
			||||||
 | 
					                            ('64 Bit Integer',            8, lambda x: (x[7] << 56) + (x[6] << 48) + (x[5] << 40) + (x[4] << 32) + (x[3] << 24) + (x[2] << 16) + (x[1] << 8) + x[0]),
 | 
				
			||||||
 | 
					                            ('Selection for Readout',     0, None),
 | 
				
			||||||
 | 
					                            ('2 Digit BCD',               1, lambda x: MeterbusTypeConversion.bcd(x)),
 | 
				
			||||||
 | 
					                            ('4 Digit BCD',               2, lambda x: MeterbusTypeConversion.bcd(x)),
 | 
				
			||||||
 | 
					                            ('6 Digit BCD',               3, lambda x: MeterbusTypeConversion.bcd(x)),
 | 
				
			||||||
 | 
					                            ('8 Digit BCD',               4, lambda x: MeterbusTypeConversion.bcd(x)),
 | 
				
			||||||
 | 
					                            ('variable length',          -1, None),
 | 
				
			||||||
 | 
					                            ('12 Digit BCD',              6, lambda x: MeterbusTypeConversion.bcd(x)),
 | 
				
			||||||
 | 
					                            ('Special Function',          0, None),
 | 
				
			||||||
 | 
					                           )
 | 
				
			||||||
 | 
					*/                        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										165
									
								
								src/longframe.ts
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								src/longframe.ts
									
									
									
									
									
								
							@@ -6,6 +6,8 @@ import {MeterbusLibCodeTables} from './codetables'
 | 
				
			|||||||
export namespace MeterbusLibLongFrame {
 | 
					export namespace MeterbusLibLongFrame {
 | 
				
			||||||
    export class LongFrame extends MeterbusLibFrames.ControlFrame {
 | 
					    export class LongFrame extends MeterbusLibFrames.ControlFrame {
 | 
				
			||||||
        private _fixedDataHeader : FixedDataHeader
 | 
					        private _fixedDataHeader : FixedDataHeader
 | 
				
			||||||
 | 
					        private _variableDataBlocks : DataBlock[] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        get fixedDataHeader() : FixedDataHeader { return this._fixedDataHeader }
 | 
					        get fixedDataHeader() : FixedDataHeader { return this._fixedDataHeader }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        constructor(telegram : number[]) {
 | 
					        constructor(telegram : number[]) {
 | 
				
			||||||
@@ -16,6 +18,16 @@ export namespace MeterbusLibLongFrame {
 | 
				
			|||||||
            super.parse2() // control frame parse2 method
 | 
					            super.parse2() // control frame parse2 method
 | 
				
			||||||
            this._fixedDataHeader = new FixedDataHeader(this._telegram.slice(7, 19))
 | 
					            this._fixedDataHeader = new FixedDataHeader(this._telegram.slice(7, 19))
 | 
				
			||||||
            this._fixedDataHeader.parse()
 | 
					            this._fixedDataHeader.parse()
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            let consumed : number = 0
 | 
				
			||||||
 | 
					            while (true) {
 | 
				
			||||||
 | 
					                let die : DataBlock = 
 | 
				
			||||||
 | 
					                    new DataBlock(this._telegram.slice(19 + consumed))
 | 
				
			||||||
 | 
					                die.parse()
 | 
				
			||||||
 | 
					                this._variableDataBlocks.push(die)
 | 
				
			||||||
 | 
					                consumed += die.consumed
 | 
				
			||||||
 | 
					                break  //FIXME                
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -61,4 +73,157 @@ export namespace MeterbusLibLongFrame {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export abstract class ADataBlock {
 | 
				
			||||||
 | 
					        protected __consumed : number = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        get consumed() : number {
 | 
				
			||||||
 | 
					            return this.__consumed
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        abstract parse() : void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        toJSON() : any {
 | 
				
			||||||
 | 
					            console.log("x")
 | 
				
			||||||
 | 
					            return MeterbusLibUtils.jsonPrepaper(this, [])
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        getJSON() : string {
 | 
				
			||||||
 | 
					            return JSON.stringify(this)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export class DataBlock extends ADataBlock {
 | 
				
			||||||
 | 
					        private _content : VariableDataBlock | ManufacturerSpecificData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        constructor(data : number[]) {
 | 
				
			||||||
 | 
					            super()
 | 
				
			||||||
 | 
					            if ((data[0] & 0x0f) == 0x0f) {
 | 
				
			||||||
 | 
					                this._content = new ManufacturerSpecificData(data)
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                this._content = new VariableDataBlock(data)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parse() : void {
 | 
				
			||||||
 | 
					            this._content.parse()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        toJSON() : any {
 | 
				
			||||||
 | 
					            return MeterbusLibUtils.jsonPrepaper(this._content, [])
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export class DIF {
 | 
				
			||||||
 | 
					        raw : number
 | 
				
			||||||
 | 
					        function : number
 | 
				
			||||||
 | 
					        coding : number
 | 
				
			||||||
 | 
					        lsb : number
 | 
				
			||||||
 | 
					        extension : number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        toJSON() : any {
 | 
				
			||||||
 | 
					            let dup = MeterbusLibUtils.clone(this)
 | 
				
			||||||
 | 
					            dup.function = MeterbusLibCodeTables.DIF_FUNCTION_FIELD[dup.function]
 | 
				
			||||||
 | 
					            dup.coding = MeterbusLibCodeTables.DIF_CODING_FIELD[dup.coding].name
 | 
				
			||||||
 | 
					            return dup
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export class DIFE {
 | 
				
			||||||
 | 
					        raw : number
 | 
				
			||||||
 | 
					        extension : number
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export class VIF {
 | 
				
			||||||
 | 
					        raw : number
 | 
				
			||||||
 | 
					        unitAndMultiplier : number
 | 
				
			||||||
 | 
					        extension : number
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export class VIFE {
 | 
				
			||||||
 | 
					        raw : number
 | 
				
			||||||
 | 
					        extension : number
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export class VariableDataBlock extends ADataBlock {
 | 
				
			||||||
 | 
					        private _type : string = "VDB"
 | 
				
			||||||
 | 
					        private __indata : number[]
 | 
				
			||||||
 | 
					        private _dif : DIF
 | 
				
			||||||
 | 
					        private _dife : DIFE[] = []
 | 
				
			||||||
 | 
					        private _vif : VIF
 | 
				
			||||||
 | 
					        private _vife : VIFE[] = []
 | 
				
			||||||
 | 
					        private _data : number[]
 | 
				
			||||||
 | 
					        private _value : any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        constructor(data : number[]) {
 | 
				
			||||||
 | 
					            super()
 | 
				
			||||||
 | 
					            this.__indata = data
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parse() : void {
 | 
				
			||||||
 | 
					            this._dif = new DIF()
 | 
				
			||||||
 | 
					            this._dif.raw = this.__indata[0]
 | 
				
			||||||
 | 
					            this.__consumed++
 | 
				
			||||||
 | 
					            this._dif.function = (this._dif.raw & 0x30) >> 4
 | 
				
			||||||
 | 
					            this._dif.coding = this._dif.raw & 0x0f
 | 
				
			||||||
 | 
					            this._dif.lsb = (this._dif.raw & 0x40) >> 6
 | 
				
			||||||
 | 
					            this._dif.extension = (this._dif.raw & 0x80) >> 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (this._dif.extension == 1) {
 | 
				
			||||||
 | 
					                while (true) {
 | 
				
			||||||
 | 
					                    let dife = new DIFE()
 | 
				
			||||||
 | 
					                    dife.raw = this.__indata[this.__consumed]
 | 
				
			||||||
 | 
					                    this.__consumed++
 | 
				
			||||||
 | 
					                    dife.extension = (dife.raw & 0x80) >> 7
 | 
				
			||||||
 | 
					                    this._dife.push(dife)
 | 
				
			||||||
 | 
					                    if (dife.extension == 0) {
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this._vif = new VIF()
 | 
				
			||||||
 | 
					            this._vif.raw = this.__indata[this.__consumed]
 | 
				
			||||||
 | 
					            this.__consumed++
 | 
				
			||||||
 | 
					            this._vif.unitAndMultiplier = this._vif.raw & 0x7f
 | 
				
			||||||
 | 
					            this._vif.extension = (this._vif.raw & 0x80) >> 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (this._vif.extension == 1) {
 | 
				
			||||||
 | 
					                while (true) {
 | 
				
			||||||
 | 
					                    let vife = new VIFE()
 | 
				
			||||||
 | 
					                    vife.raw = this.__indata[this.__consumed]
 | 
				
			||||||
 | 
					                    this.__consumed++
 | 
				
			||||||
 | 
					                    vife.extension = (vife.raw & 0x80) >> 7
 | 
				
			||||||
 | 
					                    this._vife.push(vife)
 | 
				
			||||||
 | 
					                    if (vife.extension == 0) {
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            let dcf : MeterbusLibCodeTables.DCFt = MeterbusLibCodeTables.DIF_CODING_FIELD[this._dif.coding]
 | 
				
			||||||
 | 
					            this._data = this.__indata.slice(this.__consumed, 
 | 
				
			||||||
 | 
					                this.__consumed + dcf.length)
 | 
				
			||||||
 | 
					            this.__consumed += dcf.length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            console.log(dcf.encoder)
 | 
				
			||||||
 | 
					            this._value = dcf.encoder(this._data)
 | 
				
			||||||
 | 
					            console.log(this._value)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export class ManufacturerSpecificData extends ADataBlock {
 | 
				
			||||||
 | 
					        private _type : string = "MSD"
 | 
				
			||||||
 | 
					        private _data : number[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        constructor(data : number[]) {
 | 
				
			||||||
 | 
					            super()
 | 
				
			||||||
 | 
					            this._data = data
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parse() : void {
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -180,6 +180,7 @@ describe('The Meterbus Longframe Library', () => {
 | 
				
			|||||||
        .to.deep.equal([0,0])
 | 
					        .to.deep.equal([0,0])
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    it('should prepare itself as JSON', () => {
 | 
					    it('should prepare itself as JSON', () => {
 | 
				
			||||||
 | 
					        console.log((telegram.frame as MeterbusLibLongFrame.LongFrame).getJSON())
 | 
				
			||||||
        expect((telegram.frame as MeterbusLibLongFrame.LongFrame).getJSON()).to.equal(json_1phase_electric)
 | 
					        expect((telegram.frame as MeterbusLibLongFrame.LongFrame).getJSON()).to.equal(json_1phase_electric)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,4 +48,17 @@ describe('The jsonPrepare function in the Meterbus Library Utils', () => {
 | 
				
			|||||||
        let objOut = {'a': 1, 'b':2}
 | 
					        let objOut = {'a': 1, 'b':2}
 | 
				
			||||||
        expect(MeterbusLibUtils.jsonPrepaper(objIn, [])).to.deep.equal(objOut)
 | 
					        expect(MeterbusLibUtils.jsonPrepaper(objIn, [])).to.deep.equal(objOut)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('The clone function in the Meterbus Library Utils', () => {
 | 
				
			||||||
 | 
					    it('should clone the attributes of an object', () => {
 | 
				
			||||||
 | 
					        let objIn = {'a': 1, 'b': 2}
 | 
				
			||||||
 | 
					        let objOut = {'a': 1, 'b': 2}
 | 
				
			||||||
 | 
					        expect(MeterbusLibUtils.clone(objIn)).to.deep.equal(objOut)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    it('should not just return the same object', () => {
 | 
				
			||||||
 | 
					        let objIn = {'a': 1, 'b':2}
 | 
				
			||||||
 | 
					        let objOut = objIn
 | 
				
			||||||
 | 
					        expect(MeterbusLibUtils.clone(objIn)).to.not.equal(objOut)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
@@ -24,5 +24,14 @@ export namespace MeterbusLibUtils {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return dup
 | 
					        return dup
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export function clone(obj:any) : any {
 | 
				
			||||||
 | 
					        let dup = {}
 | 
				
			||||||
 | 
					        for (let key in obj) {
 | 
				
			||||||
 | 
					            dup[key] = obj[key]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return dup
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user