t1nder-cli-simulator 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +268 -190
- package/package.json +4 -2
package/index.js
CHANGED
|
@@ -4,288 +4,366 @@ import clipboardy from 'clipboardy'
|
|
|
4
4
|
import axios from 'axios'
|
|
5
5
|
import chalk from 'chalk'
|
|
6
6
|
import ora from 'ora'
|
|
7
|
-
import figlet from 'figlet'
|
|
8
|
-
import gradient from 'gradient-string'
|
|
9
7
|
import inquirer from 'inquirer'
|
|
10
8
|
import { Server } from 'socket.io'
|
|
11
9
|
import { createServer } from 'http'
|
|
12
10
|
import open from 'open'
|
|
13
|
-
|
|
11
|
+
import fs from 'fs'
|
|
12
|
+
import path from 'path'
|
|
13
|
+
import os from 'os'
|
|
14
|
+
import { HttpsProxyAgent } from 'https-proxy-agent'
|
|
15
|
+
import randomUseragent from 'random-useragent'
|
|
16
|
+
|
|
17
|
+
const APP_NAME = 'T1NDER'
|
|
18
|
+
const APP_VERSION = '2.1.0-PERSIST'
|
|
14
19
|
const SECRET_PASS = 'admin123'
|
|
15
20
|
const CHECK_INTERVAL = 800
|
|
16
21
|
const PORT = 3456
|
|
17
22
|
const CLIENT_URL = `https://t1nder.vercel.app/`
|
|
23
|
+
const CONFIG_FILE = path.join(os.homedir(), '.t1nder_conf.json')
|
|
24
|
+
const PROXY_URL = ''
|
|
18
25
|
|
|
19
26
|
const SERVER_LIST = [
|
|
20
27
|
{
|
|
21
|
-
name: '
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
image: 'https://t1nder.vercel.app/api/image',
|
|
25
|
-
},
|
|
28
|
+
name: 'HAN-01 (Ha Noi)',
|
|
29
|
+
ai: 'https://t1nder.vercel.app/api/ai',
|
|
30
|
+
upload: 'https://t1nder.vercel.app/api/upload',
|
|
26
31
|
},
|
|
27
32
|
{
|
|
28
|
-
name: '
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
image: 'https://t1nder-vip.vercel.app/api/image',
|
|
32
|
-
},
|
|
33
|
+
name: 'TH-02 (Thanh Hoa)',
|
|
34
|
+
ai: 'https://t1nder-vip.vercel.app/api/ai',
|
|
35
|
+
upload: 'https://t1nder-vip.vercel.app/api/upload',
|
|
33
36
|
},
|
|
34
37
|
{
|
|
35
|
-
name: '
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
image: 'https://tinder-server-2.vercel.app/api/image',
|
|
39
|
-
},
|
|
38
|
+
name: 'TB-03 (Thai Binh)',
|
|
39
|
+
ai: 'https://tinder-server-2.vercel.app/api/ai',
|
|
40
|
+
upload: 'https://tinder-server-2.vercel.app/api/upload',
|
|
40
41
|
},
|
|
41
42
|
{
|
|
42
|
-
name: '
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
image: 'https://tinder-server-3.vercel.app/api/image',
|
|
46
|
-
},
|
|
43
|
+
name: 'PT-04 (Phu Tho)',
|
|
44
|
+
ai: 'https://tinder-server-3.vercel.app/api/ai',
|
|
45
|
+
upload: 'https://tinder-server-3.vercel.app/api/upload',
|
|
47
46
|
},
|
|
48
47
|
]
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
const state = {
|
|
50
|
+
apiKey: '',
|
|
51
|
+
endpoint: '',
|
|
52
|
+
serverName: '',
|
|
53
|
+
uploadEndpoint: '',
|
|
54
|
+
serverIndex: 0,
|
|
55
|
+
isProcessing: false,
|
|
56
|
+
stats: {
|
|
57
|
+
queries: 0,
|
|
58
|
+
success: 0,
|
|
59
|
+
errors: 0,
|
|
60
|
+
},
|
|
61
|
+
}
|
|
53
62
|
|
|
54
63
|
const httpServer = createServer()
|
|
55
64
|
const io = new Server(httpServer, {
|
|
56
|
-
cors: {
|
|
57
|
-
origin: '*',
|
|
58
|
-
methods: ['GET', 'POST'],
|
|
59
|
-
},
|
|
65
|
+
cors: { origin: '*', methods: ['GET', 'POST'] },
|
|
60
66
|
})
|
|
67
|
+
io.on('connection', () => {})
|
|
68
|
+
|
|
69
|
+
const timestamp = () => {
|
|
70
|
+
const now = new Date()
|
|
71
|
+
return now.toLocaleTimeString('en-US', { hour12: false })
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const log = {
|
|
75
|
+
info: (msg) =>
|
|
76
|
+
console.log(
|
|
77
|
+
chalk.gray(`[${timestamp()}]`) + chalk.cyan(' [INFO] ') + msg
|
|
78
|
+
),
|
|
79
|
+
success: (msg) =>
|
|
80
|
+
console.log(
|
|
81
|
+
chalk.gray(`[${timestamp()}]`) + chalk.green(' [SUCCESS] ') + msg
|
|
82
|
+
),
|
|
83
|
+
warn: (msg) =>
|
|
84
|
+
console.log(
|
|
85
|
+
chalk.gray(`[${timestamp()}]`) + chalk.yellow(' [WARN] ') + msg
|
|
86
|
+
),
|
|
87
|
+
error: (msg) =>
|
|
88
|
+
console.log(
|
|
89
|
+
chalk.gray(`[${timestamp()}]`) + chalk.red(' [ERROR] ') + msg
|
|
90
|
+
),
|
|
91
|
+
system: (msg) =>
|
|
92
|
+
console.log(
|
|
93
|
+
chalk.gray(`[${timestamp()}]`) + chalk.magenta(' [SYSTEM] ') + msg
|
|
94
|
+
),
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const drawBox = (title, lines, color = 'cyan') => {
|
|
98
|
+
const width = 60
|
|
99
|
+
const c = chalk[color]
|
|
100
|
+
console.log(
|
|
101
|
+
c(`┌─ ${chalk.bold(title)} ${'─'.repeat(width - title.length - 4)}┐`)
|
|
102
|
+
)
|
|
103
|
+
lines.forEach((line) => {
|
|
104
|
+
const visibleLength = line.replace(/\u001b\[\d+m/g, '').length
|
|
105
|
+
const padding = width - visibleLength - 1
|
|
106
|
+
console.log(c('│ ') + line + ' '.repeat(padding > 0 ? padding : 0) + c('│'))
|
|
107
|
+
})
|
|
108
|
+
console.log(c(`└${'─'.repeat(width - 1)}┘`))
|
|
109
|
+
}
|
|
61
110
|
|
|
62
|
-
|
|
111
|
+
const mapAnswerToNumber = (char) => {
|
|
112
|
+
const map = { a: '1', b: '2', c: '3', d: '4', e: '5', f: '6' }
|
|
113
|
+
return map[char?.toLowerCase()] || '?'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const ConfigManager = {
|
|
117
|
+
save: (key, idx) => {
|
|
118
|
+
try {
|
|
119
|
+
const data = JSON.stringify({
|
|
120
|
+
key,
|
|
121
|
+
serverIndex: idx,
|
|
122
|
+
lastRun: new Date(),
|
|
123
|
+
})
|
|
124
|
+
fs.writeFileSync(CONFIG_FILE, data)
|
|
125
|
+
log.system('Session configuration saved to disk.')
|
|
126
|
+
} catch (e) {
|
|
127
|
+
log.warn('Failed to save session.')
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
load: () => {
|
|
131
|
+
try {
|
|
132
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
133
|
+
const raw = fs.readFileSync(CONFIG_FILE)
|
|
134
|
+
return JSON.parse(raw)
|
|
135
|
+
}
|
|
136
|
+
} catch (e) {
|
|
137
|
+
return null
|
|
138
|
+
}
|
|
139
|
+
return null
|
|
140
|
+
},
|
|
141
|
+
clear: () => {
|
|
142
|
+
try {
|
|
143
|
+
if (fs.existsSync(CONFIG_FILE)) fs.unlinkSync(CONFIG_FILE)
|
|
144
|
+
log.system('Previous session cleared.')
|
|
145
|
+
} catch (e) {}
|
|
146
|
+
},
|
|
147
|
+
}
|
|
63
148
|
|
|
64
|
-
const
|
|
149
|
+
const initSystem = async () => {
|
|
65
150
|
console.clear()
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
151
|
+
console.log('\n')
|
|
152
|
+
drawBox(
|
|
153
|
+
APP_NAME,
|
|
154
|
+
[
|
|
155
|
+
`Version: ${APP_VERSION}`,
|
|
156
|
+
`System: T1nder ${APP_VERSION}`,
|
|
157
|
+
`Mode: ${chalk.green('SECURE & PERSISTENT')}`,
|
|
158
|
+
],
|
|
159
|
+
'blue'
|
|
160
|
+
)
|
|
161
|
+
console.log('')
|
|
70
162
|
}
|
|
71
163
|
|
|
72
|
-
const
|
|
73
|
-
const
|
|
164
|
+
const authenticateAndConfigure = async () => {
|
|
165
|
+
const savedConfig = ConfigManager.load()
|
|
166
|
+
|
|
167
|
+
if (savedConfig) {
|
|
168
|
+
console.log(chalk.gray('─'.repeat(60)))
|
|
169
|
+
const { useSaved } = await inquirer.prompt([
|
|
170
|
+
{
|
|
171
|
+
type: 'confirm',
|
|
172
|
+
name: 'useSaved',
|
|
173
|
+
message: chalk.cyan(
|
|
174
|
+
`? SESSION FOUND :: Resume session for key ending in ...${savedConfig.key.slice(
|
|
175
|
+
-4
|
|
176
|
+
)}?`
|
|
177
|
+
),
|
|
178
|
+
default: true,
|
|
179
|
+
},
|
|
180
|
+
])
|
|
181
|
+
|
|
182
|
+
if (useSaved) {
|
|
183
|
+
state.apiKey = savedConfig.key
|
|
184
|
+
state.serverIndex = savedConfig.serverIndex
|
|
185
|
+
|
|
186
|
+
const server = SERVER_LIST[state.serverIndex] || SERVER_LIST[0]
|
|
187
|
+
state.serverName = server.name
|
|
188
|
+
state.endpoint = server.ai.trim()
|
|
189
|
+
|
|
190
|
+
log.success('Session restored successfully.')
|
|
191
|
+
return
|
|
192
|
+
} else {
|
|
193
|
+
ConfigManager.clear()
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const { inputPass } = await inquirer.prompt([
|
|
74
198
|
{
|
|
75
199
|
type: 'password',
|
|
76
200
|
name: 'inputPass',
|
|
77
|
-
message: '
|
|
78
|
-
mask: '
|
|
201
|
+
message: chalk.cyan('? ACCESS CONTROL :: Enter Passphrase:'),
|
|
202
|
+
mask: '•',
|
|
79
203
|
},
|
|
80
204
|
])
|
|
81
205
|
|
|
82
|
-
if (
|
|
83
|
-
|
|
206
|
+
if (inputPass !== SECRET_PASS) {
|
|
207
|
+
log.error('Authentication Failed. Terminating process.')
|
|
84
208
|
process.exit(1)
|
|
85
209
|
}
|
|
86
|
-
|
|
87
|
-
}
|
|
210
|
+
log.success('Identity Verified.')
|
|
88
211
|
|
|
89
|
-
|
|
90
|
-
console.log(chalk.yellow('\n⚙️ THIẾT LẬP HỆ THỐNG'))
|
|
212
|
+
console.log(chalk.gray('─'.repeat(60)))
|
|
91
213
|
|
|
92
|
-
const
|
|
214
|
+
const { key } = await inquirer.prompt([
|
|
93
215
|
{
|
|
94
216
|
type: 'input',
|
|
95
217
|
name: 'key',
|
|
96
|
-
message: '
|
|
97
|
-
validate: (input) =>
|
|
98
|
-
input.trim() !== '' ? true : 'Key không được để trống!',
|
|
218
|
+
message: chalk.cyan('? CONFIGURATION :: Input Invite Key:'),
|
|
219
|
+
validate: (input) => (input.trim() !== '' ? true : 'Required field.'),
|
|
99
220
|
},
|
|
100
221
|
])
|
|
101
222
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
})
|
|
106
|
-
console.log('')
|
|
223
|
+
const choices = SERVER_LIST.map((s, i) => ({
|
|
224
|
+
name: `${chalk.bold(i + 1)}. ${s.name}`,
|
|
225
|
+
value: i,
|
|
226
|
+
}))
|
|
107
227
|
|
|
108
|
-
const
|
|
228
|
+
const { serverIndex } = await inquirer.prompt([
|
|
109
229
|
{
|
|
110
|
-
type: '
|
|
111
|
-
name: '
|
|
112
|
-
message: '
|
|
113
|
-
|
|
114
|
-
validate: (input) => {
|
|
115
|
-
const num = parseInt(input)
|
|
116
|
-
if (!isNaN(num) && num >= 1 && num <= SERVER_LIST.length) {
|
|
117
|
-
return true
|
|
118
|
-
}
|
|
119
|
-
return `Vui lòng nhập số từ 1 đến ${SERVER_LIST.length}`
|
|
120
|
-
},
|
|
230
|
+
type: 'list',
|
|
231
|
+
name: 'serverIndex',
|
|
232
|
+
message: chalk.cyan('? NETWORK :: Select Uplink Node:'),
|
|
233
|
+
choices: choices,
|
|
121
234
|
},
|
|
122
235
|
])
|
|
123
236
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
CURRENT_API_ENDPOINT = selectedConfig.ai.trim()
|
|
129
|
-
CURRENT_IMAGE_ENDPOINT = selectedConfig.image.trim()
|
|
237
|
+
state.apiKey = key.trim()
|
|
238
|
+
state.serverIndex = serverIndex
|
|
239
|
+
state.serverName = SERVER_LIST[serverIndex].name
|
|
240
|
+
state.endpoint = SERVER_LIST[serverIndex].ai.trim()
|
|
130
241
|
|
|
131
|
-
|
|
132
|
-
console.log(chalk.dim('-----------------------------------'))
|
|
133
|
-
console.log(chalk.blue(`Key: `) + chalk.white(maskedKey))
|
|
134
|
-
console.log(
|
|
135
|
-
chalk.blue(`Selected: `) + chalk.green(SERVER_LIST[selectedIndex].name)
|
|
136
|
-
)
|
|
137
|
-
console.log(chalk.blue(`Endpoint: `) + chalk.white(selectedIndex))
|
|
138
|
-
console.log(chalk.green('\n✅ Configuration Loaded.\n'))
|
|
242
|
+
ConfigManager.save(state.apiKey, state.serverIndex)
|
|
139
243
|
}
|
|
140
244
|
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
F: '6',
|
|
155
|
-
}
|
|
156
|
-
const key = answerChar ? answerChar.charAt(0) : ''
|
|
157
|
-
return map[key] || '?'
|
|
245
|
+
const displayStatus = () => {
|
|
246
|
+
console.log('')
|
|
247
|
+
drawBox(
|
|
248
|
+
'SYSTEM READY',
|
|
249
|
+
[
|
|
250
|
+
`Target: ${state.serverName}`,
|
|
251
|
+
`Key: ${state.apiKey.substring(0, 4)}...${state.apiKey.slice(-4)}`,
|
|
252
|
+
`Endpoint: Active`,
|
|
253
|
+
`Socket: Port ${PORT}`,
|
|
254
|
+
],
|
|
255
|
+
'green'
|
|
256
|
+
)
|
|
257
|
+
console.log('')
|
|
158
258
|
}
|
|
159
259
|
|
|
160
|
-
const
|
|
161
|
-
|
|
260
|
+
const solve = async (text) => {
|
|
261
|
+
state.stats.queries++
|
|
262
|
+
const spinner = ora({
|
|
263
|
+
text: chalk.gray('Processing stream data...'),
|
|
264
|
+
color: 'cyan',
|
|
265
|
+
}).start()
|
|
162
266
|
|
|
163
267
|
try {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
268
|
+
const config = {
|
|
269
|
+
timeout: 8000,
|
|
270
|
+
headers: {
|
|
271
|
+
'User-Agent': randomUseragent.getRandom(),
|
|
272
|
+
'Content-Type': 'application/json',
|
|
273
|
+
Referer: CLIENT_URL,
|
|
274
|
+
Origin: CLIENT_URL,
|
|
275
|
+
},
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (PROXY_URL && PROXY_URL.length > 5) {
|
|
279
|
+
const agent = new HttpsProxyAgent(PROXY_URL)
|
|
280
|
+
config.httpsAgent = agent
|
|
281
|
+
config.proxy = false
|
|
168
282
|
}
|
|
169
283
|
|
|
170
|
-
const
|
|
171
|
-
|
|
284
|
+
const { data } = await axios.post(
|
|
285
|
+
state.endpoint,
|
|
172
286
|
{
|
|
173
287
|
question: text,
|
|
174
|
-
inviteKey:
|
|
288
|
+
inviteKey: state.apiKey,
|
|
175
289
|
},
|
|
176
|
-
|
|
177
|
-
timeout: 10000,
|
|
178
|
-
headers: {
|
|
179
|
-
'Content-Type': 'application/json',
|
|
180
|
-
},
|
|
181
|
-
}
|
|
290
|
+
config
|
|
182
291
|
)
|
|
183
292
|
|
|
184
|
-
const apiResult = response.data
|
|
185
293
|
const finalAnswer =
|
|
186
|
-
typeof
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
chalk.bold.green(`${finalAnswer} ➔ ${numberResult}`)
|
|
294
|
+
typeof data === 'object' && data.answer ? data.answer : data
|
|
295
|
+
const numericAnswer = mapAnswerToNumber(finalAnswer)
|
|
296
|
+
|
|
297
|
+
state.stats.success++
|
|
298
|
+
spinner.stop()
|
|
299
|
+
|
|
300
|
+
io.emit('solution_found', { answer: finalAnswer, number: numericAnswer })
|
|
301
|
+
|
|
302
|
+
drawBox(
|
|
303
|
+
`QUERY #${state.stats.queries}`,
|
|
304
|
+
[
|
|
305
|
+
chalk.gray('Q: ') +
|
|
306
|
+
(text.length > 55 ? text.substring(0, 52) + '...' : text),
|
|
307
|
+
chalk.gray('─'.repeat(56)),
|
|
308
|
+
chalk.bold('RESULT: ') +
|
|
309
|
+
chalk.green(`${finalAnswer.toUpperCase()} ➔ [ ${numericAnswer} ]`),
|
|
310
|
+
PROXY_URL
|
|
311
|
+
? chalk.dim(`(Routed via Proxy)`)
|
|
312
|
+
: chalk.dim(`(Direct Connection)`),
|
|
313
|
+
],
|
|
314
|
+
'yellow'
|
|
208
315
|
)
|
|
209
316
|
|
|
210
317
|
await clipboardy.write(' ')
|
|
211
|
-
return
|
|
318
|
+
return true
|
|
212
319
|
} catch (error) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return 'ERROR'
|
|
320
|
+
state.stats.errors++
|
|
321
|
+
spinner.stop()
|
|
322
|
+
const msg = error.response
|
|
323
|
+
? `HTTP ${error.response.status}`
|
|
324
|
+
: 'Connection Refused'
|
|
325
|
+
log.error(`Analysis Failed: ${msg}`)
|
|
326
|
+
return false
|
|
221
327
|
}
|
|
222
328
|
}
|
|
223
329
|
|
|
224
|
-
const
|
|
330
|
+
const monitorClipboard = async () => {
|
|
225
331
|
let lastClip = ''
|
|
226
332
|
try {
|
|
227
333
|
await clipboardy.write(' ')
|
|
228
334
|
lastClip = ' '
|
|
229
335
|
} catch (e) {}
|
|
230
336
|
|
|
231
|
-
|
|
232
|
-
chalk.
|
|
233
|
-
chalk.yellow(`System:`),
|
|
234
|
-
chalk.cyan('Auto-reset enabled. Ready for Ctrl+C...'),
|
|
235
|
-
chalk.cyan(`]`)
|
|
236
|
-
)
|
|
337
|
+
log.info(`Clipboard Watcher: ${chalk.green('ENABLED')}`)
|
|
338
|
+
log.info(`Browser Bridge: ${chalk.green('CONNECTED')}`)
|
|
237
339
|
|
|
238
|
-
setInterval(async () => {
|
|
340
|
+
const loop = setInterval(async () => {
|
|
239
341
|
try {
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
if (
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
) {
|
|
247
|
-
if (currentClip.trim().length > 3) {
|
|
248
|
-
lastClip = currentClip
|
|
249
|
-
const result = await processQuestion(currentClip)
|
|
250
|
-
if (result === 'CLEARED') {
|
|
251
|
-
lastClip = ' '
|
|
252
|
-
}
|
|
253
|
-
}
|
|
342
|
+
const current = await clipboardy.read()
|
|
343
|
+
|
|
344
|
+
if (current && current.trim().length > 3 && current !== lastClip) {
|
|
345
|
+
lastClip = current
|
|
346
|
+
const result = await solve(current)
|
|
347
|
+
if (result) lastClip = ' '
|
|
254
348
|
}
|
|
255
349
|
} catch (err) {}
|
|
256
350
|
}, CHECK_INTERVAL)
|
|
257
351
|
}
|
|
258
352
|
|
|
259
353
|
const main = async () => {
|
|
260
|
-
|
|
261
|
-
await
|
|
262
|
-
|
|
354
|
+
await initSystem()
|
|
355
|
+
await authenticateAndConfigure()
|
|
356
|
+
displayStatus()
|
|
263
357
|
|
|
264
358
|
httpServer.listen(PORT, async () => {
|
|
265
|
-
console.log(chalk.gray(`[Signal] Broadcasting on port ${PORT}...`))
|
|
266
|
-
|
|
267
359
|
try {
|
|
268
|
-
console.log(chalk.yellow(`[Browser] Opening Default Browser...`))
|
|
269
360
|
await open(CLIENT_URL)
|
|
270
|
-
} catch (
|
|
271
|
-
|
|
272
|
-
chalk.red(`[Error] Không thể mở trình duyệt: ${error.message}`)
|
|
273
|
-
)
|
|
361
|
+
} catch (e) {
|
|
362
|
+
log.warn('Could not auto-launch browser.')
|
|
274
363
|
}
|
|
275
364
|
})
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
chalk.cyan(`[`),
|
|
279
|
-
chalk.yellow(`Objective:`),
|
|
280
|
-
chalk.cyan(`Copy question to retrieve answer.`),
|
|
281
|
-
chalk.cyan(`]`)
|
|
282
|
-
)
|
|
283
|
-
console.log(
|
|
284
|
-
chalk.red.italic(
|
|
285
|
-
`(!) Lưu ý: Clipboard sẽ tự động bị xóa sau khi lấy đáp án.`
|
|
286
|
-
)
|
|
287
|
-
)
|
|
288
|
-
startClipboardWatcher()
|
|
365
|
+
|
|
366
|
+
await monitorClipboard()
|
|
289
367
|
}
|
|
290
368
|
|
|
291
369
|
main()
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "t1nder-cli-simulator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Simulator for SungJinWoo system",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"tinder": "
|
|
8
|
+
"tinder": "index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"index.js",
|
|
@@ -27,10 +27,12 @@
|
|
|
27
27
|
"figlet": "^1.9.4",
|
|
28
28
|
"fs-extra": "^11.3.3",
|
|
29
29
|
"gradient-string": "^3.0.0",
|
|
30
|
+
"https-proxy-agent": "^7.0.6",
|
|
30
31
|
"inquirer": "^13.1.0",
|
|
31
32
|
"node-notifier": "^10.0.1",
|
|
32
33
|
"open": "^11.0.0",
|
|
33
34
|
"ora": "^9.0.0",
|
|
35
|
+
"random-useragent": "^0.5.0",
|
|
34
36
|
"semver": "^7.7.3",
|
|
35
37
|
"socket.io": "^4.8.3",
|
|
36
38
|
"update-notifier": "^7.3.1"
|