实验3 web之前端逆向安全

发现snake.js,源码:

  1 /*
  2 JavaScript Snake
  3 By Patrick Gillespie
  4 http://patorjk.com/games/snake
  5 */
  6 
  7 /**
  8 * @module Snake
  9 * @class SNAKE
 10 */
 11 
 12 var SNAKE = SNAKE || {};
 13 
 14 /**
 15 * @method addEventListener
 16 * @param {Object} obj The object to add an event listener to.
 17 * @param {String} event The event to listen for.
 18 * @param {Function} funct The function to execute when the event is triggered.
 19 * @param {Boolean} evtCapturing True to do event capturing, false to do event bubbling.
 20 */
 21 
 22 SNAKE.addEventListener = (function() {
 23     if (window.addEventListener) {
 24         return function(obj, event, funct, evtCapturing) {
 25             obj.addEventListener(event, funct, evtCapturing);
 26         };
 27     } else if (window.attachEvent) {
 28         return function(obj, event, funct) {
 29             obj.attachEvent("on" + event, funct);
 30         };
 31     }
 32 })();
 33 
 34 /**
 35 * @method removeEventListener
 36 * @param {Object} obj The object to remove an event listener from.
 37 * @param {String} event The event that was listened for.
 38 * @param {Function} funct The function that was executed when the event is triggered.
 39 * @param {Boolean} evtCapturing True if event capturing was done, false otherwise.
 40 */
 41 
 42 SNAKE.removeEventListener = (function() {
 43     if (window.removeEventListener) {
 44         return function(obj, event, funct, evtCapturing) {
 45             obj.removeEventListener(event, funct, evtCapturing);
 46         };
 47     } else if (window.detachEvent) {
 48         return function(obj, event, funct) {
 49             obj.detachEvent("on" + event, funct);
 50         };
 51     }
 52 })();
 53 
 54 /**
 55 * This class manages the snake which will reside inside of a SNAKE.Board object.
 56 * @class Snake
 57 * @constructor
 58 * @namespace SNAKE
 59 * @param {Object} config The configuration object for the class. Contains playingBoard (the SNAKE.Board that this snake resides in), startRow and startCol.
 60 */
 61 SNAKE.Snake = SNAKE.Snake || (function() {
 62     
 63     // -------------------------------------------------------------------------
 64     // Private static variables and methods
 65     // -------------------------------------------------------------------------
 66     
 67     var instanceNumber = 0;
 68     var blockPool = [];
 69     
 70     var SnakeBlock = function() {
 71         this.elm = null;
 72         this.elmStyle = null;
 73         this.row = -1;
 74         this.col = -1;
 75         this.xPos = -1000;
 76         this.yPos = -1000;
 77         this.next = null;
 78         this.prev = null;
 79     };
 80     
 81     // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html
 82     function getNextHighestZIndex(myObj) {
 83         var highestIndex = 0,
 84             currentIndex = 0,
 85             ii;
 86         for (ii in myObj) {
 87             if (myObj[ii].elm.currentStyle){  
 88                 currentIndex = parseFloat(myObj[ii].elm.style["z-index"],10);
 89             }else if(window.getComputedStyle) {
 90                 currentIndex = parseFloat(document.defaultView.getComputedStyle(myObj[ii].elm,null).getPropertyValue("z-index"),10);  
 91             }
 92             if(!isNaN(currentIndex) && currentIndex > highestIndex){
 93                 highestIndex = currentIndex;
 94             }
 95         }
 96         return(highestIndex+1);  
 97     }
 98     
 99     // -------------------------------------------------------------------------
100     // Contructor + public and private definitions
101     // -------------------------------------------------------------------------
102     
103     /*
104         config options:
105             playingBoard - the SnakeBoard that this snake belongs too.
106             startRow - The row the snake should start on.
107             startCol - The column the snake should start on.
108     */
109     return function(config) {
110     
111         if (!config||!config.playingBoard) {return;}
112     
113         // ----- private variables -----
114 
115         var me = this,
116             playingBoard = config.playingBoard,
117             myId = instanceNumber++,
118             growthIncr = 5,
119             moveQueue = [], // a queue that holds the next moves of the snake
120             currentDirection = 1, // 0: up, 1: left, 2: down, 3: right
121             columnShift = [0, 1, 0, -1],
122             rowShift = [-1, 0, 1, 0],
123             xPosShift = [],
124             yPosShift = [],
125             snakeSpeed = 75,
126             isDead = false;
127         
128         // ----- public variables -----
129 
130         me.snakeBody = {};
131         me.snakeBody["b0"] = new SnakeBlock(); // create snake head
132         me.snakeBody["b0"].row = config.startRow || 1;
133         me.snakeBody["b0"].col = config.startCol || 1;
134         me.snakeBody["b0"].xPos = me.snakeBody["b0"].row * playingBoard.getBlockWidth();
135         me.snakeBody["b0"].yPos = me.snakeBody["b0"].col * playingBoard.getBlockHeight();
136         me.snakeBody["b0"].elm = createSnakeElement();
137         me.snakeBody["b0"].elmStyle = me.snakeBody["b0"].elm.style;
138         playingBoard.getBoardContainer().appendChild( me.snakeBody["b0"].elm );
139         me.snakeBody["b0"].elm.style.left = me.snakeBody["b0"].xPos + "px";
140         me.snakeBody["b0"].elm.style.top = me.snakeBody["b0"].yPos + "px";
141         me.snakeBody["b0"].next = me.snakeBody["b0"];
142         me.snakeBody["b0"].prev = me.snakeBody["b0"];
143         
144         me.snakeLength = 1;
145         me.snakeHead = me.snakeBody["b0"];
146         me.snakeTail = me.snakeBody["b0"];
147         me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-dead/,'');
148         me.snakeHead.elm.className += " snake-snakebody-alive";
149         
150         // ----- private methods -----
151         
152         function createSnakeElement() {
153             var tempNode = document.createElement("div");
154             tempNode.className = "snake-snakebody-block";
155             tempNode.style.left = "-1000px";
156             tempNode.style.top = "-1000px";
157             tempNode.style.width = playingBoard.getBlockWidth() + "px";
158             tempNode.style.height = playingBoard.getBlockHeight() + "px";
159             return tempNode;
160         }
161         
162         function createBlocks(num) {
163             var tempBlock;
164             var tempNode = createSnakeElement();
165 
166             for (var ii = 1; ii < num; ii++){
167                 tempBlock = new SnakeBlock();
168                 tempBlock.elm = tempNode.cloneNode(true);
169                 tempBlock.elmStyle = tempBlock.elm.style;
170                 playingBoard.getBoardContainer().appendChild( tempBlock.elm );
171                 blockPool[blockPool.length] = tempBlock;
172             }
173             
174             tempBlock = new SnakeBlock();
175             tempBlock.elm = tempNode;
176             playingBoard.getBoardContainer().appendChild( tempBlock.elm );
177             blockPool[blockPool.length] = tempBlock;
178         }
179         
180         // ----- public methods -----
181         
182         /**
183         * This method is called when a user presses a key. It logs arrow key presses in "moveQueue", which is used when the snake needs to make its next move.
184         * @method handleArrowKeys
185         * @param {Number} keyNum A number representing the key that was pressed.
186         */
187         /*
188             Handles what happens when an arrow key is pressed. 
189             Direction explained (0 = up, etc etc)
190                     0
191                   3   1
192                     2
193         */
194         me.handleArrowKeys = function(keyNum) {
195             if (isDead) {return;}
196             
197             var snakeLength = me.snakeLength;
198             var lastMove = moveQueue[0] || currentDirection;
199 
200             switch (keyNum) {
201                 case 37:
202                     if ( lastMove !== 1 || snakeLength === 1 ) {
203                         moveQueue.unshift(3); //SnakeDirection = 3;
204                     }
205                     break;    
206                 case 38:
207                     if ( lastMove !== 2 || snakeLength === 1 ) {
208                         moveQueue.unshift(0);//SnakeDirection = 0;
209                     }
210                     break;    
211                 case 39:
212                     if ( lastMove !== 3 || snakeLength === 1 ) {
213                         moveQueue.unshift(1); //SnakeDirection = 1;
214                     }
215                     break;    
216                 case 40:
217                     if ( lastMove !== 0 || snakeLength === 1 ) {
218                         moveQueue.unshift(2);//SnakeDirection = 2;
219                     }
220                     break;  
221             }
222         };
223         
224         /**
225         * This method is executed for each move of the snake. It determines where the snake will go and what will happen to it. This method needs to run quickly.
226         * @method go
227         */
228         me.go = function() {
229         
230             var oldHead = me.snakeHead,
231                 newHead = me.snakeTail,
232                 myDirection = currentDirection,
233                 grid = playingBoard.grid; // cache grid for quicker lookup
234         
235             me.snakeTail = newHead.prev;
236             me.snakeHead = newHead;
237         
238             // clear the old board position
239             if ( grid[newHead.row] && grid[newHead.row][newHead.col] ) {
240                 grid[newHead.row][newHead.col] = 0;
241             }
242         
243             if (moveQueue.length){
244                 myDirection = currentDirection = moveQueue.pop();
245             }
246         
247             newHead.col = oldHead.col + columnShift[myDirection];
248             newHead.row = oldHead.row + rowShift[myDirection];
249             newHead.xPos = oldHead.xPos + xPosShift[myDirection];
250             newHead.yPos = oldHead.yPos + yPosShift[myDirection];
251             
252             if ( !newHead.elmStyle ) {
253                 newHead.elmStyle = newHead.elm.style;
254             }
255             
256             newHead.elmStyle.left = newHead.xPos + "px";
257             newHead.elmStyle.top = newHead.yPos + "px";
258 
259             // check the new spot the snake moved into
260 
261             if (grid[newHead.row][newHead.col] === 0) {
262                 grid[newHead.row][newHead.col] = 1;
263                 setTimeout(function(){me.go();}, snakeSpeed); 
264             } else if (grid[newHead.row][newHead.col] > 0) {
265                 me.handleDeath();
266             } else if (grid[newHead.row][newHead.col] === playingBoard.getGridFoodValue()) {
267                 grid[newHead.row][newHead.col] = 1;
268                 me.eatFood();
269                 setTimeout(function(){me.go();}, snakeSpeed);
270             }
271         };
272         
273         /**
274         * This method is called when it is determined that the snake has eaten some food.
275         * @method eatFood
276         */
277         me.eatFood = function() {
278             if (blockPool.length <= growthIncr) {
279                 createBlocks(growthIncr*2);
280             }
281             var blocks = blockPool.splice(0, growthIncr);
282             
283             var ii = blocks.length,
284                 index,
285                 prevNode = me.snakeTail;
286             while (ii--) {
287                 index = "b" + me.snakeLength++;
288                 me.snakeBody[index] = blocks[ii];
289   
290 
291 
292 if (me.snakeLength > 2500){
293 ゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
294 
295 }
296 
297 
298 
299 
300 
301               me.snakeBody[index].prev = prevNode;
302                 me.snakeBody[index].elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-dead/,'')
303                 me.snakeBody[index].elm.className += " snake-snakebody-alive";
304                 prevNode.next = me.snakeBody[index];
305                 prevNode = me.snakeBody[index];
306 
307               
308 
309             }
310             me.snakeTail = me.snakeBody[index];
311             me.snakeTail.next = me.snakeHead;
312             me.snakeHead.prev = me.snakeTail;
313 
314             playingBoard.foodEaten();
315         };
316         
317         /**
318         * This method handles what happens when the snake dies.
319         * @method handleDeath
320         */
321         me.handleDeath = function() {
322             me.snakeHead.elm.style.zIndex = getNextHighestZIndex(me.snakeBody);
323             me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-alive/,'')
324             me.snakeHead.elm.className += " snake-snakebody-dead";
325 
326             isDead = true;
327             playingBoard.handleDeath();
328             moveQueue.length = 0;
329         };
330 
331         /**
332         * This method sets a flag that lets the snake be alive again.
333         * @method rebirth
334         */   
335         me.rebirth = function() {
336             isDead = false;
337         };
338         
339         /**
340         * This method reset the snake so it is ready for a new game.
341         * @method reset
342         */        
343         me.reset = function() {
344             if (isDead === false) {return;}
345             
346             var blocks = [],
347                 curNode = me.snakeHead.next,
348                 nextNode;
349             while (curNode !== me.snakeHead) {
350                 nextNode = curNode.next;
351                 curNode.prev = null;
352                 curNode.next = null;
353                 blocks.push(curNode);
354                 curNode = nextNode;
355             }
356             me.snakeHead.next = me.snakeHead;
357             me.snakeHead.prev = me.snakeHead;
358             me.snakeTail = me.snakeHead;
359             me.snakeLength = 1;
360             
361             for (var ii = 0; ii < blocks.length; ii++) {
362                 blocks[ii].elm.style.left = "-1000px";
363                 blocks[ii].elm.style.top = "-1000px";
364                 blocks[ii].elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-dead/,'')
365                 blocks[ii].elm.className += " snake-snakebody-alive";
366             }
367             
368             blockPool.concat(blocks);
369             me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/snake-snakebody-dead/,'')
370             me.snakeHead.elm.className += " snake-snakebody-alive";
371             me.snakeHead.row = config.startRow || 1;
372             me.snakeHead.col = config.startCol || 1;
373             me.snakeHead.xPos = me.snakeHead.row * playingBoard.getBlockWidth();
374             me.snakeHead.yPos = me.snakeHead.col * playingBoard.getBlockHeight();
375             me.snakeHead.elm.style.left = me.snakeHead.xPos + "px";
376             me.snakeHead.elm.style.top = me.snakeHead.yPos + "px";
377         };
378         
379         // ---------------------------------------------------------------------
380         // Initialize
381         // ---------------------------------------------------------------------
382         
383         createBlocks(growthIncr*2);
384         xPosShift[0] = 0;
385         xPosShift[1] = playingBoard.getBlockWidth();
386         xPosShift[2] = 0;
387         xPosShift[3] = -1 * playingBoard.getBlockWidth();
388         
389         yPosShift[0] = -1 * playingBoard.getBlockHeight();
390         yPosShift[1] = 0;
391         yPosShift[2] = playingBoard.getBlockHeight();
392         yPosShift[3] = 0;
393     };
394 })();
395 
396 /**
397 * This class manages the food which the snake will eat.
398 * @class Food
399 * @constructor
400 * @namespace SNAKE
401 * @param {Object} config The configuration object for the class. Contains playingBoard (the SNAKE.Board that this food resides in).
402 */
403 
404 SNAKE.Food = SNAKE.Food || (function() {
405     
406     // -------------------------------------------------------------------------
407     // Private static variables and methods
408     // -------------------------------------------------------------------------
409     
410     var instanceNumber = 0;
411     
412     function getRandomPosition(x, y){
413         return Math.floor(Math.random()*(y+1-x)) + x; 
414     }
415     
416     // -------------------------------------------------------------------------
417     // Contructor + public and private definitions
418     // -------------------------------------------------------------------------
419     
420     /*
421         config options:
422             playingBoard - the SnakeBoard that this object belongs too.
423     */
424     return function(config) {
425         
426         if (!config||!config.playingBoard) {return;}
427 
428         // ----- private variables -----
429 
430         var me = this;
431         var playingBoard = config.playingBoard;
432         var fRow, fColumn;
433         var myId = instanceNumber++;
434 
435         var elmFood = document.createElement("div");
436         elmFood.setAttribute("id", "snake-food-"+myId);
437         elmFood.className = "snake-food-block";
438         elmFood.style.width = playingBoard.getBlockWidth() + "px";
439         elmFood.style.height = playingBoard.getBlockHeight() + "px";
440         elmFood.style.left = "-1000px";
441         elmFood.style.top = "-1000px";
442         playingBoard.getBoardContainer().appendChild(elmFood);
443         
444         // ----- public methods -----
445         
446         /**
447         * @method getFoodElement
448         * @return {DOM Element} The div the represents the food.
449         */        
450         me.getFoodElement = function() {
451             return elmFood;  
452         };
453         
454         /**
455         * Randomly places the food onto an available location on the playing board.
456         * @method randomlyPlaceFood
457         */    
458         me.randomlyPlaceFood = function() {
459             // if there exist some food, clear its presence from the board
460             if (playingBoard.grid[fRow] && playingBoard.grid[fRow][fColumn] === playingBoard.getGridFoodValue()){
461                 playingBoard.grid[fRow][fColumn] = 0; 
462             }
463 
464             var row = 0, col = 0, numTries = 0;
465 
466             var maxRows = playingBoard.grid.length-1;
467             var maxCols = playingBoard.grid[0].length-1;
468             
469             while (playingBoard.grid[row][col] !== 0){
470                 row = getRandomPosition(1, maxRows);
471                 col = getRandomPosition(1, maxCols);
472 
473                 // in some cases there may not be any room to put food anywhere
474                 // instead of freezing, exit out
475                 numTries++;
476                 if (numTries > 20000){
477                     row = -1;
478                     col = -1;
479                     break; 
480                 } 
481             }
482 
483             playingBoard.grid[row][col] = playingBoard.getGridFoodValue();
484             fRow = row;
485             fColumn = col;
486             elmFood.style.top = row * playingBoard.getBlockHeight() + "px";
487             elmFood.style.left = col * playingBoard.getBlockWidth() + "px";
488         };
489     };
490 })();
491 
492 /**
493 * This class manages playing board for the game.
494 * @class Board
495 * @constructor
496 * @namespace SNAKE
497 * @param {Object} config The configuration object for the class. Set fullScreen equal to true if you want the game to take up the full screen, otherwise, set the top, left, width and height parameters.
498 */
499 
500 SNAKE.Board = SNAKE.Board || (function() {
501 
502     // -------------------------------------------------------------------------
503     // Private static variables and methods
504     // -------------------------------------------------------------------------
505 
506     var instanceNumber = 0;
507 
508     // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html
509     function getNextHighestZIndex(myObj) {
510         var highestIndex = 0,
511             currentIndex = 0,
512             ii;
513         for (ii in myObj) {
514             if (myObj[ii].elm.currentStyle){  
515                 currentIndex = parseFloat(myObj[ii].elm.style["z-index"],10);
516             }else if(window.getComputedStyle) {
517                 currentIndex = parseFloat(document.defaultView.getComputedStyle(myObj[ii].elm,null).getPropertyValue("z-index"),10);  
518             }
519             if(!isNaN(currentIndex) && currentIndex > highestIndex){
520                 highestIndex = currentIndex;
521             }
522         }
523         return(highestIndex+1);  
524     }
525 
526     /*
527         This function returns the width of the available screen real estate that we have
528     */
529     function getClientWidth(){
530         var myWidth = 0;
531         if( typeof window.innerWidth === "number" ) {
532             myWidth = window.innerWidth;//Non-IE
533         } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
534             myWidth = document.documentElement.clientWidth;//IE 6+ in 'standards compliant mode'
535         } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
536             myWidth = document.body.clientWidth;//IE 4 compatible
537         } 
538         return myWidth;
539     }
540     /*
541         This function returns the height of the available screen real estate that we have
542     */
543     function getClientHeight(){
544         var myHeight = 0;
545         if( typeof window.innerHeight === "number" ) {
546             myHeight = window.innerHeight;//Non-IE
547         } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
548             myHeight = document.documentElement.clientHeight;//IE 6+ in 'standards compliant mode'
549         } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
550             myHeight = document.body.clientHeight;//IE 4 compatible
551         } 
552         return myHeight;
553     }
554 
555     // -------------------------------------------------------------------------
556     // Contructor + public and private definitions
557     // -------------------------------------------------------------------------
558     
559     return function(inputConfig) {
560     
561         // --- private variables ---
562         var me = this,
563             myId = instanceNumber++,
564             config = inputConfig || {},
565             MAX_BOARD_COLS = 250,
566             MAX_BOARD_ROWS = 250,
567             blockWidth = 20,
568             blockHeight = 20,
569             GRID_FOOD_VALUE = -1, // the value of a spot on the board that represents snake food, MUST BE NEGATIVE
570             myFood,
571             mySnake,
572             boardState = 1, // 0: in active; 1: awaiting game start; 2: playing game
573             myKeyListener,
574             // Board components
575             elmContainer, elmPlayingField, elmAboutPanel, elmLengthPanel, elmWelcome, elmTryAgain;
576         
577         // --- public variables ---
578         me.grid = [];
579         
580         // ---------------------------------------------------------------------
581         // private functions
582         // ---------------------------------------------------------------------
583         
584         function createBoardElements() {
585             elmPlayingField = document.createElement("div");
586             elmPlayingField.setAttribute("id", "playingField");
587             elmPlayingField.className = "snake-playing-field";
588             
589             SNAKE.addEventListener(elmPlayingField, "click", function() {
590                 elmContainer.focus();
591             }, false);
592             
593             elmAboutPanel = document.createElement("div");
594             elmAboutPanel.className = "snake-panel-component";
595             elmAboutPanel.innerHTML = "";
596             
597             elmLengthPanel = document.createElement("div");
598             elmLengthPanel.className = "snake-panel-component";
599             elmLengthPanel.innerHTML = "";
600             
601             elmWelcome = createWelcomeElement();
602             elmTryAgain = createTryAgainElement();
603             
604             SNAKE.addEventListener( elmContainer, "keyup", function(evt) {
605                 if (!evt) var evt = window.event;
606                 evt.cancelBubble = true;
607                 if (evt.stopPropagation) {evt.stopPropagation();}
608                 if (evt.preventDefault) {evt.preventDefault();}
609                 return false;
610             }, false);
611             
612             elmContainer.className = "snake-game-container";
613             
614             elmContainer.appendChild(elmPlayingField);
615             elmContainer.appendChild(elmAboutPanel);
616             elmContainer.appendChild(elmLengthPanel);
617             elmContainer.appendChild(elmWelcome);
618             elmContainer.appendChild(elmTryAgain);
619             
620             mySnake = new SNAKE.Snake({playingBoard:me,startRow:2,startCol:2});
621             myFood = new SNAKE.Food({playingBoard: me});
622             
623             elmWelcome.style.zIndex = 1000;
624         }
625         function maxBoardWidth() {
626             return MAX_BOARD_COLS * me.getBlockWidth();   
627         }
628         function maxBoardHeight() {
629             return MAX_BOARD_ROWS * me.getBlockHeight();
630         }
631         
632         function createWelcomeElement() {
633             var tmpElm = document.createElement("div");
634             tmpElm.id = "sbWelcome" + myId;
635             tmpElm.className = "snake-welcome-dialog";
636             
637             var welcomeTxt = document.createElement("div");
638             var fullScreenText = "";
639             if (config.fullScreen) {
640                 fullScreenText = "2.请使用Firefox或者chrome运行";   
641             }
642             welcomeTxt.innerHTML = "1.按箭头开始游戏,祝君好运 :) " +"</br>"+ fullScreenText + "<p></p>";
643             var welcomeStart = document.createElement("button");
644             welcomeStart.appendChild( document.createTextNode("Play Game"));
645             
646             var loadGame = function() {
647                 SNAKE.removeEventListener(window, "keyup", kbShortcut, false);
648                 tmpElm.style.display = "none";
649                 me.setBoardState(1);
650                 me.getBoardContainer().focus();
651             };
652             
653             var kbShortcut = function(evt) {
654                 if (!evt) var evt = window.event;
655                 var keyNum = (evt.which) ? evt.which : evt.keyCode;
656                 if (keyNum === 32 || keyNum === 13) {
657                     loadGame();
658                 }
659             };
660             SNAKE.addEventListener(window, "keyup", kbShortcut, false);
661             SNAKE.addEventListener(welcomeStart, "click", loadGame, false);
662             
663             tmpElm.appendChild(welcomeTxt);
664             tmpElm.appendChild(welcomeStart);
665             return tmpElm;
666         }
667         
668         function createTryAgainElement() {
669             var tmpElm = document.createElement("div");
670             tmpElm.id = "sbTryAgain" + myId;
671             tmpElm.className = "snake-try-again-dialog";
672             
673             var tryAgainTxt = document.createElement("div");
674             tryAgainTxt.innerHTML = "啧啧,你死了! :(<p></p>";
675             var tryAgainStart = document.createElement("button");
676             tryAgainStart.appendChild( document.createTextNode("Play Again?"));
677             
678             var reloadGame = function() {
679                 tmpElm.style.display = "none";
680                 me.resetBoard();
681                 me.setBoardState(1);
682                 me.getBoardContainer().focus();
683             };
684             
685             var kbTryAgainShortcut = function(evt) {
686                 if (boardState !== 0 || tmpElm.style.display !== "block") {return;}
687                 if (!evt) var evt = window.event;
688                 var keyNum = (evt.which) ? evt.which : evt.keyCode;
689                 if (keyNum === 32 || keyNum === 13) {
690                     reloadGame();
691                 }
692             };
693             SNAKE.addEventListener(window, "keyup", kbTryAgainShortcut, true);
694             
695             SNAKE.addEventListener(tryAgainStart, "click", reloadGame, false);
696             tmpElm.appendChild(tryAgainTxt);
697             tmpElm.appendChild(tryAgainStart);
698             return tmpElm;
699         }
700         
701         // ---------------------------------------------------------------------
702         // public functions
703         // ---------------------------------------------------------------------
704         
705         /**
706         * Resets the playing board for a new game.
707         * @method resetBoard
708         */   
709         me.resetBoard = function() {
710             SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false);
711             mySnake.reset();
712             elmLengthPanel.innerHTML = "Length: 1";
713             me.setupPlayingField();
714         };
715         /**
716         * Gets the current state of the playing board. There are 3 states: 0 - Welcome or Try Again dialog is present. 1 - User has pressed "Start Game" on the Welcome or Try Again dialog but has not pressed an arrow key to move the snake. 2 - The game is in progress and the snake is moving.
717         * @method getBoardState
718         * @return {Number} The state of the board.
719         */  
720         me.getBoardState = function() {
721             return boardState;
722         };
723         /**
724         * Sets the current state of the playing board. There are 3 states: 0 - Welcome or Try Again dialog is present. 1 - User has pressed "Start Game" on the Welcome or Try Again dialog but has not pressed an arrow key to move the snake. 2 - The game is in progress and the snake is moving.
725         * @method setBoardState
726         * @param {Number} state The state of the board.
727         */  
728         me.setBoardState = function(state) {
729             boardState = state;
730         };
731         /**
732         * @method getGridFoodValue
733         * @return {Number} A number that represents food on a number representation of the playing board.
734         */  
735         me.getGridFoodValue = function() {
736             return GRID_FOOD_VALUE;
737         };
738         /**
739         * @method getPlayingFieldElement
740         * @return {DOM Element} The div representing the playing field (this is where the snake can move).
741         */ 
742         me.getPlayingFieldElement = function() {
743             return elmPlayingField;
744         };
745         /**
746         * @method setBoardContainer
747         * @param {DOM Element or String} myContainer Sets the container element for the game.
748         */ 
749         me.setBoardContainer = function(myContainer) {
750             if (typeof myContainer === "string") {
751                 myContainer = document.getElementById(myContainer);   
752             }
753             if (myContainer === elmContainer) {return;}
754             elmContainer = myContainer;
755             elmPlayingField = null;
756             
757             me.setupPlayingField();
758         };
759         /**
760         * @method getBoardContainer
761         * @return {DOM Element}
762         */ 
763         me.getBoardContainer = function() {
764             return elmContainer;
765         };
766         /**
767         * @method getBlockWidth
768         * @return {Number}
769         */ 
770         me.getBlockWidth = function() {
771             return blockWidth;  
772         };
773         /**
774         * @method getBlockHeight
775         * @return {Number}
776         */ 
777         me.getBlockHeight = function() {
778             return blockHeight;  
779         };
780         /**
781         * Sets up the playing field.
782         * @method setupPlayingField
783         */ 
784         me.setupPlayingField = function () {
785             
786             if (!elmPlayingField) {createBoardElements();} // create playing field
787             
788             // calculate width of our game container
789             var cWidth, cHeight;
790             if (config.fullScreen === true) {
791                 cTop = 0;
792                 cLeft = 0;
793                 cWidth = getClientWidth()-5;
794                 cHeight = getClientHeight()-5;
795                 document.body.style.backgroundColor = "#FC5454";
796             } else {
797                 cTop = config.top;
798                 cLeft = config.left;
799                 cWidth = config.width;
800                 cHeight = config.height;
801             }
802             
803             // define the dimensions of the board and playing field
804             var wEdgeSpace = me.getBlockWidth()*2 + (cWidth % me.getBlockWidth());
805             var fWidth = Math.min(maxBoardWidth()-wEdgeSpace,cWidth-wEdgeSpace);
806             var hEdgeSpace = me.getBlockHeight()*3 + (cHeight % me.getBlockHeight());
807             var fHeight = Math.min(maxBoardHeight()-hEdgeSpace,cHeight-hEdgeSpace);
808             
809             elmContainer.style.left = cLeft + "px";
810             elmContainer.style.top = cTop + "px";
811             elmContainer.style.width = cWidth + "px";
812             elmContainer.style.height = cHeight + "px";
813             elmPlayingField.style.left = me.getBlockWidth() + "px";
814             elmPlayingField.style.top  = me.getBlockHeight() + "px";
815             elmPlayingField.style.width = fWidth + "px";
816             elmPlayingField.style.height = fHeight + "px";
817             
818             // the math for this will need to change depending on font size, padding, etc
819             // assuming height of 14 (font size) + 8 (padding)
820             var bottomPanelHeight = hEdgeSpace - me.getBlockHeight();
821             var pLabelTop = me.getBlockHeight() + fHeight + Math.round((bottomPanelHeight - 30)/2) + "px";
822             
823             elmAboutPanel.style.top = pLabelTop;
824             elmAboutPanel.style.width = "450px";
825             elmAboutPanel.style.left = Math.round(cWidth/2) - Math.round(450/2) + "px";
826             
827             elmLengthPanel.style.top = pLabelTop;
828             elmLengthPanel.style.left = cWidth - 120 + "px";
829             
830             // if width is too narrow, hide the about panel
831             if (cWidth < 700) {
832                 elmAboutPanel.style.display = "none";
833             } else {
834                 elmAboutPanel.style.display = "block";
835             }
836             
837             me.grid = [];
838             var numBoardCols = fWidth / me.getBlockWidth() + 2;
839             var numBoardRows = fHeight / me.getBlockHeight() + 2;
840             
841             for (var row = 0; row < numBoardRows; row++) {
842                 me.grid[row] = [];
843                 for (var col = 0; col < numBoardCols; col++) {
844                     if (col === 0 || row === 0 || col === (numBoardCols-1) || row === (numBoardRows-1)) {
845                         me.grid[row][col] = 1; // an edge
846                     } else {
847                         me.grid[row][col] = 0; // empty space
848                     }
849                 }
850             }
851             
852             myFood.randomlyPlaceFood();
853             
854             // setup event listeners
855             
856             myKeyListener = function(evt) {
857                 if (!evt) var evt = window.event;
858                 var keyNum = (evt.which) ? evt.which : evt.keyCode;
859 
860                 if (me.getBoardState() === 1) {
861                     if ( !(keyNum >= 37 && keyNum <= 40) ) {return;} // if not an arrow key, leave
862                     
863                     // This removes the listener added at the #listenerX line
864                     SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false);
865                     
866                     myKeyListener = function(evt) {
867                         if (!evt) var evt = window.event;
868                         var keyNum = (evt.which) ? evt.which : evt.keyCode;
869                         
870                         mySnake.handleArrowKeys(keyNum);
871                         
872                         evt.cancelBubble = true;
873                         if (evt.stopPropagation) {evt.stopPropagation();}
874                         if (evt.preventDefault) {evt.preventDefault();}
875                         return false;
876                     };
877                     SNAKE.addEventListener( elmContainer, "keydown", myKeyListener, false);
878                     
879                     mySnake.rebirth();
880                     mySnake.handleArrowKeys(keyNum);
881                     me.setBoardState(2); // start the game!
882                     mySnake.go();
883                 }
884                 
885                 evt.cancelBubble = true;
886                 if (evt.stopPropagation) {evt.stopPropagation();}
887                 if (evt.preventDefault) {evt.preventDefault();}
888                 return false;
889             };
890             
891             // Search for #listenerX to see where this is removed
892             SNAKE.addEventListener( elmContainer, "keydown", myKeyListener, false);
893         };
894         
895         /**
896         * This method is called when the snake has eaten some food.
897         * @method foodEaten
898         */ 
899         me.foodEaten = function() {
900             elmLengthPanel.innerHTML = "Length: " + mySnake.snakeLength;
901             myFood.randomlyPlaceFood();
902         };
903         
904         /**
905         * This method is called when the snake dies.
906         * @method handleDeath
907         */ 
908         me.handleDeath = function() {
909             var index = Math.max(getNextHighestZIndex( mySnake.snakeBody), getNextHighestZIndex( {tmp:{elm:myFood.getFoodElement()}} ));
910             elmContainer.removeChild(elmTryAgain);
911             elmContainer.appendChild(elmTryAgain);
912             elmTryAgain.style.zIndex = index;
913             elmTryAgain.style.display = "block";
914             me.setBoardState(0);
915         };
916         
917         // ---------------------------------------------------------------------
918         // Initialize
919         // ---------------------------------------------------------------------
920 
921         config.fullScreen = (typeof config.fullScreen === "undefined") ? false : config.fullScreen;        
922         config.top = (typeof config.top === "undefined") ? 0 : config.top;
923         config.left = (typeof config.left === "undefined") ? 0 : config.left;
924         config.width = (typeof config.width === "undefined") ? 400 : config.width;        
925         config.height = (typeof config.height === "undefined") ? 400 : config.height;
926         
927         if (config.fullScreen) {
928             SNAKE.addEventListener(window,"resize", function() {
929                 me.setupPlayingField();
930             }, false);
931         }
932         
933         me.setBoardState(0);
934         
935         if (config.boardContainer) {
936             me.setBoardContainer(config.boardContainer);
937         }
938         
939     }; // end return function
940 
941 })();
View Code

其中有段加密js代码:

 直接将加密代码放入控制台执行:

PS:这里的flag是错误的!!!

在DOM树发现flag:

火狐浏览器在这里

 

PS:需要勾选这些(输入日志类里)

 

谷歌浏览器在这里:

 

奶奶问孙子:4+1等于几 孙子说:等于6-1。 奶奶说:你明明知道答案,为什么不说? 孙子说:年轻人不讲5的……..
原文地址:https://www.cnblogs.com/jasy/p/13791649.html