Tema


SUBMITTED BY: Laranjo

DATE: June 9, 2023, 12:37 p.m.

UPDATED: May 27, 2024, 11:49 p.m.

FORMAT: Text only

SIZE: 114.5 kB

HITS: 852

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>DTunnel</title>
  8. </head>
  9. <style>
  10. * {
  11. font-family: 'roboto';
  12. margin: 0;
  13. padding: 0;
  14. box-sizing: border-box;
  15. -webkit-tap-highlight-color: transparent;
  16. }
  17. ::placeholder {
  18. color: #FFF;
  19. }
  20. body {
  21. height: 100vh;
  22. }
  23. @keyframes fade-in {
  24. from {
  25. opacity: 0;
  26. }
  27. to {
  28. opacity: 1;
  29. }
  30. }
  31. @keyframes fade-out {
  32. from {
  33. opacity: 1;
  34. }
  35. to {
  36. opacity: 0;
  37. }
  38. }
  39. @keyframes pulse {
  40. 0% {
  41. transform: scale(1);
  42. box-shadow: none;
  43. }
  44. 50% {
  45. transform: scale(1.2);
  46. box-shadow: 0 0 20px 5px #ffffff5d;
  47. }
  48. 100% {
  49. transform: scale(1);
  50. box-shadow: none;
  51. }
  52. }
  53. @keyframes spin {
  54. from {
  55. transform: rotate(0deg);
  56. }
  57. to {
  58. transform: rotate(360deg);
  59. }
  60. }
  61. </style>
  62. <body>
  63. <div id="root"></div>
  64. <script>
  65. const BACKGROUND_IMAGE = JSON.parse(window?.DtGetAppConfig?.execute('APP_BACKGROUND_IMAGE') ?? '{"value": "https://i.ibb.co/pjtTQC8/487f7b22f68312d2c1bbc93b1aea445b-1702526703602.jpg"}').value;
  66. const BACKGROUND_COLOR = BACKGROUND_IMAGE
  67. ? `url(${BACKGROUND_IMAGE}) center center / cover rgb(0, 0, 0)`
  68. : 'linear-gradient(45deg, #000000, #000000 25%, #000000 25%, #000000 50%, #000000 50%, #000000 75%, #000000 75%, #000000)'
  69. const INPUT_COLOR = '#36374959'
  70. const BUTTON_BACKGROUND_COLOR = '#36374959'
  71. const ICON_COLOR = '#FFFFFF'
  72. const TEXT_COLOR = '#FFFFFF'
  73. const TOOLS_BUTTON_BACKGROUND_COLOR = '#36374959'
  74. const VPN_BUTTON_BACKGROUND_COLOR = '#36374959'
  75. const VPN_STOPPED_COLOR = '#ff0000'
  76. const VPN_STARTING_COLOR = '#ffff00'
  77. const VPN_RUNNING_COLOR = '#00ff00'
  78. const CHECKUSER_TEXT_COLOR = '#FFFFFF'
  79. const LOGGER_TEXT_COLOR = '#FFFFFF'
  80. const DIALOG_HEADER_TITLE_COLOR = '#FFFFFF'
  81. const DIALOG_HEADER_CLOSE_BUTTON_COLOR = '#FFFFFF'
  82. const DIALOG_CONTENT_BACKGROUND_COLOR = '#36374959'
  83. const DIALOG_FOOTER_BUTTON_COLOR = '#36374959'
  84. const DIALOG_FOOTER_BUTTON_TEXT_COLOR = '#FFFFFF'
  85. const LINK_SUPPORT = 'https://wa.me/+5579991996384'
  86. const TERMS_URL = 'https://termos.devws.xyz/'
  87. const URL_RENOVAR = 'https://laranjo.gestorssh.com.br/index.php'
  88. const URL_TESTE = 'https://laranjo.gestorssh.com.br/views/home/criar_teste.php?id=zw6&byid=1&mainid=760653'
  89. const URL_MP3 = 'https://temp-mail.org/pt/'
  90. const URL_FILMES = 'https://redecanais.dev'
  91. const URL_FILMES2 = 'https://wetv.vip/pt'
  92. const URL_FILMES3 = 'https://vizertv.in'
  93. const URL_GPT = 'https://chatgpt.com'
  94. const URL_TV = 'https://pluto.tv/br/live-tv/63eb9c5351f5d000085e8d7e?lang=en'
  95. const URL_TV2 = 'https://redecanaistv.dev'
  96. const URL_TV3 = 'https://canaisplay.com/categoria/futebol-ao-vivo/'
  97. const URL_JOGOS = 'https://www.friv.com/?gad_source=1&gclid=Cj0KCQjwxqayBhDFARIsAANWRnRuJ8YvDQ_Pt8DFecPWTFSeopS0DSzlMBcQUiv3tJx5ilZQeKSV5YgaAo_AEALw_wcB'
  98. class Component {
  99. constructor(element) {
  100. this.element = element;
  101. }
  102. addEventListener(event, listener) {
  103. this.element.addEventListener(event, listener);
  104. }
  105. append(component) {
  106. if (component instanceof Component) {
  107. this.element.appendChild(component.element);
  108. } else {
  109. this.element.append(component);
  110. }
  111. }
  112. appendChild(component) {
  113. if (component instanceof Component) {
  114. this.element.appendChild(component.element);
  115. } else {
  116. this.element.appendChild(component);
  117. }
  118. }
  119. remove() {
  120. this.element.remove();
  121. }
  122. contains(component) {
  123. if (component instanceof Component) {
  124. return this.element.contains(component.element);
  125. } else {
  126. return this.element.contains(component);
  127. }
  128. }
  129. }
  130. class StyledComponent extends Component {
  131. constructor(element, styles = {}) {
  132. super(element);
  133. this.styles = styles;
  134. this.setStyles(styles);
  135. }
  136. setStyles(styles) {
  137. Object.keys(styles).forEach((key) => {
  138. if (this.element.style.hasOwnProperty(key)) {
  139. this.element.style[key] = styles[key];
  140. }
  141. });
  142. }
  143. }
  144. class Toast extends StyledComponent {
  145. constructor(element, styles = {}) {
  146. super(element, styles);
  147. }
  148. showToast(message, type, duration = 3000) {
  149. this.element.innerHTML = message;
  150. this.element.style.wordWrap = 'break-word';
  151. this.element.style.width = '90%';
  152. this.element.style.maxWidth = '400px';
  153. this.element.style.textAlign = 'center';
  154. this.element.style.display = 'block';
  155. this.element.style.position = 'fixed';
  156. this.element.style.bottom = '10%';
  157. this.element.style.left = '50%';
  158. this.element.style.transform = 'translateX(-50%)';
  159. this.element.style.opacity = '0';
  160. this.element.style.color = '#FFFFFF';
  161. switch (type) {
  162. case 'success':
  163. this.element.style.background = 'linear-gradient(135deg, #4CAF50, #009688)';
  164. break;
  165. case 'error':
  166. this.element.style.background = 'linear-gradient(135deg, #F44336, #FF5722)';
  167. break;
  168. case 'info':
  169. default:
  170. this.element.style.background = 'linear-gradient(135deg, #2196F3, #03A9F4)';
  171. break;
  172. }
  173. this.element.style.padding = '10px';
  174. this.element.style.borderRadius = '4px';
  175. this.element.style.opacity = '0';
  176. this.element.style.transition = 'opacity 0.3s ease-in-out';
  177. setTimeout(() => {
  178. this.element.style.opacity = '1';
  179. }, 100);
  180. setTimeout(() => this.hideToast(), duration);
  181. this.element.addEventListener('click', () => this.hideToast());
  182. }
  183. hideToast() {
  184. this.element.style.transition = 'opacity 0.3s ease-in-out';
  185. this.element.style.opacity = '0';
  186. setTimeout(() => {
  187. this.element.remove();
  188. }, 300);
  189. }
  190. static success(message, duration = 3000) {
  191. const toastElement = document.createElement('div');
  192. document.body.appendChild(toastElement);
  193. const toast = new Toast(toastElement);
  194. toast.showToast(message, 'success', duration);
  195. }
  196. static error(message, duration = 3000) {
  197. const toastElement = document.createElement('div');
  198. document.body.appendChild(toastElement);
  199. const toast = new Toast(toastElement);
  200. toast.showToast(message, 'error', duration);
  201. }
  202. static info(message, duration = 3000) {
  203. const toastElement = document.createElement('div');
  204. document.body.appendChild(toastElement);
  205. const toast = new Toast(toastElement);
  206. toast.showToast(message, 'info', duration);
  207. }
  208. }
  209. class AppComponent extends StyledComponent {
  210. constructor(element, styles = {}) {
  211. const defaultStyles = {
  212. width: '100%',
  213. height: '100%',
  214. background: '#404258',
  215. display: 'flex',
  216. flexDirection: 'column',
  217. justifyContent: 'center',
  218. alignItems: 'center',
  219. };
  220. super(element, { ...defaultStyles, ...styles });
  221. }
  222. }
  223. class CardComponent extends StyledComponent {
  224. constructor(styles = {}) {
  225. const defaultStyles = {
  226. display: 'flex',
  227. flexDirection: 'column',
  228. alignItems: 'center',
  229. justifyContent: 'center',
  230. width: '85%',
  231. maxWidth: '23rem',
  232. margin: '1.2rem',
  233. borderRadius: '5px',
  234. border: 'none',
  235. };
  236. super(document.createElement('div'), { ...defaultStyles, ...styles });
  237. }
  238. }
  239. class InputGroupComponent extends StyledComponent {
  240. constructor(styles = {}) {
  241. const defaultStyles = {
  242. display: 'flex',
  243. width: '100%',
  244. alignItems: 'center',
  245. background: '#363749',
  246. color: '#FFF',
  247. padding: '0.2rem',
  248. borderRadius: '5px',
  249. boxShadow: 'rgba(0, 0, 0, 0.35) 0px 5px 15px',
  250. };
  251. super(document.createElement('div'), { ...defaultStyles, ...styles });
  252. }
  253. append(...components) {
  254. components.forEach((component) => super.append(component));
  255. }
  256. }
  257. class InputComponent extends StyledComponent {
  258. constructor(styles = {}) {
  259. const defaultStyles = {
  260. background: 'transparent',
  261. border: 'none',
  262. width: '100%',
  263. outline: 'none',
  264. color: TEXT_COLOR,
  265. fontSize: '15px',
  266. };
  267. super(document.createElement('input'), { ...defaultStyles, ...styles });
  268. }
  269. setEnabled(value) {
  270. this.element.disabled = !value;
  271. }
  272. }
  273. class InputText extends InputComponent {
  274. constructor(styles = {}) {
  275. super(styles);
  276. this.element.type = 'text';
  277. }
  278. get value() {
  279. return this.element.value;
  280. }
  281. setPlaceholder(text) {
  282. this.element.placeholder = text;
  283. }
  284. setOnInputListener(callback) {
  285. this.addEventListener('input', callback);
  286. }
  287. setValue(value) {
  288. this.element.value = value;
  289. }
  290. setOnInputListener(callback) {
  291. this.addEventListener('input', callback);
  292. }
  293. }
  294. class InputPassword extends InputText {
  295. constructor(styles = {}) {
  296. super(styles);
  297. this.element.type = 'password';
  298. }
  299. setShowing(value) {
  300. this.element.type = !value ? 'password' : 'text';
  301. }
  302. get isShowing() { return this.element.type != 'password' }
  303. }
  304. class SvgComponent extends StyledComponent {
  305. constructor(styles = {}, ...paths) {
  306. const defaultStyles = {
  307. fill: '#FFFFFF',
  308. padding: '5px',
  309. width: '2.2rem',
  310. height: '2.2rem',
  311. };
  312. super(document.createElementNS('http://www.w3.org/2000/svg', 'svg'), {
  313. ...defaultStyles,
  314. ...styles,
  315. });
  316. this.applyOptions();
  317. paths.forEach((p) => this.addPath(p));
  318. }
  319. applyOptions() {
  320. this.setFill(this.styles.fill || 'currentColor');
  321. this.setWidth(this.styles.width || '16');
  322. this.setHeight(this.styles.height || '16');
  323. this.setViewBox(this.styles.viewBox || '0 0 16 16');
  324. this.setXmlns(this.styles.xmlns || 'http://www.w3.org/2000/svg');
  325. }
  326. setFill(color) {
  327. this.element.setAttribute('fill', color);
  328. }
  329. setWidth(width) {
  330. this.element.setAttribute('width', width);
  331. }
  332. setHeight(height) {
  333. this.element.setAttribute('height', height);
  334. }
  335. setViewBox(viewBox) {
  336. this.element.setAttribute('viewBox', viewBox);
  337. }
  338. setXmlns(xmlns) {
  339. this.element.setAttribute('xmlns', xmlns);
  340. }
  341. addPath(...path) {
  342. path.forEach((item) => {
  343. const pathElement = document.createElementNS(
  344. 'http://www.w3.org/2000/svg',
  345. 'path'
  346. );
  347. pathElement.setAttribute('d', item);
  348. this.element.appendChild(pathElement);
  349. });
  350. }
  351. }
  352. class Spinner extends StyledComponent {
  353. constructor() {
  354. super(document.createElement('div'), {
  355. display: 'flex',
  356. width: '100%',
  357. alignItems: 'center',
  358. justifyContent: 'center',
  359. padding: '20px'
  360. });
  361. this.createSpinnerElements();
  362. }
  363. createSpinnerElements() {
  364. const spinnerElement = new StyledComponent(document.createElement('div'));
  365. spinnerElement.setStyles({
  366. borderTop: '4px solid transparent',
  367. borderRight: '4px solid #ccc',
  368. borderBottom: '4px solid #ccc',
  369. borderLeft: '4px solid #ccc',
  370. borderRadius: '50%',
  371. width: '45px',
  372. height: '45px',
  373. animation: 'spin 1s linear infinite',
  374. });
  375. this.append(spinnerElement)
  376. }
  377. }
  378. class IconComponent extends SvgComponent {
  379. constructor(styles = {}, ...iconPath) {
  380. super({
  381. cursor: 'pointer',
  382. background: TOOLS_BUTTON_BACKGROUND_COLOR,
  383. borderRadius: '20%',
  384. height: '45px',
  385. width: '45px',
  386. padding: '10px',
  387. boxShadow: 'rgba(0, 0, 0, 0.35) 0px 5px 15px',
  388. fill: ICON_COLOR,
  389. ...styles,
  390. },
  391. ...iconPath,
  392. );
  393. }
  394. }
  395. class CalanderIconComponent extends IconComponent {
  396. constructor(styles = {}) {
  397. super(styles,
  398. 'M10.854 7.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7.5 9.793l2.646-2.647a.5.5 0 0 1 .708 0z',
  399. 'M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z'
  400. );
  401. }
  402. }
  403. class LoggerIconComponent extends IconComponent {
  404. constructor(styles = {}) {
  405. super(styles,
  406. 'M5 4a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1H5zm-.5 2.5A.5.5 0 0 1 5 6h6a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zM5 8a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1H5zm0 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1H5z',
  407. 'M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2zm10-1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1z'
  408. )
  409. }
  410. }
  411. class ArrowRepeatIconComponent extends IconComponent {
  412. constructor(styles = {}) {
  413. super(styles,
  414. 'M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41zm-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9z',
  415. 'M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5.002 5.002 0 0 0 8 3zM3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9H3.1z'
  416. );
  417. }
  418. }
  419. class MoreIconComponent extends IconComponent {
  420. constructor(styles = {}) {
  421. super(styles,
  422. 'M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z'
  423. );
  424. }
  425. }
  426. class BatteryIconComponent extends SvgComponent {
  427. constructor(styles = {}) {
  428. super(styles,
  429. 'M2 6h10v4H2V6z', 'M2 4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H2zm10 1a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h10zm4 3a1.5 1.5 0 0 1-1.5 1.5v-3A1.5 1.5 0 0 1 16 8z'
  430. );
  431. }
  432. }
  433. class HeadsetIconComponent extends SvgComponent {
  434. constructor(styles = {}) {
  435. super(styles,
  436. 'M8 1a5 5 0 0 0-5 5v1h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6a6 6 0 1 1 12 0v6a2.5 2.5 0 0 1-2.5 2.5H9.366a1 1 0 0 1-.866.5h-1a1 1 0 1 1 0-2h1a1 1 0 0 1 .866.5H11.5A1.5 1.5 0 0 0 13 12h-1a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h1V6a5 5 0 0 0-5-5z'
  437. );
  438. }
  439. }
  440. class RenovarIconComponent extends SvgComponent {
  441. constructor(styles = {}) {
  442. super(styles,
  443. 'M11 15a4 4 0 1 0 0-8 4 4 0 0 0 0 8m5-4a5 5 0 1 1-10 0 5 5 0 0 1 10 0',
  444. 'M9.438 11.944c.047.596.518 1.06 1.363 1.116v.44h.375v-.443c.875-.061 1.386-.529 1.386-1.207 0-.618-.39-.936-1.09-1.1l-.296-.07v-1.2c.376.043.614.248.671.532h.658c-.047-.575-.54-1.024-1.329-1.073V8.5h-.375v.45c-.747.073-1.255.522-1.255 1.158 0 .562.378.92 1.007 1.066l.248.061v1.272c-.384-.058-.639-.27-.696-.563h-.668zm1.36-1.354c-.369-.085-.569-.26-.569-.522 0-.294.216-.514.572-.578v1.1h-.003zm.432.746c.449.104.655.272.655.569 0 .339-.257.571-.709.614v-1.195l.054.012z',
  445. 'M1 0a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h4.083c.058-.344.145-.678.258-1H3a2 2 0 0 0-2-2V3a2 2 0 0 0 2-2h10a2 2 0 0 0 2 2v3.528c.38.34.717.728 1 1.154V1a1 1 0 0 0-1-1z',
  446. 'M9.998 5.083 10 5a2 2 0 1 0-3.132 1.65 5.982 5.982 0 0 1 3.13-1.567z'
  447. );
  448. }
  449. }
  450. class testeIconComponent extends SvgComponent {
  451. constructor(styles = {}) {
  452. super(styles,
  453. 'M2.5 15a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1zm2-13v1c0 .537.12 1.045.337 1.5h6.326c.216-.455.337-.963.337-1.5V2zm3 6.35c0 .701-.478 1.236-1.011 1.492A3.5 3.5 0 0 0 4.5 13s.866-1.299 3-1.48zm1 0v3.17c2.134.181 3 1.48 3 1.48a3.5 3.5 0 0 0-1.989-3.158C8.978 9.586 8.5 9.052 8.5 8.351z'
  454. );
  455. }
  456. }
  457. class Mp3IconComponent extends SvgComponent {
  458. constructor(styles = {}) {
  459. super(styles,
  460. 'M6 13c0 1.105-1.12 2-2.5 2S1 14.105 1 13c0-1.104 1.12-2 2.5-2s2.5.896 2.5 2m9-2c0 1.105-1.12 2-2.5 2s-2.5-.895-2.5-2 1.12-2 2.5-2 2.5.895 2.5 2',
  461. 'M14 11V2h1v9zM6 3v10H5V3z',
  462. 'M5 2.905a1 1 0 0 1 .9-.995l8-.8a1 1 0 0 1 1.1.995V3L5 4z',
  463. );
  464. }
  465. }
  466. class TrashIconComponent extends SvgComponent {
  467. constructor(styles = {}) {
  468. super(styles,
  469. 'M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z',
  470. 'M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z'
  471. );
  472. }
  473. }
  474. class ReceptionIconComponent extends SvgComponent {
  475. constructor(styles = {}) {
  476. super(styles,
  477. 'M0 11.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-5zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-8zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-11z'
  478. );
  479. }
  480. }
  481. class InfoIconComponent extends SvgComponent {
  482. constructor(styles = {}) {
  483. super(styles,
  484. 'M8.051 1.999h.089c.822.003 4.987.033 6.11.335a2.01 2.01 0 0 1 1.415 1.42c.101.38.172.883.22 1.402l.01.104.022.26.008.104c.065.914.073 1.77.074 1.957v.075c-.001.194-.01 1.108-.082 2.06l-.008.105-.009.104c-.05.572-.124 1.14-.235 1.558a2.007 2.007 0 0 1-1.415 1.42c-1.16.312-5.569.334-6.18.335h-.142c-.309 0-1.587-.006-2.927-.052l-.17-.006-.087-.004-.171-.007-.171-.007c-1.11-.049-2.167-.128-2.654-.26a2.007 2.007 0 0 1-1.415-1.419c-.111-.417-.185-.986-.235-1.558L.09 9.82l-.008-.104A31.4 31.4 0 0 1 0 7.68v-.123c.002-.215.01-.958.064-1.778l.007-.103.003-.052.008-.104.022-.26.01-.104c.048-.519.119-1.023.22-1.402a2.007 2.007 0 0 1 1.415-1.42c.487-.13 1.544-.21 2.654-.26l.17-.007.172-.006.086-.003.171-.007A99.788 99.788 0 0 1 7.858 2h.193zM6.4 5.209v4.818l4.157-2.408L6.4 5.209z'
  485. );
  486. }
  487. }
  488. class ArrowDownIconComponent extends SvgComponent {
  489. constructor(style = {}) {
  490. super({
  491. fill: ICON_COLOR,
  492. ...style,
  493. },
  494. 'M1 3.5a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13a.5.5 0 0 1-.5-.5zM8 6a.5.5 0 0 1 .5.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 0 1 .708-.708L7.5 12.293V6.5A.5.5 0 0 1 8 6z'
  495. );
  496. }
  497. }
  498. class NetworkIconComponent extends SvgComponent {
  499. constructor(style = {}) {
  500. super({
  501. fill: ICON_COLOR,
  502. ...style,
  503. },
  504. 'M4.5 5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zM3 4.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0z',
  505. 'M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v1a2 2 0 0 1-2 2H8.5v3a1.5 1.5 0 0 1 1.5 1.5h5.5a.5.5 0 0 1 0 1H10A1.5 1.5 0 0 1 8.5 14h-1A1.5 1.5 0 0 1 6 12.5H.5a.5.5 0 0 1 0-1H6A1.5 1.5 0 0 1 7.5 10V7H2a2 2 0 0 1-2-2V4zm1 0v1a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1zm6 7.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5z'
  506. );
  507. }
  508. }
  509. class RouterIconComponent extends SvgComponent {
  510. constructor(style = {}) {
  511. super({
  512. fill: ICON_COLOR,
  513. ...style,
  514. },
  515. 'M5.525 3.025a3.5 3.5 0 0 1 4.95 0 .5.5 0 1 0 .707-.707 4.5 4.5 0 0 0-6.364 0 .5.5 0 0 0 .707.707Z',
  516. 'M6.94 4.44a1.5 1.5 0 0 1 2.12 0 .5.5 0 0 0 .708-.708 2.5 2.5 0 0 0-3.536 0 .5.5 0 0 0 .707.707ZM2.5 11a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1Zm4.5-.5a.5.5 0 1 0 1 0 .5.5 0 0 0-1 0Zm2.5.5a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1Zm1.5-.5a.5.5 0 1 0 1 0 .5.5 0 0 0-1 0Zm2 0a.5.5 0 1 0 1 0 .5.5 0 0 0-1 0Z',
  517. 'M2.974 2.342a.5.5 0 1 0-.948.316L3.806 8H1.5A1.5 1.5 0 0 0 0 9.5v2A1.5 1.5 0 0 0 1.5 13H2a.5.5 0 0 0 .5.5h2A.5.5 0 0 0 5 13h6a.5.5 0 0 0 .5.5h2a.5.5 0 0 0 .5-.5h.5a1.5 1.5 0 0 0 1.5-1.5v-2A1.5 1.5 0 0 0 14.5 8h-2.306l1.78-5.342a.5.5 0 1 0-.948-.316L11.14 8H4.86L2.974 2.342ZM14.5 9a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-2a.5.5 0 0 1 .5-.5h13Z',
  518. 'M8.5 5.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0Z'
  519. );
  520. }
  521. }
  522. class PersonIconComponent extends SvgComponent {
  523. constructor(style = {}) {
  524. super({
  525. fill: ICON_COLOR,
  526. ...style,
  527. },
  528. 'M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4Zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10Z'
  529. );
  530. }
  531. }
  532. class LockIconComponent extends SvgComponent {
  533. constructor(style = {}) {
  534. super({
  535. fill: ICON_COLOR,
  536. ...style,
  537. },
  538. 'M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2zM5 8h6a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1z'
  539. );
  540. }
  541. }
  542. class EyeIconComponent extends SvgComponent {
  543. constructor(style = {}) {
  544. super({
  545. fill: ICON_COLOR,
  546. ...style,
  547. },
  548. 'M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z',
  549. 'M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z',
  550. );
  551. }
  552. }
  553. class ArrowDownShortIconComponent extends SvgComponent {
  554. constructor(style = {}) {
  555. super({
  556. fill: ICON_COLOR,
  557. ...style,
  558. },
  559. 'M8 4a.5.5 0 0 1 .5.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5A.5.5 0 0 1 8 4z'
  560. );
  561. }
  562. }
  563. class ArrowUpShortIconComponent extends SvgComponent {
  564. constructor(style = {}) {
  565. super({
  566. fill: ICON_COLOR,
  567. ...style,
  568. },
  569. 'M8 12a.5.5 0 0 0 .5-.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 .5.5z'
  570. );
  571. }
  572. }
  573. ////////////NOVOS////////
  574. class FilmesIconComponent extends SvgComponent {
  575. constructor(styles = {}) {
  576. super(styles,
  577. 'M13.218 4.246L7.087 6.238a.502.502 0 0 1-.24.079L4.741 7H13.5a.5.5 0 0 1 .5.5v5a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 2 12.5v-5c0-.106.033-.205.09-.287l-.195-.602A2.5 2.5 0 0 1 3.5 3.461l6.657-2.163a2.5 2.5 0 0 1 3.15 1.605l.232.713a.5.5 0 0 1-.321.63Zm-3.744.165l1.285-2.226a1.508 1.508 0 0 0-.293.064l-1.245.404l-1.308 2.265l1.56-.507Zm2.295-1.979a.515.515 0 0 1-.02.037l-.854 1.48l1.538-.5l-.077-.237a1.494 1.494 0 0 0-.587-.78Zm-3.97.683l-1.56.507L4.93 5.887l1.56-.507L7.8 3.115ZM2.923 6.54l.587-.19l1.307-2.266l-1.008.328a1.5 1.5 0 0 0-.963 1.89l.077.238Z'
  578. );
  579. }
  580. }
  581. class TicketIconComponent extends SvgComponent {
  582. constructor(styles = {}) {
  583. super(styles,
  584. 'M4 4.85v.9h1v-.9zm7 0v.9h1v-.9zm-7 1.8v.9h1v-.9zm7 0v.9h1v-.9zm-7 1.8v.9h1v-.9zm7 0v.9h1v-.9zm-7 1.8v.9h1v-.9zm7 0v.9h1v-.9z',
  585. 'M1.5 3A1.5 1.5 0 0 0 0 4.5V6a.5.5 0 0 0 .5.5 1.5 1.5 0 1 1 0 3 .5.5 0 0 0-.5.5v1.5A1.5 1.5 0 0 0 1.5 13h13a1.5 1.5 0 0 0 1.5-1.5V10a.5.5 0 0 0-.5-.5 1.5 1.5 0 0 1 0-3A.5.5 0 0 0 16 6V4.5A1.5 1.5 0 0 0 14.5 3zM1 4.5a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 .5.5v1.05a2.5 2.5 0 0 0 0 4.9v1.05a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-1.05a2.5 2.5 0 0 0 0-4.9z'
  586. );
  587. }
  588. }
  589. class RobotIconComponent extends SvgComponent {
  590. constructor(styles = {}) {
  591. super(styles,
  592. 'M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.6 26.6 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.93.93 0 0 1-.765.935c-.845.147-2.34.346-4.235.346s-3.39-.2-4.235-.346A.93.93 0 0 1 3 9.219zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a25 25 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25 25 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135',
  593. 'M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2zM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5'
  594. );
  595. }
  596. }
  597. class GptIconComponent extends SvgComponent {
  598. constructor(styles = {}) {
  599. super(styles,
  600. 'M6 13c0 1.105-1.12 2-2.5 2S1 14.105 1 13c0-1.104 1.12-2 2.5-2s2.5.896 2.5 2',
  601. 'M9 11c0 1.105-1.12 2-2.5 2S4 12.105 4 11c0-1.104 1.12-2 2.5-2s2.5.896 2.5 2',
  602. 'M14 11V2h1v9zM6 3v10H5V3',
  603. 'M5 2.905a1 1 0 0 1 .9-.9');
  604. }
  605. }
  606. class Gpt2IconComponent extends SvgComponent {
  607. constructor(styles = {}) {
  608. super(styles,
  609. 'M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z'
  610. );
  611. }
  612. }
  613. class JogosIconComponent extends SvgComponent {
  614. constructor(styles = {}) {
  615. super(styles,
  616. 'M11.5 6.027a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0m-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1m2.5-.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0m-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1m-6.5-3h1v1h1v1h-1v1h-1v-1h-1v-1h1z',
  617. 'M3.051 3.26a.5.5 0 0 1 .354-.613l1.932-.518a.5.5 0 0 1 .62.39c.655-.079 1.35-.117 2.043-.117.72 0 1.443.041 2.12.126a.5.5 0 0 1 .622-.399l1.932.518a.5.5 0 0 1 .306.729q.211.136.373.297c.408.408.78 1.05 1.095 1.772.32.733.599 1.591.805 2.466s.34 1.78.364 2.606c.024.816-.059 1.602-.328 2.21a1.42 1.42 0 0 1-1.445.83c-.636-.067-1.115-.394-1.513-.773-.245-.232-.496-.526-.739-.808-.126-.148-.25-.292-.368-.423-.728-.804-1.597-1.527-3.224-1.527s-2.496.723-3.224 1.527c-.119.131-.242.275-.368.423-.243.282-.494.575-.739.808-.398.38-.877.706-1.513.773a1.42 1.42 0 0 1-1.445-.83c-.27-.608-.352-1.395-.329-2.21.024-.826.16-1.73.365-2.606.206-.875.486-1.733.805-2.466.315-.722.687-1.364 1.094-1.772a2.3 2.3 0 0 1 .433-.335l-.028-.079zm2.036.412c-.877.185-1.469.443-1.733.708-.276.276-.587.783-.885 1.465a14 14 0 0 0-.748 2.295 12.4 12.4 0 0 0-.339 2.406c-.022.755.062 1.368.243 1.776a.42.42 0 0 0 .426.24c.327-.034.61-.199.929-.502.212-.202.4-.423.615-.674.133-.156.276-.323.44-.504C4.861 9.969 5.978 9.027 8 9.027s3.139.942 3.965 1.855c.164.181.307.348.44.504.214.251.403.472.615.674.318.303.601.468.929.503a.42.42 0 0 0 .426-.241c.18-.408.265-1.02.243-1.776a12.4 12.4 0 0 0-.339-2.406 14 14 0 0 0-.748-2.295c-.298-.682-.61-1.19-.885-1.465-.264-.265-.856-.523-1.733-.708-.85-.179-1.877-.27-2.913-.27s-2.063.091-2.913.27'
  618. );
  619. }
  620. }
  621. class TvIconComponent extends SvgComponent {
  622. constructor(styles = {}) {
  623. super(styles,
  624. 'M2.5 13.5A.5.5 0 0 1 3 13h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5M13.991 3l.024.001a1.5 1.5 0 0 1 .538.143.76.76 0 0 1 .302.254c.067.1.145.277.145.602v5.991l-.001.024a1.5 1.5 0 0 1-.143.538.76.76 0 0 1-.254.302c-.1.067-.277.145-.602.145H2.009l-.024-.001a1.5 1.5 0 0 1-.538-.143.76.76 0 0 1-.302-.254C1.078 10.502 1 10.325 1 10V4.009l.001-.024a1.5 1.5 0 0 1 .143-.538.76.76 0 0 1 .254-.302C1.498 3.078 1.675 3 2 3zM14 2H2C0 2 0 4 0 4v6c0 2 2 2 2 2h12c2 0 2-2 2-2V4c0-2-2-2-2-2'
  625. );
  626. }
  627. }
  628. class MenuIconComponent extends SvgComponent {
  629. constructor(styles = {}) {
  630. super(styles,
  631. 'M2 10h3a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1m9-9h3a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1m0 9a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1zm0-10a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h3a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zM2 9a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h3a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2zm7 2a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-3a2 2 0 0 1-2-2zM0 2a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm5.354.854a.5.5 0 1 0-.708-.708L3 3.793l-.646-.647a.5.5 0 1 0-.708.708l1 1a.5.5 0 0 0 .708 0z'
  632. );
  633. }
  634. }
  635. class AjudaIconComponent extends SvgComponent {
  636. constructor(styles = {}) {
  637. super(styles,
  638. 'M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10s10-4.486 10-10S17.514 2 12 2zm1 16h-2v-2h2v2zm.976-4.885c-.196.158-.385.309-.535.459c-.408.407-.44.777-.441.793v.133h-2v-.167c0-.118.029-1.177 1.026-2.174c.195-.195.437-.393.691-.599c.734-.595 1.216-1.029 1.216-1.627a1.934 1.934 0 0 0-3.867.001h-2C8.066 7.765 9.831 6 12 6s3.934 1.765 3.934 3.934c0 1.597-1.179 2.55-1.958 3.181z'
  639. );
  640. }
  641. }
  642. class Menu2IconComponent extends SvgComponent {
  643. constructor(styles = {}) {
  644. super(styles,
  645. 'M18 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2Zm0 24H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V30a2 2 0 0 0-2-2ZM42 4H30a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2Z',
  646. 'M28 28h16m-8 8h8m-16 8h16'
  647. );
  648. }
  649. }
  650. class PowerIconComponent extends SvgComponent {
  651. constructor(style = {}) {
  652. super({
  653. cursor: 'pointer',
  654. height: '8.5rem',
  655. width: '8.5rem',
  656. background: VPN_BUTTON_BACKGROUND_COLOR,
  657. borderRadius: '100%',
  658. boxShadow: 'rgba(0, 0, 0, 0.35) 0px 5px 15px',
  659. padding: '20px',
  660. animation: 'pulse 2.5s infinite',
  661. fill: ICON_COLOR,
  662. ...style,
  663. },
  664. 'M7.5 1v7h1V1h-1z',
  665. 'M3 8.812a4.999 4.999 0 0 1 2.578-4.375l-.485-.874A6 6 0 1 0 11 3.616l-.501.865A5 5 0 1 1 3 8.812z',
  666. );
  667. }
  668. }
  669. class DialogComponent extends StyledComponent {
  670. constructor(styles = {}) {
  671. super(document.createElement('div'), {
  672. position: 'absolute',
  673. top: '0',
  674. bottom: '0',
  675. left: '0',
  676. right: '0',
  677. height: '100vh',
  678. background: 'rgba(0, 0, 0, 0.5)',
  679. backdropFilter: 'blur(5px)',
  680. display: 'flex',
  681. alignItems: 'center',
  682. justifyContent: 'center',
  683. visibility: 'hidden',
  684. opacity: '0',
  685. ...styles,
  686. });
  687. this.element.addEventListener('click', (event) => {
  688. if (event.target === this.element) {
  689. this.close();
  690. }
  691. });
  692. this.onCloseEvent = null
  693. }
  694. setOnCloseEventListener(callback) {
  695. this.onCloseEvent = callback
  696. }
  697. setContent(content) {
  698. if (!(content instanceof DialogContentComponent)) {
  699. throw new TypeError('Content must be a DialogContentComponent');
  700. }
  701. if (!this.contains(content)) {
  702. this.append(content);
  703. }
  704. }
  705. show() {
  706. this.setStyles({
  707. opacity: '1',
  708. visibility: 'visible',
  709. display: 'flex',
  710. animation: 'fade-in 0.3s forwards',
  711. pointerEvents: 'auto',
  712. })
  713. if (!document.body.contains(this.element)) {
  714. document.body.append(this.element);
  715. }
  716. }
  717. close() {
  718. this.setStyles({
  719. opacity: '0',
  720. animation: 'fade-out 0.3s forwards',
  721. })
  722. setTimeout(() => {
  723. this.setStyles({
  724. display: 'none',
  725. pointerEvents: 'none',
  726. })
  727. if (this.onCloseEvent != null) {
  728. this.onCloseEvent()
  729. }
  730. }, 300);
  731. }
  732. remove() {
  733. if (document.body.contains(this.element)) {
  734. this.element.remove();
  735. }
  736. }
  737. }
  738. class DialogContentComponent extends StyledComponent {
  739. constructor(styles = {}) {
  740. super(document.createElement('div'), {
  741. display: 'flex',
  742. flexDirection: 'column',
  743. justifyContent: 'center',
  744. alignItems: 'center',
  745. background: DIALOG_CONTENT_BACKGROUND_COLOR,
  746. borderRadius: '5px',
  747. maxWidth: '30rem',
  748. width: '85%',
  749. ...styles,
  750. });
  751. this.lastHeader = null;
  752. this.lastBody = null;
  753. this.lastFooter = null;
  754. }
  755. setHeader(component) {
  756. this?.lastHeader?.remove()
  757. this.lastHeader = component
  758. this.append(component);
  759. }
  760. setBody(component) {
  761. this?.lastBody?.remove()
  762. this.lastBody = component
  763. this.append(component);
  764. }
  765. setFooter(component) {
  766. this?.lastFooter?.remove()
  767. this.lastFooter = component
  768. this.append(component);
  769. }
  770. }
  771. class DialogHeaderComponent extends StyledComponent {
  772. constructor(styles = {}) {
  773. super(document.createElement('div'), {
  774. display: 'flex',
  775. justifyContent: 'space-between',
  776. alignItems: 'center',
  777. width: '100%',
  778. padding: '5px',
  779. ...styles,
  780. });
  781. this.title = new StyledComponent(document.createElement('span'), {
  782. fontSize: '16px',
  783. color: DIALOG_HEADER_TITLE_COLOR,
  784. fontFamily: 'sans-serif',
  785. fontWeight: 'bold',
  786. padding: '5px',
  787. });
  788. this.closeButton = new SvgComponent({
  789. cursor: 'pointer',
  790. height: '35px',
  791. width: '35px',
  792. fill: DIALOG_HEADER_CLOSE_BUTTON_COLOR,
  793. },
  794. 'M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z'
  795. );
  796. this.initialize();
  797. }
  798. setTitleText(title) {
  799. this.title.element.innerText = title;
  800. }
  801. setCloseButtonClickListener(callback) {
  802. this.closeButton.addEventListener('click', callback);
  803. }
  804. initialize() {
  805. this.append(this.title);
  806. this.append(this.closeButton);
  807. }
  808. }
  809. class DialogBodyComponent extends StyledComponent {
  810. constructor(styles = {}) {
  811. super(document.createElement('div'), {
  812. display: 'flex',
  813. width: '100%',
  814. padding: '5px',
  815. ...styles,
  816. });
  817. }
  818. }
  819. class DialogFooterComponent extends StyledComponent {
  820. constructor(styles = {}) {
  821. super(document.createElement('div'), {
  822. display: 'flex',
  823. justifyContent: 'space-between',
  824. gap: '5px',
  825. alignItems: 'center',
  826. width: '100%',
  827. padding: '5px',
  828. ...styles,
  829. });
  830. }
  831. addButton(button) {
  832. if (!(button instanceof DialogFooterButtonComponent)) {
  833. throw new TypeError('Button must be a DialogFooterButtonComponent instance');
  834. }
  835. this.append(button);
  836. return this;
  837. }
  838. }
  839. class DialogFooterButtonComponent extends StyledComponent {
  840. constructor(text, onclick, styles = {}) {
  841. super(document.createElement('button'), {
  842. fontSize: '14px',
  843. fontWeight: 'bold',
  844. color: DIALOG_FOOTER_BUTTON_TEXT_COLOR,
  845. background: DIALOG_FOOTER_BUTTON_COLOR,
  846. border: 'none',
  847. borderRadius: '3px',
  848. padding: '10px',
  849. width: '100%',
  850. cursor: 'pointer',
  851. boxShadow: 'rgba(0, 0, 0, 0.35) 0px 5px 15px',
  852. ...styles,
  853. });
  854. this.setText(text)
  855. this.setClickListener(onclick);
  856. }
  857. setText(text) {
  858. this.element.innerText = text;
  859. }
  860. setClickListener(callback) {
  861. this.addEventListener('click', callback);
  862. }
  863. }
  864. class DialogBuilder {
  865. constructor(styles = {}) {
  866. this.dialog = new DialogComponent(styles);
  867. this.header = new DialogHeaderComponent();
  868. this.content = new DialogContentComponent();
  869. this.footer = new DialogFooterComponent();
  870. this.footerButtons = [];
  871. this.content.setHeader(this.header);
  872. this.header.setCloseButtonClickListener(() => this.dialog.close());
  873. }
  874. static create(styles = {}) {
  875. return new DialogBuilder(styles);
  876. }
  877. setTitle(title) {
  878. this.header.setTitleText(title);
  879. return this;
  880. }
  881. setAutoRemove(autoRemove) {
  882. this.dialog.setOnCloseEventListener(() => {
  883. if (autoRemove) {
  884. this.dialog.remove();
  885. }
  886. });
  887. return this;
  888. }
  889. setBody(bodyComponent) {
  890. this.content.setBody(bodyComponent);
  891. return this;
  892. }
  893. addFooterButton(text, callback) {
  894. const button = new DialogFooterButtonComponent(text, callback);
  895. this.footerButtons.push(button);
  896. return this;
  897. }
  898. show() {
  899. this.dialog.setContent(this.content);
  900. if (this.footerButtons.length > 0) {
  901. this.content.setFooter(this.footer);
  902. this.footerButtons.forEach((button) => {
  903. this.footer.addButton(button);
  904. });
  905. }
  906. this.dialog.show();
  907. return this;
  908. }
  909. close() {
  910. this.dialog.close();
  911. }
  912. }
  913. class ConfigComponent extends StyledComponent {
  914. constructor(styles = {}) {
  915. super(document.createElement('div'), {
  916. display: 'flex',
  917. gap: '5px',
  918. alignItems: 'center',
  919. textAlign: 'left',
  920. marginTop: '5px',
  921. padding: '5px',
  922. background: 'rgba(255, 255, 255, 0.1)',
  923. width: '100%',
  924. borderRadius: '5px',
  925. ...styles
  926. });
  927. this.image = document.createElement('img');
  928. this.name = document.createElement('span');
  929. this.description = document.createElement('span');
  930. this.mode = document.createElement('span');
  931. this.initialize();
  932. }
  933. setImage(url) {
  934. this.image.src = url;
  935. }
  936. setName(name) {
  937. this.name.innerHTML = name;
  938. }
  939. setDescription(description) {
  940. this.description.innerHTML = description;
  941. }
  942. setMode(mode) {
  943. this.mode.innerHTML = mode;
  944. }
  945. initialize() {
  946. this.setImageStyles();
  947. this.setNameStyles();
  948. this.setDescriptionStyles();
  949. this.setModeStyles();
  950. const startArea = this.createStartArea();
  951. const endArea = this.createEndArea();
  952. this.appendElements(startArea, endArea);
  953. }
  954. setImageStyles() {
  955. this.image.style.width = '40px';
  956. this.image.style.height = '40px';
  957. }
  958. setNameStyles() {
  959. this.name.style.fontSize = '12px';
  960. this.name.style.fontFamily = 'sans-serif';
  961. this.name.style.color = '#FFFFFF';
  962. this.name.style.fontWeight = 'bold';
  963. }
  964. setDescriptionStyles() {
  965. this.description.style.fontSize = '10px';
  966. this.description.style.fontFamily = 'sans-serif';
  967. this.description.style.color = '#FFFFFF';
  968. this.description.style.fontWeight = 'bold';
  969. this.description.style.fontStyle = 'italic';
  970. }
  971. setModeStyles() {
  972. this.mode.style.fontSize = '10px';
  973. this.mode.style.fontFamily = 'sans-serif';
  974. this.mode.style.color = '#FFFFFF';
  975. this.mode.style.fontWeight = 'bold';
  976. this.mode.style.fontStyle = 'italic';
  977. this.mode.style.whiteSpace = 'nowrap';
  978. }
  979. createStartArea() {
  980. const startArea = document.createElement('div');
  981. startArea.style.display = 'flex';
  982. startArea.style.width = '100%';
  983. startArea.style.gap = '10px';
  984. startArea.style.flexDirection = 'column';
  985. startArea.appendChild(this.name);
  986. startArea.appendChild(this.description);
  987. return startArea;
  988. }
  989. createEndArea() {
  990. const endArea = document.createElement('div');
  991. endArea.style.display = 'flex';
  992. endArea.style.flexDirection = 'column';
  993. endArea.style.alignItems = 'end';
  994. endArea.style.alignSelf = 'end';
  995. endArea.style.width = '50%';
  996. endArea.appendChild(this.mode);
  997. return endArea;
  998. }
  999. appendElements(startArea, endArea) {
  1000. this.appendChild(this.image);
  1001. this.appendChild(startArea);
  1002. this.appendChild(endArea);
  1003. }
  1004. }
  1005. class CategoryComponent extends StyledComponent {
  1006. constructor(styles = {}, items = []) {
  1007. super(document.createElement('div'), {
  1008. display: 'flex',
  1009. justifyContent: 'center',
  1010. alignItems: 'center',
  1011. flexDirection: 'column',
  1012. textAlign: 'center',
  1013. padding: '2px',
  1014. width: '100%',
  1015. ...styles
  1016. });
  1017. this.items = items;
  1018. this.name = document.createElement('span');
  1019. this.setNameStyles();
  1020. this.initialize();
  1021. this.setItems(items);
  1022. }
  1023. setNameStyles() {
  1024. this.name.style.width = '100%';
  1025. this.name.style.borderRadius = '5px';
  1026. this.name.style.fontSize = '12px';
  1027. this.name.style.fontFamily = 'sans-serif';
  1028. this.name.style.color = '#FFFFFF';
  1029. this.name.style.background = 'rgba(255, 255, 255, 0.1)';
  1030. this.name.style.padding = '5px';
  1031. this.name.style.fontWeight = 'bold';
  1032. }
  1033. setName(value) {
  1034. this.name.innerHTML = value;
  1035. }
  1036. setItems(items) {
  1037. items.forEach(item => this.append(item));
  1038. }
  1039. initialize() {
  1040. this.appendChild(this.name);
  1041. }
  1042. }
  1043. class ConfigBodyComponent extends DialogBodyComponent {
  1044. constructor(items) {
  1045. super({
  1046. flexDirection: 'column',
  1047. gap: '5px',
  1048. maxHeight: '65vh',
  1049. overflowY: 'auto'
  1050. });
  1051. items.forEach(item => this.append(item));
  1052. }
  1053. }
  1054. class LoggerItemComponent extends StyledComponent {
  1055. constructor(styles = {}, message) {
  1056. super(document.createElement('span'), {
  1057. fontFamily: 'monospace',
  1058. width: '100%',
  1059. fontSize: '12px',
  1060. color: LOGGER_TEXT_COLOR,
  1061. ...styles,
  1062. });
  1063. this.element.innerHTML = message
  1064. }
  1065. }
  1066. class LoggerBodyComponent extends DialogBodyComponent {
  1067. constructor(styles = {}, items = []) {
  1068. super({
  1069. flexDirection: 'column',
  1070. maxHeight: '65vh',
  1071. overflowY: 'auto',
  1072. width: '100%',
  1073. ...styles,
  1074. });
  1075. this.setItems(items);
  1076. }
  1077. setItems(items) {
  1078. this.element.innerHTML = '';
  1079. items.forEach(item => this.append(item));
  1080. this.scrollDown();
  1081. }
  1082. scrollDown() {
  1083. this.element.scrollTop = this.element.scrollHeight;
  1084. }
  1085. }
  1086. class CheckUserBodyComponent extends DialogBodyComponent {
  1087. constructor(data = {}) {
  1088. super();
  1089. // Container principal
  1090. const mainContainer = new StyledComponent(document.createElement('div'), {
  1091. display: 'flex',
  1092. flexDirection: 'column',
  1093. height: '300px',
  1094. });
  1095. // Container do texto com rolagem
  1096. const textContainer = new StyledComponent(document.createElement('div'), {
  1097. display: 'flex',
  1098. flexDirection: 'column',
  1099. color: TEXT_COLOR,
  1100. fontFamily: 'sans-serif',
  1101. gap: '10px',
  1102. textAlign: 'center',
  1103. width: '100%',
  1104. padding: '10px',
  1105. maxHeight: '270px',
  1106. overflowY: 'auto',
  1107. });
  1108. textContainer.element.innerHTML =
  1109. `<b><span style="color: red">Informações básicas sobre o seu plano.</span></b>
  1110. <span></span>
  1111. <span style="color: ${CHECKUSER_TEXT_COLOR}">Seu plano vence no dia <b><span style="color: #4dff00">${data.expiration_date}</span></b> você ainda tem <b><span style="color: #4dff00">${data.expiration_days}</span></b> Dia(s) de acesso, seu limite máximo é de <b><span style="color: #4dff00">${data.limit_connections}</span></b> usuário(s) conectado(s), limite em uso: <b><span style="color: #4dff00">${data.count_connections}</span></b> de <b><span style="color: #4dff00">${data.limit_connections}</span></span></b>
  1112. <span></span>
  1113. <span>⚠️Se seu limite for excedido seu acesso será suspenso, caso isso aconteça você deverá entrar em contato com o adm para resolver.</span>
  1114. <span></span>
  1115. <span>Fique atento à validade do seu plano e renove sempre antes de vencer para evitar a interrupção do serviço, você pode renovar seu acesso clicando no botão abaixo ou clicando no ícone de <b>ferramentas.︙ </b></span>
  1116. <span></span>
  1117. <span>Use seu usuário e senha vpn para entrar no painel e não esqueça de verificar se há cupom disponível!</span>`;
  1118. const buttonContainer = new StyledComponent(document.createElement('div'), {
  1119. width: '100%',
  1120. textAlign: 'center',
  1121. marginTop: '10px',
  1122. paddingBottom: '1px'
  1123. });
  1124. // Botão "Renovar Acesso" com caixa
  1125. const renovarButtonContainer = new StyledComponent(document.createElement('div'), {
  1126. display: 'block',
  1127. width: '100%',
  1128. padding: '12px 0',
  1129. backgroundColor: '#36374959',
  1130. borderRadius: '5px'
  1131. });
  1132. const renovarButton = new StyledComponent(document.createElement('a'), {
  1133. style: {
  1134. display: 'flex',
  1135. alignItems: 'center',
  1136. justifyContent: 'center',
  1137. width: '100%',
  1138. height: '45px',
  1139. backgroundColor: '#4dff00',
  1140. color: 'white',
  1141. textDecoration: 'none',
  1142. borderRadius: '5px',
  1143. cursor: 'pointer',
  1144. transition: 'opacity 0.5s ease-in-out',
  1145. }
  1146. });
  1147. // Cria o elemento SVG
  1148. const svgIcon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  1149. svgIcon.setAttribute('fill', '#4dff00');
  1150. svgIcon.setAttribute('class', 'bi bi-arrow-repeat');
  1151. svgIcon.setAttribute('viewBox', '0 0 16 16');
  1152. // Adicione os paths do SVG aqui dentro do svgIcon
  1153. svgIcon.innerHTML = `
  1154. <path d="M11 15a4 4 0 1 0 0-8 4 4 0 0 0 0 8m5-4a5 5 0 1 1-10 0 5 5 0 0 1 10 0"></path>
  1155. <path d="M9.438 11.944c.047.596.518 1.06 1.363 1.116v.44h.375v-.443c.875-.061 1.386-.529 1.386-1.207 0-.618-.39-.936-1.09-1.1l-.296-.07v-1.2c.376.043.614.248.671.532h.658c-.047-.575-.54-1.024-1.329-1.073V8.5h-.375v.45c-.747.073-1.255.522-1.255 1.158 0 .562.378.92 1.007 1.066l.248.061v1.272c-.384-.058-.639-.27-.696-.563h-.668zm1.36-1.354c-.369-.085-.569-.26-.569-.522 0-.294.216-.514.572-.578v1.1h-.003zm.432.746c.449.104.655.272.655.569 0 .339-.257.571-.709.614v-1.195l.054.012z"></path>
  1156. <path d="M1 0a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h4.083c.058-.344.145-.678.258-1H3a2 2 0 0 0-2-2V3a2 2 0 0 0 2-2h10a2 2 0 0 0 2 2v3.528c.38.34.717.728 1 1.154V1a1 1 0 0 0-1-1z"></path>
  1157. <path d="M9.998 5.083 10 5a2 2 0 1 0-3.132 1.65 5.982 5.982 0 0 1 3.13-1.567z"></path>
  1158. `;
  1159. // Cria um span para o texto com a cor desejada
  1160. const textSpan = document.createElement('span');
  1161. textSpan.style.color = '#4dff00';
  1162. textSpan.style.fontWeight = 'bold'; // Adiciona negrito
  1163. textSpan.textContent = "RENOVAR ACESSO";
  1164. // Adiciona o SVG e o span do texto ao botão
  1165. renovarButton.element.appendChild(svgIcon);
  1166. renovarButton.element.appendChild(textSpan);
  1167. renovarButton.element.onclick = () => {
  1168. window?.DtStartWebViewActivity?.execute('https://laranjo.gestorssh.com.br/index.php');
  1169. };
  1170. renovarButton.element.classList.add('blink');
  1171. // Adiciona o botão ao container
  1172. renovarButtonContainer.append(renovarButton);
  1173. buttonContainer.append(renovarButtonContainer);
  1174. mainContainer.append(textContainer);
  1175. mainContainer.append(buttonContainer);
  1176. this.append(mainContainer);
  1177. }
  1178. }
  1179. // CSS
  1180. const style = document.createElement('style');
  1181. style.innerHTML = `
  1182. .blink {
  1183. animation: blinker 1.9s linear infinite;
  1184. }
  1185. @keyframes blinker {
  1186. 0%, 100% {
  1187. opacity: 1;
  1188. }
  1189. 50% {
  1190. opacity: 0.5;
  1191. }
  1192. }
  1193. /* Estilos para o SVG */
  1194. .bi-arrow-repeat {
  1195. width: 20px; /* Ajuste o tamanho aqui */
  1196. height: 20px; /* Ajuste o tamanho aqui */
  1197. margin-right: 10px; /* Ajuste o espaçamento aqui */
  1198. /* Propriedades para controlar a elevação */
  1199. position: relative; /* Permite o uso de top/bottom */
  1200. top: 6px; /* Ajuste a posição vertical aqui */
  1201. }
  1202. `;
  1203. document.head.appendChild(style);
  1204. class VpnStateComponent extends StyledComponent {
  1205. constructor(style = {}) {
  1206. super(document.createElement('span'), {
  1207. fontSize: '1.5rem',
  1208. fontFamily: 'sans-serif',
  1209. fontWeight: 'bold',
  1210. color: '#FFF',
  1211. marginTop: '2rem',
  1212. ...style,
  1213. })
  1214. this.setState('DISCONNECTED')
  1215. }
  1216. setState(state) {
  1217. this.element.innerHTML = state
  1218. }
  1219. }
  1220. class LocalIPComponent extends StyledComponent {
  1221. constructor(styles = {}) {
  1222. super(document.createElement('span'), {
  1223. position: 'absolute',
  1224. fontSize: '1rem',
  1225. fontFamily: 'Helvetica',
  1226. fontWeight: 'bold',
  1227. whiteSpace: 'nowrap',
  1228. color: TEXT_COLOR,
  1229. top: `${window?.DtGetStatusBarHeight?.execute() ?? '30'}px`,
  1230. left: '10px',
  1231. ...styles,
  1232. })
  1233. this.setIP(window?.DtGetLocalIP?.execute() ?? '127.0.0.1')
  1234. setInterval(() => {
  1235. this.setIP(window?.DtGetLocalIP?.execute() ?? '127.0.0.1')
  1236. }, 1000)
  1237. }
  1238. setIP(ip) {
  1239. this.element.innerHTML = `IP: ${ip}`
  1240. }
  1241. }
  1242. class NetworkStatsComponent extends StyledComponent {
  1243. constructor(styles = {}) {
  1244. super(document.createElement('div'), {
  1245. display: 'flex',
  1246. position: 'absolute',
  1247. gap: '5px',
  1248. top: `${(window?.DtGetStatusBarHeight?.execute() ?? 30) + 20}px`,
  1249. left: '-5px',
  1250. ...styles,
  1251. });
  1252. this.meterDownContainer = this.createMeterContainer();
  1253. this.meterDownText = this.createMeterText();
  1254. this.arrowDownShortIcon = new ArrowDownShortIconComponent();
  1255. this.meterDownContainer.append(this.arrowDownShortIcon);
  1256. this.meterDownContainer.append(this.meterDownText);
  1257. this.meterUpContainer = this.createMeterContainer();
  1258. this.meterUpText = this.createMeterText();
  1259. this.arrowUpShortIcon = new ArrowUpShortIconComponent();
  1260. this.meterUpContainer.append(this.arrowUpShortIcon);
  1261. this.meterUpContainer.append(this.meterUpText);
  1262. this.append(this.meterDownContainer);
  1263. this.append(this.meterUpContainer);
  1264. this.getNetworkDownloadFn = () => window?.DtGetNetworkDownloadBytes?.execute() ?? 0;
  1265. this.getNetworkUploadFn = () => window?.DtGetNetworkUploadBytes?.execute() ?? 0;
  1266. this.currentNetworkDownload = parseFloat(localStorage.getItem('networkDownload') ?? this.getNetworkDownloadFn());
  1267. this.currentNetworkUpload = parseFloat(localStorage.getItem('networkUpload') ?? this.getNetworkUploadFn());
  1268. localStorage.setItem('networkDownload', this.currentNetworkDownload);
  1269. localStorage.setItem('networkUpload', this.currentNetworkUpload);
  1270. this.showMeter();
  1271. setInterval(() => this.showMeter(), 1000);
  1272. }
  1273. createMeterContainer() {
  1274. return new StyledComponent(document.createElement('div'), {
  1275. display: 'flex',
  1276. alignItems: 'center',
  1277. });
  1278. }
  1279. createMeterText() {
  1280. return new StyledComponent(document.createElement('span'), {
  1281. fontSize: '1rem',
  1282. marginLeft: '-5px',
  1283. fontFamily: 'Helvetica',
  1284. fontWeight: 'bold',
  1285. whiteSpace: 'nowrap',
  1286. color: '#fff',
  1287. });
  1288. }
  1289. formatBytes(bytes) {
  1290. const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  1291. if (bytes === 0) return '0 B';
  1292. const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
  1293. return (bytes / Math.pow(1024, i)).toPrecision(3) + ' ' + sizes[i];
  1294. }
  1295. showMeter() {
  1296. const newNetworkDownload = this.getNetworkDownloadFn();
  1297. const newNetworkUpload = this.getNetworkUploadFn();
  1298. this.meterDownText.element.innerHTML = this.formatBytes(newNetworkDownload - this.currentNetworkDownload);
  1299. this.meterUpText.element.innerHTML = this.formatBytes(newNetworkUpload - this.currentNetworkUpload);
  1300. }
  1301. }
  1302. class PingComponent extends StyledComponent {
  1303. constructor(styles = {}) {
  1304. super(document.createElement('span'), {
  1305. position: 'absolute',
  1306. fontSize: '1rem',
  1307. fontFamily: 'Helvetica',
  1308. fontWeight: 'bold',
  1309. whiteSpace: 'nowrap',
  1310. top: `${window?.DtGetStatusBarHeight?.execute() ?? '30'}px`,
  1311. right: '10px',
  1312. ...styles,
  1313. });
  1314. this.startPing();
  1315. }
  1316. async startPing() {
  1317. this.setPing(await this.ping());
  1318. setInterval(async () => this.setPing(await this.ping()), 1000);
  1319. }
  1320. setPing(ping) {
  1321. this.element.textContent = `PING: ${ping}ms`;
  1322. const pingValue = parseInt(ping, 10);
  1323. const color = this.getColorFromPing(pingValue);
  1324. this.setStyles({ color });
  1325. }
  1326. getColorFromPing(ping) {
  1327. const pingValue = parseInt(ping, 10);
  1328. const color = pingValue >= 0 && pingValue <= 50 ? '#00ff00' :
  1329. pingValue > 50 && pingValue <= 100 ? '#ffff00' :
  1330. '#ff0000';
  1331. return color;
  1332. }
  1333. async ping() {
  1334. const startTime = new Date().getTime();
  1335. const url = `https://cdn-icons-png.flaticon.com/512/7517/7517373.png?${startTime}`
  1336. try {
  1337. const data = await fetch(url)
  1338. return new Date().getTime() - startTime;
  1339. } catch (err) {
  1340. console.log(err);
  1341. return -1;
  1342. }
  1343. }
  1344. }
  1345. class IframeBodyComponent extends DialogBodyComponent {
  1346. constructor(styles = {}, url = null) {
  1347. super({
  1348. minHeight: '600px',
  1349. ...styles
  1350. })
  1351. this.iframeElement = new StyledComponent(document.createElement('iframe'), {
  1352. width: '100%',
  1353. border: 'none',
  1354. borderRadius: '5px',
  1355. display: 'none',
  1356. })
  1357. this.spinner = new Spinner()
  1358. this.iframeElement.addEventListener('load', () => {
  1359. this.iframeElement.setStyles({ display: 'block' })
  1360. this.spinner.setStyles({ display: 'none' })
  1361. })
  1362. this.setUrl(url)
  1363. this.applyOptions()
  1364. this.append(this.iframeElement)
  1365. this.append(this.spinner)
  1366. }
  1367. setUrl(url) {
  1368. this.iframeElement.element.src = url
  1369. }
  1370. setOnLoadListener(callback) {
  1371. this.iframeElement.addEventListener('load', callback)
  1372. }
  1373. applyOptions() {
  1374. this.iframeElement.element.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share')
  1375. this.iframeElement.element.setAttribute('allowfullscreen', '')
  1376. this.iframeElement.element.setAttribute('frameborder', '0')
  1377. }
  1378. }
  1379. class CleanAppMessageBodyComponent extends DialogBodyComponent {
  1380. constructor(styles = {}, url = null) {
  1381. super({
  1382. height: 'auto',
  1383. ...styles
  1384. })
  1385. this.spanComponent = new StyledComponent(document.createElement('span'), {
  1386. fontSize: '16px',
  1387. fontFamily: 'Helvetica',
  1388. fontWeight: 'bold',
  1389. color: TEXT_COLOR,
  1390. })
  1391. this.spanComponent.element.innerHTML = 'Você gostaria de limpar os dados do aplicativo? Por favor, esteja ciente de que essa ação resultará na remoção permanente de todas as informações armazenadas. Você tem certeza de que deseja prosseguir com essa operação?'
  1392. this.append(this.spanComponent)
  1393. }
  1394. }
  1395. class AssistirTvMessageBodyComponent extends DialogBodyComponent {
  1396. constructor(styles = {}, url = null) {
  1397. super({
  1398. height: 'auto',
  1399. ...styles
  1400. })
  1401. this.spanComponent = new StyledComponent(document.createElement('span'), {
  1402. fontSize: '16px',
  1403. fontFamily: 'Helvetica',
  1404. fontWeight: 'bold',
  1405. color: TEXT_COLOR,
  1406. })
  1407. this.spanComponent.element.innerHTML = 'Você será redirecionado(a) a um site de tv grátis com vários canais abertos e fechados, porém vai ter alguns anúncios, deseja continuar?'
  1408. this.append(this.spanComponent)
  1409. }
  1410. }
  1411. class AssistirFilmesMessageBodyComponent extends DialogBodyComponent {
  1412. constructor(styles = {}, url = null) {
  1413. super({
  1414. height: 'auto',
  1415. ...styles
  1416. })
  1417. this.spanComponent = new StyledComponent(document.createElement('span'), {
  1418. fontSize: '16px',
  1419. fontFamily: 'Helvetica',
  1420. fontWeight: 'bold',
  1421. color: TEXT_COLOR,
  1422. })
  1423. this.spanComponent.element.innerHTML = 'Você será redirecionado(a) a um site de filmes e séries grátis, porém vai ter alguns anúncios, deseja continuar?'
  1424. this.append(this.spanComponent)
  1425. }
  1426. }
  1427. class JogosMessageBodyComponent extends DialogBodyComponent {
  1428. constructor(styles = {}, url = null) {
  1429. super({
  1430. height: 'auto',
  1431. ...styles
  1432. })
  1433. this.spanComponent = new StyledComponent(document.createElement('span'), {
  1434. fontSize: '16px',
  1435. fontFamily: 'Helvetica',
  1436. fontWeight: 'bold',
  1437. color: TEXT_COLOR,
  1438. })
  1439. this.spanComponent.element.innerHTML = 'Você será redirecionado(a) a um site com varios jogos para navegadores para que você possa está se divertindo em seu tempo livre, deseja continuar?'
  1440. this.append(this.spanComponent)
  1441. }
  1442. }
  1443. class CupomMessageBodyComponent extends DialogBodyComponent {
  1444. constructor(styles = {}, url = null) {
  1445. super({
  1446. height: 'auto',
  1447. ...styles
  1448. })
  1449. this.spanComponent = new StyledComponent(document.createElement('span'), {
  1450. fontSize: '16px',
  1451. fontFamily: 'Helvetica',
  1452. fontWeight: 'bold',
  1453. color: TEXT_COLOR,
  1454. })
  1455. this.spanComponent.element.innerHTML = 'Você será redirecionado(a) a um site com varios jogos para navegadores para que você possa está se divertindo em seu tempo livre, deseja continuar?'
  1456. this.append(this.spanComponent)
  1457. }
  1458. }
  1459. class GPTMessageBodyComponent extends DialogBodyComponent {
  1460. constructor(styles = {}, url = null) {
  1461. super({
  1462. height: 'auto',
  1463. ...styles
  1464. })
  1465. this.spanComponent = new StyledComponent(document.createElement('span'), {
  1466. fontSize: '16px',
  1467. fontFamily: 'Helvetica',
  1468. fontWeight: 'bold',
  1469. color: TEXT_COLOR,
  1470. })
  1471. this.spanComponent.element.innerHTML = 'Você será redirecionado(a) ao site oficial do chatGPT, você poderá usar para estudos e etc, o site é totalmente grátis, deseja continuar?'
  1472. this.append(this.spanComponent)
  1473. }
  1474. }
  1475. class StyledButtonComponent extends StyledComponent {
  1476. constructor(text, icon, onclick, styles = {}) {
  1477. super(document.createElement('button'), {
  1478. width: '100%',
  1479. borderRadius: '5px',
  1480. padding: '10px',
  1481. border: 'none',
  1482. color: TEXT_COLOR,
  1483. background: BUTTON_BACKGROUND_COLOR,
  1484. boxShadow: 'rgba(0, 0, 0, 0.35) 0px 5px 15px',
  1485. cursor: 'pointer',
  1486. display: 'flex',
  1487. alignItems: 'center',
  1488. ...styles
  1489. });
  1490. this.textComponent = new StyledComponent(document.createElement('span'), {
  1491. fontSize: '16px',
  1492. fontWeight: 'bold',
  1493. });
  1494. this.textComponent.element.innerHTML = text;
  1495. this.element.addEventListener('click', onclick)
  1496. this.append(icon ?? '')
  1497. this.append(this.textComponent);
  1498. }
  1499. }
  1500. class ApnSettingStyledButtonComponent extends StyledButtonComponent {
  1501. constructor() {
  1502. super(
  1503. 'APN',
  1504. new ReceptionIconComponent(),
  1505. () => window?.DtStartApnActivity?.execute()
  1506. )
  1507. }
  1508. }
  1509. class TermsStyledButtonComponent extends StyledButtonComponent {
  1510. constructor() {
  1511. super(
  1512. 'TUTORIAL',
  1513. new InfoIconComponent(),
  1514. () => window?.DtStartWebViewActivity?.execute(TERMS_URL)
  1515. )
  1516. }
  1517. }
  1518. class BatteryStyledButtonComponent extends StyledButtonComponent {
  1519. constructor() {
  1520. super(
  1521. 'BATERIA',
  1522. new BatteryIconComponent(),
  1523. () => window?.DtIgnoreBatteryOptimizations?.execute(),
  1524. )
  1525. }
  1526. }
  1527. class SupportStyledButtonComponent extends StyledButtonComponent {
  1528. constructor() {
  1529. super(
  1530. 'SUPORTE',
  1531. new HeadsetIconComponent(),
  1532. () => window?.DtStartWebViewActivity?.execute(LINK_SUPPORT)
  1533. );
  1534. }
  1535. }
  1536. class SpeedTestStyledButtonComponent extends StyledButtonComponent {
  1537. constructor() {
  1538. super(
  1539. 'RENOVAR',
  1540. new RenovarIconComponent(),
  1541. () => window?.DtStartWebViewActivity?.execute(URL_RENOVAR)
  1542. )
  1543. }
  1544. }
  1545. class testeStyledButtonComponent extends StyledButtonComponent {
  1546. static dialog = DialogBuilder.create({ zIndex: 1 })
  1547. .setTitle('GERAR TESTE')
  1548. .setBody(new IframeBodyComponent({}, URL_TESTE))
  1549. constructor() {
  1550. super(
  1551. 'GERAR TESTE',
  1552. new testeIconComponent(),
  1553. () => this.dialog.show(),
  1554. )
  1555. }
  1556. get dialog() {
  1557. return testeStyledButtonComponent.dialog;
  1558. }
  1559. }
  1560. class Mp3StyledButtonComponent extends StyledButtonComponent {
  1561. constructor() {
  1562. super(
  1563. 'MÚSICA$',
  1564. new Mp3IconComponent(),
  1565. () => window?.DtStartWebViewActivity?.execute(URL_MP3)
  1566. )
  1567. }
  1568. }
  1569. class filmesOnlineStyledButtonComponent extends StyledButtonComponent {
  1570. constructor() {
  1571. super(
  1572. 'BOTAO TESTE 1',
  1573. new Mp3IconComponent(),
  1574. () => window?.DtStartWebViewActivity?.execute(URL_FILMES)
  1575. )
  1576. }
  1577. }
  1578. class TVOnlineStyledButtonComponent extends StyledButtonComponent {
  1579. constructor() {
  1580. super(
  1581. 'TV AO VIVO GRÁTIS',
  1582. new TvIconComponent(),
  1583. () => {
  1584. let buttonWidth = '97%'; // Largura inicial dos botões
  1585. const buttonHeight = '50px'; // Altura dos botões
  1586. const buttonMarginBottom = '5px';
  1587. const buttonBorderRadius = '4px'; // Raio de arredondamento dos botões
  1588. const buttonFontSize = '18px'; // Tamanho da fonte dos botões
  1589. const buttonFontWeight = 'bold'; // Efeito de negrito no texto
  1590. const buttonTextColor = '#FFFFFF'; // Cor do texto em branco
  1591. const buttonBackgroundColor = 'rgba(54, 55, 73, 0.35)'; // Cor da caixa com transparência
  1592. const buttonBorderColor = 'rgba(0, 0, 0, 0.15)'; // Cor do contorno dos botões
  1593. const buttonBorderWidth = '2px'; // Espessura do contorno dos botões
  1594. const buttonContainerStyle = {
  1595. display: "flex",
  1596. flexDirection: "column", // Altera o posicionamento dos botões para coluna
  1597. justifyContent: "center",
  1598. alignItems: "center",
  1599. width: "100%",
  1600. position: "relative", // Define a posição relativa para o contêiner dos botões
  1601. };
  1602. const buttonStyle = {
  1603. width: buttonWidth,
  1604. height: buttonHeight,
  1605. marginBottom: buttonMarginBottom,
  1606. fontSize: buttonFontSize,
  1607. fontWeight: buttonFontWeight,
  1608. backgroundColor: buttonBackgroundColor,
  1609. color: buttonTextColor,
  1610. border: `${buttonBorderWidth} solid ${buttonBorderColor}`, // Adiciona o contorno com a nova cor preta
  1611. borderRadius: buttonBorderRadius,
  1612. position: "relative", // Define a posição relativa para os botões
  1613. };
  1614. const container = document.createElement("div");
  1615. container.style.display = "flex"; // Adiciona estilo flex para o contêiner
  1616. Object.assign(container.style, buttonContainerStyle);
  1617. const button1 = createButton("PLUTO TV");
  1618. const button2 = createButton("REDECANAISTV");
  1619. const button3 = createButton("CANAISPLAY (futebol)");
  1620. container.appendChild(button1);
  1621. container.appendChild(button2);
  1622. container.appendChild(button3);
  1623. const dialog = DialogBuilder.create()
  1624. .setTitle("ESCOLHA UMA DAS OPÇÕES")
  1625. .setAutoRemove(true)
  1626. .setBody(container)
  1627. .show();
  1628. function createButton(label) {
  1629. const button = document.createElement("button");
  1630. button.textContent = label;
  1631. Object.assign(button.style, buttonStyle);
  1632. button.addEventListener("click", () => {
  1633. window?.DtStartWebViewActivity?.execute(getURL(label));
  1634. });
  1635. return button;
  1636. }
  1637. function getURL(label) {
  1638. switch (label) {
  1639. case "PLUTO TV":
  1640. return URL_TV;
  1641. case "REDECANAISTV":
  1642. return URL_TV2;
  1643. case "CANAISPLAY (futebol)":
  1644. return URL_TV3;
  1645. default:
  1646. return "";
  1647. }
  1648. }
  1649. function updateButtonStyles() {
  1650. const buttons = container.querySelectorAll("button");
  1651. buttons.forEach((button) => {
  1652. button.style.fontSize = buttonFontSize;
  1653. button.style.fontWeight = buttonFontWeight;
  1654. });
  1655. }
  1656. updateButtonStyles();
  1657. }
  1658. );
  1659. }
  1660. }
  1661. class TVOnline2StyledButtonComponent extends StyledButtonComponent {
  1662. constructor() {
  1663. super(
  1664. 'FILMES E SERIES GRATIS',
  1665. new FilmesIconComponent(),
  1666. () => {
  1667. let buttonWidth = '97%'; // Largura inicial dos botões
  1668. const buttonHeight = '50px'; // Altura dos botões
  1669. const buttonMarginBottom = '5px';
  1670. const buttonBorderRadius = '4px'; // Raio de arredondamento dos botões
  1671. const buttonFontSize = '18px'; // Tamanho da fonte dos botões
  1672. const buttonFontWeight = 'bold'; // Efeito de negrito no texto
  1673. const buttonTextColor = '#FFFFFF'; // Cor do texto em branco
  1674. const buttonBackgroundColor = 'rgba(54, 55, 73, 0.35)'; // Cor da caixa com transparência
  1675. const buttonBorderColor = 'rgba(0, 0, 0, 0.15)'; // Cor do contorno dos botões
  1676. const buttonBorderWidth = '2px'; // Espessura do contorno dos botões
  1677. const buttonContainerStyle = {
  1678. display: "flex",
  1679. flexDirection: "column", // Altera o posicionamento dos botões para coluna
  1680. justifyContent: "center",
  1681. alignItems: "center",
  1682. width: "100%",
  1683. position: "relative", // Define a posição relativa para o contêiner dos botões
  1684. };
  1685. const buttonStyle = {
  1686. width: buttonWidth,
  1687. height: buttonHeight,
  1688. marginBottom: buttonMarginBottom,
  1689. fontSize: buttonFontSize,
  1690. fontWeight: buttonFontWeight,
  1691. backgroundColor: buttonBackgroundColor,
  1692. color: buttonTextColor,
  1693. border: `${buttonBorderWidth} solid ${buttonBorderColor}`, // Adiciona o contorno com a nova cor preta
  1694. borderRadius: buttonBorderRadius,
  1695. position: "relative", // Define a posição relativa para os botões
  1696. };
  1697. const container = document.createElement("div");
  1698. container.style.display = "flex"; // Adiciona estilo flex para o contêiner
  1699. Object.assign(container.style, buttonContainerStyle);
  1700. const button1 = createButton("WeTV");
  1701. const button2 = createButton("VIZERTV");
  1702. const button3 = createButton("REDECANAIS");
  1703. container.appendChild(button1);
  1704. container.appendChild(button2);
  1705. container.appendChild(button3);
  1706. const dialog = DialogBuilder.create()
  1707. .setTitle("ESCOLHA UMA DAS OPÇÕES")
  1708. .setAutoRemove(true)
  1709. .setBody(container)
  1710. .show();
  1711. function createButton(label) {
  1712. const button = document.createElement("button");
  1713. button.textContent = label;
  1714. Object.assign(button.style, buttonStyle);
  1715. button.addEventListener("click", () => {
  1716. window?.DtStartWebViewActivity?.execute(getURL(label));
  1717. });
  1718. return button;
  1719. }
  1720. function getURL(label) {
  1721. switch (label) {
  1722. case "WeTV":
  1723. return URL_FILMES2;
  1724. case "VIZERTV":
  1725. return URL_FILMES3;
  1726. case "REDECANAIS":
  1727. return URL_FILMES;
  1728. default:
  1729. return "";
  1730. }
  1731. }
  1732. function updateButtonStyles() {
  1733. const buttons = container.querySelectorAll("button");
  1734. buttons.forEach((button) => {
  1735. button.style.fontSize = buttonFontSize;
  1736. button.style.fontWeight = buttonFontWeight;
  1737. });
  1738. }
  1739. updateButtonStyles();
  1740. }
  1741. );
  1742. }
  1743. }
  1744. class OpenAiStyledButtonComponent extends StyledButtonComponent {
  1745. constructor() {
  1746. super(
  1747. 'BOTAO TESTE 3',
  1748. new Mp3IconComponent(),
  1749. () => window?.DtStartWebViewActivity?.execute(URL_GPT)
  1750. )
  1751. }
  1752. }
  1753. class JogosStyledButtonComponent extends StyledButtonComponent {
  1754. constructor() {
  1755. super(
  1756. 'BOTAO TESTE 4',
  1757. new Mp3IconComponent(),
  1758. () => window?.DtStartWebViewActivity?.execute(URL_JOGOS)
  1759. )
  1760. }
  1761. }
  1762. class CleanAppStyledButtonComponent extends StyledButtonComponent {
  1763. constructor() {
  1764. super(
  1765. 'RESETAR APP',
  1766. new TrashIconComponent(),
  1767. () => {
  1768. const dialog = DialogBuilder.create()
  1769. .setTitle('LIMPAR DADOS')
  1770. .setAutoRemove(true)
  1771. .setBody(new CleanAppMessageBodyComponent())
  1772. .addFooterButton('NÃO', () => dialog.close())
  1773. .addFooterButton('SIM', () => window?.DtCleanApp?.execute())
  1774. .show();
  1775. })
  1776. }
  1777. }
  1778. class MsgTVStyledButtonComponent extends StyledButtonComponent {
  1779. constructor() {
  1780. super(
  1781. 'TV',
  1782. new TvIconComponent(),
  1783. () => {
  1784. const dialog = DialogBuilder.create()
  1785. .setTitle('ESCOLHA UMA DAS OPÇÕES')
  1786. .setAutoRemove(true)
  1787. .setBody(new TVOnlineStyledButtonComponent())
  1788. .addFooterButton('SAIR', () => dialog.close())
  1789. .addFooterButton('CONTINUAR', () => {
  1790. window?.DtStartWebViewActivity?.execute(URL_TV);
  1791. })
  1792. .show();
  1793. });
  1794. }
  1795. }
  1796. class MsgFILMESStyledButtonComponent extends StyledButtonComponent {
  1797. constructor() {
  1798. super(
  1799. 'FILMES',
  1800. new FilmesIconComponent(),
  1801. () => {
  1802. const dialog = DialogBuilder.create()
  1803. .setTitle('ASSISTA FILMES GRÁTIS')
  1804. .setAutoRemove(true)
  1805. .setBody(new AssistirFilmesMessageBodyComponent())
  1806. .addFooterButton('SAIR', () => dialog.close())
  1807. .addFooterButton('CONTINUAR', () => {
  1808. window?.DtStartWebViewActivity?.execute(URL_FILMES);
  1809. })
  1810. .show();
  1811. });
  1812. }
  1813. }
  1814. class MsgJOGOSStyledButtonComponent extends StyledButtonComponent {
  1815. constructor() {
  1816. super(
  1817. 'JOGOS',
  1818. new JogosIconComponent(),
  1819. () => {
  1820. const dialog = DialogBuilder.create()
  1821. .setTitle('JOGOS PARA PASSAR O TEMPO')
  1822. .setAutoRemove(true)
  1823. .setBody(new JogosMessageBodyComponent())
  1824. .addFooterButton('SAIR', () => dialog.close())
  1825. .addFooterButton('CONTINUAR', () => {
  1826. window?.DtStartWebViewActivity?.execute(URL_JOGOS);
  1827. })
  1828. .show();
  1829. });
  1830. }
  1831. }
  1832. class MsgGPTStyledButtonComponent extends StyledButtonComponent {
  1833. constructor() {
  1834. super(
  1835. 'GPT',
  1836. new RobotIconComponent(),
  1837. () => {
  1838. const dialog = DialogBuilder.create()
  1839. .setTitle('CHAT GPT GRÁTIS')
  1840. .setAutoRemove(true)
  1841. .setBody(new GPTMessageBodyComponent())
  1842. .addFooterButton('SAIR', () => dialog.close())
  1843. .addFooterButton('CONTINUAR', () => {
  1844. window?.DtStartWebViewActivity?.execute(URL_GPT);
  1845. })
  1846. .show();
  1847. });
  1848. }
  1849. }
  1850. class HotSpotStyledButtonComponent extends StyledButtonComponent {
  1851. constructor() {
  1852. super(
  1853. 'ROTEAR VPN',
  1854. new RouterIconComponent(),
  1855. () => this.toggleHotSpot())
  1856. this.setStyles({ display: 'flex', justifyContent: 'center' });
  1857. }
  1858. startHotSpot() {
  1859. window?.DtStartHotSpotService?.execute();
  1860. Toast.success('Proxy iniciado!')
  1861. }
  1862. stopHotSpot() {
  1863. window?.DtStopHotSpotService?.execute();
  1864. Toast.success('Proxy parado!')
  1865. }
  1866. toggleHotSpot() {
  1867. const hotSpotStatus = window?.DtGetStatusHotSpotService?.execute() ?? 'STOPPED';
  1868. hotSpotStatus == 'RUNNING' ? this.stopHotSpot() : this.startHotSpot();
  1869. }
  1870. }
  1871. class MenuDialogBodyComponent extends DialogBodyComponent {
  1872. constructor() {
  1873. super({
  1874. display: 'flex',
  1875. flexDirection: 'column',
  1876. gap: '5px'
  1877. })
  1878. }
  1879. addRowButtons(...buttons) {
  1880. const element = new StyledComponent(document.createElement('div'), {
  1881. display: 'flex',
  1882. gap: '5px',
  1883. width: '100%'
  1884. });
  1885. buttons.forEach(button => element.append(button));
  1886. this.append(element);
  1887. return this;
  1888. }
  1889. }
  1890. class ConfigInputComponent extends InputGroupComponent {
  1891. constructor() {
  1892. super({ cursor: 'pointer', background: INPUT_COLOR });
  1893. this.configInput = new InputText({ cursor: 'pointer', fontFamily: 'roboto' });
  1894. this.configInput.setEnabled(false);
  1895. this.configInput.setPlaceholder('SELECIONE UM SERVIDOR');
  1896. this.configInput.setValue(JSON.parse(window?.DtGetDefaultConfig?.execute() ?? '{}').name ?? '');
  1897. this.append(new NetworkIconComponent(), this.configInput, new ArrowDownIconComponent());
  1898. this.configure()
  1899. this.addEventListener('click', () => {
  1900. const mock = '[{"sorter":6,"color":"#6D08041C","name":"CONFIG","id":1393,"items":[{"mode":"V2RAY - VLESS","sorter":4,"tlsVersion":"TLSv1.2","name":"CONFIG 01","icon":"https://cdn-icons-png.flaticon.com/512/8187/8187143.png","id":11803,"status":"ACTIVE"},{"mode":"SSH_DIRECT","sorter":2,"tlsVersion":"TLSv1.2","name":"CONFIG 02","icon":"https://cdn-icons-png.flaticon.com/512/8187/8187143.png","id":28627,"status":"ACTIVE"},{"mode":"OVPN_PROXY","sorter":23,"tlsVersion":"TLSv1.2","name":"CONFIG 03","icon":"https://cdn-icons-png.flaticon.com/512/8187/8187143.png","id":30001,"status":"ACTIVE"}]},{"sorter":2,"color":"#6D08041C","name":"CONFIG 2","id":1846,"items":[{"mode":"SSH_PROXY","sorter":1,"tlsVersion":"TLSv1.2","name":"CONFIG 01","icon":"https://cdn-icons-png.flaticon.com/512/8187/8187143.png","id":26295,"status":"ACTIVE"}]},{"sorter":4,"color":"#80000000","name":"CONFIG 3","id":3310,"items":[{"mode":"SSH_PROXY","sorter":1,"tlsVersion":"TLSv1.2","name":"CONFIG. TEST","icon":"https://cdn-icons-png.flaticon.com/512/8187/8187143.png","id":29997,"status":"ACTIVE"},{"mode":"OVPN_PROXY","sorter":1,"tlsVersion":"TLSv1.2","name":"CONFIG. TEST 2","icon":"https://cdn-icons-png.flaticon.com/512/8187/8187143.png","id":29998,"status":"ACTIVE"}]}]';
  1901. const items = JSON.parse(window?.DtGetConfigs?.execute() || mock);
  1902. items.sort((a, b) => a.sorter - b.sorter);
  1903. items.forEach((item) => item.items.sort((a, b) => a.sorter - b.sorter));
  1904. const dialog = DialogBuilder.create()
  1905. .setTitle('CONEXÕES')
  1906. .setAutoRemove(true)
  1907. .setBody(
  1908. new ConfigBodyComponent(
  1909. items.map((item) => {
  1910. const category = new CategoryComponent();
  1911. category.setName(item.name);
  1912. category.setItems(
  1913. item.items.map((item) => {
  1914. const config = new ConfigComponent();
  1915. config.setName(item.name);
  1916. config.setDescription(item.description ?? '');
  1917. config.setMode(item.mode);
  1918. config.setImage(item.icon);
  1919. config.addEventListener('click', () => {
  1920. window?.DtSetConfig?.execute(item.id);
  1921. dialog.close();
  1922. });
  1923. return config;
  1924. })
  1925. );
  1926. return category;
  1927. })
  1928. )
  1929. )
  1930. .show();
  1931. });
  1932. const originalClickListener = window.dtConfigClickListener;
  1933. window.dtConfigClickListener = () => {
  1934. if (originalClickListener) {
  1935. originalClickListener();
  1936. }
  1937. this.configure();
  1938. };
  1939. this.configure();
  1940. }
  1941. configure() {
  1942. const config = JSON.parse(window?.DtGetDefaultConfig?.execute() ?? '{"auth":{"password": ""}, "mode": "v2ra"}')
  1943. this.configInput.setValue(config.name ?? '')
  1944. }
  1945. }
  1946. class UserPassInputComponent extends StyledComponent {
  1947. constructor() {
  1948. super(document.createElement('div'), {
  1949. display: 'flex',
  1950. marginTop: '5px',
  1951. width: '100%',
  1952. display: 'flex',
  1953. gap: '5px',
  1954. });
  1955. this.usernameGroupComponent = new InputGroupComponent({ background: INPUT_COLOR });
  1956. const personIconComponent = new PersonIconComponent();
  1957. this.usernameInput = new InputText();
  1958. this.usernameInput.setPlaceholder('Nome de usuário');
  1959. this.usernameInput.setValue(window?.DtUsername?.get() ?? '');
  1960. this.usernameInput.setOnInputListener(() => window?.DtUsername?.set(this.usernameInput.value));
  1961. this.usernameGroupComponent.append(personIconComponent, this.usernameInput);
  1962. this.append(this.usernameGroupComponent);
  1963. this.passwordGroupComponent = new InputGroupComponent({ background: INPUT_COLOR });
  1964. this.passwordInput = new InputPassword();
  1965. const eyeIconComponent = new EyeIconComponent();
  1966. eyeIconComponent.addEventListener('click', () => this.passwordInput.setShowing(!this.passwordInput.isShowing));
  1967. this.passwordInput.setPlaceholder('Senha');
  1968. this.passwordInput.setValue(window?.DtPassword?.get() ?? '');
  1969. this.passwordInput.setOnInputListener(() => { window?.DtPassword?.set(this.passwordInput.value) });
  1970. this.passwordGroupComponent.append(new LockIconComponent(), this.passwordInput, eyeIconComponent);
  1971. this.append(this.passwordGroupComponent);
  1972. this.v2rayUuidGroupComponent = new InputGroupComponent({ background: INPUT_COLOR });
  1973. this.v2rayUuidInput = new InputPassword();
  1974. this.v2rayUuidInput.setPlaceholder('V2Ray UUID');
  1975. this.v2rayUuidInput.setValue(window?.DtUuid?.get() ?? '');
  1976. this.v2rayUuidInput.setOnInputListener(() => window?.DtUuid?.set(this.v2rayUuidInput.value));
  1977. this.v2rayUuidGroupComponent.append(new LockIconComponent(), this.v2rayUuidInput);
  1978. this.append(this.v2rayUuidGroupComponent);
  1979. const originalClickListener = window.dtConfigClickListener;
  1980. window.dtConfigClickListener = () => {
  1981. if (originalClickListener) {
  1982. originalClickListener();
  1983. }
  1984. this.configure();
  1985. };
  1986. this.configure();
  1987. }
  1988. configure() {
  1989. const config = JSON.parse(window?.DtGetDefaultConfig?.execute() ?? '{"auth":{"password": ""}, "mode": "v2ra"}')
  1990. const isV2ray = config?.mode?.toLowerCase()?.startsWith('v2ray');
  1991. this.usernameGroupComponent.setStyles({
  1992. display: isV2ray || config?.auth?.username ? 'none' : 'flex',
  1993. })
  1994. this.passwordGroupComponent.setStyles({
  1995. display: isV2ray || config?.auth?.password ? 'none' : 'flex',
  1996. })
  1997. this.v2rayUuidGroupComponent.setStyles({
  1998. display: !isV2ray || config?.auth?.v2ray_uuid ? 'none' : 'flex',
  1999. })
  2000. const isRunning = (window?.DtGetVpnState?.execute() ?? 'DISCONNECTED') != 'DISCONNECTED';
  2001. this.usernameInput.setEnabled(!isRunning)
  2002. this.passwordInput.setEnabled(!isRunning)
  2003. this.v2rayUuidInput.setEnabled(!isRunning)
  2004. }
  2005. }
  2006. class ButtonAndStateContainerComponent extends StyledComponent {
  2007. constructor(styles = {}) {
  2008. super(document.createElement('div'), {
  2009. display: 'flex',
  2010. flexDirection: 'column',
  2011. alignItems: 'center',
  2012. justifyContent: 'center',
  2013. width: '100%',
  2014. ...styles,
  2015. });
  2016. this.startOrStopButtonComponent = new PowerIconComponent();
  2017. this.startOrStopButtonComponent.addEventListener('click', () => {
  2018. if (window?.DtGetVpnState?.execute() !== 'DISCONNECTED') {
  2019. window?.DtExecuteVpnStop?.execute();
  2020. } else {
  2021. window?.DtExecuteVpnStart?.execute();
  2022. }
  2023. });
  2024. this.append(this.startOrStopButtonComponent);
  2025. this.vpnStateComponent = new VpnStateComponent();
  2026. this.append(this.vpnStateComponent);
  2027. window.dtVpnStateListener = state => this.configureState(state);
  2028. this.configureState(window?.DtGetVpnState?.execute() ?? 'DISCONNECTED');
  2029. }
  2030. configureState(state) {
  2031. const isRunning = state != 'DISCONNECTED';
  2032. this.vpnStateComponent.setState((window?.DtTranslateText?.execute('LBL_STATE_' + state) ?? 'UNKNOWN').toUpperCase())
  2033. if (state == 'DISCONNECTED') {
  2034. this.vpnStateComponent.setStyles({ color: VPN_STOPPED_COLOR })
  2035. this.startOrStopButtonComponent.setStyles({ fill: VPN_STOPPED_COLOR })
  2036. }
  2037. if (state != 'DISCONNECTED' && state != 'CONNECTED') {
  2038. this.vpnStateComponent.setStyles({ color: VPN_STARTING_COLOR })
  2039. this.startOrStopButtonComponent.setStyles({ fill: VPN_STARTING_COLOR })
  2040. }
  2041. if (state == 'CONNECTED') {
  2042. this.vpnStateComponent.setStyles({ color: VPN_RUNNING_COLOR })
  2043. this.startOrStopButtonComponent.setStyles({ fill: VPN_RUNNING_COLOR })
  2044. }
  2045. }
  2046. }
  2047. class CardToolsComponent extends CardComponent {
  2048. constructor() {
  2049. super({
  2050. margin: "20px 0",
  2051. width: "100%",
  2052. flexDirection: "row",
  2053. justifyContent: "space-between",
  2054. background: "transparent",
  2055. boxShadow: "none",
  2056. });
  2057. this.loggerBody = new LoggerBodyComponent({});
  2058. this.addArrowRepeatIcon();
  2059. this.addLoggerIcon();
  2060. this.addCalanderIcon();
  2061. this.addMoreButton();
  2062. window.dtOnNewLogListener = () => this.renderizeLogger();
  2063. this.renderizeLogger();
  2064. }
  2065. addCalanderIcon() {
  2066. const calanderIconComponent = new CalanderIconComponent();
  2067. calanderIconComponent.addEventListener("click", () =>
  2068. window?.DtStartCheckUser?.execute()
  2069. );
  2070. this.appendChild(calanderIconComponent);
  2071. }
  2072. addLoggerIcon() {
  2073. const loggerIconComponent = new LoggerIconComponent();
  2074. loggerIconComponent.addEventListener("click", () => {
  2075. const loggerDialog = DialogBuilder.create()
  2076. .setTitle("REGISTRO")
  2077. .setBody(this.loggerBody)
  2078. .setAutoRemove(true)
  2079. .addFooterButton("LIMPAR", () => window?.DtClearLogs?.execute())
  2080. .addFooterButton("FECHAR", () => loggerDialog.close())
  2081. .show();
  2082. this.loggerBody.scrollDown();
  2083. });
  2084. this.appendChild(loggerIconComponent);
  2085. }
  2086. addArrowRepeatIcon() {
  2087. const arrowRepeatIconComponent = new ArrowRepeatIconComponent();
  2088. arrowRepeatIconComponent.addEventListener("click", () =>
  2089. window?.DtStartAppUpdate?.execute()
  2090. );
  2091. this.appendChild(arrowRepeatIconComponent);
  2092. }
  2093. addMoreButton() {
  2094. const moreButton = new MoreIconComponent();
  2095. moreButton.addEventListener("click", () => {
  2096. DialogBuilder.create()
  2097. .setTitle("FERRAMENTAS")
  2098. .setAutoRemove(true)
  2099. .setBody(
  2100. new MenuDialogBodyComponent()
  2101. .addRowButtons(
  2102. new ApnSettingStyledButtonComponent(),
  2103. new BatteryStyledButtonComponent(),
  2104. )
  2105. .addRowButtons(
  2106. new SpeedTestStyledButtonComponent(),
  2107. new testeStyledButtonComponent(),
  2108. )
  2109. .addRowButtons(
  2110. new TermsStyledButtonComponent(),
  2111. new Mp3StyledButtonComponent(),
  2112. )
  2113. .addRowButtons(
  2114. new CleanAppStyledButtonComponent(),
  2115. new SupportStyledButtonComponent(),
  2116. )
  2117. .addRowButtons(
  2118. new MsgJOGOSStyledButtonComponent(),
  2119. new MsgGPTStyledButtonComponent(),
  2120. )
  2121. .addRowButtons(
  2122. new TVOnlineStyledButtonComponent(),
  2123. new TVOnline2StyledButtonComponent(),
  2124. )
  2125. .addRowButtons(
  2126. new HotSpotStyledButtonComponent(),
  2127. )
  2128. )
  2129. .show();
  2130. });
  2131. this.appendChild(moreButton);
  2132. }
  2133. renderizeLogger() {
  2134. const mock = Array.from({ length: 300 }, (_, i) => ({
  2135. TIME: `MESSAGE ${i}`,
  2136. }));
  2137. const data = JSON.parse(
  2138. window?.DtGetLogs?.execute() ?? JSON.stringify(mock)
  2139. );
  2140. const items = data.map((log) => {
  2141. const message =
  2142. Object.keys(log)[0] + " " + log[Object.keys(log)];
  2143. return new LoggerItemComponent({}, message);
  2144. });
  2145. this.loggerBody.setItems(items);
  2146. }
  2147. }
  2148. /////////////////////// NOVO BOTÃO COMEÇO
  2149. class CardTools2Component extends CardComponent {
  2150. constructor() {
  2151. super({
  2152. margin: "20px 0",
  2153. width: "100%",
  2154. flexDirection: "row",
  2155. justifyContent: "space-between",
  2156. background: "transparent",
  2157. boxShadow: "none",
  2158. position: "fixed",
  2159. bottom: "0",
  2160. left: "0",
  2161. });
  2162. this.loggerBody = new LoggerBodyComponent({});
  2163. this.addGifIcon();
  2164. }
  2165. addGifIcon() {
  2166. const gifUrl = "https://i.ibb.co/jvR5PvS/ezgif-5-74ffdb67c9.gif"; // Substitua com a URL do seu GIF desejado
  2167. const gifIconComponent = document.createElement("img");
  2168. gifIconComponent.src = gifUrl;
  2169. gifIconComponent.style.cursor = "pointer";
  2170. gifIconComponent.style.width = "60px"; // Tamanho ajustado para 100px de largura
  2171. gifIconComponent.style.position = "relative";
  2172. gifIconComponent.style.right = "0px"; // Ajuste para a direita
  2173. gifIconComponent.style.left = "25px"; // Ajuste para a esquerda
  2174. gifIconComponent.style.top = "0px"; // Ajuste para cima
  2175. gifIconComponent.style.bottom = "100px"; // Ajuste para baixo
  2176. gifIconComponent.addEventListener("click", () => {
  2177. const loggerDialog = DialogBuilder.create()
  2178. .setTitle("ÁREA DE CUPOM")
  2179. .setBody(new CupomMessageBodyComponent())
  2180. .setAutoRemove(true)
  2181. .addFooterButton("COPIAR", () => {
  2182. const textToCopy = "Teste";
  2183. navigator.clipboard.writeText(textToCopy);
  2184. window?.DtClearLogs?.execute();
  2185. const alertBox = document.createElement("div");
  2186. alertBox.textContent = " Cupom copiado. ";
  2187. alertBox.style.position = "fixed";
  2188. alertBox.style.bottom = "50px"; // Ajuste para cima
  2189. alertBox.style.left = "50%";
  2190. alertBox.style.transform = "translateX(-50%)";
  2191. alertBox.style.backgroundColor = "rgba(34, 139, 34, 0.7)"; // Alteração para verde transparente
  2192. alertBox.style.color = "#ffffff"; // Cor do texto branco
  2193. alertBox.style.padding = "10px";
  2194. alertBox.style.borderRadius = "20px"; // Arredondamento da caixa
  2195. alertBox.style.zIndex = "9999";
  2196. document.body.appendChild(alertBox);
  2197. setTimeout(() => {
  2198. alertBox.style.opacity = 0;
  2199. setTimeout(() => {
  2200. document.body.removeChild(alertBox);
  2201. }, 1000);
  2202. }, 2000);
  2203. })
  2204. .addFooterButton("FECHAR", () => loggerDialog.close())
  2205. .show();
  2206. this.loggerBody.scrollDown();
  2207. });
  2208. this.appendChild(gifIconComponent);
  2209. }
  2210. }
  2211. /////////////////////// NOVO BOTÃO FINAL
  2212. /////////////////////// NOVO BOTÃO PARA TV COMEÇO
  2213. class CardTools3Component extends CardComponent {
  2214. constructor() {
  2215. super({
  2216. margin: "20px 0",
  2217. width: "100%",
  2218. flexDirection: "row",
  2219. justifyContent: "space-between",
  2220. background: "transparent",
  2221. boxShadow: "none",
  2222. position: "fixed",
  2223. bottom: "0",
  2224. left: "0",
  2225. });
  2226. this.loggerBody = new LoggerBodyComponent({});
  2227. this.addGifIcon();
  2228. this.addFilmesOnlineIcon();
  2229. this.addMp3Icon();
  2230. }
  2231. addGifIcon() {
  2232. const gifUrl = "https://i.ibb.co/jvR5PvS/ezgif-5-74ffdb67c9.gif"; // Substitua com a URL do seu GIF desejado
  2233. const gifIconComponent = document.createElement("img");
  2234. gifIconComponent.src = gifUrl;
  2235. gifIconComponent.style.cursor = "pointer";
  2236. gifIconComponent.style.width = "60px"; // Tamanho ajustado para 100px de largura
  2237. gifIconComponent.style.position = "relative";
  2238. gifIconComponent.style.right = "100px"; // Ajuste para a direita
  2239. gifIconComponent.style.left = "0px"; // Ajuste para a esquerda
  2240. gifIconComponent.style.top = "0px"; // Ajuste para cima
  2241. gifIconComponent.style.bottom = "100px"; // Ajuste para baixo
  2242. gifIconComponent.addEventListener("click", () => {
  2243. // Ação ao clicar no ícone do GIF
  2244. console.log("Clique no GIF");
  2245. });
  2246. this.appendChild(gifIconComponent);
  2247. }
  2248. addFilmesOnlineIcon() {
  2249. const filmesOnlineIconComponent = document.createElement("img");
  2250. filmesOnlineIconComponent.src = "URL_DO_ÍCONE_FILMES_ONLINE"; // Substitua pela URL do ícone desejado para Filmes Online
  2251. filmesOnlineIconComponent.style.cursor = "pointer";
  2252. filmesOnlineIconComponent.style.width = "60px";
  2253. filmesOnlineIconComponent.style.position = "relative";
  2254. filmesOnlineIconComponent.style.right = "50px"; // Ajuste para a direita
  2255. filmesOnlineIconComponent.style.left = "0px"; // Ajuste para a esquerda
  2256. filmesOnlineIconComponent.style.top = "0px"; // Ajuste para cima
  2257. filmesOnlineIconComponent.style.bottom = "100px"; // Ajuste para baixo
  2258. filmesOnlineIconComponent.addEventListener("click", () => {
  2259. // Ação ao clicar no ícone de Filmes Online
  2260. window?.DtStartWebViewActivity?.execute("URL_DO_SITE_FILMES_ONLINE"); // Substitua com a URL do site de Filmes Online
  2261. });
  2262. this.appendChild(filmesOnlineIconComponent);
  2263. }
  2264. addMp3Icon() {
  2265. const mp3IconComponent = document.createElement("img");
  2266. mp3IconComponent.src = "URL_DO_ÍCONE_MP3"; // Substitua pela URL do ícone desejado para reproduzir MP3
  2267. mp3IconComponent.style.cursor = "pointer";
  2268. mp3IconComponent.style.width = "60px";
  2269. mp3IconComponent.style.position = "relative";
  2270. mp3IconComponent.style.right = "0px"; // Ajuste para a direita
  2271. mp3IconComponent.style.left = "0px"; // Ajuste para a esquerda
  2272. mp3IconComponent.style.top = "0px"; // Ajuste para cima
  2273. mp3IconComponent.style.bottom = "100px"; // Ajuste para baixo
  2274. mp3IconComponent.addEventListener("click", () => {
  2275. // Ação ao clicar no ícone de reproduzir MP3
  2276. window?.DtStartWebViewActivity?.execute("URL_DO_SITE_MP3"); // Substitua com a URL do site de reprodução de MP3
  2277. });
  2278. this.appendChild(mp3IconComponent);
  2279. }
  2280. }
  2281. /////////////////////// NOVO BOTÃO PARA TV FINAL
  2282. class CheckUserDialog {
  2283. constructor() {
  2284. this.dialog = DialogBuilder.create()
  2285. .setAutoRemove(true)
  2286. .setTitle('CHECKUSER')
  2287. .setBody(new Spinner());
  2288. }
  2289. initialize() {
  2290. window.dtCheckUserStartedListener = () => this.checkUserStartedListener();
  2291. window.dtCheckUserModelListener = model => this.checkUserModelListener(model);
  2292. }
  2293. checkUserStartedListener() {
  2294. const config = JSON.parse(window?.DtGetDefaultConfig?.execute() ?? '{}');
  2295. if (!config.url_check_user) return;
  2296. this.dialog.show();
  2297. }
  2298. checkUserModelListener(model) {
  2299. const data = JSON.parse(model ?? '{"username": "test"}');
  2300. const now = new Date();
  2301. const hour = now.getUTCHours();
  2302. let greeting;
  2303. if (hour >= 5 && hour < 12) {
  2304. greeting = Math.random() < 0.5 ? 'bom dia' : 'bom dia, hoje está um belo dia';
  2305. } else if (hour >= 12 && hour < 18) {
  2306. greeting = Math.random() < 0.5 ? 'boa tarde' : 'boa tarde, como está se sentindo?';
  2307. } else {
  2308. greeting = Math.random() < 0.5 ? 'boa noite' : 'boa noite, a noite hoje está linda!';
  2309. }
  2310. this.dialog
  2311. .setTitle(`🟢 Olá ${data.username}, ${greeting}`)
  2312. .setBody(new CheckUserBodyComponent(data));
  2313. }
  2314. }
  2315. const rootComponent = new AppComponent(document.querySelector('#root'), { background: BACKGROUND_COLOR });
  2316. window.onerror = e => {
  2317. rootComponent.element.style.color = '#FFFFFF';
  2318. rootComponent.element.style.fontSize = '18px';
  2319. rootComponent.element.innerHTML = e
  2320. return false;
  2321. };
  2322. const cardComponent = new CardComponent({ position: 'absolute', top: '15%' });
  2323. const configInput = new ConfigInputComponent();
  2324. cardComponent.append(configInput);
  2325. const userPassInputComponent = new UserPassInputComponent()
  2326. cardComponent.append(userPassInputComponent);
  2327. const cardToolsComponent = new CardToolsComponent();
  2328. cardComponent.append(cardToolsComponent);
  2329. const buttonAndStateContainer = new ButtonAndStateContainerComponent({ marginTop: '3rem' });
  2330. cardComponent.append(buttonAndStateContainer);
  2331. rootComponent.append(new LocalIPComponent());
  2332. rootComponent.append(new PingComponent());
  2333. rootComponent.append(new NetworkStatsComponent());
  2334. rootComponent.append(cardComponent);
  2335. const checkUserDialog = new CheckUserDialog();
  2336. checkUserDialog.initialize();
  2337. const cardTools2Component = new CardTools2Component();
  2338. cardComponent.append(cardTools2Component);
  2339. </script>
  2340. </body>
  2341. </html>

comments powered by Disqus