diff --git a/index.js b/index.js index fca892b..1f95e78 100644 --- a/index.js +++ b/index.js @@ -142,7 +142,6 @@ class Ora { } this._indent = indent; - this.updateLineCount(); } _updateInterval(interval) { @@ -216,7 +215,7 @@ class Ora { const columns = this.stream.columns || 80; const fullPrefixText = this.getFullPrefixText(this.prefixText, '-'); this.lineCount = 0; - for (const line of stripAnsi(' '.repeat(this.indent) + fullPrefixText + '--' + this[TEXT]).split('\n')) { + for (const line of stripAnsi(fullPrefixText + '--' + this[TEXT]).split('\n')) { this.lineCount += Math.max(1, Math.ceil(wcwidth(line) / columns)); } } @@ -265,22 +264,15 @@ class Ora { return this; } - this.stream.cursorTo(0); - for (let i = 0; i < this.linesToClear; i++) { if (i > 0) { this.stream.moveCursor(0, -1); } - this.stream.clearLine(1); - } - - if (this.indent || this.lastIndent !== this.indent) { + this.stream.clearLine(); this.stream.cursorTo(this.indent); } - this.lastIndent = this.indent; - this.linesToClear = 0; return this; diff --git a/package.json b/package.json index 323c489..aca2c2b 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,6 @@ "@types/node": "^14.14.35", "ava": "^2.4.0", "get-stream": "^6.0.0", - "transform-tty": "^1.0.11", "tsd": "^0.14.0", "xo": "^0.38.2" } diff --git a/test.js b/test.js index a2a87d9..e0b8f2a 100644 --- a/test.js +++ b/test.js @@ -3,8 +3,6 @@ import getStream from 'get-stream'; import test from 'ava'; import stripAnsi from 'strip-ansi'; import Ora from './index.js'; -import TransformTTY from 'transform-tty'; -import cliSpinners from 'cli-spinners'; const spinnerCharacter = process.platform === 'win32' ? '-' : 'โ ‹'; const noop = () => {}; @@ -367,27 +365,6 @@ test('indent option throws', t => { }, 'The `indent` option must be an integer from 0 and up'); }); -test('handles wrapped lines when length of indent + text is greater than columns', t => { - const stream = getPassThroughStream(); - stream.isTTY = true; - stream.columns = 20; - - const spinner = new Ora({ - stream, - text: 'foo', - color: false, - isEnabled: true - }); - - spinner.render(); - - spinner.text = '0'.repeat(spinner.stream.columns - 5); - spinner.indent = 15; - spinner.render(); - - t.is(spinner.lineCount, 2); -}); - test('.stopAndPersist() with prefixText', macro, spinner => { spinner.stopAndPersist({symbol: '@', text: 'foo'}); }, /bar @ foo\n$/, {prefixText: 'bar'}); @@ -407,548 +384,3 @@ test('.stopAndPersist() with manual empty prefixText', macro, spinner => { test('.stopAndPersist() with dynamic prefixText', macro, spinner => { spinner.stopAndPersist({symbol: '&', prefixText: () => 'babeee', text: 'yorkie'}); }, /babeee & yorkie\n$/, {prefixText: () => 'babeee'}); - -// New clear method tests - -const currentClearMethod = transFormTTY => { - const spinner = new Ora({ - text: 'foo', - color: false, - isEnabled: true, - stream: transFormTTY, - spinner: { - frames: ['-'] - } - }); - - let firstIndent = true; - - spinner.clear = function () { - if (!this.isEnabled || !this.stream.isTTY) { - return this; - } - - for (let i = 0; i < this.linesToClear; i++) { - if (i > 0) { - this.stream.moveCursor(0, -1); - } - - this.stream.clearLine(); - this.stream.cursorTo(this.indent); - } - - // It's too quick to be noticeable, but indent doesn't get applied - // for the first render if linesToClear = 0. New clear method - // doesn't have this issue, since it's called outside of the loop - if (this.linesToClear === 0 && firstIndent && this.indent) { - this.stream.cursorTo(this.indent); - firstIndent = false; - } - - this.linesToClear = 0; - - return this; - }.bind(spinner); - - return spinner; -}; - -test.serial('new clear method test, basic', t => { - const transformTTY = new TransformTTY({crlf: true}); - transformTTY.addSequencer(); - transformTTY.addSequencer(null, true); - /* - If the frames from this sequence differ from the previous sequence, - it means the spinner.clear method has failed to fully clear output between calls to render - */ - - const currentClearTTY = new TransformTTY({crlf: true}); - currentClearTTY.addSequencer(); - - const currentOra = currentClearMethod(currentClearTTY); - - const spinner = new Ora({ - text: 'foo', - color: false, - isEnabled: true, - stream: transformTTY, - spinner: { - frames: ['-'] - } - }); - - currentOra.render(); - spinner.render(); - - currentOra.text = 'bar'; - currentOra.indent = 5; - currentOra.render(); - - spinner.text = 'bar'; - spinner.indent = 5; - spinner.render(); - - currentOra.text = 'baz'; - currentOra.indent = 10; - currentOra.render(); - - spinner.text = 'baz'; - spinner.indent = 10; - spinner.render(); - - currentOra.succeed('boz?'); - - spinner.succeed('boz?'); - - const [sequenceString, clearedSequenceString] = transformTTY.getSequenceStrings(); - const [frames, clearedFrames] = transformTTY.getFrames(); - - t.is(sequenceString, ' โœ” boz?\n'); - t.is(sequenceString, clearedSequenceString); - - t.deepEqual(clearedFrames, ['- foo', ' - bar', ' - baz', ' โœ” boz?\n']); - t.deepEqual(frames, clearedFrames); - - const currentString = currentClearTTY.getSequenceStrings(); - - t.is(currentString, ' โœ” boz?\n'); - - const currentFrames = currentClearTTY.getFrames(); - - t.deepEqual(frames, currentFrames); - // Frames created using new clear method are deep equal to frames created using current clear method -}); - -test('new clear method test, erases wrapped lines', t => { - const transformTTY = new TransformTTY({crlf: true, columns: 40}); - transformTTY.addSequencer(); - transformTTY.addSequencer(null, true); - - const currentClearTTY = new TransformTTY({crlf: true, columns: 40}); - currentClearTTY.addSequencer(); - - const currentOra = currentClearMethod(currentClearTTY); - - const cursorAtRow = () => { - const cursor = transformTTY.getCursorPos(); - return cursor.y === 0 ? 0 : cursor.y * -1; - }; - - const clearedLines = () => { - return transformTTY.toString().split('\n').length; - }; - - const spinner = new Ora({ - text: 'foo', - color: false, - isEnabled: true, - stream: transformTTY, - spinner: { - frames: ['-'] - } - }); - - currentOra.render(); - - spinner.render(); - t.is(clearedLines(), 1); // Cleared 'foo' - t.is(cursorAtRow(), 0); - - currentOra.text = 'foo\n\nbar'; - currentOra.render(); - - spinner.text = 'foo\n\nbar'; - spinner.render(); - t.is(clearedLines(), 3); // Cleared 'foo\n\nbar' - t.is(cursorAtRow(), -2); - - currentOra.clear(); - currentOra.text = '0'.repeat(currentOra.stream.columns + 10); - currentOra.render(); - currentOra.render(); - - spinner.clear(); - spinner.text = '0'.repeat(spinner.stream.columns + 10); - spinner.render(); - spinner.render(); - t.is(clearedLines(), 2); - t.is(cursorAtRow(), -1); - - currentOra.clear(); - currentOra.text = '๐Ÿฆ„'.repeat(currentOra.stream.columns + 10); - currentOra.render(); - currentOra.render(); - - spinner.clear(); - spinner.text = '๐Ÿฆ„'.repeat(spinner.stream.columns + 10); - spinner.render(); - spinner.render(); - t.is(clearedLines(), 3); - t.is(cursorAtRow(), -2); - - currentOra.clear(); - currentOra.text = '๐Ÿฆ„'.repeat(currentOra.stream.columns - 2) + '\nfoo'; - currentOra.render(); - currentOra.render(); - - spinner.clear(); - spinner.text = '๐Ÿฆ„'.repeat(spinner.stream.columns - 2) + '\nfoo'; - spinner.render(); - spinner.render(); - t.is(clearedLines(), 3); - t.is(cursorAtRow(), -2); - - currentOra.clear(); - currentOra.prefixText = 'foo\n'; - currentOra.text = '\nbar'; - currentOra.render(); - currentOra.render(); - - spinner.clear(); - spinner.prefixText = 'foo\n'; - spinner.text = '\nbar'; - spinner.render(); - spinner.render(); - t.is(clearedLines(), 3); // Cleared 'foo\n\nbar' - t.is(cursorAtRow(), -2); - - const [sequenceString, clearedSequenceString] = transformTTY.getSequenceStrings(); - const [frames, clearedFrames] = transformTTY.getFrames(); - - t.is(sequenceString, 'foo\n - \nbar'); - t.is(sequenceString, clearedSequenceString); - - t.deepEqual(clearedFrames, [ - '- foo', - '- foo\n\nbar', - '- 00000000000000000000000000000000000000\n000000000000', - '- 00000000000000000000000000000000000000\n000000000000', - '- ๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„\n' + - '๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„\n' + - '๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„', - '- ๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„\n' + - '๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„\n' + - '๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„', - '- ๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„\n' + - '๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„\n' + - 'foo', - '- ๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„\n' + - '๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„๐Ÿฆ„\n' + - 'foo', - 'foo\n - \nbar', - 'foo\n - \nbar' - ]); - - t.deepEqual(frames, clearedFrames); - - const currentClearString = currentClearTTY.toString(); - t.is(currentClearString, 'foo\n - \nbar'); - - const currentFrames = currentClearTTY.getFrames(); - t.deepEqual(frames, currentFrames); -}); - -test('new clear method, stress test', t => { - const rando = (min, max) => { - min = Math.ceil(min); - max = Math.floor(max); - return Math.floor(Math.random() * ((max - min) + min)); - }; - - const rAnDoMaNiMaLs = (min, max) => { - const length = rando(min, max); - let result = ''; - const THEAMINALS = ['๐Ÿฏ', '๐Ÿฆ', '๐Ÿฎ', '๐Ÿท', '๐Ÿฝ', '๐Ÿธ', '๐Ÿ™', '๐Ÿต', '๐Ÿฆ', '๐Ÿง', '๐Ÿ”', '๐Ÿ’', '๐Ÿ™‰', '๐Ÿ™ˆ', '๐Ÿฃ', '๐Ÿฅ', '๐Ÿบ', '๐Ÿ—', '๐Ÿด', '๐Ÿฆ„', '๐Ÿ', '๐Ÿ›', ...Array.from({length: 5}).fill('\n')]; - - for (let i = 0; i < length; i++) { - result += THEAMINALS[Math.floor(Math.random() * THEAMINALS.length)]; - } - - return result; - }; - - const randos = () => { - return rAnDoMaNiMaLs(rando(5, 15), rando(25, 50)); - }; - - const randomize = (s1, s2) => { - const spnr = cliSpinners.random; - const txt = randos(); - const indent = rando(0, 15); - - s1.spinner = spnr; - s2.spinner = spnr; - s1.text = txt; - s2.text = txt; - s1.indent = indent; - s2.indent = indent; - }; - - const transformTTY = new TransformTTY({crlf: true}); - transformTTY.addSequencer(); - transformTTY.addSequencer(null, true); - - const currentClearTTY = new TransformTTY({crlf: true}); - currentClearTTY.addSequencer(); - - const currentOra = currentClearMethod(currentClearTTY); - - const spinner = new Ora({ - color: false, - isEnabled: true, - stream: transformTTY - }); - - randomize(spinner, currentOra); - - for (let x = 0; x < 100; x++) { - if (x % 10 === 0) { - randomize(spinner, currentOra); - } - - if (x % 5 === 0) { - const indent = rando(0, 25); - spinner.indent = indent; - currentOra.indent = indent; - } - - if (x % 15 === 0) { - let {text} = spinner; - const loops = rando(1, 10); - - for (let x = 0; x < loops; x++) { - const pos = Math.floor(Math.random() * text.length); - text = text.slice(0, pos) + '\n' + text.slice(pos + 1); - } - - spinner.text = text; - currentOra.text = text; - } - - spinner.render(); - currentOra.render(); - } - - spinner.succeed('๐Ÿ™‰'); - currentOra.succeed('๐Ÿ™‰'); - - const currentFrames = currentClearTTY.getFrames(); - const [frames, clearedFrames] = transformTTY.getFrames(); - - t.deepEqual(frames, clearedFrames); - - t.deepEqual(frames.slice(0, currentFrames.length), currentFrames); - - // Console.log(frames); - // console.log(clearFrames); -}); -/* -Example output: - -[ - ' โ– \n', - ' โ–Ž \n', - ' โ– \n', - ' โ–Œ \n', - ' โ–‹ \n', - ' โ–Š \n', - ' โ–‰ \n', - ' โ–Š \n', - ' โ–‹ \n', - ' โ–Œ \n', - ' d ', - ' q ', - ' p ', - ' b ', - ' d ', - ' q \n', - ' p \n', - ' b \n', - ' d \n', - ' q \n', - ' โ—ข ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฃ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ค ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฅ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ข ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฃ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ค ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฅ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ข ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฃ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ ‹ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ™ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ น \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ธ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ผ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ด \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ฆ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ง \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ‡ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ  \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ–ก ', - ' โ–  ', - ' โ–ก ', - ' โ–  ', - ' โ–ก ', - ' โ–  \n', - ' โ–ก \n', - ' โ–  \n', - ' โ–ก \n', - ' โ–  \n', - ' . ๐Ÿ—', - ' .. ๐Ÿ—', - ' ... ๐Ÿ—', - ' ๐Ÿ—', - ' . ๐Ÿ—', - ' .. ๐Ÿ—', - ' ... ๐Ÿ—', - ' ๐Ÿ—', - ' . ๐Ÿ—', - ' .. ๐Ÿ—', - ' โ–– ๐Ÿ”\n๐Ÿธ\n', - ' โ–˜ ๐Ÿ”\n๐Ÿธ\n', - ' โ– ๐Ÿ”\n๐Ÿธ\n', - ' โ–— ๐Ÿ”\n๐Ÿธ\n', - ' โ–– ๐Ÿ”\n๐Ÿธ\n', - ' โ–˜ ๐Ÿ”\n๐Ÿธ\n', - ' โ– ๐Ÿ”\n๐Ÿธ\n', - ' โ–— ๐Ÿ”\n๐Ÿธ\n', - ' โ–– ๐Ÿ”\n๐Ÿธ\n', - ' โ–˜ ๐Ÿ”\n๐Ÿธ\n', - ' ( โ— ) ๐Ÿ”๐Ÿ—', - ' ( โ— ) ๐Ÿ”๐Ÿ—', - ' ( โ— ) ๐Ÿ”๐Ÿ—', - ' ( โ— ) ๐Ÿ”๐Ÿ—', - ' ( โ—) ๐Ÿ”๐Ÿ—', - '( โ— ) ๏ฟฝ\n\n๏ฟฝ', - '( โ— ) ๏ฟฝ\n\n๏ฟฝ', - '( โ— ) ๏ฟฝ\n\n๏ฟฝ', - '( โ— ) ๏ฟฝ\n\n๏ฟฝ', - '(โ— ) ๏ฟฝ\n\n๏ฟฝ', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' _ ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' _ ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' _ ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' - ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' ` ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' ` ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - " ' ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n", - ' ยด ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' - ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' _ ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ... 1 more item -] -[ - ' โ– \n', - ' โ–Ž \n', - ' โ– \n', - ' โ–Œ \n', - ' โ–‹ \n', - ' โ–Š \n', - ' โ–‰ \n', - ' โ–Š \n', - ' โ–‹ \n', - ' โ–Œ \n', - ' d ', - ' q ', - ' p ', - ' b ', - ' d ', - ' q \n', - ' p \n', - ' b \n', - ' d \n', - ' q \n', - ' โ—ข ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฃ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ค ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฅ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ข ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฃ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ค ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฅ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ข ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ—ฃ ๐Ÿ—๐Ÿง๐Ÿฅ๐Ÿบ๐Ÿต\n\n', - ' โ ‹ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ™ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ น \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ธ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ผ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ด \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ฆ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ง \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ ‡ \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ  \n๏ฟฝ๐Ÿฎ๏ฟฝ\n\n๏ฟฝ\n', - ' โ–ก ', - ' โ–  ', - ' โ–ก ', - ' โ–  ', - ' โ–ก ', - ' โ–  \n', - ' โ–ก \n', - ' โ–  \n', - ' โ–ก \n', - ' โ–  \n', - ' . ๐Ÿ—', - ' .. ๐Ÿ—', - ' ... ๐Ÿ—', - ' ๐Ÿ—', - ' . ๐Ÿ—', - ' .. ๐Ÿ—', - ' ... ๐Ÿ—', - ' ๐Ÿ—', - ' . ๐Ÿ—', - ' .. ๐Ÿ—', - ' โ–– ๐Ÿ”\n๐Ÿธ\n', - ' โ–˜ ๐Ÿ”\n๐Ÿธ\n', - ' โ– ๐Ÿ”\n๐Ÿธ\n', - ' โ–— ๐Ÿ”\n๐Ÿธ\n', - ' โ–– ๐Ÿ”\n๐Ÿธ\n', - ' โ–˜ ๐Ÿ”\n๐Ÿธ\n', - ' โ– ๐Ÿ”\n๐Ÿธ\n', - ' โ–— ๐Ÿ”\n๐Ÿธ\n', - ' โ–– ๐Ÿ”\n๐Ÿธ\n', - ' โ–˜ ๐Ÿ”\n๐Ÿธ\n', - ' ( โ— ) ๐Ÿ”๐Ÿ—', - ' ( โ— ) ๐Ÿ”๐Ÿ—', - ' ( โ— ) ๐Ÿ”๐Ÿ—', - ' ( โ— ) ๐Ÿ”๐Ÿ—', - ' ( โ—) ๐Ÿ”๐Ÿ—', - '( โ— ) ๏ฟฝ\n\n๏ฟฝ', - '( โ— ) ๏ฟฝ\n\n๏ฟฝ', - '( โ— ) ๏ฟฝ\n\n๏ฟฝ', - '( โ— ) ๏ฟฝ\n\n๏ฟฝ', - '(โ— ) ๏ฟฝ\n\n๏ฟฝ', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง‡ ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' โง† ๐Ÿท๐Ÿ›๐Ÿ”๐Ÿฆ๐Ÿท๐Ÿ™‰', - ' _ ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' _ ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' _ ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' - ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' ` ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' ` ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - " ' ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n", - ' ยด ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' - ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ' _ ๐Ÿฝ๐Ÿฆ„๐Ÿฃ\n๐Ÿฃ๐Ÿง๐Ÿ”๐Ÿฆ๐Ÿฆ๏ฟฝ\n', - ... 1 more item -] -*/