├── 39459__THE_bizniss__laser.wav ├── 51467__smcameron__missile_explosion.wav ├── LICENSE ├── README.md ├── game.js ├── index.html ├── ipad.js ├── jquery-1.4.1.min.js └── vector_battle_regular.typeface.js /39459__THE_bizniss__laser.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/asteroids/5420686136f9722a0089672df7add38236858b59/39459__THE_bizniss__laser.wav -------------------------------------------------------------------------------- /51467__smcameron__missile_explosion.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/asteroids/5420686136f9722a0089672df7add38236858b59/51467__smcameron__missile_explosion.wav -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Doug McInnes 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTML5 Asteroids 2 | 3 | This game was created Doug McInnes. His code can be found 4 | [here](https://github.com/dmcinnes/HTML5-Asteroids), and you can play his 5 | version of the game online at his website 6 | [here](http://dougmcinnes.com/2010/05/12/html-5-asteroids/). 7 | 8 | Caroline Buckey and Sarah Spikes modified the repository to create exercises for 9 | the Udacity course [Version Control Using Git and Github](TODO). These 10 | modifications included introducing bugs and other changes into Doug’s commits he 11 | did not in fact create! The bugs are intended to give learners experience using 12 | Git to find the commit where a bug was introduced. To play the modified version 13 | of the game, simply open the index.html file in your web browser. 14 | 15 | Many thanks to Doug for creating this awesome game. 16 | 17 | # Archival Note 18 | This repository is deprecated; therefore, we are going to archive it. However, learners will be able to fork it to their personal Github account but cannot submit PRs to this repository. If you have any issues or suggestions to make, feel free to: 19 | - Utilize the https://knowledge.udacity.com/ forum to seek help on content-specific issues. 20 | - Submit a support ticket along with the link to your forked repository if (learners are) blocked for other reasons. Here are the links for the [retail consumers](https://udacity.zendesk.com/hc/en-us/requests/new) and [enterprise learners](https://udacityenterprise.zendesk.com/hc/en-us/requests/new?ticket_form_id=360000279131). -------------------------------------------------------------------------------- /game.js: -------------------------------------------------------------------------------- 1 | // Canvas Asteroids 2 | // 3 | // Copyright (c) 2010 Doug McInnes 4 | // 5 | 6 | KEY_CODES = { 7 | 32: 'space', 8 | 37: 'left', 9 | 38: 'up', 10 | 39: 'right', 11 | 40: 'down', 12 | 70: 'f', 13 | 71: 'g', 14 | 72: 'h', 15 | 77: 'm', 16 | 80: 'p' 17 | } 18 | 19 | KEY_STATUS = { keyDown:false }; 20 | for (code in KEY_CODES) { 21 | KEY_STATUS[KEY_CODES[code]] = false; 22 | } 23 | 24 | $(window).keydown(function (e) { 25 | KEY_STATUS.keyDown = true; 26 | if (KEY_CODES[e.keyCode]) { 27 | e.preventDefault(); 28 | KEY_STATUS[KEY_CODES[e.keyCode]] = true; 29 | } 30 | }).keyup(function (e) { 31 | KEY_STATUS.keyDown = false; 32 | if (KEY_CODES[e.keyCode]) { 33 | e.preventDefault(); 34 | KEY_STATUS[KEY_CODES[e.keyCode]] = false; 35 | } 36 | }); 37 | 38 | GRID_SIZE = 60; 39 | 40 | Matrix = function (rows, columns) { 41 | var i, j; 42 | this.data = new Array(rows); 43 | for (i = 0; i < rows; i++) { 44 | this.data[i] = new Array(columns); 45 | } 46 | 47 | this.configure = function (rot, scale, transx, transy) { 48 | var rad = (rot * Math.PI)/180; 49 | var sin = Math.sin(rad) * scale; 50 | var cos = Math.cos(rad) * scale; 51 | this.set(cos, -sin, transx, 52 | sin, cos, transy); 53 | }; 54 | 55 | this.set = function () { 56 | var k = 0; 57 | for (i = 0; i < rows; i++) { 58 | for (j = 0; j < columns; j++) { 59 | this.data[i][j] = arguments[k]; 60 | k++; 61 | } 62 | } 63 | } 64 | 65 | this.multiply = function () { 66 | var vector = new Array(rows); 67 | for (i = 0; i < rows; i++) { 68 | vector[i] = 0; 69 | for (j = 0; j < columns; j++) { 70 | vector[i] += this.data[i][j] * arguments[j]; 71 | } 72 | } 73 | return vector; 74 | }; 75 | }; 76 | 77 | Sprite = function () { 78 | this.init = function (name, points) { 79 | this.name = name; 80 | this.points = points; 81 | 82 | this.vel = { 83 | x: 0, 84 | y: 0, 85 | rot: 0 86 | }; 87 | 88 | this.acc = { 89 | x: 0, 90 | y: 0, 91 | rot: 0 92 | }; 93 | }; 94 | 95 | this.children = {}; 96 | 97 | this.color = 'black'; 98 | this.solid = false; 99 | this.visible = false; 100 | this.reap = false; 101 | this.bridgesH = true; 102 | this.bridgesV = true; 103 | 104 | this.collidesWith = []; 105 | 106 | this.x = 0; 107 | this.y = 0; 108 | this.rot = 0; 109 | this.scale = 1; 110 | 111 | this.currentNode = null; 112 | this.nextSprite = null; 113 | 114 | this.preMove = null; 115 | this.postMove = null; 116 | 117 | this.run = function(delta) { 118 | 119 | this.move(delta); 120 | this.updateGrid(); 121 | 122 | this.context.save(); 123 | this.configureTransform(); 124 | this.draw(); 125 | 126 | var canidates = this.findCollisionCanidates(); 127 | 128 | this.matrix.configure(this.rot, this.scale, this.x, this.y); 129 | this.checkCollisionsAgainst(canidates); 130 | 131 | this.context.restore(); 132 | 133 | if (this.bridgesH && this.currentNode && this.currentNode.dupe.horizontal) { 134 | this.x += this.currentNode.dupe.horizontal; 135 | this.context.save(); 136 | this.configureTransform(); 137 | this.draw(); 138 | this.checkCollisionsAgainst(canidates); 139 | this.context.restore(); 140 | if (this.currentNode) { 141 | this.x -= this.currentNode.dupe.horizontal; 142 | } 143 | } 144 | if (this.bridgesV && this.currentNode && this.currentNode.dupe.vertical) { 145 | this.y += this.currentNode.dupe.vertical; 146 | this.context.save(); 147 | this.configureTransform(); 148 | this.draw(); 149 | this.checkCollisionsAgainst(canidates); 150 | this.context.restore(); 151 | if (this.currentNode) { 152 | this.y -= this.currentNode.dupe.vertical; 153 | } 154 | } 155 | if (this.bridgesH && this.bridgesV && 156 | this.currentNode && 157 | this.currentNode.dupe.vertical && 158 | this.currentNode.dupe.horizontal) { 159 | this.x += this.currentNode.dupe.horizontal; 160 | this.y += this.currentNode.dupe.vertical; 161 | this.context.save(); 162 | this.configureTransform(); 163 | this.draw(); 164 | this.checkCollisionsAgainst(canidates); 165 | this.context.restore(); 166 | if (this.currentNode) { 167 | this.x -= this.currentNode.dupe.horizontal; 168 | this.y -= this.currentNode.dupe.vertical; 169 | } 170 | } 171 | }; 172 | this.move = function (delta) { 173 | if (!this.visible) return; 174 | this.transPoints = null; // clear cached points 175 | 176 | if ($.isFunction(this.preMove)) { 177 | this.preMove(delta); 178 | } 179 | 180 | this.vel.x += this.acc.x * delta; 181 | this.vel.y += this.acc.y * delta; 182 | this.x += this.vel.x * delta; 183 | this.y += this.vel.y * delta; 184 | this.rot += this.vel.rot * delta; 185 | if (this.rot > 360) { 186 | this.rot -= 360; 187 | } else if (this.rot < 0) { 188 | this.rot += 360; 189 | } 190 | 191 | if ($.isFunction(this.postMove)) { 192 | this.postMove(delta); 193 | } 194 | }; 195 | this.updateGrid = function () { 196 | if (!this.visible) return; 197 | var gridx = Math.floor(this.x / GRID_SIZE); 198 | var gridy = Math.floor(this.y / GRID_SIZE); 199 | gridx = (gridx >= this.grid.length) ? 0 : gridx; 200 | gridy = (gridy >= this.grid[0].length) ? 0 : gridy; 201 | gridx = (gridx < 0) ? this.grid.length-1 : gridx; 202 | gridy = (gridy < 0) ? this.grid[0].length-1 : gridy; 203 | var newNode = this.grid[gridx][gridy]; 204 | if (newNode != this.currentNode) { 205 | if (this.currentNode) { 206 | this.currentNode.leave(this); 207 | } 208 | newNode.enter(this); 209 | this.currentNode = newNode; 210 | } 211 | 212 | if (KEY_STATUS.g && this.currentNode) { 213 | this.context.lineWidth = 3.0; 214 | this.context.strokeStyle = 'green'; 215 | this.context.strokeRect(gridx*GRID_SIZE+2, gridy*GRID_SIZE+2, GRID_SIZE-4, GRID_SIZE-4); 216 | this.context.strokeStyle = 'black'; 217 | this.context.lineWidth = 1.0; 218 | } 219 | }; 220 | this.configureTransform = function () { 221 | if (!this.visible) return; 222 | 223 | var rad = (this.rot * Math.PI)/180; 224 | 225 | this.context.translate(this.x, this.y); 226 | this.context.rotate(rad); 227 | this.context.scale(this.scale, this.scale); 228 | }; 229 | this.draw = function () { 230 | if (!this.visible) return; 231 | 232 | this.context.lineWidth = 1.0 / this.scale; 233 | 234 | for (child in this.children) { 235 | this.children[child].draw(); 236 | } 237 | 238 | this.context.strokeStyle = this.color; 239 | this.context.fillStyle = this.color; 240 | 241 | this.context.beginPath(); 242 | 243 | this.context.moveTo(this.points[0], this.points[1]); 244 | for (var i = 1; i < this.points.length/2; i++) { 245 | var xi = i*2; 246 | var yi = xi + 1; 247 | this.context.lineTo(this.points[xi], this.points[yi]); 248 | } 249 | 250 | this.context.closePath(); 251 | this.context.stroke(); 252 | if (this.solid) { 253 | this.context.fill(); 254 | } 255 | }; 256 | this.findCollisionCanidates = function () { 257 | if (!this.visible || !this.currentNode) return []; 258 | var cn = this.currentNode; 259 | var canidates = []; 260 | if (cn.nextSprite) canidates.push(cn.nextSprite); 261 | if (cn.north.nextSprite) canidates.push(cn.north.nextSprite); 262 | if (cn.south.nextSprite) canidates.push(cn.south.nextSprite); 263 | if (cn.east.nextSprite) canidates.push(cn.east.nextSprite); 264 | if (cn.west.nextSprite) canidates.push(cn.west.nextSprite); 265 | if (cn.north.east.nextSprite) canidates.push(cn.north.east.nextSprite); 266 | if (cn.north.west.nextSprite) canidates.push(cn.north.west.nextSprite); 267 | if (cn.south.east.nextSprite) canidates.push(cn.south.east.nextSprite); 268 | if (cn.south.west.nextSprite) canidates.push(cn.south.west.nextSprite); 269 | return canidates 270 | }; 271 | this.checkCollisionsAgainst = function (canidates) { 272 | for (var i = 0; i < canidates.length; i++) { 273 | var ref = canidates[i]; 274 | do { 275 | this.checkCollision(ref); 276 | ref = ref.nextSprite; 277 | } while (ref) 278 | } 279 | }; 280 | this.checkCollision = function (other) { 281 | if (!other.visible || 282 | this == other || 283 | this.collidesWith.indexOf(other.name) == -1) return; 284 | var trans = other.transformedPoints(); 285 | var px, py; 286 | var count = trans.length/2; 287 | for (var i = 0; i < count; i++) { 288 | px = trans[i*2]; 289 | py = trans[i*2 + 1]; 290 | // mozilla doesn't take into account transforms with isPointInPath >:-P 291 | if (($.browser.mozilla) ? this.pointInPolygon(px, py) : this.context.isPointInPath(px, py)) { 292 | other.collision(this); 293 | this.collision(other); 294 | return; 295 | } 296 | } 297 | }; 298 | this.pointInPolygon = function (x, y) { 299 | var points = this.transformedPoints(); 300 | var j = 2; 301 | var y0, y1; 302 | var oddNodes = false; 303 | for (var i = 0; i < points.length; i += 2) { 304 | y0 = points[i + 1]; 305 | y1 = points[j + 1]; 306 | if ((y0 < y && y1 >= y) || 307 | (y1 < y && y0 >= y)) { 308 | if (points[i]+(y-y0)/(y1-y0)*(points[j]-points[i]) < x) { 309 | oddNodes = !oddNodes; 310 | } 311 | } 312 | j += 2 313 | if (j == points.length) j = 0; 314 | } 315 | return oddNodes; 316 | }; 317 | this.collision = function () { 318 | }; 319 | this.die = function () { 320 | this.visible = false; 321 | this.reap = true; 322 | if (this.currentNode) { 323 | this.currentNode.leave(this); 324 | this.currentNode = null; 325 | } 326 | }; 327 | this.transformedPoints = function () { 328 | if (this.transPoints) return this.transPoints; 329 | var trans = new Array(this.points.length); 330 | this.matrix.configure(this.rot, this.scale, this.x, this.y); 331 | for (var i = 0; i < this.points.length/2; i++) { 332 | var xi = i*2; 333 | var yi = xi + 1; 334 | var pts = this.matrix.multiply(this.points[xi], this.points[yi], 1); 335 | trans[xi] = pts[0]; 336 | trans[yi] = pts[1]; 337 | } 338 | this.transPoints = trans; // cache translated points 339 | return trans; 340 | }; 341 | this.isClear = function () { 342 | if (this.collidesWith.length == 0) return true; 343 | var cn = this.currentNode; 344 | if (cn == null) { 345 | var gridx = Math.floor(this.x / GRID_SIZE); 346 | var gridy = Math.floor(this.y / GRID_SIZE); 347 | gridx = (gridx >= this.grid.length) ? 0 : gridx; 348 | gridy = (gridy >= this.grid[0].length) ? 0 : gridy; 349 | cn = this.grid[gridx][gridy]; 350 | } 351 | return (cn.isEmpty(this.collidesWith) && 352 | cn.north.isEmpty(this.collidesWith) && 353 | cn.south.isEmpty(this.collidesWith) && 354 | cn.east.isEmpty(this.collidesWith) && 355 | cn.west.isEmpty(this.collidesWith) && 356 | cn.north.east.isEmpty(this.collidesWith) && 357 | cn.north.west.isEmpty(this.collidesWith) && 358 | cn.south.east.isEmpty(this.collidesWith) && 359 | cn.south.west.isEmpty(this.collidesWith)); 360 | }; 361 | this.wrapPostMove = function () { 362 | if (this.x > Game.canvasWidth) { 363 | this.x = 0; 364 | } else if (this.x < 0) { 365 | this.x = Game.canvasWidth; 366 | } 367 | if (this.y > Game.canvasHeight) { 368 | this.y = 0; 369 | } else if (this.y < 0) { 370 | this.y = Game.canvasHeight; 371 | } 372 | }; 373 | 374 | }; 375 | 376 | Ship = function () { 377 | this.init("ship", 378 | [-6, 7, 379 | 0, -11, 380 | 6, 7]); 381 | 382 | this.color = 'navy'; 383 | this.solid = true; 384 | 385 | this.children.exhaust = new Sprite(); 386 | this.children.exhaust.solid = true; 387 | this.children.exhaust.color = 'red'; 388 | this.children.exhaust.init("exhaust", 389 | [-3, 6, 390 | 0, 11, 391 | 3, 6]); 392 | 393 | this.delayBeforeBullet = 0; 394 | 395 | this.postMove = this.wrapPostMove; 396 | 397 | this.collidesWith = ["asteroid", "bigalien", "alienbullet"]; 398 | 399 | this.preMove = function (delta) { 400 | if (KEY_STATUS.left) { 401 | this.vel.rot = -6; 402 | } else if (KEY_STATUS.right) { 403 | this.vel.rot = 6; 404 | } else { 405 | this.vel.rot = 0; 406 | } 407 | 408 | if (KEY_STATUS.up) { 409 | var rad = ((this.rot-90) * Math.PI)/180; 410 | this.acc.x = 0.5 * Math.cos(rad); 411 | this.acc.y = 0.5 * Math.sin(rad); 412 | this.children.exhaust.visible = Math.random() > 0.1; 413 | } else { 414 | this.acc.x = 0; 415 | this.acc.y = 0; 416 | this.children.exhaust.visible = false; 417 | } 418 | 419 | if (this.delayBeforeBullet > 0) { 420 | this.delayBeforeBullet -= delta; 421 | } 422 | if (KEY_STATUS.space) { 423 | if (this.delayBeforeBullet <= 0) { 424 | for (var i = 0; i < this.bullets.length; i++) { 425 | if (!this.bullets[i].visible) { 426 | SFX.laser(); 427 | var bullet = this.bullets[i]; 428 | var rad = ((this.rot-90) * Math.PI)/180; 429 | var vectorx = Math.cos(rad); 430 | var vectory = Math.sin(rad); 431 | // move to the nose of the ship 432 | bullet.x = this.x + vectorx * 4; 433 | bullet.y = this.y + vectory * 4; 434 | bullet.vel.x = 6 * vectorx + this.vel.x; 435 | bullet.vel.y = 6 * vectory + this.vel.y; 436 | bullet.visible = true; 437 | break; 438 | } 439 | } 440 | } 441 | } 442 | 443 | // limit the ship's speed 444 | if (Math.sqrt(this.vel.x * this.vel.x + this.vel.y * this.vel.y) > 8) { 445 | this.vel.x *= 0.95; 446 | this.vel.y *= 0.95; 447 | } 448 | }; 449 | 450 | this.collision = function (other) { 451 | SFX.explosion(); 452 | Game.explosionAt(other.x, other.y); 453 | Game.FSM.state = 'player_died'; 454 | this.visible = false; 455 | this.currentNode.leave(this); 456 | this.currentNode = null; 457 | Game.lives--; 458 | }; 459 | 460 | }; 461 | Ship.prototype = new Sprite(); 462 | 463 | BigAlien = function () { 464 | this.init("bigalien", 465 | [-20, 0, 466 | -12, -4, 467 | 12, -4, 468 | 20, 0, 469 | 12, 4, 470 | -12, 4, 471 | -20, 0, 472 | 20, 0]); 473 | 474 | this.children.top = new Sprite(); 475 | this.children.top.init("bigalien_top", 476 | [-8, -4, 477 | -6, -6, 478 | 6, -6, 479 | 8, -4]); 480 | this.children.top.visible = true; 481 | 482 | this.children.bottom = new Sprite(); 483 | this.children.bottom.init("bigalien_top", 484 | [ 8, 4, 485 | 6, 6, 486 | -6, 6, 487 | -8, 4]); 488 | this.children.bottom.visible = true; 489 | 490 | this.collidesWith = ["asteroid", "ship", "bullet"]; 491 | 492 | this.bridgesH = false; 493 | 494 | this.bullets = []; 495 | this.delayBeforeBullet = 0; 496 | 497 | this.newPosition = function () { 498 | if (Math.random() < 0.5) { 499 | this.x = -20; 500 | this.vel.x = 1.5; 501 | } else { 502 | this.x = Game.canvasWidth + 20; 503 | this.vel.x = -1.5; 504 | } 505 | this.y = Math.random() * Game.canvasHeight; 506 | }; 507 | 508 | this.setup = function () { 509 | this.newPosition(); 510 | 511 | for (var i = 0; i < 3; i++) { 512 | var bull = new AlienBullet(); 513 | this.bullets.push(bull); 514 | Game.sprites.push(bull); 515 | } 516 | }; 517 | 518 | this.preMove = function (delta) { 519 | var cn = this.currentNode; 520 | if (cn == null) return; 521 | 522 | var topCount = 0; 523 | if (cn.north.nextSprite) topCount++; 524 | if (cn.north.east.nextSprite) topCount++; 525 | if (cn.north.west.nextSprite) topCount++; 526 | 527 | var bottomCount = 0; 528 | if (cn.south.nextSprite) bottomCount++; 529 | if (cn.south.east.nextSprite) bottomCount++; 530 | if (cn.south.west.nextSprite) bottomCount++; 531 | 532 | if (topCount > bottomCount) { 533 | this.vel.y = 1; 534 | } else if (topCount < bottomCount) { 535 | this.vel.y = -1; 536 | } else if (Math.random() < 0.01) { 537 | this.vel.y = -this.vel.y; 538 | } 539 | 540 | this.delayBeforeBullet -= delta; 541 | if (this.delayBeforeBullet <= 0) { 542 | this.delayBeforeBullet = 22; 543 | for (var i = 0; i < this.bullets.length; i++) { 544 | if (!this.bullets[i].visible) { 545 | bullet = this.bullets[i]; 546 | var rad = 2 * Math.PI * Math.random(); 547 | var vectorx = Math.cos(rad); 548 | var vectory = Math.sin(rad); 549 | bullet.x = this.x; 550 | bullet.y = this.y; 551 | bullet.vel.x = 6 * vectorx; 552 | bullet.vel.y = 6 * vectory; 553 | bullet.visible = true; 554 | SFX.laser(); 555 | break; 556 | } 557 | } 558 | } 559 | 560 | }; 561 | 562 | BigAlien.prototype.collision = function (other) { 563 | if (other.name == "bullet") Game.score += 200; 564 | SFX.explosion(); 565 | Game.explosionAt(other.x, other.y); 566 | this.visible = false; 567 | this.newPosition(); 568 | }; 569 | 570 | this.postMove = function () { 571 | if (this.y > Game.canvasHeight) { 572 | this.y = 0; 573 | } else if (this.y < 0) { 574 | this.y = Game.canvasHeight; 575 | } 576 | 577 | if ((this.vel.x > 0 && this.x > Game.canvasWidth + 20) || 578 | (this.vel.x < 0 && this.x < -20)) { 579 | // why did the alien cross the road? 580 | this.visible = false; 581 | this.newPosition(); 582 | } 583 | } 584 | }; 585 | BigAlien.prototype = new Sprite(); 586 | 587 | Bullet = function () { 588 | this.init("bullet", [0, 0]); 589 | this.time = 0; 590 | this.bridgesH = false; 591 | this.bridgesV = false; 592 | this.postMove = this.wrapPostMove; 593 | // asteroid can look for bullets so doesn't have 594 | // to be other way around 595 | //this.collidesWith = ["asteroid"]; 596 | 597 | this.configureTransform = function () {}; 598 | this.draw = function () { 599 | if (this.visible) { 600 | this.context.save(); 601 | this.context.lineWidth = 2; 602 | this.context.beginPath(); 603 | this.context.moveTo(this.x-1, this.y-1); 604 | this.context.lineTo(this.x+1, this.y+1); 605 | this.context.moveTo(this.x+1, this.y-1); 606 | this.context.lineTo(this.x-1, this.y+1); 607 | this.context.stroke(); 608 | this.context.restore(); 609 | } 610 | }; 611 | this.preMove = function (delta) { 612 | if (this.visible) { 613 | this.time += delta; 614 | } 615 | if (this.time > 50) { 616 | this.visible = false; 617 | this.time = 0; 618 | } 619 | }; 620 | this.collision = function (other) { 621 | this.time = 0; 622 | this.visible = false; 623 | this.currentNode.leave(this); 624 | this.currentNode = null; 625 | }; 626 | this.transformedPoints = function (other) { 627 | return [this.x, this.y]; 628 | }; 629 | 630 | }; 631 | Bullet.prototype = new Sprite(); 632 | 633 | AlienBullet = function () { 634 | this.init("alienbullet"); 635 | 636 | this.draw = function () { 637 | if (this.visible) { 638 | this.context.save(); 639 | this.context.lineWidth = 2; 640 | this.context.beginPath(); 641 | this.context.moveTo(this.x, this.y); 642 | this.context.lineTo(this.x-this.vel.x, this.y-this.vel.y); 643 | this.context.stroke(); 644 | this.context.restore(); 645 | } 646 | }; 647 | }; 648 | AlienBullet.prototype = new Bullet(); 649 | 650 | Asteroid = function () { 651 | this.init("asteroid", 652 | [-10, 0, 653 | -5, 7, 654 | -3, 4, 655 | 1, 10, 656 | 5, 4, 657 | 10, 0, 658 | 5, -6, 659 | 2, -10, 660 | -4, -10, 661 | -4, -5]); 662 | 663 | this.color = 'lightgray'; 664 | this.solid = true; 665 | this.visible = true; 666 | this.scale = 6; 667 | this.postMove = this.wrapPostMove; 668 | 669 | this.collidesWith = ["ship", "bullet", "bigalien", "alienbullet"]; 670 | 671 | this.collision = function (other) { 672 | SFX.explosion(); 673 | if (other.name == "bullet") Game.score += 120 / this.scale; 674 | this.scale /= 3; 675 | if (this.scale > 0.5) { 676 | // break into fragments 677 | for (var i = 0; i < 3; i++) { 678 | var roid = $.extend(true, {}, this); 679 | roid.vel.x = Math.random() * 6 - 3; 680 | roid.vel.y = Math.random() * 6 - 3; 681 | if (Math.random() > 0.5) { 682 | roid.points.reverse(); 683 | } 684 | roid.vel.rot = Math.random() * 2 - 1; 685 | roid.move(roid.scale * 3); // give them a little push 686 | Game.sprites.push(roid); 687 | } 688 | } 689 | Game.explosionAt(other.x, other.y); 690 | this.die(); 691 | }; 692 | }; 693 | Asteroid.prototype = new Sprite(); 694 | 695 | Explosion = function () { 696 | this.init("explosion"); 697 | 698 | this.bridgesH = false; 699 | this.bridgesV = false; 700 | 701 | this.lines = []; 702 | for (var i = 0; i < 5; i++) { 703 | var rad = 2 * Math.PI * Math.random(); 704 | var x = Math.cos(rad); 705 | var y = Math.sin(rad); 706 | this.lines.push([x, y, x*2, y*2]); 707 | } 708 | 709 | this.draw = function () { 710 | if (this.visible) { 711 | this.context.save(); 712 | this.context.strokeStyle = 'red'; 713 | this.context.lineWidth = 1.0 / this.scale; 714 | this.context.beginPath(); 715 | for (var i = 0; i < 5; i++) { 716 | var line = this.lines[i]; 717 | this.context.moveTo(line[0], line[1]); 718 | this.context.lineTo(line[2], line[3]); 719 | } 720 | this.context.stroke(); 721 | this.context.restore(); 722 | } 723 | }; 724 | 725 | this.preMove = function (delta) { 726 | if (this.visible) { 727 | this.scale += delta; 728 | } 729 | if (this.scale > 8) { 730 | this.die(); 731 | } 732 | }; 733 | }; 734 | Explosion.prototype = new Sprite(); 735 | 736 | GridNode = function () { 737 | this.north = null; 738 | this.south = null; 739 | this.east = null; 740 | this.west = null; 741 | 742 | this.nextSprite = null; 743 | 744 | this.dupe = { 745 | horizontal: null, 746 | vertical: null 747 | }; 748 | 749 | this.enter = function (sprite) { 750 | sprite.nextSprite = this.nextSprite; 751 | this.nextSprite = sprite; 752 | }; 753 | 754 | this.leave = function (sprite) { 755 | var ref = this; 756 | while (ref && (ref.nextSprite != sprite)) { 757 | ref = ref.nextSprite; 758 | } 759 | if (ref) { 760 | ref.nextSprite = sprite.nextSprite; 761 | sprite.nextSprite = null; 762 | } 763 | }; 764 | 765 | this.eachSprite = function(sprite, callback) { 766 | var ref = this; 767 | while (ref.nextSprite) { 768 | ref = ref.nextSprite; 769 | callback.call(sprite, ref); 770 | } 771 | }; 772 | 773 | this.isEmpty = function (collidables) { 774 | var empty = true; 775 | var ref = this; 776 | while (ref.nextSprite) { 777 | ref = ref.nextSprite; 778 | empty = !ref.visible || collidables.indexOf(ref.name) == -1 779 | if (!empty) break; 780 | } 781 | return empty; 782 | }; 783 | }; 784 | 785 | // borrowed from typeface-0.14.js 786 | // http://typeface.neocracy.org 787 | Text = { 788 | renderGlyph: function (ctx, face, char) { 789 | 790 | var glyph = face.glyphs[char]; 791 | 792 | if (glyph.o) { 793 | 794 | var outline; 795 | if (glyph.cached_outline) { 796 | outline = glyph.cached_outline; 797 | } else { 798 | outline = glyph.o.split(' '); 799 | glyph.cached_outline = outline; 800 | } 801 | 802 | var outlineLength = outline.length; 803 | for (var i = 0; i < outlineLength; ) { 804 | 805 | var action = outline[i++]; 806 | 807 | switch(action) { 808 | case 'm': 809 | ctx.moveTo(outline[i++], outline[i++]); 810 | break; 811 | case 'l': 812 | ctx.lineTo(outline[i++], outline[i++]); 813 | break; 814 | 815 | case 'q': 816 | var cpx = outline[i++]; 817 | var cpy = outline[i++]; 818 | ctx.quadraticCurveTo(outline[i++], outline[i++], cpx, cpy); 819 | break; 820 | 821 | case 'b': 822 | var x = outline[i++]; 823 | var y = outline[i++]; 824 | ctx.bezierCurveTo(outline[i++], outline[i++], outline[i++], outline[i++], x, y); 825 | break; 826 | } 827 | } 828 | } 829 | if (glyph.ha) { 830 | ctx.translate(glyph.ha, 0); 831 | } 832 | }, 833 | 834 | renderText: function(text, size, x, y) { 835 | this.context.save(); 836 | 837 | this.context.translate(x, y); 838 | 839 | var pixels = size * 72 / (this.face.resolution * 100); 840 | this.context.scale(pixels, -1 * pixels); 841 | this.context.beginPath(); 842 | var chars = text.split(''); 843 | var charsLength = chars.length; 844 | for (var i = 0; i < charsLength; i++) { 845 | this.renderGlyph(this.context, this.face, chars[i]); 846 | } 847 | this.context.fill(); 848 | 849 | this.context.restore(); 850 | }, 851 | 852 | context: null, 853 | face: null 854 | }; 855 | 856 | SFX = { 857 | laser: new Audio('39459__THE_bizniss__laser.wav'), 858 | explosion: new Audio('51467__smcameron__missile_explosion.wav') 859 | }; 860 | 861 | // preload audio 862 | for (var sfx in SFX) { 863 | (function () { 864 | var audio = SFX[sfx]; 865 | audio.muted = true; 866 | audio.play(); 867 | 868 | SFX[sfx] = function () { 869 | if (!this.muted) { 870 | if (audio.duration == 0) { 871 | // somehow dropped out 872 | audio.load(); 873 | audio.play(); 874 | } else { 875 | audio.muted = false; 876 | audio.currentTime = 0; 877 | } 878 | } 879 | return audio; 880 | } 881 | })(); 882 | } 883 | // pre-mute audio 884 | SFX.muted = true; 885 | 886 | Game = { 887 | score: 0, 888 | totalAsteroids: 5, 889 | lives: 0, 890 | 891 | canvasWidth: 800, 892 | canvasHeight: 600, 893 | 894 | sprites: [], 895 | ship: null, 896 | bigAlien: null, 897 | 898 | nextBigAlienTime: null, 899 | 900 | 901 | spawnAsteroids: function (count) { 902 | if (!count) count = this.totalAsteroids; 903 | for (var i = 0; i < count; i++) { 904 | var roid = new Asteroid(); 905 | roid.x = Math.random() * this.canvasWidth; 906 | roid.y = Math.random() * this.canvasHeight; 907 | while (!roid.isClear()) { 908 | roid.x = Math.random() * this.canvasWidth; 909 | roid.y = Math.random() * this.canvasHeight; 910 | } 911 | roid.vel.x = Math.random() * 4 - 2; 912 | roid.vel.y = Math.random() * 4 - 2; 913 | if (Math.random() > 0.5) { 914 | roid.points.reverse(); 915 | } 916 | roid.vel.rot = Math.random() * 2 - 1; 917 | Game.sprites.push(roid); 918 | } 919 | }, 920 | 921 | explosionAt: function (x, y) { 922 | var splosion = new Explosion(); 923 | splosion.x = x; 924 | splosion.y = y; 925 | splosion.visible = true; 926 | Game.sprites.push(splosion); 927 | }, 928 | 929 | FSM: { 930 | boot: function () { 931 | Game.spawnAsteroids(5); 932 | this.state = 'waiting'; 933 | }, 934 | waiting: function () { 935 | Text.renderText(window.ipad ? 'Touch Screen to Start' : 'Press Space to Start', 36, Game.canvasWidth/2 - 270, Game.canvasHeight/2); 936 | if (KEY_STATUS.space || window.gameStart) { 937 | KEY_STATUS.space = false; // hack so we don't shoot right away 938 | window.gameStart = false; 939 | this.state = 'start'; 940 | } 941 | }, 942 | start: function () { 943 | for (var i = 0; i < Game.sprites.length; i++) { 944 | if (Game.sprites[i].name == 'asteroid') { 945 | Game.sprites[i].die(); 946 | } else if (Game.sprites[i].name == 'bullet' || 947 | Game.sprites[i].name == 'bigalien') { 948 | Game.sprites[i].visible = false; 949 | } 950 | } 951 | 952 | Game.score = 0; 953 | Game.lives = 2; 954 | Game.totalAsteroids = 2; 955 | Game.spawnAsteroids(); 956 | 957 | Game.nextBigAlienTime = Date.now() + 30000 + (30000 * Math.random()); 958 | 959 | this.state = 'spawn_ship'; 960 | }, 961 | spawn_ship: function () { 962 | Game.ship.x = Game.canvasWidth / 2; 963 | Game.ship.y = Game.canvasHeight / 2; 964 | if (Game.ship.isClear()) { 965 | Game.ship.rot = 0; 966 | Game.ship.vel.x = 0; 967 | Game.ship.vel.y = 0; 968 | Game.ship.visible = true; 969 | this.state = 'run'; 970 | } 971 | }, 972 | run: function () { 973 | for (var i = 0; i < Game.sprites.length; i++) { 974 | if (Game.sprites[i].name == 'asteroid') { 975 | break; 976 | } 977 | } 978 | if (i == Game.sprites.length) { 979 | this.state = 'new_level'; 980 | } 981 | if (!Game.bigAlien.visible && 982 | Date.now() > Game.nextBigAlienTime) { 983 | Game.bigAlien.visible = true; 984 | Game.nextBigAlienTime = Date.now() + (30000 * Math.random()); 985 | } 986 | }, 987 | new_level: function () { 988 | if (this.timer == null) { 989 | this.timer = Date.now(); 990 | } 991 | // wait a second before spawning more asteroids 992 | if (Date.now() - this.timer > 1000) { 993 | this.timer = null; 994 | Game.totalAsteroids++; 995 | if (Game.totalAsteroids > 12) Game.totalAsteroids = 12; 996 | Game.spawnAsteroids(); 997 | this.state = 'run'; 998 | } 999 | }, 1000 | player_died: function () { 1001 | if (Game.lives < 0) { 1002 | this.state = 'end_game'; 1003 | } else { 1004 | if (this.timer == null) { 1005 | this.timer = Date.now(); 1006 | } 1007 | // wait a second before spawning 1008 | if (Date.now() - this.timer > 1000) { 1009 | this.timer = null; 1010 | this.state = 'spawn_ship'; 1011 | } 1012 | } 1013 | }, 1014 | end_game: function () { 1015 | Text.renderText('GAME OVER', 50, Game.canvasWidth/2 - 160, Game.canvasHeight/2 + 10); 1016 | if (this.timer == null) { 1017 | this.timer = Date.now(); 1018 | } 1019 | // wait 5 seconds then go back to waiting state 1020 | if (Date.now() - this.timer > 5000) { 1021 | this.timer = null; 1022 | this.state = 'waiting'; 1023 | } 1024 | 1025 | window.gameStart = false; 1026 | }, 1027 | 1028 | execute: function () { 1029 | this[this.state](); 1030 | }, 1031 | state: 'boot' 1032 | } 1033 | 1034 | }; 1035 | 1036 | 1037 | $(function () { 1038 | var canvas = $("#canvas"); 1039 | Game.canvasWidth = canvas.width(); 1040 | Game.canvasHeight = canvas.height(); 1041 | 1042 | var context = canvas[0].getContext("2d"); 1043 | 1044 | Text.context = context; 1045 | Text.face = vector_battle; 1046 | 1047 | var gridWidth = Math.round(Game.canvasWidth / GRID_SIZE); 1048 | var gridHeight = Math.round(Game.canvasHeight / GRID_SIZE); 1049 | var grid = new Array(gridWidth); 1050 | for (var i = 0; i < gridWidth; i++) { 1051 | grid[i] = new Array(gridHeight); 1052 | for (var j = 0; j < gridHeight; j++) { 1053 | grid[i][j] = new GridNode(); 1054 | } 1055 | } 1056 | 1057 | // set up the positional references 1058 | for (var i = 0; i < gridWidth; i++) { 1059 | for (var j = 0; j < gridHeight; j++) { 1060 | var node = grid[i][j]; 1061 | node.north = grid[i][(j == 0) ? gridHeight-1 : j-1]; 1062 | node.south = grid[i][(j == gridHeight-1) ? 0 : j+1]; 1063 | node.west = grid[(i == 0) ? gridWidth-1 : i-1][j]; 1064 | node.east = grid[(i == gridWidth-1) ? 0 : i+1][j]; 1065 | } 1066 | } 1067 | 1068 | // set up borders 1069 | for (var i = 0; i < gridWidth; i++) { 1070 | grid[i][0].dupe.vertical = Game.canvasHeight; 1071 | grid[i][gridHeight-1].dupe.vertical = -Game.canvasHeight; 1072 | } 1073 | 1074 | for (var j = 0; j < gridHeight; j++) { 1075 | grid[0][j].dupe.horizontal = Game.canvasWidth; 1076 | grid[gridWidth-1][j].dupe.horizontal = -Game.canvasWidth; 1077 | } 1078 | 1079 | var sprites = []; 1080 | Game.sprites = sprites; 1081 | 1082 | // so all the sprites can use it 1083 | Sprite.prototype.context = context; 1084 | Sprite.prototype.grid = grid; 1085 | Sprite.prototype.matrix = new Matrix(2, 3); 1086 | 1087 | var ship = new Ship(); 1088 | 1089 | ship.x = Game.canvasWidth / 2; 1090 | ship.y = Game.canvasHeight / 2; 1091 | 1092 | sprites.push(ship); 1093 | 1094 | ship.bullets = []; 1095 | for (var i = 0; i < 100; i++) { 1096 | var bull = new Bullet(); 1097 | ship.bullets.push(bull); 1098 | sprites.push(bull); 1099 | } 1100 | Game.ship = ship; 1101 | 1102 | var bigAlien = new BigAlien(); 1103 | bigAlien.setup(); 1104 | sprites.push(bigAlien); 1105 | Game.bigAlien = bigAlien; 1106 | 1107 | var extraDude = new Ship(); 1108 | extraDude.scale = 0.6; 1109 | extraDude.visible = true; 1110 | extraDude.preMove = null; 1111 | extraDude.children = []; 1112 | 1113 | var i, j = 0; 1114 | 1115 | var paused = false; 1116 | var showFramerate = false; 1117 | var avgFramerate = 0; 1118 | var frameCount = 0; 1119 | var elapsedCounter = 0; 1120 | 1121 | var lastFrame = Date.now(); 1122 | var thisFrame; 1123 | var elapsed; 1124 | var delta; 1125 | 1126 | var canvasNode = canvas[0]; 1127 | 1128 | // shim layer with setTimeout fallback 1129 | // from here: 1130 | // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 1131 | window.requestAnimFrame = (function () { 1132 | return window.requestAnimationFrame || 1133 | window.webkitRequestAnimationFrame || 1134 | window.mozRequestAnimationFrame || 1135 | window.oRequestAnimationFrame || 1136 | window.msRequestAnimationFrame || 1137 | function (/* function */ callback, /* DOMElement */ element) { 1138 | window.setTimeout(callback, 1000 / 60); 1139 | }; 1140 | })(); 1141 | 1142 | var mainLoop = function () { 1143 | context.clearRect(0, 0, Game.canvasWidth, Game.canvasHeight); 1144 | 1145 | Game.FSM.execute(); 1146 | 1147 | if (KEY_STATUS.g) { 1148 | context.beginPath(); 1149 | for (var i = 0; i < gridWidth; i++) { 1150 | context.moveTo(i * GRID_SIZE, 0); 1151 | context.lineTo(i * GRID_SIZE, Game.canvasHeight); 1152 | } 1153 | for (var j = 0; j < gridHeight; j++) { 1154 | context.moveTo(0, j * GRID_SIZE); 1155 | context.lineTo(Game.canvasWidth, j * GRID_SIZE); 1156 | } 1157 | context.closePath(); 1158 | context.stroke(); 1159 | } 1160 | 1161 | thisFrame = Date.now(); 1162 | elapsed = thisFrame - lastFrame; 1163 | lastFrame = thisFrame; 1164 | delta = elapsed / 30; 1165 | 1166 | for (i = 0; i < sprites.length; i++) { 1167 | 1168 | sprites[i].run(delta); 1169 | 1170 | if (sprites[i].reap) { 1171 | sprites[i].reap = false; 1172 | sprites.splice(i, 1); 1173 | i--; 1174 | } 1175 | } 1176 | 1177 | // score 1178 | var score_text = ''+Game.score; 1179 | Text.renderText(score_text, 21, Game.canvasWidth - 16 * score_text.length, 25); 1180 | 1181 | // extra dudes 1182 | for (i = 0; i < Game.lives; i++) { 1183 | context.save(); 1184 | extraDude.x = Game.canvasWidth - (8 * (i + 1)); 1185 | extraDude.y = 40; 1186 | extraDude.configureTransform(); 1187 | extraDude.draw(); 1188 | context.restore(); 1189 | } 1190 | 1191 | if (showFramerate) { 1192 | Text.renderText(''+avgFramerate, 24, Game.canvasWidth - 38, Game.canvasHeight - 2); 1193 | } 1194 | 1195 | frameCount++; 1196 | elapsedCounter += elapsed; 1197 | if (elapsedCounter > 1000) { 1198 | elapsedCounter -= 1000; 1199 | avgFramerate = frameCount; 1200 | frameCount = 0; 1201 | } 1202 | 1203 | if (paused) { 1204 | Text.renderText('PAUSED', 72, Game.canvasWidth/2 - 160, 120); 1205 | } else { 1206 | requestAnimFrame(mainLoop, canvasNode); 1207 | } 1208 | }; 1209 | 1210 | mainLoop(); 1211 | 1212 | $(window).keydown(function (e) { 1213 | switch (KEY_CODES[e.keyCode]) { 1214 | case 'f': // show framerate 1215 | showFramerate = !showFramerate; 1216 | break; 1217 | case 'p': // pause 1218 | paused = !paused; 1219 | if (!paused) { 1220 | // start up again 1221 | lastFrame = Date.now(); 1222 | mainLoop(); 1223 | } 1224 | break; 1225 | case 'm': // mute 1226 | SFX.muted = !SFX.muted; 1227 | break; 1228 | } 1229 | }); 1230 | }); 1231 | 1232 | // vim: fdl=0 1233 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 17 | 18 | 19 |
20 | 21 |
22 |
THRUST
23 |
LEFT
24 | 25 |
26 |
27 |
FIRE
28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /ipad.js: -------------------------------------------------------------------------------- 1 | var ipad = navigator.userAgent.match(/iPad/i) != null; 2 | 3 | if (ipad) { 4 | $(function () { 5 | $('#left-controls, #right-controls').show(); 6 | $('body > *').hide(); 7 | $('body').css('margin', '0px').css('background', 'black').prepend($('#game-container').remove()); 8 | $('#game-container').width(1024).css('margin-top', 26).show(); 9 | $('#canvas').attr('width', 1020).attr('height', 660).css('background', 'white').css('margin', '0 1'); 10 | 11 | $('head').prepend($('').attr('name', 'viewport').attr('content', 'width=device-width; height=device-height; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;')); 12 | 13 | $('#left-controls, #right-controls').bind('touchstart touchmove touchend', function (e) { 14 | if (e.type != 'touchend') { 15 | for (k in KEY_STATUS) { 16 | KEY_STATUS[k] = false; 17 | } 18 | } 19 | var touches = e.type == 'touchend' ? e.originalEvent.changedTouches : e.originalEvent.touches 20 | for (var i = 0; i < touches.length; i++) { 21 | var ele = document.elementFromPoint(touches[i].pageX, touches[i].pageY); 22 | KEY_STATUS[ele.id] = (e.type != 'touchend'); 23 | } 24 | }); 25 | 26 | $(document).bind('touchstart', function (e) { 27 | window.gameStart = true; 28 | }); 29 | 30 | $(document).bind('gesturestart gesturechange gestureend touchstart touchmove touchend', function (e) { 31 | e.preventDefault(); 32 | }); 33 | }); 34 | } 35 | 36 | -------------------------------------------------------------------------------- /jquery-1.4.1.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery JavaScript Library v1.4.1 3 | * http://jquery.com/ 4 | * 5 | * Copyright 2010, John Resig 6 | * Dual licensed under the MIT or GPL Version 2 licenses. 7 | * http://jquery.org/license 8 | * 9 | * Includes Sizzle.js 10 | * http://sizzlejs.com/ 11 | * Copyright 2010, The Dojo Foundation 12 | * Released under the MIT, BSD, and GPL Licenses. 13 | * 14 | * Date: Mon Jan 25 19:43:33 2010 -0500 15 | */ 16 | (function(z,v){function la(){if(!c.isReady){try{r.documentElement.doScroll("left")}catch(a){setTimeout(la,1);return}c.ready()}}function Ma(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var n in b)X(a,n,b[n],f,e,d);return a}if(d!==v){f=!i&&f&&c.isFunction(d);for(n=0;n-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete x[o]}i=c(a.target).closest(f, 18 | a.currentTarget);m=0;for(s=i.length;m)[^>]*$|^#([\w-]+)$/,Qa=/^.[^:#\[\.,]*$/,Ra=/\S/,Sa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Ta=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,O=navigator.userAgent, 21 | va=false,P=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,Q=Array.prototype.slice,wa=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Pa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:r;if(a=Ta.exec(a))if(c.isPlainObject(b)){a=[r.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ra([d[1]], 22 | [f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=r.getElementById(d[2])){if(b.id!==d[2])return S.find(a);this.length=1;this[0]=b}this.context=r;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=r;a=r.getElementsByTagName(a)}else return!b||b.jquery?(b||S).find(a):c(b).find(a);else if(c.isFunction(a))return S.ready(a);if(a.selector!==v){this.selector=a.selector;this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a, 23 | this)},selector:"",jquery:"1.4.1",length:0,size:function(){return this.length},toArray:function(){return Q.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=0;ba.apply(this,a);return this},each:function(a,b){return c.each(this, 24 | a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(r,c);else P&&P.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Q.apply(this,arguments),"slice",Q.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice}; 25 | c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,n;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support= 34 | {leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:r.createElement("select").appendChild(r.createElement("option")).selected,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null}; 35 | b.type="text/javascript";try{b.appendChild(r.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,a.firstChild);if(z[f]){c.support.scriptEval=true;delete z[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function n(){c.support.noCloneEvent=false;d.detachEvent("onclick",n)});d.cloneNode(true).fireEvent("onclick")}d=r.createElement("div");d.innerHTML="";a=r.createDocumentFragment();a.appendChild(d.firstChild); 36 | c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var n=r.createElement("div");n.style.width=n.style.paddingLeft="1px";r.body.appendChild(n);c.boxModel=c.support.boxModel=n.offsetWidth===2;r.body.removeChild(n).style.display="none"});a=function(n){var o=r.createElement("div");n="on"+n;var m=n in o;if(!m){o.setAttribute(n,"return;");m=typeof o[n]==="function"}return m};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props= 37 | {"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ua=0,xa={},Va={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var f=a[G],e=c.cache;if(!b&&!f)return null;f||(f=++Ua);if(typeof b==="object"){a[G]=f;e=e[f]=c.extend(true, 38 | {},b)}else e=e[f]?e[f]:typeof d==="undefined"?Va:(e[f]={});if(d!==v){a[G]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[G]}catch(i){a.removeAttribute&&a.removeAttribute(G)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this, 39 | a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===v){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===v&&this.length)f=c.data(this[0],a);return f===v&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d); 40 | return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===v)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]|| 41 | a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var ya=/[\n\t]/g,ca=/\s+/,Wa=/\r/g,Xa=/href|src|style/,Ya=/(button|input)/i,Za=/(button|input|object|select|textarea)/i,$a=/^(a|area)$/i,za=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(o){var m= 42 | c(this);m.addClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===v){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value|| 45 | {}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i=0;else if(c.nodeName(this,"select")){var x=c.makeArray(s);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),x)>=0});if(!x.length)this.selectedIndex=-1}else this.value=s}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return v;if(f&&b in c.attrFn)return c(a)[b](d); 47 | f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==v;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Xa.test(b);if(b in a&&f&&!i){if(e){b==="type"&&Ya.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Za.test(a.nodeName)||$a.test(a.nodeName)&&a.href?0:v;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText= 48 | ""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?v:a}return c.style(a,b,d)}});var ab=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==z&&!a.frameElement)a=z;if(!d.guid)d.guid=c.guid++;if(f!==v){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j= 49 | function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):v};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var n,o=0;n=b[o++];){var m=n.split(".");n=m.shift();if(o>1){d=c.proxy(d);if(f!==v)d.data=f}d.type=m.slice(0).sort().join(".");var s=e[n],x=this.special[n]||{};if(!s){s=e[n]={};if(!x.setup||x.setup.call(a,f,m,d)===false)if(a.addEventListener)a.addEventListener(n,i,false);else a.attachEvent&&a.attachEvent("on"+n,i)}if(x.add)if((m=x.add.call(a, 50 | d,f,m,s))&&c.isFunction(m)){m.guid=m.guid||d.guid;m.data=m.data||d.data;m.type=m.type||d.type;d=m}s[d.guid]=d;this.global[n]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===v||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);for(var n=0;i=b[n++];){var o=i.split(".");i=o.shift();var m=!o.length,s=c.map(o.slice(0).sort(),ab);s=new RegExp("(^|\\.)"+ 51 | s.join("\\.(?:.*\\.)?")+"(\\.|$)");var x=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var A in f[i])if(m||s.test(f[i][A].type))delete f[i][A];x.remove&&x.remove.call(a,o,j);for(e in f[i])break;if(!e){if(!x.teardown||x.teardown.call(a,o)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(A=c.data(a,"handle"))A.elem=null;c.removeData(a, 52 | "events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return v;a.result=v;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d, 53 | b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(i){}if(!a.isPropagationStopped()&&f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){d=a.target;var j;if(!(c.nodeName(d,"a")&&e==="click")&&!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){try{if(d[e]){if(j=d["on"+e])d["on"+e]=null;this.triggered=true;d[e]()}}catch(n){}if(j)d["on"+e]=j;this.triggered=false}}},handle:function(a){var b, 54 | d;a=arguments[0]=c.event.fix(a||z.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==v){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), 55 | fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||r;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=r.documentElement;d=r.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop|| 56 | d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==v)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;b.liveProxy=a;c.event.add(this,b.live,na,b)},remove:function(a){if(a.length){var b= 57 | 0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],na)}},special:{}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true}; 58 | c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y};var Aa=function(a){for(var b= 59 | a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ba=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ba:Aa,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ba:Aa)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!== 60 | "form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return ma("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return ma("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this, 61 | "keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var da=/textarea|input|select/i;function Ca(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ea(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Ca(d);if(a.type!=="focusout"|| 62 | d.type!=="radio")c.data(d,"_change_data",e);if(!(f===v||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}}c.event.special.change={filters:{focusout:ea,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ea.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ea.call(this,a)},beforeactivate:function(a){a= 63 | a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Ca(a))}},setup:function(a,b,d){for(var f in T)c.event.add(this,f+".specialChange."+d.guid,T[f]);return da.test(this.nodeName)},remove:function(a,b){for(var d in T)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),T[d]);return da.test(this.nodeName)}};var T=c.event.special.change.filters}r.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this, 64 | f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){e=f;f=v}var j=b==="one"?c.proxy(e,function(n){c(this).unbind(n,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a, 65 | b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d0){y=t;break}}t=t[g]}l[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,i=Object.prototype.toString,j=false,n=true;[0,0].sort(function(){n=false;return 0});var o=function(g,h,k,l){k=k||[];var q=h=h||r;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g|| 70 | typeof g!=="string")return k;for(var p=[],u,t,y,R,H=true,M=w(h),I=g;(f.exec(""),u=f.exec(I))!==null;){I=u[3];p.push(u[1]);if(u[2]){R=u[3];break}}if(p.length>1&&s.exec(g))if(p.length===2&&m.relative[p[0]])t=fa(p[0]+p[1],h);else for(t=m.relative[p[0]]?[h]:o(p.shift(),h);p.length;){g=p.shift();if(m.relative[g])g+=p.shift();t=fa(g,t)}else{if(!l&&p.length>1&&h.nodeType===9&&!M&&m.match.ID.test(p[0])&&!m.match.ID.test(p[p.length-1])){u=o.find(p.shift(),h,M);h=u.expr?o.filter(u.expr,u.set)[0]:u.set[0]}if(h){u= 71 | l?{expr:p.pop(),set:A(l)}:o.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=u.expr?o.filter(u.expr,u.set):u.set;if(p.length>0)y=A(t);else H=false;for(;p.length;){var D=p.pop();u=D;if(m.relative[D])u=p.pop();else D="";if(u==null)u=h;m.relative[D](y,u,M)}}else y=[]}y||(y=t);y||o.error(D||g);if(i.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))k.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&& 72 | y[g].nodeType===1&&k.push(t[g]);else k.push.apply(k,y);else A(y,k);if(R){o(R,q,k,l);o.uniqueSort(k)}return k};o.uniqueSort=function(g){if(C){j=n;g.sort(C);if(j)for(var h=1;h":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var l=0,q=g.length;l=0))k||l.push(u);else if(k)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&& 79 | "2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,l,q,p){h=g[1].replace(/\\/g,"");if(!p&&m.attrMap[h])g[1]=m.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,l,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=o(g[3],null,null,h);else{g=o.filter(g[3],h,k,true^q);k||l.push.apply(l,g);return false}else if(m.match.POS.test(g[0])||m.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true); 80 | return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!o(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"=== 81 | g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,h){return h===0},last:function(g,h,k,l){return h===l.length-1},even:function(g,h){return h%2=== 82 | 0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return hk[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,l){var q=h[1],p=m.filters[q];if(p)return p(g,k,h,l);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=h[3];k=0;for(l=h.length;k= 84 | 0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=m.attrHandle[k]?m.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var l=h[2];h=h[4];return g==null?l==="!=":l==="="?k===h:l==="*="?k.indexOf(h)>=0:l==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:l==="!="?k!==h:l==="^="? 85 | k.indexOf(h)===0:l==="$="?k.substr(k.length-h.length)===h:l==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,l){var q=m.setFilters[h[2]];if(q)return q(g,k,h,l)}}},s=m.match.POS;for(var x in m.match){m.match[x]=new RegExp(m.match[x].source+/(?![^\[]*\])(?![^\(]*\))/.source);m.leftMatch[x]=new RegExp(/(^(?:.|\r|\n)*?)/.source+m.match[x].source.replace(/\\(\d+)/g,function(g,h){return"\\"+(h-0+1)}))}var A=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g}; 86 | try{Array.prototype.slice.call(r.documentElement.childNodes,0)}catch(B){A=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,l=g.length;k";var k=r.documentElement;k.insertBefore(g,k.firstChild);if(r.getElementById(h)){m.find.ID=function(l,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(l[1]))?q.id===l[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===l[1]?[q]:v:[]};m.filter.ID=function(l,q){var p=typeof l.getAttributeNode!=="undefined"&&l.getAttributeNode("id"); 89 | return l.nodeType===1&&p&&p.nodeValue===q}}k.removeChild(g);k=g=null})();(function(){var g=r.createElement("div");g.appendChild(r.createComment(""));if(g.getElementsByTagName("*").length>0)m.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var l=0;k[l];l++)k[l].nodeType===1&&h.push(k[l]);k=h}return k};g.innerHTML="";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")m.attrHandle.href=function(h){return h.getAttribute("href", 90 | 2)};g=null})();r.querySelectorAll&&function(){var g=o,h=r.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){o=function(l,q,p,u){q=q||r;if(!u&&q.nodeType===9&&!w(q))try{return A(q.querySelectorAll(l),p)}catch(t){}return g(l,q,p,u)};for(var k in g)o[k]=g[k];h=null}}();(function(){var g=r.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length=== 91 | 0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){m.order.splice(1,0,"CLASS");m.find.CLASS=function(h,k,l){if(typeof k.getElementsByClassName!=="undefined"&&!l)return k.getElementsByClassName(h[1])};g=null}}})();var E=r.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,h){return g!==h&&(g.contains?g.contains(h):true)},w=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},fa=function(g,h){var k=[], 92 | l="",q;for(h=h.nodeType?[h]:h;q=m.match.PSEUDO.exec(g);){l+=q[0];g=g.replace(m.match.PSEUDO,"")}g=m.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var i=d;i0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i={},j;if(f&&a.length){e=0;for(var n=a.length;e 95 | -1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var o=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(m,s){for(;s&&s.ownerDocument&&s!==b;){if(o?o.index(s)>-1:c(s).is(a))return s;s=s.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(), 96 | a);return this.pushStack(pa(a[0])||pa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")}, 97 | nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);bb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e): 98 | e;if((this.length>1||db.test(f))&&cb.test(a))e=e.reverse();return this.pushStack(e,a,Q.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===v||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!== 99 | b&&d.push(a);return d}});var Fa=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ga=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"], 100 | col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==v)return this.empty().append((this[0]&&this[0].ownerDocument||r).createTextNode(a));return c.getText(this)}, 101 | wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length? 102 | d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments, 103 | false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&& 104 | !c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Fa,"").replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){qa(this,b);qa(this.find("*"),b.find("*"))}return b},html:function(a){if(a===v)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Fa,""):null;else if(typeof a==="string"&&!/