@rich-automation/lotto 2.0.6 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/controllers/factory.js +7 -0
- package/lib/cjs/controllers/webview/bridgeScript.js +125 -0
- package/lib/cjs/controllers/webview/index.js +35 -0
- package/lib/cjs/controllers/webview/types.js +2 -0
- package/lib/cjs/controllers/webview/webview.page.js +106 -0
- package/lib/cjs/index.js +1 -1
- package/lib/cjs/{lottoService.js → services/lottoService.core.js} +18 -20
- package/lib/cjs/services/lottoService.js +17 -0
- package/lib/esm/controllers/factory.js +7 -0
- package/lib/esm/controllers/webview/bridgeScript.js +122 -0
- package/lib/esm/controllers/webview/index.js +31 -0
- package/lib/esm/controllers/webview/types.js +1 -0
- package/lib/esm/controllers/webview/webview.page.js +102 -0
- package/lib/esm/index.js +1 -1
- package/lib/esm/index.native.js +163 -0
- package/lib/esm/{lottoService.js → services/lottoService.core.js} +16 -18
- package/lib/esm/services/lottoService.js +10 -0
- package/lib/tsconfig.native.tsbuildinfo +1 -0
- package/lib/typescript/controllers/webview/bridgeScript.d.ts +1 -0
- package/lib/typescript/controllers/webview/index.d.ts +12 -0
- package/lib/typescript/controllers/webview/types.d.ts +11 -0
- package/lib/typescript/controllers/webview/webview.page.d.ts +22 -0
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.native.d.ts +19 -0
- package/lib/typescript/{lottoService.d.ts → services/lottoService.core.d.ts} +4 -4
- package/lib/typescript/services/lottoService.d.ts +5 -0
- package/lib/typescript/types.d.ts +2 -1
- package/package.json +32 -6
|
@@ -3,11 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createBrowserController = void 0;
|
|
4
4
|
const puppeteer_1 = require("./puppeteer");
|
|
5
5
|
const playwright_1 = require("./playwright");
|
|
6
|
+
const webview_1 = require("./webview");
|
|
6
7
|
const api_1 = require("./api");
|
|
7
8
|
function createBrowserController(configs, logger) {
|
|
8
9
|
if (isAPIMode(configs)) {
|
|
9
10
|
return new api_1.APIModeController(configs, logger);
|
|
10
11
|
}
|
|
12
|
+
if (isWebView(configs)) {
|
|
13
|
+
return new webview_1.WebViewController(configs, logger);
|
|
14
|
+
}
|
|
11
15
|
if (isPlaywright(configs)) {
|
|
12
16
|
return new playwright_1.PlaywrightController(configs, logger);
|
|
13
17
|
}
|
|
@@ -20,6 +24,9 @@ exports.createBrowserController = createBrowserController;
|
|
|
20
24
|
function isAPIMode(configs) {
|
|
21
25
|
return configs.controller === 'api';
|
|
22
26
|
}
|
|
27
|
+
function isWebView(configs) {
|
|
28
|
+
return (typeof configs.controller === 'object' && '__type' in configs.controller && configs.controller.__type === 'webview');
|
|
29
|
+
}
|
|
23
30
|
function isPlaywright(configs) {
|
|
24
31
|
return typeof configs.controller !== 'string' && 'connectOverCDP' in configs.controller;
|
|
25
32
|
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BRIDGE_SCRIPT = void 0;
|
|
4
|
+
// WebView에 주입되는 브릿지 스크립트
|
|
5
|
+
// 모든 DOM 조작은 이 스크립트 내부에서 실행되며, postMessage로 결과를 반환함
|
|
6
|
+
exports.BRIDGE_SCRIPT = `
|
|
7
|
+
(function() {
|
|
8
|
+
if (window.__LOTTO_BRIDGE__) return;
|
|
9
|
+
|
|
10
|
+
window.__LOTTO_BRIDGE__ = {
|
|
11
|
+
fill: function(selector, value) {
|
|
12
|
+
var el = document.querySelector(selector);
|
|
13
|
+
if (!el) return { ok: false, error: 'Element not found: ' + selector };
|
|
14
|
+
el.focus();
|
|
15
|
+
el.value = value;
|
|
16
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
17
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
18
|
+
return { ok: true };
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
click: function(selector, domDirect) {
|
|
22
|
+
var el = document.querySelector(selector);
|
|
23
|
+
if (!el) return { ok: false, error: 'Element not found: ' + selector };
|
|
24
|
+
el.click();
|
|
25
|
+
return { ok: true };
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
select: function(selector, value) {
|
|
29
|
+
var el = document.querySelector(selector);
|
|
30
|
+
if (!el) return { ok: false, error: 'Element not found: ' + selector };
|
|
31
|
+
el.value = value;
|
|
32
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
33
|
+
return { ok: true };
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
exists: function(selector, containsText) {
|
|
37
|
+
var el = document.querySelector(selector);
|
|
38
|
+
if (!el) return false;
|
|
39
|
+
if (containsText) return (el.textContent || '').indexOf(containsText) !== -1;
|
|
40
|
+
return true;
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
querySelectorAll: function(selector) {
|
|
44
|
+
var MAX_DEPTH = 5;
|
|
45
|
+
function toFakeDOM(el, depth) {
|
|
46
|
+
return {
|
|
47
|
+
className: el.className || '',
|
|
48
|
+
innerHTML: el.innerHTML || '',
|
|
49
|
+
children: depth < MAX_DEPTH
|
|
50
|
+
? Array.from(el.children).map(function(c) { return toFakeDOM(c, depth + 1); })
|
|
51
|
+
: []
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return Array.from(document.querySelectorAll(selector)).map(function(el) { return toFakeDOM(el, 0); });
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
getUrl: function() {
|
|
58
|
+
return window.location.href;
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
getCookies: function() {
|
|
62
|
+
return document.cookie;
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
setCookies: function(cookieString) {
|
|
66
|
+
cookieString.split('; ').forEach(function(cookie) {
|
|
67
|
+
document.cookie = cookie;
|
|
68
|
+
});
|
|
69
|
+
return { ok: true };
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
waitForSelector: function(selector, timeout) {
|
|
73
|
+
return new Promise(function(resolve) {
|
|
74
|
+
var el = document.querySelector(selector);
|
|
75
|
+
if (el) { resolve({ ok: true }); return; }
|
|
76
|
+
|
|
77
|
+
var observer = new MutationObserver(function() {
|
|
78
|
+
var found = document.querySelector(selector);
|
|
79
|
+
if (found) {
|
|
80
|
+
observer.disconnect();
|
|
81
|
+
clearTimeout(timer);
|
|
82
|
+
resolve({ ok: true });
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
observer.observe(document.body || document.documentElement, { childList: true, subtree: true });
|
|
86
|
+
|
|
87
|
+
var timer = setTimeout(function() {
|
|
88
|
+
observer.disconnect();
|
|
89
|
+
resolve({ ok: false, error: 'Timeout waiting for: ' + selector });
|
|
90
|
+
}, timeout || 10000);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
var ALLOWED_METHODS = ['fill','click','select','exists','querySelectorAll','getUrl','getCookies','setCookies','waitForSelector'];
|
|
96
|
+
|
|
97
|
+
// 커맨드 수신 리스너
|
|
98
|
+
window.addEventListener('message', function(e) {
|
|
99
|
+
try {
|
|
100
|
+
var msg = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;
|
|
101
|
+
if (!msg || !msg.__lotto_call_id__ || !msg.method) return;
|
|
102
|
+
if (ALLOWED_METHODS.indexOf(msg.method) === -1) return;
|
|
103
|
+
|
|
104
|
+
var fn = window.__LOTTO_BRIDGE__[msg.method];
|
|
105
|
+
if (!fn) return;
|
|
106
|
+
|
|
107
|
+
Promise.resolve(fn.apply(null, msg.args || [])).then(function(result) {
|
|
108
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
109
|
+
__lotto_call_id__: msg.__lotto_call_id__,
|
|
110
|
+
result: result
|
|
111
|
+
}));
|
|
112
|
+
});
|
|
113
|
+
} catch (err) {
|
|
114
|
+
if (msg && msg.__lotto_call_id__) {
|
|
115
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
116
|
+
__lotto_call_id__: msg.__lotto_call_id__,
|
|
117
|
+
result: { ok: false, error: String(err) }
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
true;
|
|
124
|
+
})();
|
|
125
|
+
`;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.WebViewController = void 0;
|
|
13
|
+
const webview_page_1 = require("./webview.page");
|
|
14
|
+
class WebViewController {
|
|
15
|
+
constructor(configs, logger) {
|
|
16
|
+
this.page = null;
|
|
17
|
+
this.focus = () => __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
if (!this.page) {
|
|
19
|
+
this.page = new webview_page_1.WebViewPage(this.configs.controller, this.logger);
|
|
20
|
+
}
|
|
21
|
+
return this.page;
|
|
22
|
+
});
|
|
23
|
+
this.close = () => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
this.configs.controller.destroy();
|
|
25
|
+
this.page = null;
|
|
26
|
+
});
|
|
27
|
+
this.cleanPages = () => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
// WebView는 단일 페이지이므로 no-op
|
|
29
|
+
this.logger.debug('[WebViewController]', 'cleanPages is no-op for WebView');
|
|
30
|
+
});
|
|
31
|
+
this.configs = configs;
|
|
32
|
+
this.logger = logger;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.WebViewController = WebViewController;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.WebViewPage = void 0;
|
|
13
|
+
const lazyRun_1 = require("../../utils/lazyRun");
|
|
14
|
+
const deferred_1 = require("../../utils/deferred");
|
|
15
|
+
class WebViewPage {
|
|
16
|
+
constructor(bridge, logger) {
|
|
17
|
+
this.bridge = bridge;
|
|
18
|
+
this.logger = logger;
|
|
19
|
+
}
|
|
20
|
+
url() {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
return this.bridge.getCurrentUrl();
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
goto(url, options) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
yield this.bridge.navigateTo(url, options === null || options === void 0 ? void 0 : options.waitUntil);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
fill(selector, value) {
|
|
31
|
+
var _a;
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
const result = (yield this.bridge.call('fill', [selector, value.toString()]));
|
|
34
|
+
if (!result.ok) {
|
|
35
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('[WebViewPage]', 'fill failed', result.error);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
click(selector, _domDirect = false) {
|
|
40
|
+
var _a;
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
const result = (yield this.bridge.call('click', [selector]));
|
|
43
|
+
if (!result.ok) {
|
|
44
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('[WebViewPage]', 'click failed', result.error);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
select(selector, value) {
|
|
49
|
+
var _a;
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const result = (yield this.bridge.call('select', [selector, value]));
|
|
52
|
+
if (!result.ok) {
|
|
53
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('[WebViewPage]', 'select failed', result.error);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
querySelectorAll(selector, callback) {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
const elems = (yield this.bridge.call('querySelectorAll', [selector]));
|
|
60
|
+
return callback(elems);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
exists(selector, containsText) {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
return (yield this.bridge.call('exists', [selector, containsText]));
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
wait(param) {
|
|
69
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
const p = (0, deferred_1.deferred)();
|
|
71
|
+
if (param === 'idle' || param === 'load') {
|
|
72
|
+
// WebView에서는 네비게이션 대기를 직접 지원하지 않으므로 짧은 대기로 대체
|
|
73
|
+
yield (0, lazyRun_1.lazyRun)(() => __awaiter(this, void 0, void 0, function* () { return p.resolve(); }), 1000);
|
|
74
|
+
}
|
|
75
|
+
if (typeof param === 'number') {
|
|
76
|
+
yield (0, lazyRun_1.lazyRun)(() => __awaiter(this, void 0, void 0, function* () { return p.resolve(); }), param);
|
|
77
|
+
}
|
|
78
|
+
return p.promise;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
waitForSelector(selector, timeout = 10000) {
|
|
82
|
+
var _a;
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
const result = (yield this.bridge.call('waitForSelector', [selector, timeout]));
|
|
85
|
+
if (!result.ok) {
|
|
86
|
+
throw new Error((_a = result.error) !== null && _a !== void 0 ? _a : `waitForSelector timeout: ${selector}`);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
getCookies() {
|
|
91
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
return (yield this.bridge.call('getCookies', []));
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
setCookies(cookies) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
yield this.bridge.call('setCookies', [cookies]);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
on(_event, _callback) {
|
|
101
|
+
var _a;
|
|
102
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('[WebViewPage]', 'on() is not supported in WebView controller');
|
|
103
|
+
return () => { };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.WebViewPage = WebViewPage;
|
package/lib/cjs/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.checkWinning = exports.getCheckWinningLink = exports.getNextLottoRound = exports.getLastLottoRound = exports.LogLevel = exports.LottoService = void 0;
|
|
18
|
-
var lottoService_1 = require("./lottoService");
|
|
18
|
+
var lottoService_1 = require("./services/lottoService");
|
|
19
19
|
Object.defineProperty(exports, "LottoService", { enumerable: true, get: function () { return lottoService_1.LottoService; } });
|
|
20
20
|
var logger_1 = require("./logger");
|
|
21
21
|
Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return logger_1.LogLevel; } });
|
|
@@ -12,23 +12,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
16
|
-
const lottoError_1 = __importDefault(require("
|
|
17
|
-
const selectors_1 = require("
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class LottoService {
|
|
31
|
-
constructor(configs) {
|
|
15
|
+
exports.LottoServiceCore = void 0;
|
|
16
|
+
const lottoError_1 = __importDefault(require("../lottoError"));
|
|
17
|
+
const selectors_1 = require("../constants/selectors");
|
|
18
|
+
const urls_1 = require("../constants/urls");
|
|
19
|
+
const constants_1 = require("../constants");
|
|
20
|
+
const lazyRun_1 = require("../utils/lazyRun");
|
|
21
|
+
const getLastLottoRound_1 = require("../utils/getLastLottoRound");
|
|
22
|
+
const validateLottoNumber_1 = require("../utils/validateLottoNumber");
|
|
23
|
+
const getWinningNumbers_1 = require("../apis/dhlottery/getWinningNumbers");
|
|
24
|
+
const checkWinning_1 = require("../utils/checkWinning");
|
|
25
|
+
const validatePurchaseAvailability_1 = require("../utils/validatePurchaseAvailability");
|
|
26
|
+
const getCheckWinningLink_1 = require("../utils/getCheckWinningLink");
|
|
27
|
+
const getNextLottoRound_1 = require("../utils/getNextLottoRound");
|
|
28
|
+
class LottoServiceCore {
|
|
29
|
+
constructor(controller, logger) {
|
|
32
30
|
this.context = {
|
|
33
31
|
authenticated: false
|
|
34
32
|
};
|
|
@@ -179,8 +177,8 @@ class LottoService {
|
|
|
179
177
|
this.logger.debug('[getCheckWinningLink]', 'getCheckWinningLink');
|
|
180
178
|
return (0, getCheckWinningLink_1.getCheckWinningLink)(numbers, round);
|
|
181
179
|
};
|
|
182
|
-
this.
|
|
183
|
-
this.
|
|
180
|
+
this.browserController = controller;
|
|
181
|
+
this.logger = logger;
|
|
184
182
|
}
|
|
185
183
|
}
|
|
186
|
-
exports.
|
|
184
|
+
exports.LottoServiceCore = LottoServiceCore;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LottoService = void 0;
|
|
7
|
+
const factory_1 = require("../controllers/factory");
|
|
8
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
9
|
+
const lottoService_core_1 = require("./lottoService.core");
|
|
10
|
+
class LottoService extends lottoService_core_1.LottoServiceCore {
|
|
11
|
+
constructor(configs) {
|
|
12
|
+
const logger = new logger_1.default(configs.logLevel, '[LottoService]');
|
|
13
|
+
const controller = (0, factory_1.createBrowserController)(Object.assign({ defaultViewport: { width: 1080, height: 1024 } }, configs), logger);
|
|
14
|
+
super(controller, logger);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.LottoService = LottoService;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { PuppeteerController } from './puppeteer';
|
|
2
2
|
import { PlaywrightController } from './playwright';
|
|
3
|
+
import { WebViewController } from './webview';
|
|
3
4
|
import { APIModeController } from './api';
|
|
4
5
|
export function createBrowserController(configs, logger) {
|
|
5
6
|
if (isAPIMode(configs)) {
|
|
6
7
|
return new APIModeController(configs, logger);
|
|
7
8
|
}
|
|
9
|
+
if (isWebView(configs)) {
|
|
10
|
+
return new WebViewController(configs, logger);
|
|
11
|
+
}
|
|
8
12
|
if (isPlaywright(configs)) {
|
|
9
13
|
return new PlaywrightController(configs, logger);
|
|
10
14
|
}
|
|
@@ -16,6 +20,9 @@ export function createBrowserController(configs, logger) {
|
|
|
16
20
|
function isAPIMode(configs) {
|
|
17
21
|
return configs.controller === 'api';
|
|
18
22
|
}
|
|
23
|
+
function isWebView(configs) {
|
|
24
|
+
return (typeof configs.controller === 'object' && '__type' in configs.controller && configs.controller.__type === 'webview');
|
|
25
|
+
}
|
|
19
26
|
function isPlaywright(configs) {
|
|
20
27
|
return typeof configs.controller !== 'string' && 'connectOverCDP' in configs.controller;
|
|
21
28
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// WebView에 주입되는 브릿지 스크립트
|
|
2
|
+
// 모든 DOM 조작은 이 스크립트 내부에서 실행되며, postMessage로 결과를 반환함
|
|
3
|
+
export const BRIDGE_SCRIPT = `
|
|
4
|
+
(function() {
|
|
5
|
+
if (window.__LOTTO_BRIDGE__) return;
|
|
6
|
+
|
|
7
|
+
window.__LOTTO_BRIDGE__ = {
|
|
8
|
+
fill: function(selector, value) {
|
|
9
|
+
var el = document.querySelector(selector);
|
|
10
|
+
if (!el) return { ok: false, error: 'Element not found: ' + selector };
|
|
11
|
+
el.focus();
|
|
12
|
+
el.value = value;
|
|
13
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
14
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
15
|
+
return { ok: true };
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
click: function(selector, domDirect) {
|
|
19
|
+
var el = document.querySelector(selector);
|
|
20
|
+
if (!el) return { ok: false, error: 'Element not found: ' + selector };
|
|
21
|
+
el.click();
|
|
22
|
+
return { ok: true };
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
select: function(selector, value) {
|
|
26
|
+
var el = document.querySelector(selector);
|
|
27
|
+
if (!el) return { ok: false, error: 'Element not found: ' + selector };
|
|
28
|
+
el.value = value;
|
|
29
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
30
|
+
return { ok: true };
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
exists: function(selector, containsText) {
|
|
34
|
+
var el = document.querySelector(selector);
|
|
35
|
+
if (!el) return false;
|
|
36
|
+
if (containsText) return (el.textContent || '').indexOf(containsText) !== -1;
|
|
37
|
+
return true;
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
querySelectorAll: function(selector) {
|
|
41
|
+
var MAX_DEPTH = 5;
|
|
42
|
+
function toFakeDOM(el, depth) {
|
|
43
|
+
return {
|
|
44
|
+
className: el.className || '',
|
|
45
|
+
innerHTML: el.innerHTML || '',
|
|
46
|
+
children: depth < MAX_DEPTH
|
|
47
|
+
? Array.from(el.children).map(function(c) { return toFakeDOM(c, depth + 1); })
|
|
48
|
+
: []
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return Array.from(document.querySelectorAll(selector)).map(function(el) { return toFakeDOM(el, 0); });
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
getUrl: function() {
|
|
55
|
+
return window.location.href;
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
getCookies: function() {
|
|
59
|
+
return document.cookie;
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
setCookies: function(cookieString) {
|
|
63
|
+
cookieString.split('; ').forEach(function(cookie) {
|
|
64
|
+
document.cookie = cookie;
|
|
65
|
+
});
|
|
66
|
+
return { ok: true };
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
waitForSelector: function(selector, timeout) {
|
|
70
|
+
return new Promise(function(resolve) {
|
|
71
|
+
var el = document.querySelector(selector);
|
|
72
|
+
if (el) { resolve({ ok: true }); return; }
|
|
73
|
+
|
|
74
|
+
var observer = new MutationObserver(function() {
|
|
75
|
+
var found = document.querySelector(selector);
|
|
76
|
+
if (found) {
|
|
77
|
+
observer.disconnect();
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
resolve({ ok: true });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
observer.observe(document.body || document.documentElement, { childList: true, subtree: true });
|
|
83
|
+
|
|
84
|
+
var timer = setTimeout(function() {
|
|
85
|
+
observer.disconnect();
|
|
86
|
+
resolve({ ok: false, error: 'Timeout waiting for: ' + selector });
|
|
87
|
+
}, timeout || 10000);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
var ALLOWED_METHODS = ['fill','click','select','exists','querySelectorAll','getUrl','getCookies','setCookies','waitForSelector'];
|
|
93
|
+
|
|
94
|
+
// 커맨드 수신 리스너
|
|
95
|
+
window.addEventListener('message', function(e) {
|
|
96
|
+
try {
|
|
97
|
+
var msg = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;
|
|
98
|
+
if (!msg || !msg.__lotto_call_id__ || !msg.method) return;
|
|
99
|
+
if (ALLOWED_METHODS.indexOf(msg.method) === -1) return;
|
|
100
|
+
|
|
101
|
+
var fn = window.__LOTTO_BRIDGE__[msg.method];
|
|
102
|
+
if (!fn) return;
|
|
103
|
+
|
|
104
|
+
Promise.resolve(fn.apply(null, msg.args || [])).then(function(result) {
|
|
105
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
106
|
+
__lotto_call_id__: msg.__lotto_call_id__,
|
|
107
|
+
result: result
|
|
108
|
+
}));
|
|
109
|
+
});
|
|
110
|
+
} catch (err) {
|
|
111
|
+
if (msg && msg.__lotto_call_id__) {
|
|
112
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
113
|
+
__lotto_call_id__: msg.__lotto_call_id__,
|
|
114
|
+
result: { ok: false, error: String(err) }
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
true;
|
|
121
|
+
})();
|
|
122
|
+
`;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { WebViewPage } from './webview.page';
|
|
11
|
+
export class WebViewController {
|
|
12
|
+
constructor(configs, logger) {
|
|
13
|
+
this.page = null;
|
|
14
|
+
this.focus = () => __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
if (!this.page) {
|
|
16
|
+
this.page = new WebViewPage(this.configs.controller, this.logger);
|
|
17
|
+
}
|
|
18
|
+
return this.page;
|
|
19
|
+
});
|
|
20
|
+
this.close = () => __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
this.configs.controller.destroy();
|
|
22
|
+
this.page = null;
|
|
23
|
+
});
|
|
24
|
+
this.cleanPages = () => __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
// WebView는 단일 페이지이므로 no-op
|
|
26
|
+
this.logger.debug('[WebViewController]', 'cleanPages is no-op for WebView');
|
|
27
|
+
});
|
|
28
|
+
this.configs = configs;
|
|
29
|
+
this.logger = logger;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { lazyRun } from '../../utils/lazyRun';
|
|
11
|
+
import { deferred } from '../../utils/deferred';
|
|
12
|
+
export class WebViewPage {
|
|
13
|
+
constructor(bridge, logger) {
|
|
14
|
+
this.bridge = bridge;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
}
|
|
17
|
+
url() {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
return this.bridge.getCurrentUrl();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
goto(url, options) {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
yield this.bridge.navigateTo(url, options === null || options === void 0 ? void 0 : options.waitUntil);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
fill(selector, value) {
|
|
28
|
+
var _a;
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
const result = (yield this.bridge.call('fill', [selector, value.toString()]));
|
|
31
|
+
if (!result.ok) {
|
|
32
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('[WebViewPage]', 'fill failed', result.error);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
click(selector, _domDirect = false) {
|
|
37
|
+
var _a;
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const result = (yield this.bridge.call('click', [selector]));
|
|
40
|
+
if (!result.ok) {
|
|
41
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('[WebViewPage]', 'click failed', result.error);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
select(selector, value) {
|
|
46
|
+
var _a;
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
const result = (yield this.bridge.call('select', [selector, value]));
|
|
49
|
+
if (!result.ok) {
|
|
50
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('[WebViewPage]', 'select failed', result.error);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
querySelectorAll(selector, callback) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const elems = (yield this.bridge.call('querySelectorAll', [selector]));
|
|
57
|
+
return callback(elems);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
exists(selector, containsText) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
return (yield this.bridge.call('exists', [selector, containsText]));
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
wait(param) {
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
const p = deferred();
|
|
68
|
+
if (param === 'idle' || param === 'load') {
|
|
69
|
+
// WebView에서는 네비게이션 대기를 직접 지원하지 않으므로 짧은 대기로 대체
|
|
70
|
+
yield lazyRun(() => __awaiter(this, void 0, void 0, function* () { return p.resolve(); }), 1000);
|
|
71
|
+
}
|
|
72
|
+
if (typeof param === 'number') {
|
|
73
|
+
yield lazyRun(() => __awaiter(this, void 0, void 0, function* () { return p.resolve(); }), param);
|
|
74
|
+
}
|
|
75
|
+
return p.promise;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
waitForSelector(selector, timeout = 10000) {
|
|
79
|
+
var _a;
|
|
80
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
const result = (yield this.bridge.call('waitForSelector', [selector, timeout]));
|
|
82
|
+
if (!result.ok) {
|
|
83
|
+
throw new Error((_a = result.error) !== null && _a !== void 0 ? _a : `waitForSelector timeout: ${selector}`);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
getCookies() {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
return (yield this.bridge.call('getCookies', []));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
setCookies(cookies) {
|
|
93
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
+
yield this.bridge.call('setCookies', [cookies]);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
on(_event, _callback) {
|
|
98
|
+
var _a;
|
|
99
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('[WebViewPage]', 'on() is not supported in WebView controller');
|
|
100
|
+
return () => { };
|
|
101
|
+
}
|
|
102
|
+
}
|
package/lib/esm/index.js
CHANGED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { View, StyleSheet } from 'react-native';
|
|
3
|
+
import { WebView } from 'react-native-webview';
|
|
4
|
+
import { BRIDGE_SCRIPT } from './controllers/webview/bridgeScript';
|
|
5
|
+
import { LottoServiceCore } from './services/lottoService.core';
|
|
6
|
+
import { WebViewController } from './controllers/webview';
|
|
7
|
+
import Logger, {} from './logger';
|
|
8
|
+
const CALL_TIMEOUT = 15000;
|
|
9
|
+
const BLOCKED_PROTOCOLS = ['javascript:', 'data:', 'file:', 'vbscript:'];
|
|
10
|
+
const DEDUP_METHODS = new Set(['exists', 'querySelectorAll', 'getUrl', 'getCookies']);
|
|
11
|
+
export function useLottoService(options = {}) {
|
|
12
|
+
const { headless = true, logLevel } = options;
|
|
13
|
+
const webviewRef = useRef(null);
|
|
14
|
+
const pendingCalls = useRef(new Map());
|
|
15
|
+
const inflightCalls = useRef(new Map());
|
|
16
|
+
const navigationPromise = useRef(null);
|
|
17
|
+
const currentUrl = useRef('');
|
|
18
|
+
const logLevelRef = useRef(logLevel);
|
|
19
|
+
logLevelRef.current = logLevel;
|
|
20
|
+
// P5: 네비게이션 promise resolve 헬퍼 (null 먼저 설정하여 이중 resolve 방지)
|
|
21
|
+
const resolveNavigation = useCallback(() => {
|
|
22
|
+
const pending = navigationPromise.current;
|
|
23
|
+
if (pending) {
|
|
24
|
+
navigationPromise.current = null;
|
|
25
|
+
pending.resolve();
|
|
26
|
+
}
|
|
27
|
+
}, []);
|
|
28
|
+
// WebView → RN 메시지 수신
|
|
29
|
+
const handleMessage = useCallback((event) => {
|
|
30
|
+
try {
|
|
31
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
32
|
+
if (!data.__lotto_call_id__)
|
|
33
|
+
return;
|
|
34
|
+
const pending = pendingCalls.current.get(data.__lotto_call_id__);
|
|
35
|
+
if (pending) {
|
|
36
|
+
pending.resolve(data.result);
|
|
37
|
+
pendingCalls.current.delete(data.__lotto_call_id__);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (_a) {
|
|
41
|
+
// non-bridge 메시지 무시
|
|
42
|
+
}
|
|
43
|
+
}, []);
|
|
44
|
+
// 네비게이션 상태 추적
|
|
45
|
+
const handleNavigationStateChange = useCallback((navState) => {
|
|
46
|
+
currentUrl.current = navState.url;
|
|
47
|
+
if (!navState.loading)
|
|
48
|
+
resolveNavigation();
|
|
49
|
+
}, [resolveNavigation]);
|
|
50
|
+
// WebView 로드 완료
|
|
51
|
+
const handleLoadEnd = useCallback(() => {
|
|
52
|
+
resolveNavigation();
|
|
53
|
+
}, [resolveNavigation]);
|
|
54
|
+
// Bridge 구현
|
|
55
|
+
const bridge = useMemo(() => {
|
|
56
|
+
function callBridge(method, args) {
|
|
57
|
+
const callId = Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
var _a;
|
|
60
|
+
const timer = setTimeout(() => {
|
|
61
|
+
pendingCalls.current.delete(callId);
|
|
62
|
+
reject(new Error(`WebView bridge timeout: ${method}(${JSON.stringify(args)})`));
|
|
63
|
+
}, CALL_TIMEOUT);
|
|
64
|
+
pendingCalls.current.set(callId, {
|
|
65
|
+
resolve: v => {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
resolve(v);
|
|
68
|
+
},
|
|
69
|
+
reject: e => {
|
|
70
|
+
clearTimeout(timer);
|
|
71
|
+
reject(e);
|
|
72
|
+
},
|
|
73
|
+
timer
|
|
74
|
+
});
|
|
75
|
+
const message = JSON.stringify({ __lotto_call_id__: callId, method, args });
|
|
76
|
+
(_a = webviewRef.current) === null || _a === void 0 ? void 0 : _a.injectJavaScript(`window.postMessage(${JSON.stringify(message)}, '*'); true;`);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// P7: 읽기 전용 메서드 중복 호출 제거
|
|
80
|
+
function call(method, args) {
|
|
81
|
+
if (DEDUP_METHODS.has(method)) {
|
|
82
|
+
const key = method + ':' + JSON.stringify(args);
|
|
83
|
+
const inflight = inflightCalls.current.get(key);
|
|
84
|
+
if (inflight)
|
|
85
|
+
return inflight;
|
|
86
|
+
const promise = callBridge(method, args).finally(() => inflightCalls.current.delete(key));
|
|
87
|
+
inflightCalls.current.set(key, promise);
|
|
88
|
+
return promise;
|
|
89
|
+
}
|
|
90
|
+
return callBridge(method, args);
|
|
91
|
+
}
|
|
92
|
+
function navigateTo(url, _waitUntil) {
|
|
93
|
+
// H1: 위험한 프로토콜 차단
|
|
94
|
+
const lower = url.toLowerCase().trim();
|
|
95
|
+
if (BLOCKED_PROTOCOLS.some(p => lower.startsWith(p))) {
|
|
96
|
+
return Promise.reject(new Error(`Blocked navigation to unsafe URL: ${url}`));
|
|
97
|
+
}
|
|
98
|
+
return new Promise(resolve => {
|
|
99
|
+
var _a;
|
|
100
|
+
resolveNavigation();
|
|
101
|
+
navigationPromise.current = { resolve };
|
|
102
|
+
(_a = webviewRef.current) === null || _a === void 0 ? void 0 : _a.injectJavaScript(`window.location.href = ${JSON.stringify(url)}; true;`);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function getCurrentUrl() {
|
|
106
|
+
return currentUrl.current;
|
|
107
|
+
}
|
|
108
|
+
function destroy() {
|
|
109
|
+
for (const [, pending] of pendingCalls.current) {
|
|
110
|
+
clearTimeout(pending.timer);
|
|
111
|
+
pending.reject(new Error('WebView bridge destroyed'));
|
|
112
|
+
}
|
|
113
|
+
pendingCalls.current.clear();
|
|
114
|
+
inflightCalls.current.clear();
|
|
115
|
+
resolveNavigation();
|
|
116
|
+
}
|
|
117
|
+
return { __type: 'webview', call, navigateTo, getCurrentUrl, destroy };
|
|
118
|
+
}, [resolveNavigation]);
|
|
119
|
+
// P1: logLevel을 ref로 안정화하여 불필요한 service 재생성 방지
|
|
120
|
+
const service = useMemo(() => {
|
|
121
|
+
const logger = new Logger(logLevelRef.current, '[LottoService]');
|
|
122
|
+
const configs = { controller: bridge, logLevel: logLevelRef.current };
|
|
123
|
+
const controller = new WebViewController(configs, logger);
|
|
124
|
+
return new LottoServiceCore(controller, logger);
|
|
125
|
+
}, [bridge]);
|
|
126
|
+
// Cleanup
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
return () => {
|
|
129
|
+
bridge.destroy();
|
|
130
|
+
};
|
|
131
|
+
}, [bridge]);
|
|
132
|
+
// WebView 컴포넌트
|
|
133
|
+
const LottoWebView = useCallback(() => React.createElement(View, { style: headless ? styles.hidden : styles.visible }, React.createElement(WebView, {
|
|
134
|
+
ref: webviewRef,
|
|
135
|
+
source: { uri: 'about:blank' },
|
|
136
|
+
javaScriptEnabled: true,
|
|
137
|
+
domStorageEnabled: true,
|
|
138
|
+
injectedJavaScriptBeforeContentLoaded: BRIDGE_SCRIPT,
|
|
139
|
+
onMessage: handleMessage,
|
|
140
|
+
onNavigationStateChange: handleNavigationStateChange,
|
|
141
|
+
onLoadEnd: handleLoadEnd
|
|
142
|
+
})), [headless, handleMessage, handleNavigationStateChange, handleLoadEnd]);
|
|
143
|
+
return { LottoWebView, service };
|
|
144
|
+
}
|
|
145
|
+
const styles = StyleSheet.create({
|
|
146
|
+
hidden: {
|
|
147
|
+
width: 0,
|
|
148
|
+
height: 0,
|
|
149
|
+
position: 'absolute',
|
|
150
|
+
opacity: 0,
|
|
151
|
+
overflow: 'hidden'
|
|
152
|
+
},
|
|
153
|
+
visible: {
|
|
154
|
+
flex: 1
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
// Re-export useful types and utils
|
|
158
|
+
export { LottoServiceCore } from './services/lottoService.core';
|
|
159
|
+
export { LogLevel } from './logger';
|
|
160
|
+
export { getLastLottoRound } from './utils/getLastLottoRound';
|
|
161
|
+
export { getNextLottoRound } from './utils/getNextLottoRound';
|
|
162
|
+
export { getCheckWinningLink } from './utils/getCheckWinningLink';
|
|
163
|
+
export { checkWinning } from './utils/checkWinning';
|
|
@@ -7,22 +7,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import LottoError from '
|
|
11
|
-
import { SELECTORS } from '
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export class LottoService {
|
|
25
|
-
constructor(configs) {
|
|
10
|
+
import LottoError from '../lottoError';
|
|
11
|
+
import { SELECTORS } from '../constants/selectors';
|
|
12
|
+
import { URLS } from '../constants/urls';
|
|
13
|
+
import { CONST } from '../constants';
|
|
14
|
+
import { lazyRun } from '../utils/lazyRun';
|
|
15
|
+
import { getLastLottoRound } from '../utils/getLastLottoRound';
|
|
16
|
+
import { validateLottoNumber } from '../utils/validateLottoNumber';
|
|
17
|
+
import { getWinningNumbers } from '../apis/dhlottery/getWinningNumbers';
|
|
18
|
+
import { checkWinning } from '../utils/checkWinning';
|
|
19
|
+
import { validatePurchaseAvailability } from '../utils/validatePurchaseAvailability';
|
|
20
|
+
import { getCheckWinningLink } from '../utils/getCheckWinningLink';
|
|
21
|
+
import { getNextLottoRound } from '../utils/getNextLottoRound';
|
|
22
|
+
export class LottoServiceCore {
|
|
23
|
+
constructor(controller, logger) {
|
|
26
24
|
this.context = {
|
|
27
25
|
authenticated: false
|
|
28
26
|
};
|
|
@@ -173,7 +171,7 @@ export class LottoService {
|
|
|
173
171
|
this.logger.debug('[getCheckWinningLink]', 'getCheckWinningLink');
|
|
174
172
|
return getCheckWinningLink(numbers, round);
|
|
175
173
|
};
|
|
176
|
-
this.
|
|
177
|
-
this.
|
|
174
|
+
this.browserController = controller;
|
|
175
|
+
this.logger = logger;
|
|
178
176
|
}
|
|
179
177
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createBrowserController } from '../controllers/factory';
|
|
2
|
+
import Logger from '../logger';
|
|
3
|
+
import { LottoServiceCore } from './lottoService.core';
|
|
4
|
+
export class LottoService extends LottoServiceCore {
|
|
5
|
+
constructor(configs) {
|
|
6
|
+
const logger = new Logger(configs.logLevel, '[LottoService]');
|
|
7
|
+
const controller = createBrowserController(Object.assign({ defaultViewport: { width: 1080, height: 1024 } }, configs), logger);
|
|
8
|
+
super(controller, logger);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"program":{"fileNames":["../node_modules/typescript/lib/lib.es5.d.ts","../node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/typescript/lib/lib.es2021.d.ts","../node_modules/typescript/lib/lib.es2022.d.ts","../node_modules/typescript/lib/lib.es2023.d.ts","../node_modules/typescript/lib/lib.esnext.d.ts","../node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/typescript/lib/lib.es2019.intl.d.ts","../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/typescript/lib/lib.es2020.number.d.ts","../node_modules/typescript/lib/lib.es2021.promise.d.ts","../node_modules/typescript/lib/lib.es2021.string.d.ts","../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../node_modules/typescript/lib/lib.es2021.intl.d.ts","../node_modules/typescript/lib/lib.es2022.array.d.ts","../node_modules/typescript/lib/lib.es2022.error.d.ts","../node_modules/typescript/lib/lib.es2022.intl.d.ts","../node_modules/typescript/lib/lib.es2022.object.d.ts","../node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2022.string.d.ts","../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../node_modules/typescript/lib/lib.es2023.array.d.ts","../node_modules/typescript/lib/lib.esnext.intl.d.ts","../node_modules/typescript/lib/lib.decorators.d.ts","../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../node_modules/@types/react/ts5.0/global.d.ts","../node_modules/csstype/index.d.ts","../node_modules/@types/react/ts5.0/index.d.ts","../node_modules/@types/react/ts5.0/jsx-runtime.d.ts","../node_modules/react-native/types/modules/BatchedBridge.d.ts","../node_modules/react-native/Libraries/vendor/emitter/EventEmitter.d.ts","../node_modules/react-native/types/modules/Codegen.d.ts","../node_modules/react-native/types/modules/Devtools.d.ts","../node_modules/react-native/Libraries/vendor/core/ErrorUtils.d.ts","../node_modules/react-native/src/types/globals.d.ts","../node_modules/react-native/types/private/Utilities.d.ts","../node_modules/react-native/types/public/Insets.d.ts","../node_modules/react-native/types/public/ReactNativeTypes.d.ts","../node_modules/react-native/Libraries/Types/CoreEventTypes.d.ts","../node_modules/react-native/types/public/ReactNativeRenderer.d.ts","../node_modules/react-native/Libraries/Components/Touchable/Touchable.d.ts","../node_modules/react-native/Libraries/Components/View/ViewAccessibility.d.ts","../node_modules/react-native/Libraries/Components/View/ViewPropTypes.d.ts","../node_modules/react-native/Libraries/Components/RefreshControl/RefreshControl.d.ts","../node_modules/react-native/Libraries/Components/View/View.d.ts","../node_modules/react-native/Libraries/Components/ScrollView/ScrollView.d.ts","../node_modules/react-native/Libraries/Image/ImageResizeMode.d.ts","../node_modules/react-native/Libraries/Image/ImageSource.d.ts","../node_modules/react-native/Libraries/Image/Image.d.ts","../node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.d.ts","../node_modules/@react-native/virtualized-lists/index.d.ts","../node_modules/react-native/Libraries/Lists/FlatList.d.ts","../node_modules/react-native/Libraries/ReactNative/RendererProxy.d.ts","../node_modules/react-native/Libraries/Lists/SectionList.d.ts","../node_modules/react-native/Libraries/Text/Text.d.ts","../node_modules/react-native/Libraries/Animated/Animated.d.ts","../node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts","../node_modules/react-native/Libraries/StyleSheet/StyleSheet.d.ts","../node_modules/react-native/Libraries/StyleSheet/processColor.d.ts","../node_modules/react-native/Libraries/ActionSheetIOS/ActionSheetIOS.d.ts","../node_modules/react-native/Libraries/Alert/Alert.d.ts","../node_modules/react-native/Libraries/Animated/Easing.d.ts","../node_modules/react-native/Libraries/Animated/useAnimatedValue.d.ts","../node_modules/react-native/Libraries/EventEmitter/RCTDeviceEventEmitter.d.ts","../node_modules/react-native/Libraries/EventEmitter/RCTNativeAppEventEmitter.d.ts","../node_modules/react-native/Libraries/AppState/AppState.d.ts","../node_modules/react-native/Libraries/BatchedBridge/NativeModules.d.ts","../node_modules/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts","../node_modules/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.d.ts","../node_modules/react-native/Libraries/Components/Clipboard/Clipboard.d.ts","../node_modules/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.d.ts","../node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.d.ts","../node_modules/react-native/Libraries/Components/Keyboard/Keyboard.d.ts","../node_modules/react-native/types/private/TimerMixin.d.ts","../node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts","../node_modules/react-native/Libraries/Components/LayoutConformance/LayoutConformance.d.ts","../node_modules/react-native/Libraries/Components/Pressable/Pressable.d.ts","../node_modules/react-native/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.d.ts","../node_modules/react-native/Libraries/Components/SafeAreaView/SafeAreaView.d.ts","../node_modules/react-native/Libraries/Components/StatusBar/StatusBar.d.ts","../node_modules/react-native/Libraries/Components/Switch/Switch.d.ts","../node_modules/react-native/Libraries/Components/TextInput/InputAccessoryView.d.ts","../node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts","../node_modules/react-native/Libraries/Components/ToastAndroid/ToastAndroid.d.ts","../node_modules/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.d.ts","../node_modules/react-native/Libraries/Components/Touchable/TouchableHighlight.d.ts","../node_modules/react-native/Libraries/Components/Touchable/TouchableOpacity.d.ts","../node_modules/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.d.ts","../node_modules/react-native/Libraries/Components/Button.d.ts","../node_modules/react-native/Libraries/Core/registerCallableModule.d.ts","../node_modules/react-native/Libraries/NativeComponent/NativeComponentRegistry.d.ts","../node_modules/react-native/Libraries/Interaction/InteractionManager.d.ts","../node_modules/react-native/Libraries/Interaction/PanResponder.d.ts","../node_modules/react-native/Libraries/LayoutAnimation/LayoutAnimation.d.ts","../node_modules/react-native/Libraries/Linking/Linking.d.ts","../node_modules/react-native/Libraries/LogBox/LogBox.d.ts","../node_modules/react-native/Libraries/Modal/Modal.d.ts","../node_modules/react-native/Libraries/Performance/Systrace.d.ts","../node_modules/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.d.ts","../node_modules/react-native/Libraries/PushNotificationIOS/PushNotificationIOS.d.ts","../node_modules/react-native/Libraries/Utilities/IPerformanceLogger.d.ts","../node_modules/react-native/Libraries/ReactNative/AppRegistry.d.ts","../node_modules/react-native/Libraries/ReactNative/I18nManager.d.ts","../node_modules/react-native/Libraries/ReactNative/RootTag.d.ts","../node_modules/react-native/Libraries/ReactNative/UIManager.d.ts","../node_modules/react-native/Libraries/ReactNative/requireNativeComponent.d.ts","../node_modules/react-native/Libraries/Settings/Settings.d.ts","../node_modules/react-native/Libraries/Share/Share.d.ts","../node_modules/react-native/Libraries/StyleSheet/PlatformColorValueTypesIOS.d.ts","../node_modules/react-native/Libraries/StyleSheet/PlatformColorValueTypes.d.ts","../node_modules/react-native/Libraries/TurboModule/RCTExport.d.ts","../node_modules/react-native/Libraries/TurboModule/TurboModuleRegistry.d.ts","../node_modules/react-native/Libraries/Types/CodegenTypesNamespace.d.ts","../node_modules/react-native/Libraries/Utilities/Appearance.d.ts","../node_modules/react-native/Libraries/Utilities/BackHandler.d.ts","../node_modules/react-native/src/private/devsupport/devmenu/DevMenu.d.ts","../node_modules/react-native/Libraries/Utilities/DevSettings.d.ts","../node_modules/react-native/Libraries/Utilities/Dimensions.d.ts","../node_modules/react-native/Libraries/Utilities/PixelRatio.d.ts","../node_modules/react-native/Libraries/Utilities/Platform.d.ts","../node_modules/react-native/Libraries/Vibration/Vibration.d.ts","../node_modules/react-native/types/public/DeprecatedPropertiesAlias.d.ts","../node_modules/react-native/Libraries/Utilities/codegenNativeCommands.d.ts","../node_modules/react-native/Libraries/Utilities/codegenNativeComponent.d.ts","../node_modules/react-native/types/index.d.ts","../node_modules/react-native-webview/lib/RNCWebViewNativeComponent.d.ts","../node_modules/react-native-webview/lib/WebViewTypes.d.ts","../node_modules/react-native-webview/index.d.ts","../src/controllers/webview/types.ts","../src/controllers/webview/bridgeScript.ts","../node_modules/dayjs/locale/types.d.ts","../node_modules/dayjs/locale/index.d.ts","../node_modules/dayjs/index.d.ts","../node_modules/dayjs/plugin/utc.d.ts","../node_modules/dayjs/plugin/timezone.d.ts","../src/logger.ts","../node_modules/@types/node/assert.d.ts","../node_modules/@types/node/assert/strict.d.ts","../node_modules/@types/node/globals.d.ts","../node_modules/@types/node/async_hooks.d.ts","../node_modules/@types/node/buffer.d.ts","../node_modules/@types/node/child_process.d.ts","../node_modules/@types/node/cluster.d.ts","../node_modules/@types/node/console.d.ts","../node_modules/@types/node/constants.d.ts","../node_modules/@types/node/crypto.d.ts","../node_modules/@types/node/dgram.d.ts","../node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/@types/node/dns.d.ts","../node_modules/@types/node/dns/promises.d.ts","../node_modules/@types/node/domain.d.ts","../node_modules/@types/node/dom-events.d.ts","../node_modules/@types/node/events.d.ts","../node_modules/@types/node/fs.d.ts","../node_modules/@types/node/fs/promises.d.ts","../node_modules/@types/node/http.d.ts","../node_modules/@types/node/http2.d.ts","../node_modules/@types/node/https.d.ts","../node_modules/@types/node/inspector.d.ts","../node_modules/@types/node/module.d.ts","../node_modules/@types/node/net.d.ts","../node_modules/@types/node/os.d.ts","../node_modules/@types/node/path.d.ts","../node_modules/@types/node/perf_hooks.d.ts","../node_modules/@types/node/process.d.ts","../node_modules/@types/node/punycode.d.ts","../node_modules/@types/node/querystring.d.ts","../node_modules/@types/node/readline.d.ts","../node_modules/@types/node/readline/promises.d.ts","../node_modules/@types/node/repl.d.ts","../node_modules/@types/node/stream.d.ts","../node_modules/@types/node/stream/promises.d.ts","../node_modules/@types/node/stream/consumers.d.ts","../node_modules/@types/node/stream/web.d.ts","../node_modules/@types/node/string_decoder.d.ts","../node_modules/@types/node/test.d.ts","../node_modules/@types/node/timers.d.ts","../node_modules/@types/node/timers/promises.d.ts","../node_modules/@types/node/tls.d.ts","../node_modules/@types/node/trace_events.d.ts","../node_modules/@types/node/tty.d.ts","../node_modules/@types/node/url.d.ts","../node_modules/@types/node/util.d.ts","../node_modules/@types/node/v8.d.ts","../node_modules/@types/node/vm.d.ts","../node_modules/@types/node/wasi.d.ts","../node_modules/@types/node/worker_threads.d.ts","../node_modules/@types/node/zlib.d.ts","../node_modules/@types/node/globals.global.d.ts","../node_modules/@types/node/index.d.ts","../node_modules/typed-query-selector/parser.d.ts","../node_modules/devtools-protocol/types/protocol.d.ts","../node_modules/devtools-protocol/types/protocol-mapping.d.ts","../node_modules/chromium-bidi/lib/cjs/protocol/generated/webdriver-bidi.d.ts","../node_modules/chromium-bidi/lib/cjs/protocol/cdp.d.ts","../node_modules/chromium-bidi/lib/cjs/protocol/generated/webdriver-bidi-bluetooth.d.ts","../node_modules/chromium-bidi/lib/cjs/protocol/generated/webdriver-bidi-permissions.d.ts","../node_modules/chromium-bidi/lib/cjs/protocol/chromium-bidi.d.ts","../node_modules/chromium-bidi/lib/cjs/protocol/ErrorResponse.d.ts","../node_modules/chromium-bidi/lib/cjs/protocol/protocol.d.ts","../node_modules/puppeteer/lib/types.d.ts","../node_modules/playwright-core/types/protocol.d.ts","../node_modules/playwright-core/types/structs.d.ts","../node_modules/playwright-core/types/types.d.ts","../src/types.ts","../src/utils/invertObject.ts","../src/lottoError.ts","../src/constants/selectors.ts","../src/constants/urls.ts","../src/constants/index.ts","../src/utils/deferred.ts","../src/utils/lazyRun.ts","../src/utils/getLastLottoRound.ts","../src/utils/validateLottoNumber.ts","../node_modules/axios/index.d.ts","../src/apis/dhlottery/getWinningNumbers.ts","../src/utils/checkWinning.ts","../src/utils/validatePurchaseAvailability.ts","../src/utils/getCheckWinningLink.ts","../src/utils/getNextLottoRound.ts","../src/services/lottoService.core.ts","../src/controllers/webview/webview.page.ts","../src/controllers/webview/index.ts","../src/index.native.ts","../src/utils/seconds.ts","../src/constants/dhlottery.ts","../src/apis/dhlottery/requestBuy.ts"],"fileInfos":[{"version":"6a6b471e7e43e15ef6f8fe617a22ce4ecb0e34efa6c3dfcfe7cebd392bcca9d2","affectsGlobalScope":true},"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","dc48272d7c333ccf58034c0026162576b7d50ea0e69c3b9292f803fc20720fd5","27147504487dc1159369da4f4da8a26406364624fa9bc3db632f7d94a5bae2c3","5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","5514e54f17d6d74ecefedc73c504eadffdeda79c7ea205cf9febead32d45c4bc","f4e736d6c8d69ae5b3ab0ddfcaa3dc365c3e76909d6660af5b4e979b3934ac20","eeeb3aca31fbadef8b82502484499dfd1757204799a6f5b33116201c810676ec",{"version":"f296963760430fb65b4e5d91f0ed770a91c6e77455bacf8fa23a1501654ede0e","affectsGlobalScope":true},{"version":"5114a95689b63f96b957e00216bc04baf9e1a1782aa4d8ee7e5e9acbf768e301","affectsGlobalScope":true},{"version":"4443e68b35f3332f753eacc66a04ac1d2053b8b035a0e0ac1d455392b5e243b3","affectsGlobalScope":true},{"version":"ab22100fdd0d24cfc2cc59d0a00fc8cf449830d9c4030dc54390a46bd562e929","affectsGlobalScope":true},{"version":"f7bd636ae3a4623c503359ada74510c4005df5b36de7f23e1db8a5c543fd176b","affectsGlobalScope":true},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true},{"version":"0c20f4d2358eb679e4ae8a4432bdd96c857a2960fd6800b21ec4008ec59d60ea","affectsGlobalScope":true},{"version":"36ae84ccc0633f7c0787bc6108386c8b773e95d3b052d9464a99cd9b8795fbec","affectsGlobalScope":true},{"version":"82d0d8e269b9eeac02c3bd1c9e884e85d483fcb2cd168bccd6bc54df663da031","affectsGlobalScope":true},{"version":"b8deab98702588840be73d67f02412a2d45a417a3c097b2e96f7f3a42ac483d1","affectsGlobalScope":true},{"version":"4738f2420687fd85629c9efb470793bb753709c2379e5f85bc1815d875ceadcd","affectsGlobalScope":true},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true},{"version":"376d554d042fb409cb55b5cbaf0b2b4b7e669619493c5d18d5fa8bd67273f82a","affectsGlobalScope":true},{"version":"9fc46429fbe091ac5ad2608c657201eb68b6f1b8341bd6d670047d32ed0a88fa","affectsGlobalScope":true},{"version":"61c37c1de663cf4171e1192466e52c7a382afa58da01b1dc75058f032ddf0839","affectsGlobalScope":true},{"version":"c4138a3dd7cd6cf1f363ca0f905554e8d81b45844feea17786cdf1626cb8ea06","affectsGlobalScope":true},{"version":"6ff3e2452b055d8f0ec026511c6582b55d935675af67cdb67dd1dc671e8065df","affectsGlobalScope":true},{"version":"03de17b810f426a2f47396b0b99b53a82c1b60e9cba7a7edda47f9bb077882f4","affectsGlobalScope":true},{"version":"8184c6ddf48f0c98429326b428478ecc6143c27f79b79e85740f17e6feb090f1","affectsGlobalScope":true},{"version":"261c4d2cf86ac5a89ad3fb3fafed74cbb6f2f7c1d139b0540933df567d64a6ca","affectsGlobalScope":true},{"version":"6af1425e9973f4924fca986636ac19a0cf9909a7e0d9d3009c349e6244e957b6","affectsGlobalScope":true},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true},{"version":"15a630d6817718a2ddd7088c4f83e4673fde19fa992d2eae2cf51132a302a5d3","affectsGlobalScope":true},{"version":"b7e9f95a7387e3f66be0ed6db43600c49cec33a3900437ce2fd350d9b7cb16f2","affectsGlobalScope":true},{"version":"01e0ee7e1f661acedb08b51f8a9b7d7f959e9cdb6441360f06522cc3aea1bf2e","affectsGlobalScope":true},{"version":"ac17a97f816d53d9dd79b0d235e1c0ed54a8cc6a0677e9a3d61efb480b2a3e4e","affectsGlobalScope":true},{"version":"bf14a426dbbf1022d11bd08d6b8e709a2e9d246f0c6c1032f3b2edb9a902adbe","affectsGlobalScope":true},{"version":"ec0104fee478075cb5171e5f4e3f23add8e02d845ae0165bfa3f1099241fa2aa","affectsGlobalScope":true},{"version":"2b72d528b2e2fe3c57889ca7baef5e13a56c957b946906d03767c642f386bbc3","affectsGlobalScope":true},{"version":"9cc66b0513ad41cb5f5372cca86ef83a0d37d1c1017580b7dace3ea5661836df","affectsGlobalScope":true},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true},{"version":"709efdae0cb5df5f49376cde61daacc95cdd44ae4671da13a540da5088bf3f30","affectsGlobalScope":true},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true},{"version":"61ed9b6d07af959e745fb11f9593ecd743b279418cc8a99448ea3cd5f3b3eb22","affectsGlobalScope":true},{"version":"038a2f66a34ee7a9c2fbc3584c8ab43dff2995f8c68e3f566f4c300d2175e31e","affectsGlobalScope":true},{"version":"4fa6ed14e98aa80b91f61b9805c653ee82af3502dc21c9da5268d3857772ca05","affectsGlobalScope":true},{"version":"f5c92f2c27b06c1a41b88f6db8299205aee52c2a2943f7ed29bd585977f254e8","affectsGlobalScope":true},{"version":"b7feb7967c6c6003e11f49efa8f5de989484e0a6ba2e5a6c41b55f8b8bd85dba","affectsGlobalScope":true},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true},{"version":"b9ea5778ff8b50d7c04c9890170db34c26a5358cccba36844fe319f50a43a61a","affectsGlobalScope":true},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true},{"version":"50d53ccd31f6667aff66e3d62adf948879a3a16f05d89882d1188084ee415bbc","affectsGlobalScope":true},{"version":"25de46552b782d43cb7284df22fe2a265de387cf0248b747a7a1b647d81861f6","affectsGlobalScope":true},{"version":"307c8b7ebbd7f23a92b73a4c6c0a697beca05b06b036c23a34553e5fe65e4fdc","affectsGlobalScope":true},{"version":"189c0703923150aa30673fa3de411346d727cc44a11c75d05d7cf9ef095daa22","affectsGlobalScope":true},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true},"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","d99a2f95af497a6fd9ef08d566365b7737c69724c7c7aa7a8986602c2f765d8d","016fe1e807dfdb88e8773616dde55bd04c087675662a393f20b1ec213b4a2b74",{"version":"3a909e8789a4f8b5377ef3fb8dc10d0c0a090c03f2e40aab599534727457475a","affectsGlobalScope":true},"fd412dd6372493eb8e3e95cae8687d35e4d34dde905a33e0ee47b74224cdd6ab","9d3b119c15e8eeb9a8fbeca47e0165ca7120704d90bf123b16ee5b612e2ecc9d","9f66eb21b8f041974625ec8f8ab3c6c36990b900b053ba962bb8b233301c8e47","005319c82222e57934c7b211013eb6931829e46b2a61c5d9a1c3c25f8dc3ea90",{"version":"8e9f2fcc90fd8ee219cd24cf8dadacd639af62907786ed5e272cf97941acfdd2","affectsGlobalScope":true},"232f660363b3b189f7be7822ed71e907195d1a85bc8d55d2b7ce3f09b2136938","e745388cfad9efb4e5a9a15a2c6b66d54094dd82f8d0c2551064e216f7b51526","84c8272b0651d84378f8d76bcc563fca1e88866f30fffd790d87648861d18ab1","cf1e23408bb2e38cb90d109cf8027c829f19424ad7a611c74edf39e1f195fe22","8ebf448e9837fda1a368acbb575b0e28843d5b2a3fda04bce76248b64326ea49","91b9f6241fca7843985aa31157cfa08cc724c77d91145a4d834d27cdde099c05","c5dc49c81f9cb20dff16b7933b50e19ac3565430cf685bbe51bcbcdb760fc03f","d78d4bc8bbda13ed147b23e63ff4ac83e3dcf4f07012afadd59e8a62473b5894","49f33cb54f1c57d269113fae1784795945957989b3b3e50e61cc6666c37698e7","f3c9bbc02c599af23defd5ca3683e46b4f3fa8a3e21a0194eac9910086050a0c","24b6109bdf5e2027f0a4366b9e1f988d648f08ea3748ebd690e76bba65115bf9","e7d56fa3c64c44b29fa11d840b1fe04f6d782fc2e341a1f01b987f5e59f34266","0f86beb951b048eb7e0a17609e934a59a8686683b2134632975baeacaf53c23d","e51855f55b01c41984044b49bd926b878a825ae696e62d77abf5b8c7f17922a3","c16b3221e31c25ef95c37c05c465abf16cbf6c9a7172f82cb5f8e697bd84ce03","42bacb33cddecbcfe3e043ee1117ba848801749e44f947626765b3e0aec74b1c","4e1bfec0f44a463f25cc26528a4505bc592feef555706311a143481f69a21d6f","cd2156bc8e4d54d52a2817d1b6f4629a5dd3173b1d8bb0fc893ee678d6a78ecd","6887bea839d87a3616091b06cfdd482b6180e62ea673341cac6a43c3493b639e","82eacfd7ea5b2ad312235aa279aaa1aecebed6b58d0f79fecc6f48a70417fa75","963dfba66d1744c7b35ae81cf6ebda2921df916806b6958ba093b63b0ef8c74a","1e6a28ff00137d6350a5e94b6ba35b4f16df851ba6b6c8fd1ba0973e2044d6a6","0600b6952abba5696c5079a62cc14430ba48682b1e1b7fbade74290c9857cd9a","9054417b5760061bc5fe31f9eee5dc9bf018339b0617d3c65dd1673c8e3c0f25","c6b68cd2e7838e91e05ede0a686815f521024281768f338644f6c0e0ad8e63cd","20c7a8cb00fda35bf50333488657c20fd36b9af9acb550f8410ef3e9bef51ef0","c94f70562ae60797cce564c3bebbaaf1752c327d5063d6ac152aa5ca1616c267","2aeb5fcdfc884b16015617d263fd8d1a8513f7efe23880be4e5f0bdb3794b37c","b561170fbe8d4292425e1dfa52406c8d97575681f7a5e420d11d9f72f7c29e38","5fe94f3f6411a0f6293f16fdc8e02ee61138941847ce91d6f6800c97fac22fcd","7f7c0ecc3eeeef905a3678e540947f4fbbc1a9c76075419dcc5fbfc3df59cb0b","df3303018d45c92be73fb4a282d5a242579f96235f5e0f8981983102caf5feca","0f1b593fc15591a6c6e8e5ee4c022b720e1c6e8524c1dd5196df42046808f033","d45c2f63eab3d231c75a446cf9578c904f17f096e712e3375934a554470c9575","084d0df6805570b6dc6c8b49c3a71d5bdfe59606901e0026c63945b68d4b080a","32bd5e456193f931b2a59b68e3801a2a0943dc641330389afc38e8277875a6da","0f066f9654e700a9cf79c75553c934eb14296aa80583bd2b5d07e2d582a3f4ee","269c5d54104033b70331343bd931c9933852a882391ed6bd98c3d8b7d6465d22","a56b8577aaf471d9e60582065a8193269310e8cae48c1ce4111ed03216f5f715","486ae83cd51b813095f6716f06cc9b2cf480ad1d6c7f8ec59674d6c858cd2407","039f0a1f6d67514bbfea62ffbb0822007ce35ba180853ec9034431f60f63dbe6","fff527e2567a24dd634a30268f1aa8a220315fed9c513d70ee872e54f67f27f3","dbd0bf577d4ec8368f3456fba405dc1989ce343f6c7a13347dbabd363ec22b4f","919492794863d6badec9ec17490ca445c3d79adf5df102eaa6ba0241a287dc20","b7d1cdc9810b334734a7d607c195daa721df6d114d99e96d595ff52db1df627b","946cce58bd3eb8d6235e288023aac2a13427e07022e9771c5bbdfa8ad6377101","77282216c61bcef9a700db98e142301d5a7d988d3076286029da63e415e98a42","e4f9959716f2d0f9946e9b9502c8aadf87aae7e389e6e5be53c27c8cc0181bb6","75ff8ea2c0c632719c14f50849c1fc7aa2d49f42b08c54373688536b3f995ee7","85a915dbb768b89cb92f5e6c165d776bfebd065883c34fee4e0219c3ed321b47","83df2f39cb14971adea51d1c84e7d146a34e9b7f84ad118450a51bdc3138412c","96d6742b440a834780d550fffc57d94d0aece2e04e485bce8d817dc5fb9b05d7","bdb2b70c74908c92ec41d8dd8375a195cb3bb07523e4de642b2b2dfbde249ca6","7b329f4137a552073f504022acbf8cd90d49cc5e5529791bef508f76ff774854","f63bbbffcfc897d22f34cf19ae13405cd267b1783cd21ec47d8a2d02947c98c1","cef48408162200abaea0c3a1be25a41fcd1b4dc41c3b90be6a89dde5ca4375c0","9da2649fb89af9bd08b2215621ad1cfda50f798d0acbd0d5fee2274ee940c827","df55b9be6ba19a6f77487e09dc7a94d7c9bf66094d35ea168dbd4bac42c46b8f","595125f3e088b883d104622ef10e6b7d5875ff6976bbe4d7dca090a3e2dca513","737fc8159cb99bf39a201c4d7097e92ad654927da76a1297ace7ffe358a2eda3","e0d7eed4ba363df3faadb8e617f95f9fc8adfbb00b87db7ade4a1098d6cf1e90","676088e53ca31e9e21e53f5a8996345d1b8a7d153737208029db964279004c3e","de115595321ce012c456f512a799679bfc874f0ac0a4928a8429557bb25086aa","896e4b676a6f55ca66d40856b63ec2ff7f4f594d6350f8ae04eaee8876da0bc5","0524cab11ba9048d151d93cc666d3908fda329eec6b1642e9a936093e6d79f28","869073d7523e75f45bd65b2072865c60002d5e0cbd3d17831e999cf011312778","bc7b5906a6ce6c5744a640c314e020856be6c50a693e77dc12aff2d77b12ca76","56503e377bc1344f155e4e3115a772cb4e59350c0b8131e3e1fb2750ac491608","6b579287217ee1320ee1c6cfec5f6730f3a1f91daab000f7131558ee531b2bf8","2586bc43511ba0f0c4d8e35dacf25ed596dde8ec50b9598ecd80194af52f992f","a793636667598e739a52684033037a67dc2d9db37fab727623626ef19aa5abb9","b15d6238a86bc0fc2368da429249b96c260debc0cec3eb7b5f838ad32587c129","9a9fba3a20769b0a74923e7032997451b61c1bd371c519429b29019399040d74","4b10e2fe52cb61035e58df3f1fdd926dd0fe9cf1a2302f92916da324332fb4e0","d1092ae8d6017f359f4758115f588e089848cc8fb359f7ba045b1a1cf3668a49","ddae9195b0da7b25a585ef43365f4dc5204a746b155fbee71e6ee1a9193fb69f","32dbced998ce74c5e76ce87044d0b4071857576dde36b0c6ed1d5957ce9cf5b5","29befd9bb08a9ed1660fd7ac0bc2ad24a56da550b75b8334ac76c2cfceda974a","ed8a8dedbd26d5c101bcc2d1691535d1fd0470dc82d7e866391e9b31b851ea8c","0aba767f26742d337f50e46f702a95f83ce694101fa9b8455786928a5672bb9b","8db57d8da0ab49e839fb2d0874cfe456553077d387f423a7730c54ef5f494318","ecc1b8878c8033bde0204b85e26fe1af6847805427759e5723882c848a11e134","cfc9c32553ad3b5be38342bc8731397438a93531118e1a226a8c79ad255b4f0c","16e5b5b023c2a1119c1878a51714861c56255778de0a7fe378391876a15f7433","f65096bb6555aad0429c5b6b21b92683398434be9b2ce0d3a1fdbb651c1243f1","a090a8a3b0ef2cceeb089acf4df95df72e7d934215896afe264ff6f734d66d15","151f422f08c8ca67b77c5c39d49278b4df452ef409237c8219be109ae3cdae9d","412a06aa68e902bc67d69f381c06f8fd52497921c5746fabddadd44f624741f5","c469120d20804fda2fc836f4d7007dfd5c1cef70443868858cb524fd6e54def1","206e2b17dd95b470b46edfa21c0e57aeca03f79fe5db994c506e7c8a6cc6de0d","e2ddbe6522370662d36ce3118411f9a6dab3e2fc847a6fc8f0e490fe0aecc323","bebc4da83fb5062fc1da3afc9f4e22b45ccd0761a2d62f860ce860fc5916b5ac","3ee52d00379b0c3df10e2bc8e988da0d1b3a4d29fe56ad81d81e1f6996053f88",{"version":"fd1e2bc8632e2c530788f496f686566f68fb161c043056306364631418a39a26","signature":"5030cacf98408543cf2fa3d42604caf3b64fd0dc9f23e01d5db394834414620e"},{"version":"1b20dae06003e918f4c2c475629160c43337fc1c11371890fd4b35f3b11a6fd5","signature":"fecdea20403edf792c98dcf24ec9d05c261df31dd67bfc494edfaa99b2fa13ad"},{"version":"73a0ee6395819b063df4b148211985f2e1442945c1a057204cf4cf6281760dc3","affectsGlobalScope":true},"d05d8c67116dceafc62e691c47ac89f8f10cf7313cd1b2fb4fe801c2bf1bb1a7","3c5bb5207df7095882400323d692957e90ec17323ccff5fd5f29a1ecf3b165d0","c868f50837eedd81fa9f61bd42de6665f74e7eb7a459135c6a14ac33ddc86798","56b2090352084289a1d572dfbddeed948906c0a0317a547ceb0ae6436ae44037",{"version":"4d01eec9373da4a15cee2a8abaa2d6c4aba1f98c9ca3c6e5ce87fa7d2b00ee2f","signature":"9150743e969ace60e593901497528427778b6f3ee9d0e6e33830342933a791ce"},"7e771891adaa85b690266bc37bd6eb43bc57eecc4b54693ead36467e7369952a","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"57b6cb95756d1fe3bfeb20205de27b0c5406e4a86e130c6dfa6bd92af641e09d","affectsGlobalScope":true},"11e2d554398d2bd460e7d06b2fa5827a297c8acfbe00b4f894a224ac0862857f",{"version":"e193e634a99c9c1d71f1c6e4e1567a4a73584328d21ea02dd5cddbaad6693f61","affectsGlobalScope":true},"374ca798f244e464346f14301dc2a8b4b111af1a83b49fffef5906c338a1f922","5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713",{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","e596c9bb2f29a2699fdd4ae89139612652245192f67f45617c5a4b20832aaae9","bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","1cdcfc1f624d6c08aa12c73935f6e13f095919cd99edf95752951796eb225729","216717f17c095cde1dc19375e1ab3af0a4a485355860c077a4f9d6ea59fab5b5","14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea",{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true},{"version":"816ad2e607a96de5bcac7d437f843f5afd8957f1fa5eefa6bba8e4ed7ca8fd84","affectsGlobalScope":true},"80473bd0dd90ca1e166514c2dfead9d5803f9c51418864ca35abbeec6e6847e1","1c84b46267610a34028edfd0d035509341751262bac1062857f3c8df7aff7153","e6c86d83bd526c8bdb5d0bf935b8e72ce983763d600743f74d812fdf4abf4df6","a3d541d303ee505053f5dcbf9fafb65cac3d5631037501cd616195863a6c5740","8d3c583a07e0c37e876908c2d5da575019f689df8d9fa4c081d99119d53dba22","2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58",{"version":"e630e5528e899219ae319e83bef54bf3bcb91b01d76861ecf881e8e614b167f0","affectsGlobalScope":true},"bcebb922784739bdb34c18ee51095d25a92b560c78ccd2eaacd6bd00f7443d83","7ee6ed878c4528215c82b664fe0cfe80e8b4da6c0d4cc80869367868774db8b1","b0973c3cbcdc59b37bf477731d468696ecaf442593ec51bab497a613a580fe30",{"version":"4989e92ba5b69b182d2caaea6295af52b7dc73a4f7a2e336a676722884e7139d","affectsGlobalScope":true},{"version":"0715e4cd28ad471b2a93f3e552ff51a3ae423417a01a10aa1d3bc7c6b95059d6","affectsGlobalScope":true},"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","210d54cd652ec0fec8c8916e4af59bb341065576ecda039842f9ffb2e908507c","36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","7d55d78cd47cf5280643b53434b16c2d9d11d144126932759fbdd51da525eec4","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","69ee23dd0d215b09907ad30d23f88b7790c93329d1faf31d7835552a10cf7cbf","44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","f69ff39996a61a0dd10f4bce73272b52e8024a4d58b13ab32bf4712909d0a2b7",{"version":"3c4ba1dd9b12ffa284b565063108f2f031d150ea15b8fafbdc17f5d2a07251f3","affectsGlobalScope":true},"e10177274a35a9d07c825615340b2fcde2f610f53f3fb40269fd196b4288dda6","c4577fb855ca259bdbf3ea663ca73988ce5f84251a92b4aef80a1f4122b6f98e","3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2",{"version":"f0900cd5d00fe1263ff41201fb8073dbeb984397e4af3b8002a5c207a30bdc33","affectsGlobalScope":true},{"version":"ff07a9a03c65732ccc59b3c65bc584173da093bd563a6565411c01f5703bd3cb","affectsGlobalScope":true},"6de4a219df57d2b27274d59b67708f13c2cbf7ed211abe57d8f9ab8b25cde776","0fe8985a28f82c450a04a6edf1279d7181c0893f37da7d2a27f8efd4fd5edb03","e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa",{"version":"da26af7362f53d122283bc69fed862b9a9fe27e01bc6a69d1d682e0e5a4df3e6","affectsGlobalScope":true},"8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"d8d555f3d607ecaa18d55de6995ea8f206342ecc93305919eac945c7c78c78c6","f21ce049835dad382b22691fb6b34076d0717307d46d92320893765be010cd56","1054238259c8e43516975f02f29161533ab43803a854579a3c9148041cc644a1","e305d9f544e14d33b5107bfcfaa15f65dff6090b2bdf316200ef3959116abbcf","bad543183ec86648236961be82294dbdb36e1872e6f00ae8f933eda8ef940178","213805012624f870635688113e692773d20b167717662e5b6e481945d4add36d","ab86380ba77855c05b584c881ad115c4b8886f7173e68480e0de4ef11d854cf3","665f83fc3e9992c7a5e15a470e4b9e10e8b588c35593b0058c8d1a9eca487c56","31494841ca6384086e59757b7e364515892b4ddb8fed214cabb6f4e524ec4969","dd36b144e0e70b4e38f588913af663ed959b10b5cf80952a4beb22a10255bf08","d064b43717b5b5dfca0d6cd738022ab377c90e45f05edbcd5a0c8753e6627d88","229ae4d4141d4c6f008d69b0cc89331c7909d0799ab7236ea2b28ad17b4a1e75","2374a7d32a94f9519c83203310d59c6eed36b14fd4e232f61649aa02326d21c4","32727845ab5bd8a9ef3e4844c567c09f6d418fcf0f90d381c00652a6f23e7f6e","6ce681121f9d9520c9a7f3fa9fcd976ce4534dc214983a9e8dac1b481c7ce7bc",{"version":"8c59bbeacf57a6eaec5304d403cb72846269e5f389a3c9096f8bb30fd5aa389d","signature":"80400cb840a2a1ce6014f5fbdec3eb9bee86056621f225fa0a0f3ef4a030dcf1","affectsGlobalScope":true},{"version":"5f7c146816f5eec0aba0c7b3780d0f0bfa8e0eec2e813da191e8b71a07d46f53","signature":"502bcfd6fa40dc81076754309039c4488b7e188c6dc796015fbc0acaacc68680"},{"version":"5ab2bf0580b2a60dd84c06980c636275596d05a7c5d4096ec587d6aef84ac07b","signature":"89270410843b3230c16760767c60c182f3573733622077de03ee9eb2f6a18c67"},{"version":"af755dbb470ac931aaf070f2872aa2b260fa9e95d881f4e737b3d3ee160e5866","signature":"af883c2ccea0bc62dab8a017ae1015e991bbcd839b78838976ebe026f4c378d4"},{"version":"1484abceed3a4bf06fd0130f3a343a3dd554767c9447e71c2acb5cfcdb01de39","signature":"10301439eab22d0595183c41e4ba64e84689bc31dd9120917f303618387f6d7d"},{"version":"64a46877a96401c42e35e3cae9251e7e8ece91960eb165f00e2a660d60ad0d72","signature":"d40c750adf6489a1be5ec3f02fa56b326b35d61b5ba6e4a22cc8a1b2ba48c739"},{"version":"77adfaac31f5ba5fd8a3cd589228d2cc4bf56a692f21bf4b9e6a403299d4a33c","signature":"ed9eae2be3e92d7886f70cce4f17e01a2e856654a79637cd5b57f66cfcb0e404"},{"version":"9df6f9ce6716278cd3dd581354e074c090f607176b88fa531a13559a1e3df705","signature":"921a20def41b946d460f971c93baa41c58fb418695a3d969392678d3a927ca79"},{"version":"1bd6467f185b74cd408e19ab044ff700c29a248625c13167036f4bef28945e35","signature":"07f551bc3d32f98fd2f5d8e1b5acfb49fb7f916816858362a8cf81913d45ee89"},{"version":"74e9b5762efbaad5d3ae4679e2492510eb4bf63803341c60746a27b75f6a138a","signature":"96ae5e96a971c0e917f3c5fc732c7cc8bbcd9ee8c9d0b22e79ed1a056fd702a9"},"331594cfe112a28054912754e428aeb2090200e06bb3477720c62eb9c4676242",{"version":"4b45d7be2d9f9fae3c46708a4b02b3e6363aa122fd81777fda04dbf6094b388b","signature":"6478b01714df9e2a13782dae044eab4bcd4b0db1217b1f0ef38598a34882141d"},{"version":"fed51b13402d3abcf138d9334d3c19b2a894e5472f7792891275c1d1c7dfee4d","signature":"7f0f05da3043e3c9762f2413d4a7551925f3aa8b75dc91865b86f7a1d0bc3610"},{"version":"f39962198cdbb2035d5b6581c29afd2176a342ff409fd33e6ecf8bfcd4537ae2","signature":"bb7126d8e3acf271c582b0281f3ae6533546d2e5794cd7420bb08be0530df459"},{"version":"44294b2043c5091301e73c8d2656e8411f4fa681b3c2294bcae668df07b91a17","signature":"e3bc7493573e7427eb77e4ca438f35c3b6b0bb543b15cb0658312e093d1ffe00"},{"version":"28a51a1a4d8b45ff6d9a8ec821ff03f9a8d282d07c57a4378274d401ec1f9c10","signature":"c186e76996a8b54e52429dc97e75d5e2d0ec6945daed4af954d209e9878e226a"},{"version":"2323be275628f17be2ba9a9c0ec02af50d1940e983b8089ad19c823660be0d65","signature":"c4eb532b58cc2778308a90abd12cbdb8d884800e768986e79d3694841ee15fed"},{"version":"d6d4801055c2e6b71dde033b1019c462568b49805469e2c6b80c2b38900fb3dc","signature":"31cfaf3f4cab3af5c3f0fb4ee77787ee4a5151dcda710d9c0cf0536a5f8613de"},{"version":"676643829f3cf8aad31ad7eaaa96089e47a357d7a5696149e5f1a4936f14c066","signature":"2f7209945df1e2b8e3b77ee01d25e40dbef66685c28a50be644821afe0002170"},{"version":"ab088ba2648d3455d79f999296acd21f738be862739846a22572389020b235a5","signature":"deabe212cc941c541fcf6b37e927e610e8231c90823119f3e91565a4cdf8f973"},{"version":"005b7a1e4ccd74d2f4695fca9503046fa2a702c3bbd333ed8e421307a0136583","signature":"25ba04d3e52e284ab064097304ca845232cd3c88e86a4f6d07d5d612675b42e1"},{"version":"e9a71fd63e806567757ebb1703c45689944a634fb8f1045e2d230a056a923909","signature":"210716e97b3a7bb26e82956403e667d0ecfed6082266d0cd4fb48d88b583af82"},{"version":"4ab8ed8191b44a654991c5d035ea15bfffc23d75cb5714c0c1e483ad57aeefe8","signature":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}],"root":[163,164,170,[239,248],[250,261]],"options":{"allowUnreachableCode":false,"allowUnusedLabels":false,"composite":true,"declaration":true,"declarationDir":"./typescript","esModuleInterop":true,"jsx":4,"module":99,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noImplicitReturns":true,"noImplicitUseStrict":false,"noStrictGenericChecks":false,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./esm","rootDir":"../src","skipLibCheck":true,"strict":true,"target":2},"fileIdsList":[[62,159,217],[84,217],[171,217],[174,217],[175,180,208,217],[176,187,188,195,205,216,217],[176,177,187,195,217],[178,217],[179,180,188,196,217],[180,205,213,217],[181,183,187,195,217],[182,217],[183,184,217],[187,217],[185,187,217],[187,188,189,205,216,217],[187,188,189,202,205,208,217],[217,221],[217],[183,190,195,205,216,217],[187,188,190,191,195,205,213,216,217],[190,192,205,213,216,217],[171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223],[187,193,217],[194,216,217],[183,187,195,205,217],[196,217],[197,217],[174,198,217],[199,215,217,221],[200,217],[201,217],[187,202,203,217],[202,204,217,219],[175,187,205,206,207,208,217],[175,205,207,217],[205,206,217],[208,217],[209,217],[187,211,212,217],[211,212,217],[180,195,205,213,217],[214,217],[195,215,217],[175,190,201,216,217],[180,217],[205,217,218],[217,219],[217,220],[175,180,187,189,198,205,216,217,219,221],[205,217,222],[60,61,217],[62,217],[217,228],[217,226,227,228],[217,228,229,230,231],[217,228,229,230,231,232,233],[166,217],[165,217],[167,168,217],[167,169,217],[217,226],[217,238],[176,188,205,217,236,237],[176,205,217,224,225,226,227,234],[62,161,217],[66,159,217],[62,159,160,217],[92,93,217],[62,73,79,80,83,86,88,89,92,217],[90,217],[99,217],[65,72,217],[62,70,72,73,77,91,92,217],[62,92,121,122,217],[62,70,72,73,77,92,217],[65,106,217],[62,70,77,91,92,108,217],[62,71,73,76,77,79,91,92,217],[62,70,72,77,92,217],[62,70,72,77,217],[62,70,71,72,73,75,77,78,79,91,92,217],[62,92,217],[62,91,92,217],[62,65,70,72,73,76,77,91,92,108,217],[62,71,73,217],[62,79,91,92,119,217],[62,70,75,92,119,121,217],[62,79,119,217],[62,70,71,73,75,76,91,92,108,217],[73,217],[62,71,73,74,75,76,91,92,217],[65,217],[98,217],[62,70,71,72,73,76,81,82,91,92,217],[73,74,217],[62,79,80,85,91,92,217],[62,80,85,87,91,92,217],[62,73,77,92,217],[62,72,217],[62,91,135,217],[72,217],[92,217],[91,217],[81,90,92,217],[62,70,72,73,76,91,92,217],[145,217],[65,159,217],[106,217],[159,217],[68,217],[64,65,66,67,68,69,71,72,73,74,75,76,77,78,79,80,81,82,83,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,217],[67,217],[63,217,239,241,249],[63,217],[63,163,170,217,239,256],[63,163,170,217,239,245,246],[62,63,159,162,163,164,170,217,239,247,251,253,254,255,257],[63,167,168,169,217],[63,217,240],[63,170,217,239,241,242,243,244,246,247,248,250,251,252,253,254],[63,163,170,217,235,238],[63,217,243],[63,217,244],[63,217,244,245],[63,217,241],[63,167,168,169,217,241],[163,170,239],[62,170,239,247,251,253,254,255],[170,239],[163,170,235,238]],"referencedMap":[[84,1],[85,2],[171,3],[172,3],[174,4],[175,5],[176,6],[177,7],[178,8],[179,9],[180,10],[181,11],[182,12],[183,13],[184,13],[186,14],[185,15],[187,14],[188,16],[189,17],[173,18],[223,19],[190,20],[191,21],[192,22],[224,23],[193,24],[194,25],[195,26],[196,27],[197,28],[198,29],[199,30],[200,31],[201,32],[202,33],[203,33],[204,34],[205,35],[207,36],[206,37],[208,38],[209,39],[210,19],[211,40],[212,41],[213,42],[214,43],[215,44],[216,45],[217,46],[218,47],[219,48],[220,49],[221,50],[222,51],[60,19],[62,52],[63,53],[249,19],[233,54],[229,55],[232,56],[230,19],[231,19],[228,19],[234,57],[61,19],[167,58],[166,59],[165,19],[169,60],[168,61],[227,62],[226,19],[236,19],[237,63],[238,64],[235,65],[162,66],[160,67],[161,68],[94,69],[95,19],[90,70],[96,19],[97,71],[100,72],[101,19],[102,73],[103,74],[123,75],[104,19],[105,76],[107,77],[109,78],[110,53],[111,79],[112,80],[78,80],[113,81],[80,82],[114,83],[115,74],[116,84],[117,85],[118,19],[75,86],[120,87],[122,88],[121,89],[119,90],[79,81],[76,91],[77,92],[124,19],[106,93],[98,93],[99,94],[83,95],[81,19],[82,19],[126,93],[127,96],[128,19],[129,77],[86,97],[88,98],[130,19],[131,99],[125,100],[132,19],[133,19],[134,19],[136,101],[137,19],[87,53],[138,53],[139,100],[140,102],[141,19],[142,103],[144,103],[143,103],[92,104],[91,105],[93,103],[89,106],[145,19],[146,107],[147,108],[73,100],[148,72],[149,72],[151,109],[152,93],[135,19],[153,19],[154,19],[157,19],[158,110],[155,19],[68,19],[65,19],[150,19],[69,111],[159,112],[64,19],[66,108],[67,113],[108,19],[70,19],[156,110],[71,19],[74,91],[72,53],[225,19],[58,19],[59,19],[13,19],[12,19],[2,19],[14,19],[15,19],[16,19],[17,19],[18,19],[19,19],[20,19],[21,19],[3,19],[4,19],[25,19],[22,19],[23,19],[24,19],[26,19],[27,19],[28,19],[5,19],[29,19],[30,19],[31,19],[32,19],[6,19],[36,19],[33,19],[34,19],[35,19],[37,19],[7,19],[38,19],[43,19],[44,19],[39,19],[40,19],[41,19],[42,19],[8,19],[48,19],[45,19],[46,19],[47,19],[49,19],[9,19],[50,19],[51,19],[52,19],[55,19],[53,19],[54,19],[56,19],[10,19],[1,19],[11,19],[57,19],[250,114],[261,115],[260,115],[244,115],[242,115],[243,115],[164,115],[257,116],[163,115],[256,117],[258,118],[170,119],[241,120],[255,121],[239,122],[251,115],[245,115],[253,123],[247,124],[254,124],[240,115],[246,125],[259,115],[248,126],[252,127]],"exportedModulesMap":[[84,1],[85,2],[171,3],[172,3],[174,4],[175,5],[176,6],[177,7],[178,8],[179,9],[180,10],[181,11],[182,12],[183,13],[184,13],[186,14],[185,15],[187,14],[188,16],[189,17],[173,18],[223,19],[190,20],[191,21],[192,22],[224,23],[193,24],[194,25],[195,26],[196,27],[197,28],[198,29],[199,30],[200,31],[201,32],[202,33],[203,33],[204,34],[205,35],[207,36],[206,37],[208,38],[209,39],[210,19],[211,40],[212,41],[213,42],[214,43],[215,44],[216,45],[217,46],[218,47],[219,48],[220,49],[221,50],[222,51],[60,19],[62,52],[63,53],[249,19],[233,54],[229,55],[232,56],[230,19],[231,19],[228,19],[234,57],[61,19],[167,58],[166,59],[165,19],[169,60],[168,61],[227,62],[226,19],[236,19],[237,63],[238,64],[235,65],[162,66],[160,67],[161,68],[94,69],[95,19],[90,70],[96,19],[97,71],[100,72],[101,19],[102,73],[103,74],[123,75],[104,19],[105,76],[107,77],[109,78],[110,53],[111,79],[112,80],[78,80],[113,81],[80,82],[114,83],[115,74],[116,84],[117,85],[118,19],[75,86],[120,87],[122,88],[121,89],[119,90],[79,81],[76,91],[77,92],[124,19],[106,93],[98,93],[99,94],[83,95],[81,19],[82,19],[126,93],[127,96],[128,19],[129,77],[86,97],[88,98],[130,19],[131,99],[125,100],[132,19],[133,19],[134,19],[136,101],[137,19],[87,53],[138,53],[139,100],[140,102],[141,19],[142,103],[144,103],[143,103],[92,104],[91,105],[93,103],[89,106],[145,19],[146,107],[147,108],[73,100],[148,72],[149,72],[151,109],[152,93],[135,19],[153,19],[154,19],[157,19],[158,110],[155,19],[68,19],[65,19],[150,19],[69,111],[159,112],[64,19],[66,108],[67,113],[108,19],[70,19],[156,110],[71,19],[74,91],[72,53],[225,19],[58,19],[59,19],[13,19],[12,19],[2,19],[14,19],[15,19],[16,19],[17,19],[18,19],[19,19],[20,19],[21,19],[3,19],[4,19],[25,19],[22,19],[23,19],[24,19],[26,19],[27,19],[28,19],[5,19],[29,19],[30,19],[31,19],[32,19],[6,19],[36,19],[33,19],[34,19],[35,19],[37,19],[7,19],[38,19],[43,19],[44,19],[39,19],[40,19],[41,19],[42,19],[8,19],[48,19],[45,19],[46,19],[47,19],[49,19],[9,19],[50,19],[51,19],[52,19],[55,19],[53,19],[54,19],[56,19],[10,19],[1,19],[11,19],[57,19],[257,128],[256,128],[258,129],[255,130],[239,131]],"semanticDiagnosticsPerFile":[84,85,171,172,174,175,176,177,178,179,180,181,182,183,184,186,185,187,188,189,173,223,190,191,192,224,193,194,195,196,197,198,199,200,201,202,203,204,205,207,206,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,60,62,63,249,233,229,232,230,231,228,234,61,167,166,165,169,168,227,226,236,237,238,235,162,160,161,94,95,90,96,97,100,101,102,103,123,104,105,107,109,110,111,112,78,113,80,114,115,116,117,118,75,120,122,121,119,79,76,77,124,106,98,99,83,81,82,126,127,128,129,86,88,130,131,125,132,133,134,136,137,87,138,139,140,141,142,144,143,92,91,93,89,145,146,147,73,148,149,151,152,135,153,154,157,158,155,68,65,150,69,159,64,66,67,108,70,156,71,74,72,225,58,59,13,12,2,14,15,16,17,18,19,20,21,3,4,25,22,23,24,26,27,28,5,29,30,31,32,6,36,33,34,35,37,7,38,43,44,39,40,41,42,8,48,45,46,47,49,9,50,51,52,55,53,54,56,10,1,11,57,250,261,260,244,242,243,164,257,163,256,258,170,241,255,239,251,245,253,247,254,240,246,259,248,252],"latestChangedDtsFile":"./typescript/apis/dhlottery/requestBuy.d.ts"},"version":"5.0.4"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const BRIDGE_SCRIPT = "\n(function() {\n if (window.__LOTTO_BRIDGE__) return;\n\n window.__LOTTO_BRIDGE__ = {\n fill: function(selector, value) {\n var el = document.querySelector(selector);\n if (!el) return { ok: false, error: 'Element not found: ' + selector };\n el.focus();\n el.value = value;\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n return { ok: true };\n },\n\n click: function(selector, domDirect) {\n var el = document.querySelector(selector);\n if (!el) return { ok: false, error: 'Element not found: ' + selector };\n el.click();\n return { ok: true };\n },\n\n select: function(selector, value) {\n var el = document.querySelector(selector);\n if (!el) return { ok: false, error: 'Element not found: ' + selector };\n el.value = value;\n el.dispatchEvent(new Event('change', { bubbles: true }));\n return { ok: true };\n },\n\n exists: function(selector, containsText) {\n var el = document.querySelector(selector);\n if (!el) return false;\n if (containsText) return (el.textContent || '').indexOf(containsText) !== -1;\n return true;\n },\n\n querySelectorAll: function(selector) {\n var MAX_DEPTH = 5;\n function toFakeDOM(el, depth) {\n return {\n className: el.className || '',\n innerHTML: el.innerHTML || '',\n children: depth < MAX_DEPTH\n ? Array.from(el.children).map(function(c) { return toFakeDOM(c, depth + 1); })\n : []\n };\n }\n return Array.from(document.querySelectorAll(selector)).map(function(el) { return toFakeDOM(el, 0); });\n },\n\n getUrl: function() {\n return window.location.href;\n },\n\n getCookies: function() {\n return document.cookie;\n },\n\n setCookies: function(cookieString) {\n cookieString.split('; ').forEach(function(cookie) {\n document.cookie = cookie;\n });\n return { ok: true };\n },\n\n waitForSelector: function(selector, timeout) {\n return new Promise(function(resolve) {\n var el = document.querySelector(selector);\n if (el) { resolve({ ok: true }); return; }\n\n var observer = new MutationObserver(function() {\n var found = document.querySelector(selector);\n if (found) {\n observer.disconnect();\n clearTimeout(timer);\n resolve({ ok: true });\n }\n });\n observer.observe(document.body || document.documentElement, { childList: true, subtree: true });\n\n var timer = setTimeout(function() {\n observer.disconnect();\n resolve({ ok: false, error: 'Timeout waiting for: ' + selector });\n }, timeout || 10000);\n });\n }\n };\n\n var ALLOWED_METHODS = ['fill','click','select','exists','querySelectorAll','getUrl','getCookies','setCookies','waitForSelector'];\n\n // \uCEE4\uB9E8\uB4DC \uC218\uC2E0 \uB9AC\uC2A4\uB108\n window.addEventListener('message', function(e) {\n try {\n var msg = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;\n if (!msg || !msg.__lotto_call_id__ || !msg.method) return;\n if (ALLOWED_METHODS.indexOf(msg.method) === -1) return;\n\n var fn = window.__LOTTO_BRIDGE__[msg.method];\n if (!fn) return;\n\n Promise.resolve(fn.apply(null, msg.args || [])).then(function(result) {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n __lotto_call_id__: msg.__lotto_call_id__,\n result: result\n }));\n });\n } catch (err) {\n if (msg && msg.__lotto_call_id__) {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n __lotto_call_id__: msg.__lotto_call_id__,\n result: { ok: false, error: String(err) }\n }));\n }\n }\n });\n\n true;\n})();\n";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BrowserConfigs, BrowserControllerInterface, BrowserPageInterface } from '../../types';
|
|
2
|
+
import type { LoggerInterface } from '../../logger';
|
|
3
|
+
import type { WebViewBridge } from './types';
|
|
4
|
+
export declare class WebViewController implements BrowserControllerInterface<WebViewBridge> {
|
|
5
|
+
configs: BrowserConfigs<WebViewBridge>;
|
|
6
|
+
logger: LoggerInterface;
|
|
7
|
+
private page;
|
|
8
|
+
constructor(configs: BrowserConfigs<WebViewBridge>, logger: LoggerInterface);
|
|
9
|
+
focus: () => Promise<BrowserPageInterface>;
|
|
10
|
+
close: () => Promise<void>;
|
|
11
|
+
cleanPages: () => Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface WebViewBridge {
|
|
2
|
+
readonly __type: 'webview';
|
|
3
|
+
/** 브릿지 메서드 호출 (postMessage → onMessage 왕복) */
|
|
4
|
+
call(method: string, args: unknown[]): Promise<unknown>;
|
|
5
|
+
/** WebView 페이지 네비게이션 (완료 시 resolve) */
|
|
6
|
+
navigateTo(url: string, waitUntil?: 'load' | 'idle'): Promise<void>;
|
|
7
|
+
/** 현재 URL 반환 */
|
|
8
|
+
getCurrentUrl(): string;
|
|
9
|
+
/** WebView 리소스 정리 */
|
|
10
|
+
destroy(): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BrowserPageEvents, BrowserPageInterface, FakeDOMElement, StringifiedCookies, Unsubscribe } from '../../types';
|
|
2
|
+
import type { LoggerInterface } from '../../logger';
|
|
3
|
+
import type { WebViewBridge } from './types';
|
|
4
|
+
export declare class WebViewPage implements BrowserPageInterface {
|
|
5
|
+
private bridge;
|
|
6
|
+
logger?: LoggerInterface;
|
|
7
|
+
constructor(bridge: WebViewBridge, logger?: LoggerInterface);
|
|
8
|
+
url(): Promise<string>;
|
|
9
|
+
goto(url: string, options?: {
|
|
10
|
+
waitUntil?: 'load' | 'idle';
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
fill(selector: string, value: string | number): Promise<void>;
|
|
13
|
+
click(selector: string, _domDirect?: boolean): Promise<void>;
|
|
14
|
+
select(selector: string, value: string): Promise<void>;
|
|
15
|
+
querySelectorAll<T>(selector: string, callback: (elems: FakeDOMElement[]) => T): Promise<T>;
|
|
16
|
+
exists(selector: string, containsText?: string): Promise<boolean>;
|
|
17
|
+
wait(param: 'idle' | 'load' | number): Promise<void>;
|
|
18
|
+
waitForSelector(selector: string, timeout?: number): Promise<void>;
|
|
19
|
+
getCookies(): Promise<StringifiedCookies>;
|
|
20
|
+
setCookies(cookies: StringifiedCookies): Promise<void>;
|
|
21
|
+
on(_event: BrowserPageEvents, _callback: (...args: unknown[]) => void): Unsubscribe;
|
|
22
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { LottoServiceInterface } from './types';
|
|
3
|
+
import { type LogLevel } from './logger';
|
|
4
|
+
interface UseLottoServiceOptions {
|
|
5
|
+
headless?: boolean;
|
|
6
|
+
logLevel?: LogLevel;
|
|
7
|
+
}
|
|
8
|
+
interface UseLottoServiceReturn {
|
|
9
|
+
LottoWebView: React.ComponentType;
|
|
10
|
+
service: LottoServiceInterface;
|
|
11
|
+
}
|
|
12
|
+
export declare function useLottoService(options?: UseLottoServiceOptions): UseLottoServiceReturn;
|
|
13
|
+
export { LottoServiceCore } from './services/lottoService.core';
|
|
14
|
+
export { LogLevel } from './logger';
|
|
15
|
+
export type { LottoServiceInterface, BrowserConfigs } from './types';
|
|
16
|
+
export { getLastLottoRound } from './utils/getLastLottoRound';
|
|
17
|
+
export { getNextLottoRound } from './utils/getNextLottoRound';
|
|
18
|
+
export { getCheckWinningLink } from './utils/getCheckWinningLink';
|
|
19
|
+
export { checkWinning } from './utils/checkWinning';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
export declare class
|
|
1
|
+
import type { BrowserControllerInterface, LottoServiceInterface } from '../types';
|
|
2
|
+
import type { LoggerInterface } from '../logger';
|
|
3
|
+
export declare class LottoServiceCore implements LottoServiceInterface {
|
|
4
4
|
context: {
|
|
5
5
|
authenticated: boolean;
|
|
6
6
|
};
|
|
7
7
|
browserController: BrowserControllerInterface;
|
|
8
8
|
logger: LoggerInterface;
|
|
9
|
-
constructor(
|
|
9
|
+
constructor(controller: BrowserControllerInterface, logger: LoggerInterface);
|
|
10
10
|
destroy: () => Promise<void>;
|
|
11
11
|
signInWithCookie: (cookies: string) => Promise<string>;
|
|
12
12
|
signIn: (id: string, password: string) => Promise<string>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { LogLevel } from './logger';
|
|
2
2
|
import type { PuppeteerNode } from 'puppeteer';
|
|
3
3
|
import type { BrowserType } from 'playwright-core';
|
|
4
|
+
import type { WebViewBridge } from './controllers/webview/types';
|
|
4
5
|
export interface LottoServiceInterface {
|
|
5
6
|
destroy(): Promise<void>;
|
|
6
7
|
signIn(id: string, password: string): Promise<string>;
|
|
@@ -12,7 +13,7 @@ export interface LottoServiceInterface {
|
|
|
12
13
|
purchase(amount: number): Promise<number[][]>;
|
|
13
14
|
getCheckWinningLink(numbers: number[][], round: number): string;
|
|
14
15
|
}
|
|
15
|
-
export type BrowserController = PuppeteerNode | BrowserType | 'api';
|
|
16
|
+
export type BrowserController = PuppeteerNode | BrowserType | WebViewBridge | 'api';
|
|
16
17
|
export interface BrowserConfigs<T extends BrowserController = BrowserController> {
|
|
17
18
|
controller: T;
|
|
18
19
|
logLevel?: LogLevel;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rich-automation/lotto",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Lotto module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -19,6 +19,17 @@
|
|
|
19
19
|
"main": "lib/cjs/index",
|
|
20
20
|
"module": "lib/esm/index",
|
|
21
21
|
"types": "lib/typescript/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./lib/typescript/index.d.ts",
|
|
25
|
+
"import": "./lib/esm/index.js",
|
|
26
|
+
"require": "./lib/cjs/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./react-native": {
|
|
29
|
+
"types": "./lib/typescript/index.native.d.ts",
|
|
30
|
+
"import": "./lib/esm/index.native.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
22
33
|
"files": [
|
|
23
34
|
"lib",
|
|
24
35
|
"package.json",
|
|
@@ -29,11 +40,12 @@
|
|
|
29
40
|
"prepack": "yarn build",
|
|
30
41
|
"release:ci": "release-it --ci --npm.skipChecks",
|
|
31
42
|
"release:ci:test": "release-it --ci --npm.skipChecks --dry-run",
|
|
32
|
-
"start": "ts-node ./example/app",
|
|
33
|
-
"build": "rm -rf lib && yarn build:cjs && yarn build:esm && yarn build:dts",
|
|
43
|
+
"start": "TS_NODE_PROJECT=tsconfig.base.json ts-node ./example/app",
|
|
44
|
+
"build": "rm -rf lib && yarn build:cjs && yarn build:esm && yarn build:dts && yarn build:native",
|
|
34
45
|
"build:cjs": "tsc --project tsconfig.cjs.json --verbatimModuleSyntax false && echo '{\"type\": \"commonjs\"}' > lib/cjs/package.json",
|
|
35
46
|
"build:esm": "tsc --project tsconfig.esm.json && echo '{\"type\": \"module\"}' > lib/esm/package.json",
|
|
36
|
-
"build:dts": "tsc --project tsconfig.json --emitDeclarationOnly --declaration --declarationDir lib/typescript",
|
|
47
|
+
"build:dts": "tsc --project tsconfig.base.json --emitDeclarationOnly --declaration --declarationDir lib/typescript",
|
|
48
|
+
"build:native": "tsc --project tsconfig.native.json",
|
|
37
49
|
"test": "jest --forceExit --detectOpenHandles",
|
|
38
50
|
"install:puppeteer": "node ./node_modules/puppeteer/install.mjs",
|
|
39
51
|
"install:playwright": "npx playwright install chromium --with-deps",
|
|
@@ -41,7 +53,7 @@
|
|
|
41
53
|
"fix:eslint": "eslint --fix src --ext js,jsx,ts,tsx ",
|
|
42
54
|
"fix:prettier": "prettier --write \"src/**/*.{ts,tsx,js}\"",
|
|
43
55
|
"lint": "yarn lint:ts && yarn lint:eslint && yarn lint:prettier",
|
|
44
|
-
"lint:ts": "tsc --noEmit",
|
|
56
|
+
"lint:ts": "tsc --noEmit -p tsconfig.base.json && tsc --noEmit -p tsconfig.native.json",
|
|
45
57
|
"lint:eslint": "eslint src --ext js,jsx,ts,tsx ",
|
|
46
58
|
"lint:prettier": "prettier --check \"src/**/*.{ts,tsx,js}\""
|
|
47
59
|
},
|
|
@@ -51,7 +63,9 @@
|
|
|
51
63
|
},
|
|
52
64
|
"peerDependencies": {
|
|
53
65
|
"playwright": "^1.35.0",
|
|
54
|
-
"puppeteer": "^20.5.0"
|
|
66
|
+
"puppeteer": "^20.5.0",
|
|
67
|
+
"react": "^19.1.0",
|
|
68
|
+
"react-native-webview": "^13.0.0"
|
|
55
69
|
},
|
|
56
70
|
"peerDependenciesMeta": {
|
|
57
71
|
"playwright": {
|
|
@@ -59,6 +73,15 @@
|
|
|
59
73
|
},
|
|
60
74
|
"puppeteer": {
|
|
61
75
|
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"react": {
|
|
78
|
+
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"react-native": {
|
|
81
|
+
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"react-native-webview": {
|
|
84
|
+
"optional": true
|
|
62
85
|
}
|
|
63
86
|
},
|
|
64
87
|
"devDependencies": {
|
|
@@ -66,6 +89,7 @@
|
|
|
66
89
|
"@babel/preset-env": "^7.21.4",
|
|
67
90
|
"@babel/preset-typescript": "^7.21.4",
|
|
68
91
|
"@types/jest": "^29.5.0",
|
|
92
|
+
"@types/react": "^19.2.14",
|
|
69
93
|
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
|
70
94
|
"@typescript-eslint/parser": "^5.58.0",
|
|
71
95
|
"babel-jest": "^29.5.0",
|
|
@@ -77,6 +101,8 @@
|
|
|
77
101
|
"playwright": "^1.51.1",
|
|
78
102
|
"prettier": "^2.8.7",
|
|
79
103
|
"puppeteer": "^24.6.1",
|
|
104
|
+
"react-native": "^0.84.0",
|
|
105
|
+
"react-native-webview": "^13.16.0",
|
|
80
106
|
"release-it": "^15.10.3",
|
|
81
107
|
"ts-node": "^10.9.1",
|
|
82
108
|
"typescript": "^5.0.4"
|