1 /**
  2  * @fileOverview LPCXpresso1769のPwmペリフェラル、ピンを制御するクラスを定義する。
  3  */
  4 (function(){
  5 var DEV=LPCXpresso1769;
  6 var BCF=DEV._BCF;
  7 var EE=DEV._EE;
  8 var isUndef=MiMicLib.isUndef;
  9 var cloneAssoc=MiMicLib.cloneAssoc;
 10 
 11 
 12 
 13 /**
 14  * LPCXPresso1769.Pwm (Pwm)クラスのコンストラクタ。
 15  * MCUに関連付けしたPwmペリフェラルを生成する。
 16  * Pwmクラスは、PWM1ペリフェラルを管理して、PWMペリフェラル全体の設定を管理する。
 17  * Pwmの分解能は、無指定の場合25MHz(1/4クロック)設定である。関数は、PWMのマッチレジスタ以外に、PCR,CTCR,TCRを同時に初期化する。
 18  * @name LPCXpresso1769.Pwm
 19  * @constructor
 20  * @param {object as LPCXpresso1769.Mcu} i_mcu
 21  * インスタンスを結びつけるMcuオブジェクト。
 22  * @param {aobject as associative array} i_opt
 23  * インスタンス生成と同時にsetOpt関数でセットする値を指定する。省略時は、{freq:100,phl:{power:1,clock:0}}である。
 24  * 詳細は、setOpt関数を参照。 
 25  * @example
 26  * //create PWM  pheripheral
 27  * var mcu=new LPCXpresso1769.Mcu("192.168.0.39");
 28  * var pwm=new LPCXpresso1769.Pwm(mcu,"");
 29  */
 30 DEV.Pwm=function Pwm(i_mcu,i_opt)
 31 {
 32 	try{
 33 		this._mcu=i_mcu;
 34 		//PHL生成。
 35 		this._phl=new DEV.Peripheral(i_mcu,DEV.PHL.PWM1);
 36 		//設定値のロード
 37 		var opt=isUndef(i_opt)?{phl:{}}:
 38 		{//i_optある。
 39 			phl:isUndef(i_opt.phl)?{}:cloneAssoc(i_opt.phl),
 40 			freq:i_opt.freq
 41 		};
 42 		//デフォルト値設定
 43 		if(isUndef(opt.phl.power)){opt.phl.power=1;};
 44 		if(isUndef(opt.phl.clock)){opt.phl.clock=0;};
 45 		if(isUndef(opt.freq)){opt.freq=100;}
 46 		
 47 		var bc="";
 48 		var db=new Array();
 49 		//optionの設定
 50 		bc+=this.BCF_setOpt(opt,db);
 51 		bc+=BCF.setMem(this._PC,0x0,db);
 52 		//PCR
 53 		bc+=BCF.setMem(this._PCR,0x0,db);
 54 		//CTCR
 55 		bc+=BCF.setMem(this._CTCR,0x0,db);
 56 		//TCRに値設定(カウンタとPWMモードを無効化)
 57 		bc+=BCF.setMem(this._TCR,0x0,db);
 58 		bc+=BCF.setMem(this._TC,0x0,db);
 59 		//TCRに値設定(カウンタとPWMモードを有効化)
 60 		bc+=BCF.setMem(this._TCR,0x9,db);
 61 		//初期化
 62 		this._mcu.callMiMicWithCheck(bc+BCF.END,db);
 63 		//ペリフェラルをMCUに登録
 64 		this._mcu.registerPhl(this,"PWM");
 65 	}catch(e){
 66 		throw new MiMicException(e);
 67 	}
 68 
 69 }
 70 DEV.Pwm.prototype=
 71 {
 72 	_cache:{
 73 		mr0:0
 74 	},
 75 	_TCR:0x40018004,
 76 	_TC:0x40018008,
 77 	_PR:0x4001800C,
 78 	_PC:0x40018010,
 79 	_MCR:0x40018018,
 80 	_PCR:0x4001804C,
 81 	_LER:0x40018050,
 82 	_CTCR:0x40018070,
 83 	_MRn:[0x40018018,0x4001801C,0x40018020,0x40018024,0x40018040,0x40018044,0x40018048],
 84 	_phl:null,
 85 	_mcu:null,
 86 
 87 	/**
 88 	 * @private
 89 	 */
 90 	BCF_setOpt:function BCF_setOpt(i_opt,i_db)
 91 	{
 92 		try{
 93 			var bc="";
 94 			var mr0;
 95 			//ペリフェラルの設定
 96 			if(!isUndef(i_opt.phl)){
 97 				bc+=this._phl.BCF_setOpt(i_opt.phl,i_db);
 98 			}
 99 			if(!isUndef(i_opt.freq)){
100 				//サイクル(Hz)とペリフェラルのクロックから、MR0のサイクルを決定
101 				mr0=Math.round(this._phl.getPCLK()/i_opt.freq);
102 				if(mr0<=0){
103 					//ペリフェラルクロック小さすぎワロタ
104 					throw new MiMicException("The peripheral clock too small.");
105 				}
106 				//MR0に値設定
107 				bc+=this.BCF_setMRn(0,mr0,i_db);
108 				//LERにビットセット
109 				bc+=this.BCF_setLER(0,i_db);
110 				this._cache.mr0=mr0;
111 			}
112 			return bc;
113 		}catch(e){
114 			throw new MiMicException(e);
115 		}
116 	},
117 	BCF_setLER:function BCF_setLER(i_ch,i_db)
118 	{
119 		try{
120 			//LERにビットをセット
121 			return BCF.setBit(this._LER,0x01,0x01,i_ch,i_db);
122 		}catch(e){
123 			throw new MiMicException(e);
124 		}
125 	},
126 	BCF_setLERs:function BCF_setLERs(i_mask,i_value,i_db)
127 	{
128 		try{
129 			//LERにビットをセット
130 			return BCF.setBit(this._LER,i_mask,i_value*i_mask,0,i_db);
131 		}catch(e){
132 			throw new MiMicException(e);
133 		}
134 	},
135 	
136 	/**
137 	 * MRnに値を設定するBC
138 	 @private
139 	 */
140 	BCF_setMRn:function BCF_setMRn(i_ch,i_val,i_db)
141 	{
142 		try{
143 			return BCF.setMem(this._MRn[i_ch],i_val,i_db);
144 		}catch(e){
145 			throw new MiMicException(e);
146 		}
147 	},
148 	BCF_setMRnByDuty:function BCF_setMRnByDuty(i_ch,i_duty,i_db)
149 	{
150 		try{
151 			return this.BCF_setMRn(i_ch,Math.round(i_duty*this._cache.mr0),i_db);
152 		}catch(e){
153 			throw new MiMicException(e);
154 		}
155 	},
156 	/**
157 	 * PCRに値を設定するBC
158 	 i_ch=1の場合、エッジモードは無視します。
159 	 @private
160 	 @param i_mask
161 	 @param i_edge
162 	 エッジモード(1/0)
163 	 @param i_en
164 	有効/無効の選択
165 	 */
166 	BCF_setPCRbits:function BCF_setPCRbits(i_mask,i_edge,i_en,i_db)
167 	{
168 		try{
169 			var m,v;
170 			m=v=0;
171 			if(!isUndef(i_edge)){
172 				var t=0xff&i_mask;
173 				v|=i_edge*t;
174 				m|=t;
175 			}
176 			if(!isUndef(i_en)){
177 				var t=0xff00&i_mask;
178 				v|=(i_en*t);
179 				m|=t;
180 			}
181 			//ビットの設定
182 			return BCF.setBit(this._PCR,m,v,0,i_db);
183 		}catch(e){
184 			throw new MiMicException(e);
185 		}
186 	},
187 	
188 	/**
189 	 * Pwmペリフェラルに値を設定する。
190 	 * 設定する値は、全てのPWMチャンネル(PIN)に共通な項目である。
191 	 * @name LPCXpresso1769.Pwm#setOpt
192 	 * @function
193 	 * @param {object as associative array} i_opt
194 	 * GPIOピンのコンフィグレーションパラメタである。必要な値を格納した連想配列で指定する。
195 	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
196 	 * <pre>{freq:int,phl:object as associative array}</pre>
197 	 * <ul>
198 	 * <li>freq - PWMの基本周波数(Hz)である。この値は、全てのPWMチャンネルで共通である。</li>
199 	 * <li>phl - ペリフェラルの共通パラメタである。LPCXpresso1769.Peripheral.setOpt関数のi_optに渡すパラメタである。詳細はLPCXpresso1769.Peripheral.setOptを参照。</li>
200 	 * </ul>
201 	 * @example
202 	 * //create PWM (logical)peripheral
203 	 * var mcu=new LPCXpresso1769.Mcu(“192.168.0.39”);
204 	 * var pwm=new LPCXpresso1769.Pwm(mcu);
205 	 * pwm.setOpt({freq:1000});
206 	 */
207 	setOpt:function setOpt(i_opt)
208 	{
209 		try{
210 			var db=new Array();
211 			var bc=this.BCF_setOpt(i_opt,db);
212 			this._mcu.callMiMicWithCheck(bc+BCF.END,db);
213 		}catch(e){
214 			throw new MiMicException(e);
215 		}
216 	},	
217 	/**
218 	 * PWM機能を持つピンを取得する。
219 	 * ピン識別子で指定されるピンをPWMペリフェラルと結合して、PwmPinを生成する。
220 	 * 関数は、PwmPinオブジェクトのコンストラクタをコールして、PwmPinを生成する。失敗すると、例外をスローする。
221 	 * 生成ルールについての詳細は、PwmPinを参照。
222 	 * @name LPCXpresso1769.Pwm#getPin
223 	 * @function
224 	 * @param {object as ピン識別子} i_pin
225 	 * PWM機能を割り当てるPINの識別子である。
226 	 * @param {object as associative array} i_opt
227 	 * PemPinのコンストラクタに渡すオプション値。省略時は{duty:0,enable:1,pin:{sel:auto}}である。
228 	 * @return {object as LPCXpresso1769.PwmPin}
229 	 * LPCXpresso1769.PwmPinクラスのオブジェクトである。
230 	 * @example
231 	 * //create 100hz d=0.5 pwm
232 	 * var mcu=new LPCXpresso1769.Mcu("192.168.0.39");
233 	 * var pwm=new LPCXpresso1769.Pwm(mcu);
234 	 * var pwmpin=pwm.getPin(LPCXpresso1769.P2[0],{duty:0.5});
235 	 */
236 	getPin:function getPin(i_pin,i_opt)
237 	{
238 		try{
239 			return new DEV.PwmPin(this,i_pin,i_opt);
240 		}catch(e){
241 			throw new MiMicException(e);
242 		}
243 	},
244 	/**
245 	 * PWM機能を持つポート(Pin集合)を取得する。
246 	 * ピン識別子で指定されるピンのセットをPWMペリフェラルと結合して、PwmPortを生成する。
247 	 * 関数は、PwmPortのコンストラクタをコールする。
248 	 * 生成ルールについては、PwmPort関数を参照すること。
249 	 * @name LPCXpresso1769.Pwm#getPort
250 	 * @function
251 	 * @param {array[ピン識別子]} i_pin
252 	 * Pwm機能を割り当てるPINの識別子の配列である。値は、LPCXpresso1769.Pn[m]のメンバ変数である。
253 	 * @param {object as associative array} i_opt
254 	 * AdcPortのコンストラクタに渡すオプション値。省略時はundefinedである。詳細はLPCXpresso1769.PwmPort.setOptを参照。
255 	 * @return {object as LPCXpresso1769.PwmPort}
256 	 * LPCXpresso1769.PwmPortクラスのオブジェクトである。
257 	 * @example
258 	 * //create 2AdcPort that has 2 pins.
259 	 * var mcu=new LPCXpresso1769.Mcu("192.168.0.39");
260 	 * var pwm=new LPCXpresso1769.Pwm(mcu);
261 	 * var port=pwm.getPort([LPCXpresso1769.P0[23],LPCXpresso1769.P0[24]]);
262 	 */
263 	getPort:function getPort(i_pins,i_opt)
264 	{
265 		try{
266 			return new DEV.PwmPort(this,i_pins,i_opt);
267 		}catch(e){
268 			throw new MiMicException(e);
269 		}
270 	}	
271 }
272 
273 /**
274  * Pwm pinからPwmInfoを取得
275  * @private
276  */
277 function pin2PwmPinInfo(i_pin)
278 {
279 	try{
280 		//pinの完全な機能名を得る。(得られれば機能がある。)
281 		var fn=DEV.completePinFunctionName(i_pin,"PWM");
282 		//portとbitを得る(AD0だけしか管理しないよ)
283 		var a=fn.substring(2).split(".");
284 		var r={port:0,ch:parseInt(a[1]),pin_sel:DEV.getPinSelByFunctionName(i_pin,fn)};
285 		if(!isNaN(r.ch)){
286 			return r;
287 		}
288 		throw new MiMicException(EE.INVALID_CFG,"The pin has not PWM fuction.");
289 	}catch(e){
290 		throw new MiMicException(e);	
291 	}
292 }
293 /**
294  * Pwmペリフェラルと複数のPin識別子から、シングルエッジPwmポートを構成する。
295  * Pwmペリフェラルオブジェクトにピン識別子の配列で指定されたピンを関連付けて、PWM機能を持つポートを生成する。
296  * 関数は、ピン識別子を元に、それぞれのピンがPWM機能に接続できるかを調べる。
297  * ピンにPWM機能を割り当てられない場合、例外が発生する。どのピンにPWM機能が割り当てられるかは、MCUのスペックシートを参照すること。
298  * PWMポートは、複数の同一周期のPWMピンのデューティ比を、同期して操作するときに便利である。
299  * @constructor
300  * @name LPCXpresso1769.PwmPort
301  * @param {object as LPCXpresso1769.Pwm} i_pwm
302  * インスタンスを結びつけるPwmオブジェクト。
303  * @param {array[pin識別子]} i_pins
304  * ピン識別子の配列。指定できるのは、LPCXpresso1796.P?[?]である。
305  * @param {object as associative array} i_opt
306  * setOpt関数のi_optに渡すパラメタである。省略可能。省略時は{duty:100,enable:1,pin{sel:auto}}を設定する。
307  * autoは、関数が自動的に決定するPINSELの値である。詳細はsetOpt関数を参照。 
308  * dutyをピン毎に設定する場合は、setDuty関数を使うこと。
309  * @example
310  * //create PWM1.0,PWM1.1
311  * var mcu=new LPCXpresso1769.Mcu(“192.168.0.39”);
312  * var pwm=new LPCXpresso1769.Pwm(mcu,{freq:100});
313  * var port=new LPCXpresso1769.PwmPort(pwm,[LPCXpresso1769.P2[0],LPCXpresso1769.P2[1]]); 
314  */
315 DEV.PwmPort=function PwmPort(i_pwm,i_pins,i_opt)
316 {
317 	try{
318 		this._pwm=i_pwm;
319 		//ピンセットを取得
320 		this._pins=new Array();
321 		//pinに変換する。
322 		for(var i=0;i<i_pins.length;i++){
323 			this._pins.push(pin2PwmPinInfo(i_pins[i]));
324 		}
325 		//pinが全て同じポートに所属しているか確認
326 		var p=this._pins[0].port;
327 		for(var i=1;i<this._pins.length;i++){
328 			if(p!=this._pins[1].port){
329 				throw new MiMicException("Invalid pin combination.");
330 			}
331 		}
332 		//ポートの生成
333 		this._port=new DEV.Port(i_pwm._mcu,i_pins);
334 		this._port_no=p;
335 		
336 		this._ler_mask=0;
337 		this._pcr_mask=0;
338 		for(var i=0;i<this._pins.length;i++){
339 			this._ler_mask|=(0x1<<this._pins[i].ch);
340 			this._pcr_mask|=(0x101<<this._pins[i].ch);
341 		}		
342 		var opt=isUndef(i_opt)?{pin:{}}:
343 		{
344 			pin:isUndef(i_opt.pin)?{}:cloneAssoc(i_opt.pin),
345 			duty:i_opt.duty,
346 			enable:i_opt.enable
347 		};
348 		//デフォルト値のロード
349 		if(isUndef(opt.pin.sel)){opt.pin.sel=this._PINSEL_AUTO_DETECT;}
350 		if(isUndef(opt.duty)){opt.duty=0;}
351 		if(isUndef(opt.enable)){opt.enable=1;}
352 		this.setOpt(opt);
353 	}catch(e){
354 		throw new MiMicException(e);
355 	}	
356 }
357 DEV.PwmPort.prototype=
358 {
359 	_PINSEL_AUTO_DETECT:0x0fffffff,
360 	_pwm:null,
361 	_pins:null,
362 	_port_no:0,
363 	_port:null,
364 	_pcr_mask:0,
365 	_ler_mask:0,
366 	/**
367 	 * PWMポートにオプション値を設定する。
368 	 * 関数は、ポートを構成する全てのピンに、同じ値を設定する。
369 	 * 設定可能な値は、LPCXpresso1769.PwmPin#setOptと同じである。	 
370 	 * @name LPCXpresso1769.PwmPort#setOpt
371 	 * @function
372 	 * @param {object as associative array} i_opt
373 	 * LPCXpresso1769.PwmPin#setOptを参照。
374 	 * @example
375 	 * var mcu=new LPCXpresso1769.Mcu("192.168.128.39",true);
376 	 * var pwm=mcu.getPeripheral("PWM",{freq:100});
377 	 * var port=pwm.getPort([LPCXpresso1769.P2[0]]);
378 	 * port.setOpt({enable:0});
379 	 */
380 	setOpt:function setOpt(i_opt)
381 	{
382 		try{
383 			var db=new Array();
384 			//BCの生成
385 			var bc="";
386 			//i_optの展開
387 			if(!isUndef(i_opt.pin)){
388 				var optset=new Array();
389 				for(var i=0;i<this._pins.length;i++){
390 					//pinselが_PINSEL_AUTO_DETECTならばauto。そうでなければundefinedも含めて設定
391 					var s=(i_opt.pin.sel==this._PINSEL_AUTO_DETECT)?this._pins[i].pin_sel:i_opt.pin.sel;
392 					optset.push({sel:s,mode:i_opt.pin.mode,od:i_opt.pin.od});
393 				}
394 				//portの設定
395 				bc+=this._port.BCF_setOpts(optset,db);
396 			}
397 			//PCRに値設定
398 			if(!isUndef(i_opt.enable)){
399 				bc+=this._pwm.BCF_setPCRbits(this._pcr_mask,0,i_opt.enable,db);
400 			}
401 			//デューティ比を
402 			if(!isUndef(i_opt.duty)){
403 				//デューティ比を設定
404 				for(var i=0;i<this._pins.length;i++){
405 					bc+=this._pwm.BCF_setMRnByDuty(this._pins[i].ch,i_opt.duty,db);
406 				}
407 				//LERにセット
408 				bc+=this._pwm.BCF_setLERs(this._ler_mask,1,db);
409 			}
410 			this._pwm._mcu.callMiMicWithCheck(bc+BCF.END,db);
411 			return;
412 		}catch(e){
413 			throw new MiMicException(e);
414 		}
415 	},
416 	/**
417 	 * PWMポートのデューティ比をまとめて変更する。
418 	 * @name LPCXpresso1769.PwmPort#setDutys
419 	 * @function
420 	 * @param {array[double]} i_duty_array
421 	 * デューティ比の配列である。0.0<=n<=1.0のdouble値を指定する。
422 	 * ポートを構成するピンの数だけ指定する。変更しないピンには、undefinedを指定すること。
423 	 * @example
424 	 * varmcu=new LPCXpresso1769.Mcu("192.168.128.39",true);
425 	 * var pwm=mcu.getPeripheral("PWM",{freq:100});
426 	 * var port=pwm.getPort([LPCXpresso1769.P2[0],LPCXpresso1769.P2[1]]);
427 	 * pwm.setDutys([0.5,0.0]);//PWM0=0.5,PWM1=0.0
428 	 * pwm.setDutys([undefined,0.0]);//PWM1=0.0
429 	 */	
430 	setDutys:function setDutys(i_duty_array)
431 	{
432 		try{
433 			if(i_duty_array.length!=this._pins.length){
434 				throw new MiMicException();
435 			}
436 			var bc="";
437 			var db=new Array();
438 			//デューティ比をまとめてセット
439 			for(var i=0;i<this._pins.length;i++){
440 				if(!isUndef(i_duty_array[i])){
441 					bc+=this._pwm.BCF_setMRnByDuty(this._pins[i].ch,i_duty_array[i],db);
442 				}
443 			}
444 			//LERにセット
445 			bc+=this._pwm.BCF_setLERs(this._ler_mask,1,db);
446 			this._pwm._mcu.callMiMicWithCheck(bc+BCF.END,db);
447 		}catch(e){
448 			throw new MiMicException(e);
449 		}
450 	}
451 }
452 /**
453  * PwmペリフェラルとPin識別子から、シングルエッジPwmピンを構成する。
454  * Pwmペリフェラルオブジェクトにピン識別子で指定されたピンを関連付けて、PWM機能を持つピンを生成する。
455  * 関数は、ピン識別子を元に、そのピンがPWM機能に接続できるかを調べる。ピンにPWM機能を割り当てられない場合、例外が発生する。どのピンにPWM機能が割り当てられるかは、MCUのスペックシートを参照すること。
456  * ピンがPWM機能を持たない場合、例外が発生する。
457  * @constructor
458  * @name LPCXpresso1769.PwmPin
459  * @param {object as LPCXpresso1769.Pwm} i_pwm
460  * インスタンスを結びつけるAdcオブジェクト。
461  * @param {object as pin識別子} i_pin
462  * ピン識別子。指定できるのは、LPCXpresso1796.P?[?]である。
463  * @param {object as associative array} i_opt
464  * setOpt関数のi_optに渡すパラメタである。省略可能。省略時は{duty:100,enable:1,pin{sel:auto}}を設定する。
465  * autoは、関数が自動的に決定するPINSELの値である。詳細はsetOpt関数を参照。 
466  * @example
467  * //create PWM1.0
468  * var mcu=new LPCXpresso1769.Mcu(“192.168.0.39”);
469  * var pwm=new LPCXpresso1769.Pwm(mcu,{freq:100});
470  * var pwmpin=new LPCXpresso1769.PwmPin(pwm,P2[0]); 
471  */
472 DEV.PwmPin=function PwmPin(i_pwm,i_pin,i_opt)
473 {
474 	try{
475 		//1pinのポートとして実装
476 		this._pport=new DEV.PwmPort(i_pwm,[i_pin],i_opt);
477 	}catch(e){
478 		throw new MiMicException(e);
479 	}
480 }
481 
482 DEV.PwmPin.prototype=
483 {
484 	_pport:null,
485 
486 	/**
487 	 * PWMピンにオプション値を設定する。
488 	 * @name LPCXpresso1769.PwmPin#setOpt
489 	 * @function
490 	 * @param {object as associative array} i_opt
491 	 * PWMピンのコンフィグレーションパラメタである。必要な値を格納した連想配列で指定する。
492 	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
493 	 * <pre>{pin:{associative array},enable:int,duty:double}</pre>
494 	 * <ul>
495 	 * <li>pin - LPCXpresso1769.Pin#setOpt関数のi_optに渡すパラメタである。</li>
496 	 * <li>enable - PWMの有効/無効を切り替える。1で有効。</li>
497 	 * <li>duty - デューティ比である。0.0<=n<=1.0のdouble値を指定する。</li>
498 	 * </ul>
499 	 * @example
500 	 * var mcu=new LPCXpresso1769.Mcu("192.168.128.39",true);
501 	 * var pwm=mcu.getPeripheral("PWM",{freq:100});
502 	 * var pin=pwm.getPin(LPCXpresso1769.P2[0]);
503 	 * pin.setOpt({duty:0});
504 	 */
505 	setOpt:function setOpt(i_opt)
506 	{
507 		try{
508 			this._pport.setOpt(i_opt);
509 		}catch(e){
510 			throw new MiMicException(e);
511 		}
512 	},
513 	/**
514 	 * PWMのデューティ比を変更する。
515 	 * @name LPCXpresso1769.PwmPin#setDuty
516 	 * @function
517 	 * @param {double} i_duty
518 	 * デューティ比である。0.0<=n<=1.0のdouble値を指定する。
519 	 * @example
520 	 * varmcu=new LPCXpresso1769.Mcu("192.168.128.39",true);
521 	 * var pwm=mcu.getPeripheral("PWM",{freq:100});
522 	 * pwmpin=pwm.getPin(LPCXpresso1769.P2[0]);
523 	 * pwmpin.setDuty(0.5);
524 	 */
525 	setDuty:function setDuty(i_duty)
526 	{
527 		try{
528 			this._pport.setDutys([i_duty]);
529 		}catch(e){
530 			throw new MiMicException(e);
531 		}
532 	}
533 }
534 	
535 
536 
537 }());
538