use css class to draw minoes
This commit is contained in:
		| @ -82,7 +82,7 @@ table { | |||||||
| } | } | ||||||
|  |  | ||||||
| td { | td { | ||||||
|     border: 1px solid transparent; |     border: 1px outset transparent; | ||||||
| } | } | ||||||
|  |  | ||||||
| #hold { | #hold { | ||||||
| @ -106,6 +106,73 @@ td { | |||||||
|     height: 480px; |     height: 480px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .invisible-row { | ||||||
|  |     background-color: transparent; | ||||||
|  |     border-color: transparent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .visible-row { | ||||||
|  |     background-color: transparent; | ||||||
|  |     border-color: rgba(128, 128, 128, 0.5); | ||||||
|  |     border-style: inset; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tetromino-I { | ||||||
|  |     background-color: rgb(153, 255, 255); | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tetromino-J { | ||||||
|  |     background-color: rgb(153, 255, 255); | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tetromino-L { | ||||||
|  |     background-color: rgb(255, 204, 153); | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tetromino-O { | ||||||
|  |     background-color: rgb(255, 255, 153); | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tetromino-S { | ||||||
|  |     background-color: rgb(153, 255, 153); | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tetromino-T { | ||||||
|  |     background-color: rgb(204, 153, 255); | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tetromino-Z { | ||||||
|  |     background-color: rgb(255, 153, 153); | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .locked-mino { | ||||||
|  |     background-color: white; | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .cleared-line { | ||||||
|  |     background-color: white; | ||||||
|  |     border-color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .trail { | ||||||
|  |     background-color: rgba(255, 255, 255, 0.5); | ||||||
|  |     border-color: rgba(255, 255, 255, 0.5); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .ghost { | ||||||
|  |     background-color: rgba(255, 255, 255, 0.5); | ||||||
|  |     border-color: rgba(128, 128, 128, 0.5); | ||||||
|  |     border-style: inset; | ||||||
|  | } | ||||||
|  |  | ||||||
| #stats { | #stats { | ||||||
|     grid-column: 1; |     grid-column: 1; | ||||||
|     grid-row: 2; |     grid-row: 2; | ||||||
|  | |||||||
							
								
								
									
										149
									
								
								js/webtris.js
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								js/webtris.js
									
									
									
									
									
								
							| @ -27,21 +27,18 @@ const MATRIX_INVISIBLE_ROWS = 4 | |||||||
| const MATRIX_COLUMNS = 10 | const MATRIX_COLUMNS = 10 | ||||||
| const NEXT_ROWS =      24 | const NEXT_ROWS =      24 | ||||||
| const NEXT_COLUMNS =    6 | const NEXT_COLUMNS =    6 | ||||||
| const HOLD_BG_COLOR =       "" | const LOCKED_CLASS = "locked-mino" | ||||||
| const HOLD_BORDER_COLOR =   "" | const INVISIBLE_ROW_CLASS = "invisible-row" | ||||||
| const MATRIX_BG_COLOR =     "" | const VISIBLE_ROW_CLASS = "visible-row" | ||||||
| const MATRIX_BORDER_COLOR = "#333" | const CLEARED_LINE_CLASS = "cleared-line" | ||||||
| const MATRIX_INVISIBLE_BORDER_COLOR = "" | const TRAIL_CLASS = "trail" | ||||||
| const LINE_CLEARED_COLOR = "white" | const GHOST_CLASS = "ghost" | ||||||
| const NEXT_BG_COLOR =       "" |  | ||||||
| const NEXT_BORDER_COLOR =   "" |  | ||||||
| const MINO_BORDER_COLOR =   "white" |  | ||||||
| const HELD_PIECE_POSITION =    [2, 3] | const HELD_PIECE_POSITION =    [2, 3] | ||||||
| const FALLING_PIECE_POSITION = [4, 3] | const FALLING_PIECE_POSITION = [4, 3] | ||||||
| const NEXT_PIECES_POSITIONS =  Array.from({length: NEXT_PIECES}, (v, k) => [2, k*4+3]) | const NEXT_PIECES_POSITIONS =  Array.from({length: NEXT_PIECES}, (v, k) => [2, k*4+3]) | ||||||
| const LOCK_DELAY =       500 | const LOCK_DELAY =       500 | ||||||
| const FALL_PERIOD =     1000 | const FALL_PERIOD =     1000 | ||||||
| const AUTOREPEAT_DELAY = 300 | const AUTOREPEAT_DELAY = 200 | ||||||
| const AUTOREPEAT_PERIOD = 10 | const AUTOREPEAT_PERIOD = 10 | ||||||
| const ANIMATION_DELAY =  100 | const ANIMATION_DELAY =  100 | ||||||
| const TEMP_TEXTS_DELAY = 700 | const TEMP_TEXTS_DELAY = 700 | ||||||
| @ -131,7 +128,6 @@ class Tetromino { | |||||||
|         this.rotationPoint5Used = false |         this.rotationPoint5Used = false | ||||||
|         this.holdEnabled = true |         this.holdEnabled = true | ||||||
|         this.locked = false |         this.locked = false | ||||||
|         this.borderColor = MINO_BORDER_COLOR |  | ||||||
|         this.srs = {}  // Super Rotation System |         this.srs = {}  // Super Rotation System | ||||||
|         this.srs[SPIN.CW] = [ |         this.srs[SPIN.CW] = [ | ||||||
|             [[0, 0], [-1, 0], [-1, -1], [0,  2], [-1,  2]], |             [[0, 0], [-1, 0], [-1, -1], [0,  2], [-1,  2]], | ||||||
| @ -149,14 +145,11 @@ class Tetromino { | |||||||
|             this.shape = shape |             this.shape = shape | ||||||
|         else { |         else { | ||||||
|             if (!randomBag.length) |             if (!randomBag.length) | ||||||
|                 randomBag = ['I', 'J', 'L', 'O', 'S', 'T', 'Z'] |                 randomBag = ['tetromino-I', 'tetromino-J', 'tetromino-L', 'tetromino-O', 'tetromino-S', 'tetromino-T', 'tetromino-Z'] | ||||||
|             this.shape = randomBag.pick() |             this.shape = randomBag.pick() | ||||||
|         } |         } | ||||||
|         switch(this.shape) { |         switch(this.shape) { | ||||||
|             case 'I': |             case 'tetromino-I': | ||||||
|                 this.color = "rgb(153, 179, 255)" |  | ||||||
|                 this.lightColor = "rgb(234, 250, 250)" |  | ||||||
|                 this.transparentColor = "rgba(234, 250, 250, 0.5)" |  | ||||||
|                 this.minoesPos = [[-1, 0], [0, 0], [1, 0], [2, 0]] |                 this.minoesPos = [[-1, 0], [0, 0], [1, 0], [2, 0]] | ||||||
|                 this.srs[SPIN.CW] = [ |                 this.srs[SPIN.CW] = [ | ||||||
|                     [[ 1,  0], [-1,  0], [ 2,  0], [-1,  1], [ 2, -2]], |                     [[ 1,  0], [-1,  0], [ 2,  0], [-1,  1], [ 2, -2]], | ||||||
| @ -171,42 +164,24 @@ class Tetromino { | |||||||
|                     [[ 1,  0], [-1,  0], [ 2,  0], [-1,  1], [ 2, -2]], |                     [[ 1,  0], [-1,  0], [ 2,  0], [-1,  1], [ 2, -2]], | ||||||
|                 ] |                 ] | ||||||
|             break |             break | ||||||
|             case 'J': |             case 'tetromino-J': | ||||||
|                 this.color = "rgb(153, 255, 255)" |  | ||||||
|                 this.lightColor = "rgb(230, 240, 255)" |  | ||||||
|                 this.transparentColor = "rgba(230, 240, 255, 0.5)" |  | ||||||
|                 this.minoesPos = [[-1, -1], [-1, 0], [0, 0], [1, 0]] |                 this.minoesPos = [[-1, -1], [-1, 0], [0, 0], [1, 0]] | ||||||
|             break |             break | ||||||
|             case 'L': |             case 'tetromino-L': | ||||||
|                 this.color = "rgb(255, 204, 153)" |  | ||||||
|                 this.lightColor = "rgb(255, 224, 204)" |  | ||||||
|                 this.transparentColor = "rgba(255, 224, 204, 0.5)" |  | ||||||
|                 this.minoesPos = [[-1, 0], [0, 0], [1, 0], [1, -1]] |                 this.minoesPos = [[-1, 0], [0, 0], [1, 0], [1, -1]] | ||||||
|             break |             break | ||||||
|             case 'O': |             case 'tetromino-O': | ||||||
|                 this.color = "	rgb(255, 255, 153)" |  | ||||||
|                 this.lightColor = "rgb(255, 255, 230)" |  | ||||||
|                 this.transparentColor = "rgba(255, 255, 230, 0.5)" |  | ||||||
|                 this.minoesPos = [[0, 0], [1, 0], [0, -1], [1, -1]] |                 this.minoesPos = [[0, 0], [1, 0], [0, -1], [1, -1]] | ||||||
|                 this.srs[SPIN.CW] = [[]] |                 this.srs[SPIN.CW] = [[]] | ||||||
|                 this.srs[SPIN.CCW] = [[]] |                 this.srs[SPIN.CCW] = [[]] | ||||||
|             break |             break | ||||||
|             case 'S': |             case 'tetromino-S': | ||||||
|                 this.color = "rgb(153, 255, 153)" |  | ||||||
|                 this.lightColor = "rgb(236, 255, 230)" |  | ||||||
|                 this.transparentColor = "rgba(236, 255, 230, 0.5)" |  | ||||||
|                 this.minoesPos = [[-1, 0], [0, 0], [0, -1], [1, -1]] |                 this.minoesPos = [[-1, 0], [0, 0], [0, -1], [1, -1]] | ||||||
|             break |             break | ||||||
|             case 'T': |             case 'tetromino-T': | ||||||
|                 this.color = "rgb(204, 153, 255)" |  | ||||||
|                 this.lightColor= "rgb(242, 230, 255)" |  | ||||||
|                 this.transparentColor = "rgba(242, 230, 255, 0.5)" |  | ||||||
|                 this.minoesPos = [[-1, 0], [0, 0], [1, 0], [0, -1]] |                 this.minoesPos = [[-1, 0], [0, 0], [1, 0], [0, -1]] | ||||||
|             break |             break | ||||||
|             case 'Z': |             case 'tetromino-Z': | ||||||
|                 this.color = "rgb(255, 153, 153)" |  | ||||||
|                 this.lightColor = "rgb(255, 230, 230)" |  | ||||||
|                 this.transparentColor = "rgba(255, 230, 230, 0.5)" |  | ||||||
|                 this.minoesPos = [[-1, -1], [0, -1], [0, 0], [1, 0]] |                 this.minoesPos = [[-1, -1], [0, -1], [0, 0], [1, 0]] | ||||||
|             break |             break | ||||||
|         } |         } | ||||||
| @ -218,33 +193,18 @@ class Tetromino { | |||||||
|  |  | ||||||
|     get ghost() { |     get ghost() { | ||||||
|         var ghost = new Tetromino(Array.from(this.pos), this.shape) |         var ghost = new Tetromino(Array.from(this.pos), this.shape) | ||||||
|         ghost.color = this.transparentColor |  | ||||||
|         ghost.borderColor = this.transparentColor |  | ||||||
|         ghost.minoesPos = Array.from(this.minoesPos) |         ghost.minoesPos = Array.from(this.minoesPos) | ||||||
|  |         ghost.shape = GHOST_CLASS | ||||||
|         return ghost |         return ghost | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     drawIn(table) { |  | ||||||
|         var bgColor = this.locked ? this.lightColor : this.color |  | ||||||
|         this.minoesAbsPos.forEach( pos => { |  | ||||||
|             drawMino(table.rows[pos[1]].cells[pos[0]], bgColor, this.borderColor)}) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| function drawMino(cell, backgroundColor, borderColor) { |  | ||||||
|     cell.style.backgroundColor = backgroundColor |  | ||||||
|     cell.style.borderColor = borderColor |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| class MinoesTable { | class MinoesTable { | ||||||
|     constructor(id, rows, columns, defaultBgColor, defaultBorderColor) { |     constructor(id, rows, columns) { | ||||||
|         this.table = document.getElementById(id) |         this.table = document.getElementById(id) | ||||||
|         this.rows = rows |         this.rows = rows | ||||||
|         this.columns = columns |         this.columns = columns | ||||||
|         this.defaultBgColor = defaultBgColor |  | ||||||
|         this.defaultBorderColor = defaultBorderColor |  | ||||||
|         this.piece = null |         this.piece = null | ||||||
|         for (var y=0; y < rows; y++) { |         for (var y=0; y < rows; y++) { | ||||||
|             var row = this.table.insertRow() |             var row = this.table.insertRow() | ||||||
| @ -254,11 +214,19 @@ class MinoesTable { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     drawMino(x, y, className) { | ||||||
|  |         this.table.rows[y].cells[x].className = className | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     drawPiece(piece, className=null) { | ||||||
|  |         if (!className) className = piece.className | ||||||
|  |         piece.minoesAbsPos.forEach(pos => this.table.rows[pos[1]].cells[pos[0]].className = piece.shape) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     clearTable() { |     clearTable() { | ||||||
|         for(var y=0; y < this.rows; y++) { |         for(var y=0; y < this.rows; y++) { | ||||||
|             for (var x=0; x < this.columns; x++) { |             for (var x=0; x < this.columns; x++) { | ||||||
|                 var cell = this.table.rows[y].cells[x] |                 this.drawMino(x, y, INVISIBLE_ROW_CLASS) | ||||||
|                 drawMino(cell, this.defaultBgColor, this.defaultBorderColor) |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -266,20 +234,20 @@ class MinoesTable { | |||||||
|  |  | ||||||
| class HoldQueue extends MinoesTable { | class HoldQueue extends MinoesTable { | ||||||
|     constructor() { |     constructor() { | ||||||
|         super("hold", HOLD_ROWS, HOLD_COLUMNS, HOLD_BG_COLOR, HOLD_BORDER_COLOR) |         super("hold", HOLD_ROWS, HOLD_COLUMNS) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     draw() { |     draw() { | ||||||
|         this.clearTable() |         this.clearTable() | ||||||
|         if (this.piece && state != STATE.PAUSED) |         if (this.piece && state != STATE.PAUSED) | ||||||
|             this.piece.drawIn(this.table) |             this.drawPiece(this.piece) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| class Matrix extends MinoesTable { | class Matrix extends MinoesTable { | ||||||
|     constructor() { |     constructor() { | ||||||
|         super("matrix", MATRIX_ROWS, MATRIX_COLUMNS, MATRIX_BG_COLOR, MATRIX_BORDER_COLOR) |         super("matrix", MATRIX_ROWS, MATRIX_COLUMNS) | ||||||
|         this.lockedMinoes = Array.from(Array(MATRIX_ROWS+3), row => Array(MATRIX_COLUMNS)) |         this.lockedMinoes = Array.from(Array(MATRIX_ROWS+3), row => Array(MATRIX_COLUMNS)) | ||||||
|         this.piece = null |         this.piece = null | ||||||
|         this.linesCleared = [] |         this.linesCleared = [] | ||||||
| @ -303,48 +271,49 @@ class Matrix extends MinoesTable { | |||||||
|     } |     } | ||||||
|      |      | ||||||
|     draw() { |     draw() { | ||||||
|  |         // grid | ||||||
|         if (state == STATE.PAUSED) { |         if (state == STATE.PAUSED) { | ||||||
|             this.clearTable() |             for (var y=0; y < this.rows; y++) { | ||||||
|         } else { |                 for (var x=0; x < this.columns; x++) { | ||||||
|             // locked minoes |                     if (this.linesCleared.includes(y)) var className = CLEARED_LINE_CLASS | ||||||
|             for(var y=0; y < this.rows; y++) { |                     else { | ||||||
|                 if (this.linesCleared.includes(y)) { |                         if (y < MATRIX_INVISIBLE_ROWS) var className = INVISIBLE_ROW_CLASS | ||||||
|                     for (var x=0; x < this.columns; x++) { |                         else var className = VISIBLE_ROW_CLASS | ||||||
|                         var cell = this.table.rows[y].cells[x] |  | ||||||
|                         drawMino(cell, LINE_CLEARED_COLOR, LINE_CLEARED_COLOR) |  | ||||||
|                     } |                     } | ||||||
|                 } else { |                     this.drawMino(x, y, className) | ||||||
|                     for (var x=0; x < this.columns; x++) { |                 } | ||||||
|                         var cell = this.table.rows[y].cells[x] |             } | ||||||
|                         var bgColor = this.lockedMinoes[y][x] |         } else { | ||||||
|                         if (bgColor) drawMino(cell, bgColor, MINO_BORDER_COLOR) |             for (var y=0; y < this.rows; y++) { | ||||||
|  |                 for (var x=0; x < this.columns; x++) { | ||||||
|  |                     var className = this.lockedMinoes[y][x] | ||||||
|  |                     if (!className) { | ||||||
|  |                         if (this.linesCleared.includes(y)) className = CLEARED_LINE_CLASS | ||||||
|                         else { |                         else { | ||||||
|                             if (y < MATRIX_INVISIBLE_ROWS) drawMino(cell, this.defaultBgColor, MATRIX_INVISIBLE_BORDER_COLOR) |                             if (y < MATRIX_INVISIBLE_ROWS) className = INVISIBLE_ROW_CLASS | ||||||
|                             else drawMino(cell, this.defaultBgColor, MATRIX_BORDER_COLOR) |                             else className = VISIBLE_ROW_CLASS | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                     this.drawMino(x, y, className) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // trail |             // trail | ||||||
|             if (this.trail.height) { |             if (this.trail.height) { | ||||||
|                 this.trail.minoesPos.forEach(pos => { |                 this.trail.minoesPos.forEach(pos => { | ||||||
|                     for (var dy=0; dy < this.trail.height; dy++) { |                     for (var dy=0; dy < this.trail.height; dy++) this.drawMino(pos[0], pos[1]+dy, TRAIL_CLASS) | ||||||
|                         var cell = this.table.rows[pos[1]+dy].cells[pos[0]] |  | ||||||
|                         drawMino(cell, this.piece.transparentColor, this.piece.transparentColor) |  | ||||||
|                     } |  | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|              |              | ||||||
|             //ghost |             //ghost | ||||||
|             if (!this.piece.locked) { |             if (!this.piece.locked) { | ||||||
|                 var ghost = this.piece.ghost |                 for (var ghost = this.piece.ghost; this.spaceToMove(ghost.minoesAbsPos); ghost.pos[1]++) {} | ||||||
|                 for (; this.spaceToMove(ghost.minoesAbsPos); ghost.pos[1]++) {} |  | ||||||
|                 ghost.pos[1]-- |                 ghost.pos[1]-- | ||||||
|                 ghost.drawIn(this.table) |                 this.drawPiece(ghost) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             this.piece.drawIn(this.table) |             var className = this.piece.locked ? LOCKED_CLASS : this.piece.className | ||||||
|  |             this.drawPiece(this.piece, this.piece.locked ? LOCKED_CLASS : this.piece.className) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // text |         // text | ||||||
| @ -381,14 +350,14 @@ class Matrix extends MinoesTable { | |||||||
|  |  | ||||||
| class NextQueue extends MinoesTable { | class NextQueue extends MinoesTable { | ||||||
|     constructor() { |     constructor() { | ||||||
|         super("next", NEXT_ROWS, NEXT_COLUMNS, NEXT_BG_COLOR, NEXT_BORDER_COLOR) |         super("next", NEXT_ROWS, NEXT_COLUMNS) | ||||||
|         this.pieces = Array.from({length: NEXT_PIECES}, (v, k) => new Tetromino(NEXT_PIECES_POSITIONS[k])) |         this.pieces = Array.from({length: NEXT_PIECES}, (v, k) => new Tetromino(NEXT_PIECES_POSITIONS[k])) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     draw() { |     draw() { | ||||||
|         this.clearTable() |         this.clearTable() | ||||||
|         if (state != STATE.PAUSED) { |         if (state != STATE.PAUSED) { | ||||||
|             this.pieces.forEach(piece => piece.drawIn(this.table)) |             this.pieces.forEach(piece => this.drawPiece(piece)) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -554,11 +523,11 @@ function lockDown(){ | |||||||
|     if (matrix.piece.minoesAbsPos.every(pos => pos.y < MATRIX_INVISIBLE_ROWS)) |     if (matrix.piece.minoesAbsPos.every(pos => pos.y < MATRIX_INVISIBLE_ROWS)) | ||||||
|         game_over() |         game_over() | ||||||
|     else { |     else { | ||||||
|         matrix.piece.minoesAbsPos.forEach(pos => matrix.lockedMinoes[pos[1]][pos[0]] = matrix.piece.color) |         matrix.piece.minoesAbsPos.forEach(pos => matrix.lockedMinoes[pos[1]][pos[0]] = matrix.piece.className) | ||||||
|  |  | ||||||
|         // T-Spin detection |         // T-Spin detection | ||||||
|         var tSpin = T_SPIN.NONE |         var tSpin = T_SPIN.NONE | ||||||
|         if (matrix.piece.rotatedLast && matrix.piece.shape == "T") { |         if (matrix.piece.rotatedLast && matrix.piece.shape == "tetromino-T") { | ||||||
|             const tSlots = T_SLOT_POS.translate(matrix.piece.pos).map(pos => matrix.cellIsOccupied(...pos)), |             const tSlots = T_SLOT_POS.translate(matrix.piece.pos).map(pos => matrix.cellIsOccupied(...pos)), | ||||||
|                   a = tSlots[(matrix.piece.orientation+T_SLOT.A)%4], |                   a = tSlots[(matrix.piece.orientation+T_SLOT.A)%4], | ||||||
|                   b = tSlots[(matrix.piece.orientation+T_SLOT.B)%4], |                   b = tSlots[(matrix.piece.orientation+T_SLOT.B)%4], | ||||||
| @ -784,5 +753,5 @@ window.onload = function() { | |||||||
|     state = STATE.PLAYING |     state = STATE.PLAYING | ||||||
|     scheduler = new Scheduler() |     scheduler = new Scheduler() | ||||||
|     scheduler.setInterval(clock, 1000) |     scheduler.setInterval(clock, 1000) | ||||||
|     this.newLevel(1) |     newLevel(1) | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user