@iyulab/chat-components 0.3.0 → 0.5.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/CHANGELOG.md +146 -0
- package/README.md +133 -16
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +9 -0
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +6 -0
- package/dist/_virtual/_glob-assets_raw/intent-prompt.md.1907474e.js +4 -0
- package/dist/_virtual/_glob-assets_raw/view-prompt.md.e0dbcffe.js +4 -0
- package/dist/components/blocks/UCodeBlock.d.ts +24 -2
- package/dist/components/blocks/UCodeBlock.js +65 -2
- package/dist/components/blocks/UCodeBlock.styles.js +10 -4
- package/dist/components/blocks/UFileBlock.d.ts +33 -0
- package/dist/components/blocks/UFileBlock.js +154 -0
- package/dist/components/blocks/UFileBlock.styles.js +128 -0
- package/dist/components/blocks/UJsonBlock.d.ts +44 -2
- package/dist/components/blocks/UJsonBlock.js +128 -3
- package/dist/components/blocks/UJsonBlock.styles.js +4 -4
- package/dist/components/blocks/UMarkedBlock.d.ts +44 -2
- package/dist/components/blocks/UMarkedBlock.js +154 -4
- package/dist/components/blocks/UMarkedBlock.styles.js +4 -4
- package/dist/components/blocks/URefBlock.d.ts +16 -2
- package/dist/components/blocks/URefBlock.js +58 -3
- package/dist/components/blocks/URefBlock.styles.js +4 -4
- package/dist/components/blocks/UTableBlock.d.ts +52 -0
- package/dist/components/blocks/UTableBlock.js +198 -0
- package/dist/components/blocks/UTableBlock.styles.js +133 -0
- package/dist/components/blocks/UTextBlock.d.ts +36 -2
- package/dist/components/blocks/UTextBlock.js +94 -4
- package/dist/components/blocks/UTextBlock.styles.js +4 -4
- package/dist/components/blocks/UThinkBlock.d.ts +30 -2
- package/dist/components/blocks/UThinkBlock.js +86 -4
- package/dist/components/blocks/UThinkBlock.styles.js +4 -4
- package/dist/components/blocks/UToolBlock.d.ts +19 -2
- package/dist/components/blocks/UToolBlock.js +68 -3
- package/dist/components/blocks/UToolBlock.styles.js +4 -4
- package/dist/components/buttons/UAttachButton.d.ts +21 -2
- package/dist/components/buttons/UAttachButton.js +61 -3
- package/dist/components/buttons/UAttachButton.styles.js +4 -4
- package/dist/components/buttons/UCopyButton.d.ts +19 -2
- package/dist/components/buttons/UCopyButton.js +57 -3
- package/dist/components/buttons/UCopyButton.styles.js +4 -4
- package/dist/components/buttons/UVoteButton.d.ts +14 -3
- package/dist/components/buttons/UVoteButton.js +62 -3
- package/dist/components/buttons/UVoteButton.styles.js +4 -4
- package/dist/components/intents/UQuestionIntent.d.ts +22 -0
- package/dist/components/intents/UQuestionIntent.js +41 -0
- package/dist/components/intents/UQuestionIntent.styles.js +43 -0
- package/dist/components/message/UMessage.d.ts +18 -2
- package/dist/components/message/UMessage.js +47 -2
- package/dist/components/message/UMessage.styles.js +42 -15
- package/dist/components/prompt/UPrompt.d.ts +32 -2
- package/dist/components/prompt/UPrompt.js +118 -2
- package/dist/components/prompt/UPrompt.styles.js +43 -5
- package/dist/components/references/URefCard.d.ts +30 -2
- package/dist/components/references/URefCard.js +97 -2
- package/dist/components/references/URefCard.styles.js +4 -4
- package/dist/components/references/URefCardGroup.d.ts +25 -2
- package/dist/components/references/URefCardGroup.js +69 -4
- package/dist/components/references/URefCardGroup.styles.js +4 -4
- package/dist/components/references/URefTag.d.ts +12 -2
- package/dist/components/references/URefTag.js +37 -2
- package/dist/components/references/URefTag.styles.js +4 -4
- package/dist/components/views/UChartView.d.ts +39 -0
- package/dist/components/views/UChartView.js +167 -0
- package/dist/components/views/UChartView.styles.js +86 -0
- package/dist/components/views/UImagesView.d.ts +33 -0
- package/dist/components/views/UImagesView.js +144 -0
- package/dist/components/views/UImagesView.styles.d.ts +1 -0
- package/dist/components/views/UImagesView.styles.js +219 -0
- package/dist/components/views/UMapView.d.ts +24 -0
- package/dist/components/views/UMapView.js +45 -0
- package/dist/components/views/UMapView.styles.d.ts +1 -0
- package/dist/components/views/UMapView.styles.js +47 -0
- package/dist/components/views/UVideoView.d.ts +25 -0
- package/dist/components/views/UVideoView.js +81 -0
- package/dist/components/views/UVideoView.styles.d.ts +1 -0
- package/dist/components/views/UVideoView.styles.js +36 -0
- package/dist/components/views/UView.d.ts +46 -0
- package/dist/components/views/UView.js +113 -0
- package/dist/components/views/UView.styles.d.ts +1 -0
- package/dist/components/views/UView.styles.js +33 -0
- package/dist/events/AttachEvent.d.ts +9 -0
- package/dist/events/ChoiceEvent.d.ts +9 -0
- package/dist/events/SendEvent.d.ts +7 -0
- package/dist/events/StopEvent.d.ts +7 -0
- package/dist/index.d.ts +15 -6
- package/dist/index.js +28 -38
- package/dist/react/UAttachButton.d.ts +11 -0
- package/dist/react/UAttachButton.js +12 -0
- package/dist/react/UChartView.d.ts +9 -0
- package/dist/react/UChartView.js +10 -0
- package/dist/react/UCodeBlock.d.ts +9 -0
- package/dist/react/UCodeBlock.js +10 -0
- package/dist/react/UCopyButton.d.ts +9 -0
- package/dist/react/UCopyButton.js +10 -0
- package/dist/react/UFileBlock.d.ts +11 -0
- package/dist/react/UFileBlock.js +12 -0
- package/dist/react/UImagesView.d.ts +9 -0
- package/dist/react/UImagesView.js +10 -0
- package/dist/react/UJsonBlock.d.ts +9 -0
- package/dist/react/UJsonBlock.js +10 -0
- package/dist/react/UMapView.d.ts +9 -0
- package/dist/react/UMapView.js +10 -0
- package/dist/react/UMarkedBlock.d.ts +9 -0
- package/dist/react/UMarkedBlock.js +10 -0
- package/dist/react/UMessage.d.ts +9 -0
- package/dist/react/UMessage.js +10 -0
- package/dist/react/UPrompt.d.ts +13 -0
- package/dist/react/UPrompt.js +13 -0
- package/dist/react/UQuestionIntent.d.ts +11 -0
- package/dist/react/UQuestionIntent.js +12 -0
- package/dist/react/URefBlock.d.ts +9 -0
- package/dist/react/URefBlock.js +10 -0
- package/dist/react/URefCard.d.ts +9 -0
- package/dist/react/URefCard.js +10 -0
- package/dist/react/URefCardGroup.d.ts +9 -0
- package/dist/react/URefCardGroup.js +10 -0
- package/dist/react/URefTag.d.ts +9 -0
- package/dist/react/URefTag.js +10 -0
- package/dist/react/UTableBlock.d.ts +9 -0
- package/dist/react/UTableBlock.js +10 -0
- package/dist/react/UTextBlock.d.ts +9 -0
- package/dist/react/UTextBlock.js +10 -0
- package/dist/react/UThinkBlock.d.ts +9 -0
- package/dist/react/UThinkBlock.js +10 -0
- package/dist/react/UToolBlock.d.ts +9 -0
- package/dist/react/UToolBlock.js +10 -0
- package/dist/react/UVideoView.d.ts +9 -0
- package/dist/react/UVideoView.js +10 -0
- package/dist/react/UView.d.ts +9 -0
- package/dist/react/UView.js +10 -0
- package/dist/react/UVoteButton.d.ts +9 -0
- package/dist/react/UVoteButton.js +10 -0
- package/dist/react/index.d.ts +23 -0
- package/dist/react/index.js +23 -0
- package/dist/types/BlockItem.d.ts +21 -1
- package/dist/types/Intents.d.ts +26 -0
- package/dist/types/Intents.js +30 -0
- package/dist/types/JsonSchema.d.ts +59 -0
- package/dist/types/Views.d.ts +34 -0
- package/dist/types/Views.js +150 -0
- package/dist/utilities/IntentPromptBuilder.d.ts +40 -0
- package/dist/utilities/IntentPromptBuilder.js +95 -0
- package/dist/utilities/ViewPromptBuilder.d.ts +28 -0
- package/dist/utilities/ViewPromptBuilder.js +76 -0
- package/dist/utilities/dom-agent/DOMAgent.d.ts +74 -0
- package/dist/utilities/dom-agent/DOMController.d.ts +78 -0
- package/dist/utilities/dom-agent/DOMPromptBuilder.d.ts +54 -0
- package/dist/utilities/dom-agent/DOMScanner.d.ts +83 -0
- package/dist/utilities/dom-agent/index.d.ts +9 -0
- package/dist/utilities/dom-agent/types.d.ts +209 -0
- package/package.json +34 -18
- package/dist/components/blocks/UCodeBlock.component.d.ts +0 -23
- package/dist/components/blocks/UCodeBlock.component.js +0 -76
- package/dist/components/blocks/UJsonBlock.component.d.ts +0 -45
- package/dist/components/blocks/UJsonBlock.component.js +0 -140
- package/dist/components/blocks/UMarkedBlock.component.d.ts +0 -45
- package/dist/components/blocks/UMarkedBlock.component.js +0 -129
- package/dist/components/blocks/URefBlock.component.d.ts +0 -17
- package/dist/components/blocks/URefBlock.component.js +0 -74
- package/dist/components/blocks/UTextBlock.component.d.ts +0 -37
- package/dist/components/blocks/UTextBlock.component.js +0 -123
- package/dist/components/blocks/UThinkBlock.component.d.ts +0 -23
- package/dist/components/blocks/UThinkBlock.component.js +0 -90
- package/dist/components/blocks/UToolBlock.component.d.ts +0 -20
- package/dist/components/blocks/UToolBlock.component.js +0 -80
- package/dist/components/buttons/UAttachButton.component.d.ts +0 -22
- package/dist/components/buttons/UAttachButton.component.js +0 -89
- package/dist/components/buttons/UCopyButton.component.d.ts +0 -20
- package/dist/components/buttons/UCopyButton.component.js +0 -81
- package/dist/components/buttons/UReportButton.component.d.ts +0 -9
- package/dist/components/buttons/UReportButton.component.js +0 -36
- package/dist/components/buttons/UReportButton.d.ts +0 -7
- package/dist/components/buttons/UReportButton.js +0 -5
- package/dist/components/buttons/UReportButton.styles.js +0 -14
- package/dist/components/buttons/URetryButton.component.d.ts +0 -11
- package/dist/components/buttons/URetryButton.component.js +0 -53
- package/dist/components/buttons/URetryButton.d.ts +0 -7
- package/dist/components/buttons/URetryButton.js +0 -5
- package/dist/components/buttons/URetryButton.styles.js +0 -26
- package/dist/components/buttons/UShareButton.component.d.ts +0 -9
- package/dist/components/buttons/UShareButton.component.js +0 -36
- package/dist/components/buttons/UShareButton.d.ts +0 -7
- package/dist/components/buttons/UShareButton.js +0 -5
- package/dist/components/buttons/UShareButton.styles.js +0 -14
- package/dist/components/buttons/UVoteButton.component.d.ts +0 -15
- package/dist/components/buttons/UVoteButton.component.js +0 -70
- package/dist/components/loaders/UDotLoader.component.d.ts +0 -9
- package/dist/components/loaders/UDotLoader.component.js +0 -23
- package/dist/components/loaders/UDotLoader.d.ts +0 -7
- package/dist/components/loaders/UDotLoader.js +0 -5
- package/dist/components/loaders/UDotLoader.styles.js +0 -50
- package/dist/components/message/UMessage.component.d.ts +0 -19
- package/dist/components/message/UMessage.component.js +0 -90
- package/dist/components/prompt/UPrompt.component.d.ts +0 -25
- package/dist/components/prompt/UPrompt.component.js +0 -113
- package/dist/components/references/URefCard.component.d.ts +0 -24
- package/dist/components/references/URefCard.component.js +0 -105
- package/dist/components/references/URefCardGroup.component.d.ts +0 -25
- package/dist/components/references/URefCardGroup.component.js +0 -88
- package/dist/components/references/URefTag.component.d.ts +0 -13
- package/dist/components/references/URefTag.component.js +0 -54
- package/dist/events/UCancelEvent.d.ts +0 -6
- package/dist/events/USubmitEvent.d.ts +0 -6
- package/dist/utilities/converters.d.ts +0 -9
- package/dist/utilities/converters.js +0 -19
- /package/dist/components/{buttons/UReportButton.styles.d.ts → blocks/UFileBlock.styles.d.ts} +0 -0
- /package/dist/components/{buttons/URetryButton.styles.d.ts → blocks/UTableBlock.styles.d.ts} +0 -0
- /package/dist/components/{buttons/UShareButton.styles.d.ts → intents/UQuestionIntent.styles.d.ts} +0 -0
- /package/dist/components/{loaders/UDotLoader.styles.d.ts → views/UChartView.styles.d.ts} +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/types/Intents.ts
|
|
2
|
+
/** 프리셋 Intent 비트 플래그 */
|
|
3
|
+
var PresetIntent = /* @__PURE__ */ function(PresetIntent) {
|
|
4
|
+
PresetIntent[PresetIntent["Questions"] = 1] = "Questions";
|
|
5
|
+
PresetIntent[PresetIntent["All"] = 1] = "All";
|
|
6
|
+
return PresetIntent;
|
|
7
|
+
}({});
|
|
8
|
+
/** 프리셋 Intent 목록 (비트 플래그 순서대로) */
|
|
9
|
+
var PRESET_INTENT_LIST = [PresetIntent.Questions];
|
|
10
|
+
/** 프리셋 Intent 정의 매핑 */
|
|
11
|
+
var PRESET_INTENT_DEFINITIONS = new Map([[PresetIntent.Questions, {
|
|
12
|
+
type: "question",
|
|
13
|
+
description: "Present a question to the user with clickable choices",
|
|
14
|
+
properties: {
|
|
15
|
+
question: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "Optional question text displayed above the choices (e.g. \"What would you like to explore?\")"
|
|
18
|
+
},
|
|
19
|
+
choices: {
|
|
20
|
+
type: "array",
|
|
21
|
+
items: { type: "string" },
|
|
22
|
+
minItems: 1,
|
|
23
|
+
maxItems: 5,
|
|
24
|
+
description: "Clickable choice buttons (1–5 items)"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
required: ["choices"]
|
|
28
|
+
}]]);
|
|
29
|
+
//#endregion
|
|
30
|
+
export { PRESET_INTENT_DEFINITIONS, PRESET_INTENT_LIST, PresetIntent };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 위젯 정의용 JSON Schema 타입
|
|
3
|
+
*
|
|
4
|
+
* 위젯의 속성을 LLM에게 설명하기 위한 최소한의 스키마 정의만 포함.
|
|
5
|
+
* 복잡한 검증 기능이나 메타 정보는 제외하여 단순화함.
|
|
6
|
+
*
|
|
7
|
+
* 제외된 기능들:
|
|
8
|
+
* - $schema, $id 등 메타 정보 (위젯 정의에 불필요)
|
|
9
|
+
* - pattern, format 등 고급 검증 (LLM이 직접 생성하므로 불필요)
|
|
10
|
+
* - allOf, anyOf 등 조합 스키마 (복잡도 증가, 위젯에 과도함)
|
|
11
|
+
* - 조건부 스키마 if/then/else (위젯 속성에 불필요)
|
|
12
|
+
* - 고급 object/array 검증들 (단순한 구조만으로 충분)
|
|
13
|
+
*/
|
|
14
|
+
export interface BaseJsonSchema {
|
|
15
|
+
/** 속성에 대한 설명 (LLM용) */
|
|
16
|
+
description?: string;
|
|
17
|
+
/** 기본값 */
|
|
18
|
+
default?: any;
|
|
19
|
+
/** 허용 가능한 값들 (제한된 선택지) */
|
|
20
|
+
enum?: any[];
|
|
21
|
+
/** 예시 값들 (LLM이 이해하기 쉽도록) */
|
|
22
|
+
examples?: any[];
|
|
23
|
+
}
|
|
24
|
+
export interface BooleanJsonSchema extends BaseJsonSchema {
|
|
25
|
+
type: 'boolean';
|
|
26
|
+
}
|
|
27
|
+
export interface StringJsonSchema extends BaseJsonSchema {
|
|
28
|
+
type: 'string';
|
|
29
|
+
/** 최소 문자열 길이 */
|
|
30
|
+
minLength?: number;
|
|
31
|
+
/** 최대 문자열 길이 */
|
|
32
|
+
maxLength?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface NumberJsonSchema extends BaseJsonSchema {
|
|
35
|
+
type: 'number' | 'integer';
|
|
36
|
+
/** 최솟값 */
|
|
37
|
+
minimum?: number;
|
|
38
|
+
/** 최댓값 */
|
|
39
|
+
maximum?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface ArrayJsonSchema extends BaseJsonSchema {
|
|
42
|
+
type: 'array';
|
|
43
|
+
/** 배열 아이템의 스키마 */
|
|
44
|
+
items?: JsonSchema;
|
|
45
|
+
/** 최소 아이템 개수 */
|
|
46
|
+
minItems?: number;
|
|
47
|
+
/** 최대 아이템 개수 */
|
|
48
|
+
maxItems?: number;
|
|
49
|
+
}
|
|
50
|
+
export interface ObjectJsonSchema extends BaseJsonSchema {
|
|
51
|
+
type: 'object';
|
|
52
|
+
/** 객체의 속성들 */
|
|
53
|
+
properties?: Record<string, JsonSchema>;
|
|
54
|
+
/** 필수 속성 목록 */
|
|
55
|
+
required?: string[];
|
|
56
|
+
/** 정의되지 않은 추가 속성 허용 여부 */
|
|
57
|
+
additionalProperties?: boolean;
|
|
58
|
+
}
|
|
59
|
+
export type JsonSchema = BooleanJsonSchema | StringJsonSchema | NumberJsonSchema | ArrayJsonSchema | ObjectJsonSchema;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { JsonSchema } from './JsonSchema.js';
|
|
2
|
+
/**
|
|
3
|
+
* View를 정의하는 구조체
|
|
4
|
+
*/
|
|
5
|
+
export interface ViewDefinition {
|
|
6
|
+
/** 등록할 커스텀 엘리먼트 클래스 */
|
|
7
|
+
element: CustomElementConstructor;
|
|
8
|
+
/** 등록할 커스텀 엘리먼트 태그명 */
|
|
9
|
+
tag: string;
|
|
10
|
+
/** LLM용 설명 */
|
|
11
|
+
description: string;
|
|
12
|
+
/** LLM용 속성 스키마 */
|
|
13
|
+
properties?: Record<string, JsonSchema>;
|
|
14
|
+
/** 필수 속성 목록 */
|
|
15
|
+
required?: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 프리셋 View 비트 플래그
|
|
19
|
+
*/
|
|
20
|
+
export declare enum PresetView {
|
|
21
|
+
Images = 1,
|
|
22
|
+
Video = 2,
|
|
23
|
+
Map = 8,
|
|
24
|
+
Chart = 16,
|
|
25
|
+
All = 27
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 전체 프리셋 View 플래그 목록
|
|
29
|
+
*/
|
|
30
|
+
export declare const PRESET_VIEW_LIST: readonly [PresetView.Images, PresetView.Video, PresetView.Map, PresetView.Chart];
|
|
31
|
+
/**
|
|
32
|
+
* 프리셋 View 정의
|
|
33
|
+
*/
|
|
34
|
+
export declare const PRESET_VIEW_DEFINITIONS: Map<PresetView, ViewDefinition>;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { UImagesView } from "../components/views/UImagesView.js";
|
|
2
|
+
import { UVideoView } from "../components/views/UVideoView.js";
|
|
3
|
+
import { UMapView } from "../components/views/UMapView.js";
|
|
4
|
+
import { UChartView } from "../components/views/UChartView.js";
|
|
5
|
+
//#region src/types/Views.ts
|
|
6
|
+
/**
|
|
7
|
+
* 프리셋 View 비트 플래그
|
|
8
|
+
*/
|
|
9
|
+
var PresetView = /* @__PURE__ */ function(PresetView) {
|
|
10
|
+
PresetView[PresetView["Images"] = 1] = "Images";
|
|
11
|
+
PresetView[PresetView["Video"] = 2] = "Video";
|
|
12
|
+
PresetView[PresetView["Map"] = 8] = "Map";
|
|
13
|
+
PresetView[PresetView["Chart"] = 16] = "Chart";
|
|
14
|
+
PresetView[PresetView["All"] = 27] = "All";
|
|
15
|
+
return PresetView;
|
|
16
|
+
}({});
|
|
17
|
+
/**
|
|
18
|
+
* 전체 프리셋 View 플래그 목록
|
|
19
|
+
*/
|
|
20
|
+
var PRESET_VIEW_LIST = [
|
|
21
|
+
PresetView.Images,
|
|
22
|
+
PresetView.Video,
|
|
23
|
+
PresetView.Map,
|
|
24
|
+
PresetView.Chart
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* 프리셋 View 정의
|
|
28
|
+
*/
|
|
29
|
+
var PRESET_VIEW_DEFINITIONS = new Map([
|
|
30
|
+
[PresetView.Images, {
|
|
31
|
+
element: UImagesView,
|
|
32
|
+
tag: "u-images-view",
|
|
33
|
+
description: "Display multiple images in a scrollable gallery",
|
|
34
|
+
properties: { items: {
|
|
35
|
+
type: "array",
|
|
36
|
+
items: {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {
|
|
39
|
+
src: {
|
|
40
|
+
type: "string",
|
|
41
|
+
description: "Image URL"
|
|
42
|
+
},
|
|
43
|
+
alt: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "Alt text for accessibility"
|
|
46
|
+
},
|
|
47
|
+
caption: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "Image caption"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
required: ["src"]
|
|
53
|
+
},
|
|
54
|
+
minItems: 1,
|
|
55
|
+
description: "Array of image objects"
|
|
56
|
+
} },
|
|
57
|
+
required: ["items"]
|
|
58
|
+
}],
|
|
59
|
+
[PresetView.Video, {
|
|
60
|
+
element: UVideoView,
|
|
61
|
+
tag: "u-video-view",
|
|
62
|
+
description: "Embed video from YouTube, Vimeo, or Others. Provide a direct video file URL or a platform URL.",
|
|
63
|
+
properties: {
|
|
64
|
+
src: {
|
|
65
|
+
type: "string",
|
|
66
|
+
description: "Video URL (YouTube, Vimeo, or direct video file URL)"
|
|
67
|
+
},
|
|
68
|
+
poster: {
|
|
69
|
+
type: "string",
|
|
70
|
+
description: "Poster image URL"
|
|
71
|
+
},
|
|
72
|
+
ratio: {
|
|
73
|
+
type: "string",
|
|
74
|
+
enum: [
|
|
75
|
+
"16:9",
|
|
76
|
+
"4:3",
|
|
77
|
+
"1:1"
|
|
78
|
+
],
|
|
79
|
+
default: "16:9",
|
|
80
|
+
description: "Video aspect ratio"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
required: ["src"]
|
|
84
|
+
}],
|
|
85
|
+
[PresetView.Map, {
|
|
86
|
+
element: UMapView,
|
|
87
|
+
tag: "u-map-view",
|
|
88
|
+
description: "Display a map showing a single location",
|
|
89
|
+
properties: {
|
|
90
|
+
lat: {
|
|
91
|
+
type: "number",
|
|
92
|
+
description: "Latitude coordinate"
|
|
93
|
+
},
|
|
94
|
+
lng: {
|
|
95
|
+
type: "number",
|
|
96
|
+
description: "Longitude coordinate"
|
|
97
|
+
},
|
|
98
|
+
zoom: {
|
|
99
|
+
type: "integer",
|
|
100
|
+
minimum: 1,
|
|
101
|
+
maximum: 20,
|
|
102
|
+
default: 15,
|
|
103
|
+
description: "Map zoom level"
|
|
104
|
+
},
|
|
105
|
+
label: {
|
|
106
|
+
type: "string",
|
|
107
|
+
description: "Location title"
|
|
108
|
+
},
|
|
109
|
+
description: {
|
|
110
|
+
type: "string",
|
|
111
|
+
description: "Location description"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
required: ["lat", "lng"]
|
|
115
|
+
}],
|
|
116
|
+
[PresetView.Chart, {
|
|
117
|
+
element: UChartView,
|
|
118
|
+
tag: "u-chart-view",
|
|
119
|
+
description: "Display charts using Chart.js v4 format. Use standard Chart.js configuration (type, data, options). The View accepts the exact same structure as Chart.js - no conversion needed.",
|
|
120
|
+
properties: {
|
|
121
|
+
type: {
|
|
122
|
+
type: "string",
|
|
123
|
+
enum: [
|
|
124
|
+
"bar",
|
|
125
|
+
"line",
|
|
126
|
+
"pie",
|
|
127
|
+
"doughnut",
|
|
128
|
+
"radar",
|
|
129
|
+
"polarArea",
|
|
130
|
+
"bubble",
|
|
131
|
+
"scatter"
|
|
132
|
+
],
|
|
133
|
+
description: "Chart.js chart type"
|
|
134
|
+
},
|
|
135
|
+
data: {
|
|
136
|
+
type: "object",
|
|
137
|
+
description: "Chart.js data configuration",
|
|
138
|
+
additionalProperties: true
|
|
139
|
+
},
|
|
140
|
+
options: {
|
|
141
|
+
type: "object",
|
|
142
|
+
description: "Chart.js options configuration (optional)",
|
|
143
|
+
additionalProperties: true
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
required: ["type", "data"]
|
|
147
|
+
}]
|
|
148
|
+
]);
|
|
149
|
+
//#endregion
|
|
150
|
+
export { PRESET_VIEW_DEFINITIONS, PRESET_VIEW_LIST, PresetView };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PresetIntent, IntentDefinition, IntentSchema } from '../types/Intents.js';
|
|
2
|
+
/**
|
|
3
|
+
* Intent 등록, LLM 인스트럭션 빌드, 텍스트 추출을 통합 제공하는 유틸리티
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* IntentPromptBuilder.use(PresetIntent.All);
|
|
7
|
+
* const prompt = IntentPromptBuilder.buildPrompt();
|
|
8
|
+
* const [clean, templates] = IntentPromptBuilder.extractPrompt(llmText);
|
|
9
|
+
*/
|
|
10
|
+
export declare class IntentPromptBuilder {
|
|
11
|
+
private static _instance;
|
|
12
|
+
private intents;
|
|
13
|
+
/**
|
|
14
|
+
* 싱글톤 인스턴스를 반환합니다. 최초 호출 시 인스턴스가 생성됩니다.
|
|
15
|
+
*/
|
|
16
|
+
static get instance(): IntentPromptBuilder;
|
|
17
|
+
/**
|
|
18
|
+
* Intent 정의를 등록합니다. 같은 type이 이미 등록되어 있으면 에러를 던집니다.
|
|
19
|
+
* @throws {Error} 같은 type의 intent가 이미 등록된 경우
|
|
20
|
+
*/
|
|
21
|
+
add(definition: IntentDefinition): IntentPromptBuilder;
|
|
22
|
+
/**
|
|
23
|
+
* 미리 정의된 프리셋 Intent를 등록합니다.
|
|
24
|
+
* @example
|
|
25
|
+
* IntentPromptBuilder.use(PresetIntent.Questions);
|
|
26
|
+
* IntentPromptBuilder.use(PresetIntent.All);
|
|
27
|
+
*/
|
|
28
|
+
use(flags: PresetIntent): IntentPromptBuilder;
|
|
29
|
+
/**
|
|
30
|
+
* 등록된 intent들에 대한 LLM 시스템 프롬프트 인스트럭션을 생성합니다.
|
|
31
|
+
*/
|
|
32
|
+
build(): string;
|
|
33
|
+
/**
|
|
34
|
+
* LLM 응답 텍스트에서 `intent-json` 코드블록을 추출합니다.
|
|
35
|
+
*
|
|
36
|
+
* @param value - LLM 응답 텍스트
|
|
37
|
+
* @returns `[intents, rest]` — intents는 파싱된 JSON 객체 배열, rest는 블록이 제거된 나머지 텍스트
|
|
38
|
+
*/
|
|
39
|
+
parse(value: string): [IntentSchema[], string];
|
|
40
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { PRESET_INTENT_DEFINITIONS, PRESET_INTENT_LIST } from "../types/Intents.js";
|
|
2
|
+
import intent_prompt_md_default from "../_virtual/_glob-assets_raw/intent-prompt.md.1907474e.js";
|
|
3
|
+
//#region src/utilities/IntentPromptBuilder.ts
|
|
4
|
+
/**
|
|
5
|
+
* Intent 등록, LLM 인스트럭션 빌드, 텍스트 추출을 통합 제공하는 유틸리티
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* IntentPromptBuilder.use(PresetIntent.All);
|
|
9
|
+
* const prompt = IntentPromptBuilder.buildPrompt();
|
|
10
|
+
* const [clean, templates] = IntentPromptBuilder.extractPrompt(llmText);
|
|
11
|
+
*/
|
|
12
|
+
var IntentPromptBuilder = class IntentPromptBuilder {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.intents = /* @__PURE__ */ new Map();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 싱글톤 인스턴스를 반환합니다. 최초 호출 시 인스턴스가 생성됩니다.
|
|
18
|
+
*/
|
|
19
|
+
static get instance() {
|
|
20
|
+
if (!this._instance) this._instance = new IntentPromptBuilder();
|
|
21
|
+
return this._instance;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Intent 정의를 등록합니다. 같은 type이 이미 등록되어 있으면 에러를 던집니다.
|
|
25
|
+
* @throws {Error} 같은 type의 intent가 이미 등록된 경우
|
|
26
|
+
*/
|
|
27
|
+
add(definition) {
|
|
28
|
+
if (this.intents.has(definition.type)) throw new Error(`Intent with type "${definition.type}" is already registered.`);
|
|
29
|
+
this.intents.set(definition.type, definition);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 미리 정의된 프리셋 Intent를 등록합니다.
|
|
34
|
+
* @example
|
|
35
|
+
* IntentPromptBuilder.use(PresetIntent.Questions);
|
|
36
|
+
* IntentPromptBuilder.use(PresetIntent.All);
|
|
37
|
+
*/
|
|
38
|
+
use(flags) {
|
|
39
|
+
for (const flag of PRESET_INTENT_LIST) if (flags & flag) {
|
|
40
|
+
const definition = PRESET_INTENT_DEFINITIONS.get(flag);
|
|
41
|
+
if (definition && !this.intents.has(definition.type)) this.intents.set(definition.type, definition);
|
|
42
|
+
}
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 등록된 intent들에 대한 LLM 시스템 프롬프트 인스트럭션을 생성합니다.
|
|
47
|
+
*/
|
|
48
|
+
build() {
|
|
49
|
+
if (this.intents.size === 0) return "";
|
|
50
|
+
const docs = Array.from(this.intents.values()).map((def) => {
|
|
51
|
+
return [
|
|
52
|
+
`### ${def.type}`,
|
|
53
|
+
"",
|
|
54
|
+
"**JSON Schema:**",
|
|
55
|
+
"```intent-json",
|
|
56
|
+
JSON.stringify({
|
|
57
|
+
type: "object",
|
|
58
|
+
description: def.description,
|
|
59
|
+
properties: {
|
|
60
|
+
type: {
|
|
61
|
+
type: "string",
|
|
62
|
+
enum: [def.type]
|
|
63
|
+
},
|
|
64
|
+
properties: {
|
|
65
|
+
type: "object",
|
|
66
|
+
properties: def.properties || {},
|
|
67
|
+
required: def.required || []
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
required: ["type"]
|
|
71
|
+
}, null, 2),
|
|
72
|
+
"```"
|
|
73
|
+
].join("\n");
|
|
74
|
+
}).join("\n\n---\n\n");
|
|
75
|
+
return intent_prompt_md_default.replace("{{INTENT_DOCS}}", docs);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* LLM 응답 텍스트에서 `intent-json` 코드블록을 추출합니다.
|
|
79
|
+
*
|
|
80
|
+
* @param value - LLM 응답 텍스트
|
|
81
|
+
* @returns `[intents, rest]` — intents는 파싱된 JSON 객체 배열, rest는 블록이 제거된 나머지 텍스트
|
|
82
|
+
*/
|
|
83
|
+
parse(value) {
|
|
84
|
+
const pattern = /```(?:intent-json)\s*([\s\S]*?)```/g;
|
|
85
|
+
const intents = [];
|
|
86
|
+
return [intents, value.replace(pattern, (_, json) => {
|
|
87
|
+
try {
|
|
88
|
+
intents.push(JSON.parse(json.trim()));
|
|
89
|
+
} catch {}
|
|
90
|
+
return "";
|
|
91
|
+
}).trim()];
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
export { IntentPromptBuilder };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PresetView, ViewDefinition } from '../types/Views.js';
|
|
2
|
+
/**
|
|
3
|
+
* 뷰 등록, LLM 인스트럭션 빌드, HTML 렌더링을 통합 제공하는 유틸리티
|
|
4
|
+
*/
|
|
5
|
+
export declare class ViewPromptBuilder {
|
|
6
|
+
private static _instance;
|
|
7
|
+
private views;
|
|
8
|
+
/**
|
|
9
|
+
* 싱글톤 인스턴스를 반환합니다. 최초 호출 시 인스턴스가 생성됩니다.
|
|
10
|
+
*/
|
|
11
|
+
static get instance(): ViewPromptBuilder;
|
|
12
|
+
/**
|
|
13
|
+
* 뷰 정의를 등록합니다. 같은 이름의 뷰이 이미 등록되어 있으면 에러를 던집니다.
|
|
14
|
+
* @throws {Error} 같은 이름의 뷰이 이미 등록된 경우 또는 같은 태그의 커스텀 요소가 다른 클래스에 의해 정의된 경우
|
|
15
|
+
*/
|
|
16
|
+
add(definition: ViewDefinition): ViewPromptBuilder;
|
|
17
|
+
/**
|
|
18
|
+
* 미리 정의된 프리셋 뷰을 사용합니다.
|
|
19
|
+
* @example
|
|
20
|
+
* ViewRegistry.use(View.Images | View.Chart);
|
|
21
|
+
* ViewRegistry.use(View.All);
|
|
22
|
+
*/
|
|
23
|
+
use(flags: PresetView): ViewPromptBuilder;
|
|
24
|
+
/**
|
|
25
|
+
* 등록된 뷰들에 대한 LLM 인스트럭션 문자열을 생성합니다.
|
|
26
|
+
*/
|
|
27
|
+
build(): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { PRESET_VIEW_DEFINITIONS, PRESET_VIEW_LIST } from "../types/Views.js";
|
|
2
|
+
import view_prompt_md_default from "../_virtual/_glob-assets_raw/view-prompt.md.e0dbcffe.js";
|
|
3
|
+
//#region src/utilities/ViewPromptBuilder.ts
|
|
4
|
+
/**
|
|
5
|
+
* 뷰 등록, LLM 인스트럭션 빌드, HTML 렌더링을 통합 제공하는 유틸리티
|
|
6
|
+
*/
|
|
7
|
+
var ViewPromptBuilder = class ViewPromptBuilder {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.views = /* @__PURE__ */ new Map();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 싱글톤 인스턴스를 반환합니다. 최초 호출 시 인스턴스가 생성됩니다.
|
|
13
|
+
*/
|
|
14
|
+
static get instance() {
|
|
15
|
+
if (!this._instance) this._instance = new ViewPromptBuilder();
|
|
16
|
+
return this._instance;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 뷰 정의를 등록합니다. 같은 이름의 뷰이 이미 등록되어 있으면 에러를 던집니다.
|
|
20
|
+
* @throws {Error} 같은 이름의 뷰이 이미 등록된 경우 또는 같은 태그의 커스텀 요소가 다른 클래스에 의해 정의된 경우
|
|
21
|
+
*/
|
|
22
|
+
add(definition) {
|
|
23
|
+
if (this.views.has(definition.tag)) throw new Error(`View with tag "${definition.tag}" is already registered.`);
|
|
24
|
+
const constructor = customElements.get(definition.tag);
|
|
25
|
+
if (constructor && constructor !== definition.element) throw new Error(`Custom element with tag "${definition.tag}" is already defined to a different class.`);
|
|
26
|
+
this.views.set(definition.tag, definition);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 미리 정의된 프리셋 뷰을 사용합니다.
|
|
31
|
+
* @example
|
|
32
|
+
* ViewRegistry.use(View.Images | View.Chart);
|
|
33
|
+
* ViewRegistry.use(View.All);
|
|
34
|
+
*/
|
|
35
|
+
use(flags) {
|
|
36
|
+
for (const flag of PRESET_VIEW_LIST) if (flags & flag) {
|
|
37
|
+
const definition = PRESET_VIEW_DEFINITIONS.get(flag);
|
|
38
|
+
if (definition) this.add(definition);
|
|
39
|
+
}
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 등록된 뷰들에 대한 LLM 인스트럭션 문자열을 생성합니다.
|
|
44
|
+
*/
|
|
45
|
+
build() {
|
|
46
|
+
if (this.views.size === 0) return "";
|
|
47
|
+
const docs = Array.from(this.views.values()).map((def) => {
|
|
48
|
+
return [
|
|
49
|
+
`### ${def.tag}`,
|
|
50
|
+
"",
|
|
51
|
+
"**JSON Schema:**",
|
|
52
|
+
"```view-json",
|
|
53
|
+
JSON.stringify({
|
|
54
|
+
type: "object",
|
|
55
|
+
description: def.description,
|
|
56
|
+
properties: {
|
|
57
|
+
tag: {
|
|
58
|
+
type: "string",
|
|
59
|
+
enum: [def.tag]
|
|
60
|
+
},
|
|
61
|
+
properties: {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: def.properties || {},
|
|
64
|
+
required: def.required || []
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
required: ["tag"]
|
|
68
|
+
}, null, 2),
|
|
69
|
+
"```"
|
|
70
|
+
].join("\n");
|
|
71
|
+
}).join("\n\n---\n\n");
|
|
72
|
+
return view_prompt_md_default.replace("{{VIEW_DOCS}}", docs);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
//#endregion
|
|
76
|
+
export { ViewPromptBuilder };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { DOMScanner } from './DOMScanner.js';
|
|
2
|
+
import { DOMController } from './DOMController.js';
|
|
3
|
+
import { ScanResult, ScanOptions, DOMCommand, ExecutionResult, HistoryItem, AutomationOptions, LLMCallback, ScanDiff } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* DOM Agent 통합 오케스트레이터
|
|
6
|
+
* Scanner와 Controller를 조합하여 전체 워크플로우 관리
|
|
7
|
+
*/
|
|
8
|
+
export declare class DOMAgent extends EventTarget {
|
|
9
|
+
private scanner;
|
|
10
|
+
private controller;
|
|
11
|
+
private history;
|
|
12
|
+
private currentScan;
|
|
13
|
+
private lastScanRoot;
|
|
14
|
+
constructor();
|
|
15
|
+
/**
|
|
16
|
+
* 초기 스캔 및 세션 시작
|
|
17
|
+
*/
|
|
18
|
+
start(root?: Element | ShadowRoot, options?: ScanOptions & {
|
|
19
|
+
includeScreenshot?: boolean;
|
|
20
|
+
}): Promise<ScanResult>;
|
|
21
|
+
/**
|
|
22
|
+
* 명령 실행 후 재스캔
|
|
23
|
+
*/
|
|
24
|
+
executeAndRescan(commands: DOMCommand | DOMCommand[], options?: ScanOptions & {
|
|
25
|
+
includeScreenshot?: boolean;
|
|
26
|
+
}): Promise<{
|
|
27
|
+
execution: ExecutionResult[];
|
|
28
|
+
scan: ScanResult;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* 현재 상태 가져오기
|
|
32
|
+
*/
|
|
33
|
+
getCurrentState(): ScanResult | null;
|
|
34
|
+
/**
|
|
35
|
+
* 히스토리 조회
|
|
36
|
+
*/
|
|
37
|
+
getHistory(): HistoryItem[];
|
|
38
|
+
/**
|
|
39
|
+
* 히스토리 초기화
|
|
40
|
+
*/
|
|
41
|
+
clearHistory(): void;
|
|
42
|
+
/**
|
|
43
|
+
* 자동 모드: LLM 콜백과 함께 반복 실행
|
|
44
|
+
*/
|
|
45
|
+
automate(llmCallback: LLMCallback, options?: AutomationOptions): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* 특정 요소 스캔
|
|
48
|
+
*/
|
|
49
|
+
scanElement(elementId: string, options?: ScanOptions): Promise<ScanResult>;
|
|
50
|
+
/**
|
|
51
|
+
* 에러 이벤트 발생
|
|
52
|
+
*/
|
|
53
|
+
private dispatchError;
|
|
54
|
+
/**
|
|
55
|
+
* 스크린샷 캡처 (html2canvas 사용)
|
|
56
|
+
*/
|
|
57
|
+
private captureScreenshot;
|
|
58
|
+
/**
|
|
59
|
+
* Scanner 인스턴스 가져오기 (고급 사용)
|
|
60
|
+
*/
|
|
61
|
+
getScanner(): DOMScanner;
|
|
62
|
+
/**
|
|
63
|
+
* Controller 인스턴스 가져오기 (고급 사용)
|
|
64
|
+
*/
|
|
65
|
+
getController(): DOMController;
|
|
66
|
+
/**
|
|
67
|
+
* 이전 스캔과 현재 스캔 비교 (Diff)
|
|
68
|
+
*/
|
|
69
|
+
scanDiff(previousScan: ScanResult, currentScan: ScanResult): ScanDiff;
|
|
70
|
+
/**
|
|
71
|
+
* 요소 변경 여부 확인
|
|
72
|
+
*/
|
|
73
|
+
private isElementModified;
|
|
74
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { DOMCommand, ExecutionResult } from './types.js';
|
|
2
|
+
import { DOMScanner } from './DOMScanner.js';
|
|
3
|
+
/**
|
|
4
|
+
* DOM 명령 실행 엔진
|
|
5
|
+
* LLM의 명령을 파싱하고 실제 DOM 조작 수행
|
|
6
|
+
*/
|
|
7
|
+
export declare class DOMController {
|
|
8
|
+
private scanner;
|
|
9
|
+
constructor(scanner: DOMScanner);
|
|
10
|
+
/**
|
|
11
|
+
* 단일 명령 실행
|
|
12
|
+
*/
|
|
13
|
+
execute(command: DOMCommand): Promise<ExecutionResult>;
|
|
14
|
+
/**
|
|
15
|
+
* 여러 명령 순차 실행
|
|
16
|
+
*/
|
|
17
|
+
executeMany(commands: DOMCommand[]): Promise<ExecutionResult[]>;
|
|
18
|
+
/**
|
|
19
|
+
* 명령 실행 (내부)
|
|
20
|
+
*/
|
|
21
|
+
private executeCommand;
|
|
22
|
+
/**
|
|
23
|
+
* 클릭 이벤트 실행
|
|
24
|
+
*/
|
|
25
|
+
private click;
|
|
26
|
+
/**
|
|
27
|
+
* 텍스트 입력 (자연스러운 타이핑 시뮬레이션)
|
|
28
|
+
*/
|
|
29
|
+
private input;
|
|
30
|
+
/**
|
|
31
|
+
* 옵션 선택
|
|
32
|
+
*/
|
|
33
|
+
private selectOption;
|
|
34
|
+
/**
|
|
35
|
+
* 포커스
|
|
36
|
+
*/
|
|
37
|
+
private focus;
|
|
38
|
+
/**
|
|
39
|
+
* 블러 (포커스 해제)
|
|
40
|
+
*/
|
|
41
|
+
private blur;
|
|
42
|
+
/**
|
|
43
|
+
* 스크롤
|
|
44
|
+
*/
|
|
45
|
+
private scroll;
|
|
46
|
+
/**
|
|
47
|
+
* 요소로 스크롤
|
|
48
|
+
*/
|
|
49
|
+
private scrollTo;
|
|
50
|
+
/**
|
|
51
|
+
* 마우스 오버 (호버)
|
|
52
|
+
*/
|
|
53
|
+
private hover;
|
|
54
|
+
/**
|
|
55
|
+
* 입력 필드 초기화
|
|
56
|
+
*/
|
|
57
|
+
private clear;
|
|
58
|
+
/**
|
|
59
|
+
* 체크박스/라디오 토글
|
|
60
|
+
*/
|
|
61
|
+
private check;
|
|
62
|
+
/**
|
|
63
|
+
* 대기
|
|
64
|
+
*/
|
|
65
|
+
private wait;
|
|
66
|
+
/**
|
|
67
|
+
* 페이지 네비게이션 대기
|
|
68
|
+
*/
|
|
69
|
+
private waitForNavigation;
|
|
70
|
+
/**
|
|
71
|
+
* 사람처럼 보이는 랜덤 딜레이
|
|
72
|
+
*/
|
|
73
|
+
private simulateHumanDelay;
|
|
74
|
+
/**
|
|
75
|
+
* ID로 요소 가져오기 (Scanner의 매핑 활용)
|
|
76
|
+
*/
|
|
77
|
+
private getElement;
|
|
78
|
+
}
|