1 cc.Class({ 2 extends: cc.Component, 3 4 properties: { 5 // foo: { 6 // default: null, // The default value will be used only when the component attaching 7 // to a node for the first time 8 // url: cc.Texture2D, // optional, default is typeof default 9 // serializable: true, // optional, default is true 10 // visible: true, // optional, default is true 11 // displayName: 'Foo', // optional 12 // readonly: false, // optional, default is false 13 // }, 14 // ... 15 starPrefab:{ 16 default:null, 17 type:cc.Prefab 18 }, 19 index: 0, 20 frame:{ 21 default:null, 22 type:cc.Node 23 }, 24 already_down_keys:0, 25 tap1Audio: {//表示按下菜单 26 default: null, 27 url: cc.AudioClip 28 }, 29 tap3Audio: {//表示按下按钮 30 default: null, 31 url: cc.AudioClip 32 }, 33 finishAudio:{ 34 default:null, 35 url:cc.AudioClip 36 }, 37 tooltip:"", 38 tooltip_RD:{ 39 default:null, 40 type:cc.Prefab 41 }, 42 tooltip_RU:{ 43 default:null, 44 type:cc.Prefab 45 }, 46 tooltip_LD:{ 47 default:null, 48 type:cc.Prefab 49 }, 50 tooltip_LU:{ 51 default:null, 52 type:cc.Prefab 53 }, 54 handPrefab:{ 55 default:null, 56 type:cc.Prefab 57 }, 58 dragPrefab:{ 59 default:null, 60 type:cc.Prefab 61 }, 62 process:{ 63 default:null, 64 type:cc.Label 65 }, 66 heigh_image:1408.0, 67 width_image:511.0, 68 factor_x:1.0, 69 factor_y:1.0, 70 lastClickTime:0,//用来检测鼠标双击 71 clickCount:0, //用来检测鼠标双击 72 holdDown:false, //用来检测鼠标长按 73 }, 74 destoryOneLevelNodes:function() 75 { 76 let background_node = this.node.getChildByName("background"); 77 for(let i=0;i) 78 { 79 let background_child_name= background_node.children[i].name 80 if(background_child_name==="starPrefab"||background_child_name==="tooltip_RD"||background_child_name==="tip"||background_child_name==="tip2"||background_child_name.name==="tip3"||background_child_name==="tip4"||background_child_name==="keyboard"||background_child_name==="drag") 81 {//starPreab 是星星 anim是动画 tip tip2 tip3 tip4 是提示 82 background_node.children[i].destroy(); 83 } 84 } 85 }, 86 findSpriteByName:function(name) 87 { 88 let i=0; 89 for(i=0;i ) 90 { 91 if(window.interactiveFrames[i].name === name) 92 return i; 93 } 94 }, 95 onKeyDown: function (event) { 96 self = this; 97 let keys = window.interactivejson.Frames[self.index].Keys; 98 if(keys==undefined||keys.length<=0) 99 return; 100 101 let expect_key_code; 102 if(cc.KEY.hasOwnProperty(keys[this.already_down_keys].StringKey.toLowerCase())) 103 expect_key_code=cc.KEY[keys[this.already_down_keys].StringKey.toLowerCase()]; 104 else 105 return; 106 if(event.keyCode=== expect_key_code) 107 { 108 this.already_down_keys++; 109 if(keys.length==this.already_down_keys) 110 { 111 this.already_down_keys=0; 112 //销毁这一级的动画 113 self.destoryOneLevelNodes(); 114 //切换背景图 115 self.index++; 116 //显示进度信息 117 self.process.string=self.index+""+"/"+window.interactivejson.Frames.length; 118 cc.audioEngine.play(self.tap1Audio, false,1); 119 // switch the frame 120 let idxOfFrame=self.findSpriteByName((self.index-1)+''); 121 self.frame.getComponent(cc.Sprite).spriteFrame=window.interactiveFrames[idxOfFrame]; 122 //结束判断,背景切换结束再进行 123 if(self.index>=window.interactivejson.Frames.length) 124 { 125 cc.audioEngine.play(self.finishAudio, false,1); 126 return; 127 } 128 //显示新的tooltip 129 let tooltip = window.interactivejson.Frames[self.index].Tooltip; 130 if (tooltip===null)//如果没写tooltip 只显示这是第几步 131 tooltip=""+self.index+" "+window.starStyle; 132 if(window.interactivejson.Frames[self.index].Keys.length>=1) 133 tooltip+=window.interactivejson.Frames[self.index].Keys[0].StringKey; 134 let newTooltip = cc.instantiate(self.tooltip_RD); 135 newTooltip.getChildByName('label').getComponent(cc.Label).overflow =cc.Label.Overflow.NONE; 136 newTooltip.getChildByName('label').getComponent(cc.Label).fontSize=20; 137 newTooltip.getChildByName('label').getComponent(cc.Label).lineHeight=20; 138 newTooltip.getChildByName('label').getComponent(cc.Label).string = tooltip; 139 if(tooltip.length>=15) 140 { 141 newTooltip.getChildByName('label').getComponent(cc.Label).overflow =cc.Label.Overflow.RESIZE_HEIGHT; 142 newTooltip.getChildByName('label').width=200; 143 } 144 self.node.getChildByName("background").addChild(newTooltip); 145 newTooltip.getChildByName('label').setPosition(cc.p(Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x-512),Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y)-300)); 146 147 } 148 } 149 }, 150 151 onKeyUp: function (event) { 152 switch(event.keyCode) { 153 case cc.KEY.a:Keys 154 console.log('release a key'); 155 break; 156 } 157 }, 158 onDestroy:function() { 159 cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this); 160 cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this); 161 this.node.off('mousedown', this.mousedown_handler, this); 162 this.node.off('mousedoubleclick',this.mouseDoubleClickHandler,this); 163 this.node.off('mouselongclick',this.mouseLongClickHandler,this); 164 }, 165 mouseDoubleClickHandler:function(event) 166 { 167 let self = this; 168 console.log("double click location X: "+event.detail.msg.getLocationX()); 169 console.log("double click location Y: "+event.detail.msg.getLocationY()); 170 //消除判断 171 let x = event.detail.msg.getLocationX(); 172 let y = event.detail.msg.getLocationY(); 173 let diffX = Math.abs(window.interactivejson.Frames[self.index].CursorX/self.factor_x-x); 174 let diffY = Math.abs(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y-y); 175 if(window.starStyle!="double")//只能销毁双击星星 176 return; 177 if(diffX<32&&diffY<32||self.index==0)//第一帧随便点击那里都可以 178 { 179 self.index++; 180 //显示进度信息 181 self.process.string=self.index+""+"/"+window.interactivejson.Frames.length; 182 183 cc.audioEngine.play(self.tap1Audio, false,1); 184 //销毁之前的小星星 185 self.destoryOneLevelNodes(); 186 //如果下一帧是按键样式的,不创建小星星,背景也不切换,而是等到键盘按下才切换 187 let keys = window.interactivejson.Frames[self.index].Keys; 188 if(keys==undefined||keys.length<=0) 189 { 190 //创建一个小星星 191 let newStar; 192 /*配置小星星的样式,普通单击、双击、长按*/ 193 window.starStyle=""; 194 if (window.interactivejson.Frames[self.index]['DoubleClicked']) { 195 window.starStyle ="double"; 196 } 197 198 newStar = cc.instantiate(self.starPrefab); 199 self.node.getChildByName("background").addChild(newStar); 200 console.log("star position x: "+Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x)); 201 console.log("start postion y: "+Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y)); 202 newStar.setPosition(cc.p(Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x),Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y))); 203 // switch the frame 204 let idxOfFrame=self.findSpriteByName(self.index+''); 205 self.frame.getComponent(cc.Sprite).spriteFrame=window.interactiveFrames[idxOfFrame]; 206 } 207 //结束判断,背景切换结束再进行 208 if(self.index>=window.interactivejson.Frames.length) 209 { 210 cc.audioEngine.play(self.finishAudio, false,1); 211 return; 212 } 213 //显示新的tooltip 214 let tooltip = window.interactivejson.Frames[self.index].Tooltip; 215 if (tooltip===null) 216 tooltip=""+self.index+" "+window.starStyle; 217 if(window.interactivejson.Frames[self.index].Keys.length>=1) 218 tooltip+=window.interactivejson.Frames[self.index].Keys[0].StringKey; 219 let newTooltip = cc.instantiate(self.tooltip_RD); 220 newTooltip.getChildByName('label').getComponent(cc.Label).overflow =cc.Label.Overflow.NONE; 221 newTooltip.getChildByName('label').getComponent(cc.Label).fontSize=20; 222 newTooltip.getChildByName('label').getComponent(cc.Label).lineHeight=20; 223 newTooltip.getChildByName('label').getComponent(cc.Label).string = tooltip; 224 if(tooltip.length>=15) 225 { 226 newTooltip.getChildByName('label').getComponent(cc.Label).overflow =cc.Label.Overflow.RESIZE_HEIGHT; 227 newTooltip.getChildByName('label').width=200; 228 } 229 self.node.getChildByName("background").addChild(newTooltip); 230 newTooltip.getChildByName('label').setPosition(cc.p(Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x-512),Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y)-300)); 231 } 232 }, 233 mousedown_handler:function(event) 234 { 235 this.holdDown=true; 236 let timespan = Date.now()-this.lastClickTime; 237 this.lastClickTime = Date.now(); 238 if(timespan<=600)//600ms内单击两次为双击 239 { 240 this.clickCount++; 241 } 242 else 243 { 244 this.clickCount =1; 245 } 246 if(this.clickCount==2) 247 { 248 this.node.emit("mousedoubleclick",{msg:event}); 249 this.clickCount=0; 250 } 251 let self = this; 252 let x = event.getLocationX(); 253 let y = event.getLocationY(); 254 console.log("current mouse x: "+x); 255 console.log("current mouse y: "+y); 256 console.log("\n"); 257 258 console.log("orgin mouse x: "+window.interactivejson.Frames[self.index].CursorX); 259 //将屏幕坐标系改成cocos 坐标系 260 console.log("orgin mouse y: "+(window.interactivejson.Frames[self.index].CursorY)); 261 262 263 console.log("expect mouse x: "+window.interactivejson.Frames[self.index].CursorX/self.factor_x); 264 //将屏幕坐标系改成cocos 坐标系 265 console.log("expect mouse y: "+(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y)); 266 267 //消除判断 268 let diffX = Math.abs(window.interactivejson.Frames[self.index].CursorX/self.factor_x-x); 269 let diffY = Math.abs(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y-y); 270 if(window.starStyle!="")//只能销毁普通的单击星星 271 return; 272 if(window.interactivejson.Frames[self.index]['DragStart']||window.interactivejson.Frames[self.index]['DragEnd']) 273 return; 274 if(diffX<32&&diffY<32||self.index==0)//第一帧随便点击那里都可以 275 { 276 self.index++; 277 //显示进度信息 278 self.process.string=self.index+""+"/"+window.interactivejson.Frames.length; 279 280 cc.audioEngine.play(self.tap1Audio, false,1); 281 //销毁之前的小星星 282 283 self.destoryOneLevelNodes(); 284 285 //如果下一帧是按键样式的,不创建小星星,背景也不切换,而是等到键盘按下才切换 286 let keys = window.interactivejson.Frames[self.index].Keys; 287 if(keys==undefined||keys.length<=0) 288 { 289 if(window.interactivejson.Frames[self.index]['DragStart']) 290 { 291 let newdragRect = cc.instantiate(self.dragPrefab); 292 let startpoint_x = Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x); 293 let startpoint_y = Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y); 294 //找到其后面的dragEnd 295 let endpoint_x = 0; 296 let endpoint_y = 0; 297 if(window.interactivejson.Frames[self.index+1]['DragEnd']) 298 { 299 endpoint_x = Math.round(window.interactivejson.Frames[self.index+1].CursorX/self.factor_x); 300 endpoint_y = Math.round(600-window.interactivejson.Frames[self.index+1].CursorY/self.factor_y); 301 } 302 else 303 { 304 console.log("error: the dragstart and dragend not adjancent"); 305 } 306 newdragRect.getComponent('drag').setPoints(startpoint_x,startpoint_y,endpoint_x,endpoint_y); 307 newdragRect.getComponent('drag').game = this; 308 self.node.addChild(newdragRect); 309 } 310 else 311 { 312 //创建一个小星星 313 let newStar; 314 /*配置小星星的样式,普通单击、双击、长按*/ 315 window.starStyle=""; 316 if (window.interactivejson.Frames[self.index]['DoubleClicked']) { 317 window.starStyle ="double"; 318 } 319 newStar = cc.instantiate(self.starPrefab); 320 self.node.getChildByName("background").addChild(newStar); 321 console.log("star position x: "+Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x)); 322 console.log("start postion y: "+Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y)); 323 newStar.setPosition(cc.p(Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x),Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y))); 324 } 325 326 // switch the frame 327 let idxOfFrame=self.findSpriteByName(self.index+''); 328 self.frame.getComponent(cc.Sprite).spriteFrame=window.interactiveFrames[idxOfFrame]; 329 } 330 //结束判断,背景切换结束再进行 331 if(self.index>=window.interactivejson.Frames.length) 332 { 333 cc.audioEngine.play(self.finishAudio, false,1); 334 return; 335 } 336 //如果有drag,显示drag的小手 337 if(window.interactivejson.Frames[self.index]['DragStart']) 338 { 339 let startpoint_x = Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x); 340 let startpoint_y = Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y); 341 //找到其后面的dragEnd 342 let endpoint_x = 0; 343 let endpoint_y = 0; 344 if(window.interactivejson.Frames[self.index+1]['DragEnd']) 345 { 346 endpoint_x = Math.round(window.interactivejson.Frames[self.index+1].CursorX/self.factor_x); 347 endpoint_y = Math.round(600-window.interactivejson.Frames[self.index+1].CursorY/self.factor_y); 348 } 349 else 350 { 351 console.log("error: the dragstart and dragend not adjancent"); 352 } 353 //添加小手 354 let newSildeHand = cc.instantiate(self.handPrefab); 355 newSildeHand.getComponent('slideHand').startPos=cc.v2(startpoint_x,startpoint_y); 356 newSildeHand.getComponent('slideHand').endPos=cc.v2(endpoint_x,endpoint_y); 357 self.node.getChildByName("background").addChild(newSildeHand); 358 359 } 360 //显示新的tooltip 361 let tooltip = window.interactivejson.Frames[self.index].Tooltip; 362 if (tooltip===null)//如果没写tooltip 只显示这是第几步 363 tooltip=""+self.index+" "+window.starStyle; 364 if(window.interactivejson.Frames[self.index].Keys.length>=1) 365 tooltip+=window.interactivejson.Frames[self.index].Keys[0].StringKey; 366 let newTooltip = cc.instantiate(self.tooltip_RD); 367 newTooltip.getChildByName('label').getComponent(cc.Label).overflow =cc.Label.Overflow.NONE; 368 newTooltip.getChildByName('label').getComponent(cc.Label).fontSize=20; 369 newTooltip.getChildByName('label').getComponent(cc.Label).lineHeight=20; 370 newTooltip.getChildByName('label').getComponent(cc.Label).string = tooltip; 371 if(tooltip.length>=15) 372 { 373 newTooltip.getChildByName('label').getComponent(cc.Label).overflow =cc.Label.Overflow.RESIZE_HEIGHT; 374 newTooltip.getChildByName('label').width=200; 375 } 376 self.node.getChildByName("background").addChild(newTooltip); 377 newTooltip.getChildByName('label').setPosition(cc.p(Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x-512),Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y)-300)); 378 } 379 }, 380 // use this for initialization 381 onLoad: function () { 382 let self = this; 383 this.already_down_keys=0; 384 window.starStyle =""; 385 //注册键盘监听事件 386 cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this); 387 cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this); 388 //加载图片资源 389 cc.loader.loadResDir("frames",cc.SpriteFrame,function(err,asset){ 390 window.interactiveFrames=asset; 391 }) 392 //加载json 393 var url = cc.url.raw('resources/Project.json'); 394 cc.loader.load(url,function(err,res){ 395 window.interactivejson = res; 396 self.tooltip=window.interactivejson.Frames[self.index].Tooltip; 397 }); 398 //创建一个小星星 399 /*var newStar; 400 newStar = cc.instantiate(this.starPrefab); 401 this.node.getChildByName("background").addChild(newStar); 402 newStar.setPosition(cc.p(512,600)); 403 */ 404 self.factor_x=this.heigh_image/1024.0; 405 self.factor_y=this.width_image/600.0; 406 this.node.on('mousedown',this.mousedown_handler,this); 407 this.node.on('mousedoubleclick',this.mouseDoubleClickHandler,this); 408 this.node.on('mouseup',this.mouseupHandler,this); 409 this.node.on('mouselongclick',this.mouseLongClickHandler,this); 410 this.node.on('mousedrag',this.mouseDragHandler,this); 411 }, 412 mouseDragHandler:function(event) 413 { 414 let self = this; 415 self.index++; 416 //显示进度信息 417 self.process.string=self.index+""+"/"+window.interactivejson.Frames.length; 418 419 cc.audioEngine.play(self.tap1Audio, false,1); 420 //销毁之前的小星星 421 422 self.destoryOneLevelNodes(); 423 424 //如果下一帧是按键样式的,不创建小星星,背景也不切换,而是等到键盘按下才切换 425 let keys = window.interactivejson.Frames[self.index].Keys; 426 if(keys==undefined||keys.length<=0) 427 { 428 if(window.interactivejson.Frames[self.index]['DragStart']) 429 { 430 let newdragRect = cc.instantiate(self.dragPrefab); 431 let startpoint_x = Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x); 432 let startpoint_y = Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y); 433 //找到其后面的dragEnd 434 let endpoint_x = 0; 435 let endpoint_y = 0; 436 if(window.interactivejson.Frames[self.index+1]['DragEnd']) 437 { 438 endpoint_x = Math.round(window.interactivejson.Frames[self.index+1].CursorX/self.factor_x); 439 endpoint_y = Math.round(600-window.interactivejson.Frames[self.index+1].CursorY/self.factor_y); 440 } 441 else 442 { 443 console.log("error: the dragstart and dragend not adjancent"); 444 } 445 newdragRect.getComponent('drag').setPoints(startpoint_x,startpoint_y,endpoint_x,endpoint_y); 446 newdragRect.getComponent('drag').game = this; 447 self.node.addChild(newdragRect); 448 } 449 else 450 { 451 //创建一个小星星 452 let newStar; 453 /*配置小星星的样式,普通单击、双击、长按*/ 454 window.starStyle=""; 455 if (window.interactivejson.Frames[self.index]['DoubleClicked']) { 456 window.starStyle ="double"; 457 } 458 newStar = cc.instantiate(self.starPrefab); 459 self.node.getChildByName("background").addChild(newStar); 460 console.log("star position x: "+Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x)); 461 console.log("start postion y: "+Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y)); 462 newStar.setPosition(cc.p(Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x),Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y))); 463 } 464 465 // switch the frame 466 let idxOfFrame=self.findSpriteByName(self.index+''); 467 self.frame.getComponent(cc.Sprite).spriteFrame=window.interactiveFrames[idxOfFrame]; 468 } 469 //结束判断,背景切换结束再进行 470 if(self.index>=window.interactivejson.Frames.length) 471 { 472 cc.audioEngine.play(self.finishAudio, false,1); 473 return; 474 } 475 //如果有drag,显示drag的小手 476 if(window.interactivejson.Frames[self.index]['DragStart']) 477 { 478 let startpoint_x = Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x); 479 let startpoint_y = Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y); 480 //找到其后面的dragEnd 481 let endpoint_x = 0; 482 let endpoint_y = 0; 483 if(window.interactivejson.Frames[self.index+1]['DragEnd']) 484 { 485 endpoint_x = Math.round(window.interactivejson.Frames[self.index+1].CursorX/self.factor_x); 486 endpoint_y = Math.round(600-window.interactivejson.Frames[self.index+1].CursorY/self.factor_y); 487 } 488 else 489 { 490 console.log("error: the dragstart and dragend not adjancent"); 491 } 492 //添加小手 493 let newSildeHand = cc.instantiate(self.handPrefab); 494 newSildeHand.getComponent('slideHand').startPos=cc.v2(startpoint_x,startpoint_y); 495 newSildeHand.getComponent('slideHand').endPos=cc.v2(endpoint_x,endpoint_y); 496 self.node.getChildByName("background").addChild(newSildeHand); 497 498 } 499 //显示新的tooltip 500 let tooltip = window.interactivejson.Frames[self.index].Tooltip; 501 if (tooltip===null)//如果没写tooltip 只显示这是第几步 502 tooltip=""+self.index+" "+window.starStyle; 503 if(window.interactivejson.Frames[self.index].Keys.length>=1) 504 tooltip+=window.interactivejson.Frames[self.index].Keys[0].StringKey; 505 let newTooltip = cc.instantiate(self.tooltip_RD); 506 newTooltip.getChildByName('label').getComponent(cc.Label).overflow =cc.Label.Overflow.NONE; 507 newTooltip.getChildByName('label').getComponent(cc.Label).fontSize=20; 508 newTooltip.getChildByName('label').getComponent(cc.Label).lineHeight=20; 509 newTooltip.getChildByName('label').getComponent(cc.Label).string = tooltip; 510 if(tooltip.length>=15) 511 { 512 newTooltip.getChildByName('label').getComponent(cc.Label).overflow =cc.Label.Overflow.RESIZE_HEIGHT; 513 newTooltip.getChildByName('label').width=200; 514 } 515 self.node.getChildByName("background").addChild(newTooltip); 516 newTooltip.getChildByName('label').setPosition(cc.p(Math.round(window.interactivejson.Frames[self.index].CursorX/self.factor_x-512),Math.round(600-window.interactivejson.Frames[self.index].CursorY/self.factor_y)-300)); 517 518 519 }, 520 mouseLongClickHandler:function(event) 521 { 522 console.log("long click location X: "+event.detail.msg.getLocationX()); 523 console.log("long click location Y: "+event.detail.msg.getLocationY()); 524 }, 525 mouseupHandler:function(event) 526 { 527 if(this.holdDown) 528 { 529 let timespan = Date.now()-this.lastClickTime; 530 if(timespan>=600)//按住600ms后弹起为长按 531 { 532 this.node.emit("mouselongclick",{msg:event}); 533 } 534 this.holdDown=false; 535 } 536 } 537 // called every frame, uncomment this function to activate update callback 538 // update: function (dt) { 539 540 // }, 541 });