@libs-ui/components-preview-text-data 0.2.356-8 → 0.2.357-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.
@@ -22,7 +22,7 @@ export const optionsLangData = [
22
22
  { id: 'go', label: 'Go' },
23
23
  ];
24
24
  export const httpRequestConfigGetOptionsLang = (langsAccept, langsChangeLabel) => {
25
- const langs = [...optionsLangData].filter((item) => !langsAccept || !langsAccept.length || langsAccept.includes(item.id));
25
+ const langs = [...optionsLangData].filter((item) => !langsAccept?.length || langsAccept.includes(item.id));
26
26
  langs.forEach((item) => ({
27
27
  id: item.id,
28
28
  label: langsChangeLabel?.label || item.label,
@@ -97,6 +97,7 @@ export const languageRegistry = {
97
97
  const { python } = await import('@codemirror/lang-python');
98
98
  return python();
99
99
  },
100
+ linter: async (component) => component.createPythonLinter(),
100
101
  },
101
102
  java: {
102
103
  loader: async () => {
@@ -123,6 +124,25 @@ export const languageRegistry = {
123
124
  },
124
125
  },
125
126
  };
127
+ /**
128
+ * Bộ pattern bảo mật mặc định cho low-code platform.
129
+ * Chặn các API nguy hiểm: eval, network calls, storage, DOM injection...
130
+ */
131
+ export const DEFAULT_SECURITY_PATTERNS = [
132
+ /eval\s*\(/i,
133
+ /new\s+Function\s*\(/i,
134
+ /document\.cookie/i,
135
+ /localStorage/i,
136
+ /sessionStorage/i,
137
+ /fetch\s*\(/i,
138
+ /new\s+XMLHttpRequest/i,
139
+ /require\s*\(/i,
140
+ /import\s*\(/i,
141
+ /process\.env/i,
142
+ /<script/i,
143
+ /document\.write\s*\(/i,
144
+ /window\.location\s*=/i,
145
+ ];
126
146
  /**
127
147
  * Tạo default language extension cho plain text
128
148
  * Sử dụng khi ngôn ngữ không được hỗ trợ
@@ -136,4 +156,4 @@ export const createDefaultLanguage = async () => {
136
156
  },
137
157
  });
138
158
  };
139
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy10ZXh0LWRhdGEuZGVmaW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL3ByZXZpZXctdGV4dC1kYXRhL3NyYy9wcmV2aWV3LXRleHQtZGF0YS5kZWZpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUd2QyxPQUFPLEVBQXNCLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDdEYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJeEQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUE0QjtJQUN0RCxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRTtJQUNuQyxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLHVCQUF1QixFQUFFO0lBQ3BELEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO0lBQzdCLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFO0lBQ3JDLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFO0lBQ3JDLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO0lBQzdCLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFO0lBQzNCLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFO0lBQzNCLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO0lBQzdCLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO0lBQ2pDLEVBQUUsRUFBRSxFQUFFLE1BQU0s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aEIsQ0FBQztLQUNGO0lBQ0QsR0FBRyxFQUFFO1FBQ0gsTUFBTSxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2pCLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQ3JELE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDZixDQUFDO0tBQ0Y7SUFDRCxHQUFHLEVBQUU7UUFDSCxNQUFNLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDakIsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUM7WUFDckQsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNmLENBQUM7S0FDRjtJQUNELEVBQUUsRUFBRTtRQUNGLE1BQU0sRUFBRSxLQUFLLElBQUksRUFBRTtZQUNqQixNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUNuRCxPQUFPLEVBQUUsRUFBRSxDQUFDO1FBQ2QsQ0FBQztLQUNGO0NBQ0YsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLEtBQUssSUFBd0IsRUFBRTtJQUNsRSxNQUFNLEVBQUUsY0FBYyxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUNoRSxPQUFPLGNBQWMsQ0FBQyxNQUFNLENBQUM7UUFDM0IsS0FBSyxDQUFDLE1BQU07WUFDVixNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICdAY29kZW1pcnJvci9zdGF0ZSc7XG5pbXBvcnQgeyBJTGlzdENvbmZpZ0l0ZW0gfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWxpc3QnO1xuaW1wb3J0IHsgSUh0dHBSZXF1ZXN0Q29uZmlnLCByZXR1cm5MaXN0T2JqZWN0IH0gZnJvbSAnQGxpYnMtdWkvc2VydmljZXMtaHR0cC1yZXF1ZXN0JztcbmltcG9ydCB7IFV0aWxzSHR0cFBhcmFtc1JlcXVlc3QgfSBmcm9tICdAbGlicy11aS91dGlscyc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzUHJldmlld1RleHREYXRhQ29tcG9uZW50IH0gZnJvbSAnLi9wcmV2aWV3LXRleHQtZGF0YS5jb21wb25lbnQnO1xuaW1wb3J0IHsgSUxhbmd1YWdlT3B0aW9ucywgUFJFVklFV19URVhUX0RBVEFfTEFOR1VBR0VfU1VQUE9SVCB9IGZyb20gJy4vcHJldmlldy10ZXh0LWRhdGEuaW50ZXJmYWNlcyc7XG5cbi8qKlxuICogRGFuaCBzw6FjaCBjw6FjIG5nw7RuIG5n4buvIMSRxrDhu6NjIGjhu5cgdHLhu6NcbiAqIFPhu60gZOG7pW5nIGNvbnN0IGFycmF5IMSR4buDIHRyw6FuaCB04bqhbyBt4bubaSBt4buXaSBs4bqnbiB0cnV5IGPhuq1wXG4gKi9cbmV4cG9ydCBjb25zdCBvcHRpb25zTGFuZ0RhdGE6IEFycmF5PElMYW5ndWFnZU9wdGlvbnM+ID0gW1xuICB7IGlkOiAndGV4dCcsIGxhYmVsOiAnUGxhaW4gVGV4dCcgfSxcbiAgeyBpZDogJ2phdmFzY3JpcHQnLCBsYWJlbDogJ0phdmFTY3JpcHQvVHlwZVNjcmlwdCcgfSxcbiAgeyBpZDogJ2h0bWwnLCBsYWJlbDogJ0hUTUwnIH0sXG4gIHsgaWQ6ICdjc3MnLCBsYWJlbDogJ0NTUy9TQ1NTL1NBU1MnIH0sXG4gIHsgaWQ6ICdtYXJrZG93bicsIGxhYmVsOiAnTWFya2Rvd24nIH0sXG4gIHsgaWQ6ICdqc29uJywgbGFiZWw6ICdKU09OJyB9LFxuICB7IGlkOiAnc3FsJywgbGFiZWw6ICdTUUwnIH0sXG4gIHsgaWQ6ICd4bWwnLCBsYWJlbDogJ1hNTCcgfSxcbiAgeyBpZDogJ3lhbWwnLCBsYWJlbDogJ1lBTUwnIH0sXG4gIHsgaWQ6ICdweXRob24nLCBsYWJlbDogJ1B5dGhvbicgfSxcbiAgeyBpZDogJ2phdmEnLCBsYWJlbDogJ0phdmEnIH0sXG4gIHsgaWQ6ICdjcHAnLCBsYWJlbDogJ0MvQysrJyB9LFxuICB7IGlkOiAncGhwJywgbGFiZWw6ICdQSFAnIH0sXG4gIHsgaWQ6ICdnbycsIGxhYmVsOiAnR28nIH0sXG5dIGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgaHR0cFJlcXVlc3RDb25maWdHZXRPcHRpb25zTGFuZyA9IChsYW5nc0FjY2VwdD86IEFycmF5PFBSRVZJRVdfVEVYVF9EQVRBX0xBTkdVQUdFX1NVUFBPUlQ+LCBsYW5nc0NoYW5nZUxhYmVsPzogSUxhbmd1YWdlT3B0aW9ucyk6IElMaXN0Q29uZmlnSXRlbSA9PiB7XG4gIGNvbnN0IGxhbmdzID0gWy4uLm9wdGlvbnNMYW5nRGF0YV0uZmlsdGVyKChpdGVtKSA9PiAhbGFuZ3NBY2NlcHQgfHwgIWxhbmdzQWNjZXB0Lmxlbmd0aCB8fCBsYW5nc0FjY2VwdC5pbmNsdWRlcyhpdGVtLmlkIGFzIFBSRVZJRVdfVEVYVF9EQVRBX0xBTkdVQUdFX1NVUFBPUlQpKTtcblxuICBsYW5ncy5mb3JFYWNoKChpdGVtKSA9PiAoe1xuICAgIGlkOiBpdGVtLmlkLFxuICAgIGxhYmVsOiBsYW5nc0NoYW5nZUxhYmVsPy5sYWJlbCB8fCBpdGVtLmxhYmVsLFxuICB9KSk7XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAndGV4dCcsXG4gICAgaHR0cFJlcXVlc3REYXRhOiBzaWduYWw8SUh0dHBSZXF1ZXN0Q29uZmlnPih7XG4gICAgICBvYmplY3RJbnN0YW5jZTogcmV0dXJuTGlzdE9iamVjdChsYW5ncyksXG4gICAgICBmdW5jdGlvbk5hbWU6ICdsaXN0JyxcbiAgICAgIGFyZ3VtZW50c1ZhbHVlOiBbbmV3IFV0aWxzSHR0cFBhcmFtc1JlcXVlc3QoeyBmcm9tT2JqZWN0OiB7IHBhZ2U6IDEsIHBlcl9wYWdlOiA0MCB9IH0pXSxcbiAgICB9KSxcbiAgICBjb25maWdUZW1wbGF0ZVRleHQ6IHNpZ25hbCh7XG4gICAgICBmaWVsZEtleTogJ2lkJyxcbiAgICAgIG5vdFVzZVZpcnR1YWxTY3JvbGw6IHRydWUsXG4gICAgfSksXG4gIH07XG59O1xuXG50eXBlIFRfTGFuZ3VhZ2VMb2FkZXIgPSAoKSA9PiBQcm9taXNlPEV4dGVuc2lvbj47XG50eXBlIFRfTGludGVyTG9hZGVyID0gKGNvbXBvbmVudDogTGlic1VpQ29tcG9uZW50c1ByZXZpZXdUZXh0RGF0YUNvbXBvbmVudCkgPT4gUHJvbWlzZTxFeHRlbnNpb24+O1xuaW50ZXJmYWNlIElfTGFuZ3VhZ2VSZWdpc3RyeUl0ZW0ge1xuICBsb2FkZXI6IFRfTGFuZ3VhZ2VMb2FkZXI7XG4gIGxpbnRlcj86IFRfTGludGVyTG9hZGVyO1xufVxuXG5leHBvcnQgY29uc3QgbGFuZ3VhZ2VSZWdpc3RyeTogUmVjb3JkPHN0cmluZywgSV9MYW5ndWFnZVJlZ2lzdHJ5SXRlbT4gPSB7XG4gIGphdmFzY3JpcHQ6IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgamF2YXNjcmlwdCB9ID0gYXdhaXQgaW1wb3J0KCdAY29kZW1pcnJvci9sYW5nLWphdmFzY3JpcHQnKTtcbiAgICAgIHJldHVybiBqYXZhc2NyaXB0KHsganN4OiB0cnVlLCB0eXBlc2NyaXB0OiB0cnVlIH0pO1xuICAgIH0sXG4gICAgbGludGVyOiBhc3luYyAoY29tcG9uZW50KSA9PiBjb21wb25lbnQuY3JlYXRlSnNMaW50ZXIoKSxcbiAgfSxcbiAgaHRtbDoge1xuICAgIGxvYWRlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBodG1sIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctaHRtbCcpO1xuICAgICAgcmV0dXJuIGh0bWwoKTtcbiAgICB9LFxuICB9LFxuICBjc3M6IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgY3NzIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctY3NzJyk7XG4gICAgICByZXR1cm4gY3NzKCk7XG4gICAgfSxcbiAgfSxcbiAgbWFya2Rvd246IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgbWFya2Rvd24gfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy1tYXJrZG93bicpO1xuICAgICAgcmV0dXJuIG1hcmtkb3duKCk7XG4gICAgfSxcbiAgfSxcbiAganNvbjoge1xuICAgIGxvYWRlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBqc29uIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctanNvbicpO1xuICAgICAgcmV0dXJuIGpzb24oKTtcbiAgICB9LFxuICAgIGxpbnRlcjogYXN5bmMgKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LmNyZWF0ZUpzb25MaW50ZXIoKSxcbiAgfSxcbiAgc3FsOiB7XG4gICAgbG9hZGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHNxbCB9ID0gYXdhaXQgaW1wb3J0KCdAY29kZW1pcnJvci9sYW5nLXNxbCcpO1xuICAgICAgcmV0dXJuIHNxbCgpO1xuICAgIH0sXG4gICAgbGludGVyOiBhc3luYyAoY29tcG9uZW50KSA9PiBjb21wb25lbnQuY3JlYXRlU3FsTGludGVyKCksXG4gIH0sXG4gIHhtbDoge1xuICAgIGxvYWRlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyB4bWwgfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy14bWwnKTtcbiAgICAgIHJldHVybiB4bWwoKTtcbiAgICB9LFxuICB9LFxuICB5YW1sOiB7XG4gICAgbG9hZGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHlhbWwgfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy15YW1sJyk7XG4gICAgICByZXR1cm4geWFtbCgpO1xuICAgIH0sXG4gIH0sXG4gIHB5dGhvbjoge1xuICAgIGxvYWRlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBweXRob24gfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy1weXRob24nKTtcbiAgICAgIHJldHVybiBweXRob24oKTtcbiAgICB9LFxuICB9LFxuICBqYXZhOiB7XG4gICAgbG9hZGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IGphdmEgfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy1qYXZhJyk7XG4gICAgICByZXR1cm4gamF2YSgpO1xuICAgIH0sXG4gIH0sXG4gIGNwcDoge1xuICAgIGxvYWRlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBjcHAgfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy1jcHAnKTtcbiAgICAgIHJldHVybiBjcHAoKTtcbiAgICB9LFxuICB9LFxuICBwaHA6IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgcGhwIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctcGhwJyk7XG4gICAgICByZXR1cm4gcGhwKCk7XG4gICAgfSxcbiAgfSxcbiAgZ286IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgZ28gfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy1nbycpO1xuICAgICAgcmV0dXJuIGdvKCk7XG4gICAgfSxcbiAgfSxcbn07XG5cbi8qKlxuICogVOG6oW8gZGVmYXVsdCBsYW5ndWFnZSBleHRlbnNpb24gY2hvIHBsYWluIHRleHRcbiAqIFPhu60gZOG7pW5nIGtoaSBuZ8O0biBuZ+G7ryBraMO0bmcgxJHGsOG7o2MgaOG7lyB0cuG7o1xuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRGVmYXVsdExhbmd1YWdlID0gYXN5bmMgKCk6IFByb21pc2U8RXh0ZW5zaW9uPiA9PiB7XG4gIGNvbnN0IHsgU3RyZWFtTGFuZ3VhZ2UgfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZ3VhZ2UnKTtcbiAgcmV0dXJuIFN0cmVhbUxhbmd1YWdlLmRlZmluZSh7XG4gICAgdG9rZW4oc3RyZWFtKSB7XG4gICAgICBzdHJlYW0uc2tpcFRvRW5kKCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICB9KTtcbn07XG4iXX0=
159
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy10ZXh0LWRhdGEuZGVmaW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL3ByZXZpZXctdGV4dC1kYXRhL3NyYy9wcmV2aWV3LXRleHQtZGF0YS5kZWZpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUd2QyxPQUFPLEVBQXNCLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDdEYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJeEQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUE0QjtJQUN0RCxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRTtJQUNuQyxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLHVCQUF1QixFQUFFO0lBQ3BELEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO0lBQzdCLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFO0lBQ3JDLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFO0lBQ3JDLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO0lBQzdCLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFO0lBQzNCLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFO0lBQzNCLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO0lBQzdCLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO0lBQ2pDLEVBQUUsRUFBRSxFQUFFLE1BQU0s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TTtZQUNWLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0YXRlJztcbmltcG9ydCB7IElMaXN0Q29uZmlnSXRlbSB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtbGlzdCc7XG5pbXBvcnQgeyBJSHR0cFJlcXVlc3RDb25maWcsIHJldHVybkxpc3RPYmplY3QgfSBmcm9tICdAbGlicy11aS9zZXJ2aWNlcy1odHRwLXJlcXVlc3QnO1xuaW1wb3J0IHsgVXRpbHNIdHRwUGFyYW1zUmVxdWVzdCB9IGZyb20gJ0BsaWJzLXVpL3V0aWxzJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNQcmV2aWV3VGV4dERhdGFDb21wb25lbnQgfSBmcm9tICcuL3ByZXZpZXctdGV4dC1kYXRhLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJTGFuZ3VhZ2VPcHRpb25zLCBQUkVWSUVXX1RFWFRfREFUQV9MQU5HVUFHRV9TVVBQT1JULCBUX0ZvcmJpZGRlblBhdHRlcm4gfSBmcm9tICcuL3ByZXZpZXctdGV4dC1kYXRhLmludGVyZmFjZXMnO1xuXG4vKipcbiAqIERhbmggc8OhY2ggY8OhYyBuZ8O0biBuZ+G7ryDEkcaw4bujYyBo4buXIHRy4bujXG4gKiBT4butIGThu6VuZyBjb25zdCBhcnJheSDEkeG7gyB0csOhbmggdOG6oW8gbeG7m2kgbeG7l2kgbOG6p24gdHJ1eSBj4bqtcFxuICovXG5leHBvcnQgY29uc3Qgb3B0aW9uc0xhbmdEYXRhOiBBcnJheTxJTGFuZ3VhZ2VPcHRpb25zPiA9IFtcbiAgeyBpZDogJ3RleHQnLCBsYWJlbDogJ1BsYWluIFRleHQnIH0sXG4gIHsgaWQ6ICdqYXZhc2NyaXB0JywgbGFiZWw6ICdKYXZhU2NyaXB0L1R5cGVTY3JpcHQnIH0sXG4gIHsgaWQ6ICdodG1sJywgbGFiZWw6ICdIVE1MJyB9LFxuICB7IGlkOiAnY3NzJywgbGFiZWw6ICdDU1MvU0NTUy9TQVNTJyB9LFxuICB7IGlkOiAnbWFya2Rvd24nLCBsYWJlbDogJ01hcmtkb3duJyB9LFxuICB7IGlkOiAnanNvbicsIGxhYmVsOiAnSlNPTicgfSxcbiAgeyBpZDogJ3NxbCcsIGxhYmVsOiAnU1FMJyB9LFxuICB7IGlkOiAneG1sJywgbGFiZWw6ICdYTUwnIH0sXG4gIHsgaWQ6ICd5YW1sJywgbGFiZWw6ICdZQU1MJyB9LFxuICB7IGlkOiAncHl0aG9uJywgbGFiZWw6ICdQeXRob24nIH0sXG4gIHsgaWQ6ICdqYXZhJywgbGFiZWw6ICdKYXZhJyB9LFxuICB7IGlkOiAnY3BwJywgbGFiZWw6ICdDL0MrKycgfSxcbiAgeyBpZDogJ3BocCcsIGxhYmVsOiAnUEhQJyB9LFxuICB7IGlkOiAnZ28nLCBsYWJlbDogJ0dvJyB9LFxuXSBhcyBjb25zdDtcblxuZXhwb3J0IGNvbnN0IGh0dHBSZXF1ZXN0Q29uZmlnR2V0T3B0aW9uc0xhbmcgPSAobGFuZ3NBY2NlcHQ/OiBBcnJheTxQUkVWSUVXX1RFWFRfREFUQV9MQU5HVUFHRV9TVVBQT1JUPiwgbGFuZ3NDaGFuZ2VMYWJlbD86IElMYW5ndWFnZU9wdGlvbnMpOiBJTGlzdENvbmZpZ0l0ZW0gPT4ge1xuICBjb25zdCBsYW5ncyA9IFsuLi5vcHRpb25zTGFuZ0RhdGFdLmZpbHRlcigoaXRlbSkgPT4gIWxhbmdzQWNjZXB0Py5sZW5ndGggfHwgKGxhbmdzQWNjZXB0IGFzIHN0cmluZ1tdKS5pbmNsdWRlcyhpdGVtLmlkKSk7XG5cbiAgbGFuZ3MuZm9yRWFjaCgoaXRlbSkgPT4gKHtcbiAgICBpZDogaXRlbS5pZCxcbiAgICBsYWJlbDogbGFuZ3NDaGFuZ2VMYWJlbD8ubGFiZWwgfHwgaXRlbS5sYWJlbCxcbiAgfSkpO1xuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ3RleHQnLFxuICAgIGh0dHBSZXF1ZXN0RGF0YTogc2lnbmFsPElIdHRwUmVxdWVzdENvbmZpZz4oe1xuICAgICAgb2JqZWN0SW5zdGFuY2U6IHJldHVybkxpc3RPYmplY3QobGFuZ3MpLFxuICAgICAgZnVuY3Rpb25OYW1lOiAnbGlzdCcsXG4gICAgICBhcmd1bWVudHNWYWx1ZTogW25ldyBVdGlsc0h0dHBQYXJhbXNSZXF1ZXN0KHsgZnJvbU9iamVjdDogeyBwYWdlOiAxLCBwZXJfcGFnZTogNDAgfSB9KV0sXG4gICAgfSksXG4gICAgY29uZmlnVGVtcGxhdGVUZXh0OiBzaWduYWwoe1xuICAgICAgZmllbGRLZXk6ICdpZCcsXG4gICAgICBub3RVc2VWaXJ0dWFsU2Nyb2xsOiB0cnVlLFxuICAgIH0pLFxuICB9O1xufTtcblxudHlwZSBUX0xhbmd1YWdlTG9hZGVyID0gKCkgPT4gUHJvbWlzZTxFeHRlbnNpb24+O1xudHlwZSBUX0xpbnRlckxvYWRlciA9IChjb21wb25lbnQ6IExpYnNVaUNvbXBvbmVudHNQcmV2aWV3VGV4dERhdGFDb21wb25lbnQpID0+IFByb21pc2U8RXh0ZW5zaW9uPjtcbmludGVyZmFjZSBJX0xhbmd1YWdlUmVnaXN0cnlJdGVtIHtcbiAgbG9hZGVyOiBUX0xhbmd1YWdlTG9hZGVyO1xuICBsaW50ZXI/OiBUX0xpbnRlckxvYWRlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGxhbmd1YWdlUmVnaXN0cnk6IFJlY29yZDxzdHJpbmcsIElfTGFuZ3VhZ2VSZWdpc3RyeUl0ZW0+ID0ge1xuICBqYXZhc2NyaXB0OiB7XG4gICAgbG9hZGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IGphdmFzY3JpcHQgfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy1qYXZhc2NyaXB0Jyk7XG4gICAgICByZXR1cm4gamF2YXNjcmlwdCh7IGpzeDogdHJ1ZSwgdHlwZXNjcmlwdDogdHJ1ZSB9KTtcbiAgICB9LFxuICAgIGxpbnRlcjogYXN5bmMgKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LmNyZWF0ZUpzTGludGVyKCksXG4gIH0sXG4gIGh0bWw6IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgaHRtbCB9ID0gYXdhaXQgaW1wb3J0KCdAY29kZW1pcnJvci9sYW5nLWh0bWwnKTtcbiAgICAgIHJldHVybiBodG1sKCk7XG4gICAgfSxcbiAgfSxcbiAgY3NzOiB7XG4gICAgbG9hZGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IGNzcyB9ID0gYXdhaXQgaW1wb3J0KCdAY29kZW1pcnJvci9sYW5nLWNzcycpO1xuICAgICAgcmV0dXJuIGNzcygpO1xuICAgIH0sXG4gIH0sXG4gIG1hcmtkb3duOiB7XG4gICAgbG9hZGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IG1hcmtkb3duIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctbWFya2Rvd24nKTtcbiAgICAgIHJldHVybiBtYXJrZG93bigpO1xuICAgIH0sXG4gIH0sXG4gIGpzb246IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsganNvbiB9ID0gYXdhaXQgaW1wb3J0KCdAY29kZW1pcnJvci9sYW5nLWpzb24nKTtcbiAgICAgIHJldHVybiBqc29uKCk7XG4gICAgfSxcbiAgICBsaW50ZXI6IGFzeW5jIChjb21wb25lbnQpID0+IGNvbXBvbmVudC5jcmVhdGVKc29uTGludGVyKCksXG4gIH0sXG4gIHNxbDoge1xuICAgIGxvYWRlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBzcWwgfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZy1zcWwnKTtcbiAgICAgIHJldHVybiBzcWwoKTtcbiAgICB9LFxuICAgIGxpbnRlcjogYXN5bmMgKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LmNyZWF0ZVNxbExpbnRlcigpLFxuICB9LFxuICB4bWw6IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgeG1sIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmcteG1sJyk7XG4gICAgICByZXR1cm4geG1sKCk7XG4gICAgfSxcbiAgfSxcbiAgeWFtbDoge1xuICAgIGxvYWRlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyB5YW1sIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmcteWFtbCcpO1xuICAgICAgcmV0dXJuIHlhbWwoKTtcbiAgICB9LFxuICB9LFxuICBweXRob246IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgcHl0aG9uIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctcHl0aG9uJyk7XG4gICAgICByZXR1cm4gcHl0aG9uKCk7XG4gICAgfSxcbiAgICBsaW50ZXI6IGFzeW5jIChjb21wb25lbnQpID0+IGNvbXBvbmVudC5jcmVhdGVQeXRob25MaW50ZXIoKSxcbiAgfSxcbiAgamF2YToge1xuICAgIGxvYWRlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBqYXZhIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctamF2YScpO1xuICAgICAgcmV0dXJuIGphdmEoKTtcbiAgICB9LFxuICB9LFxuICBjcHA6IHtcbiAgICBsb2FkZXI6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgY3BwIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctY3BwJyk7XG4gICAgICByZXR1cm4gY3BwKCk7XG4gICAgfSxcbiAgfSxcbiAgcGhwOiB7XG4gICAgbG9hZGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHBocCB9ID0gYXdhaXQgaW1wb3J0KCdAY29kZW1pcnJvci9sYW5nLXBocCcpO1xuICAgICAgcmV0dXJuIHBocCgpO1xuICAgIH0sXG4gIH0sXG4gIGdvOiB7XG4gICAgbG9hZGVyOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IGdvIH0gPSBhd2FpdCBpbXBvcnQoJ0Bjb2RlbWlycm9yL2xhbmctZ28nKTtcbiAgICAgIHJldHVybiBnbygpO1xuICAgIH0sXG4gIH0sXG59O1xuXG4vKipcbiAqIELhu5kgcGF0dGVybiBi4bqjbyBt4bqtdCBt4bq3YyDEkeG7i25oIGNobyBsb3ctY29kZSBwbGF0Zm9ybS5cbiAqIENo4bq3biBjw6FjIEFQSSBuZ3V5IGhp4buDbTogZXZhbCwgbmV0d29yayBjYWxscywgc3RvcmFnZSwgRE9NIGluamVjdGlvbi4uLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRUNVUklUWV9QQVRURVJOUzogVF9Gb3JiaWRkZW5QYXR0ZXJuW10gPSBbXG4gIC9ldmFsXFxzKlxcKC9pLFxuICAvbmV3XFxzK0Z1bmN0aW9uXFxzKlxcKC9pLFxuICAvZG9jdW1lbnRcXC5jb29raWUvaSxcbiAgL2xvY2FsU3RvcmFnZS9pLFxuICAvc2Vzc2lvblN0b3JhZ2UvaSxcbiAgL2ZldGNoXFxzKlxcKC9pLFxuICAvbmV3XFxzK1hNTEh0dHBSZXF1ZXN0L2ksXG4gIC9yZXF1aXJlXFxzKlxcKC9pLFxuICAvaW1wb3J0XFxzKlxcKC9pLFxuICAvcHJvY2Vzc1xcLmVudi9pLFxuICAvPHNjcmlwdC9pLFxuICAvZG9jdW1lbnRcXC53cml0ZVxccypcXCgvaSxcbiAgL3dpbmRvd1xcLmxvY2F0aW9uXFxzKj0vaSxcbl07XG5cbi8qKlxuICogVOG6oW8gZGVmYXVsdCBsYW5ndWFnZSBleHRlbnNpb24gY2hvIHBsYWluIHRleHRcbiAqIFPhu60gZOG7pW5nIGtoaSBuZ8O0biBuZ+G7ryBraMO0bmcgxJHGsOG7o2MgaOG7lyB0cuG7o1xuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRGVmYXVsdExhbmd1YWdlID0gYXN5bmMgKCk6IFByb21pc2U8RXh0ZW5zaW9uPiA9PiB7XG4gIGNvbnN0IHsgU3RyZWFtTGFuZ3VhZ2UgfSA9IGF3YWl0IGltcG9ydCgnQGNvZGVtaXJyb3IvbGFuZ3VhZ2UnKTtcbiAgcmV0dXJuIFN0cmVhbUxhbmd1YWdlLmRlZmluZSh7XG4gICAgdG9rZW4oc3RyZWFtKSB7XG4gICAgICBzdHJlYW0uc2tpcFRvRW5kKCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICB9KTtcbn07XG4iXX0=
@@ -1,2 +1,2 @@
1
1
  export {};
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy10ZXh0LWRhdGEuaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9wcmV2aWV3LXRleHQtZGF0YS9zcmMvcHJldmlldy10ZXh0LWRhdGEuaW50ZXJmYWNlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgUFJFVklFV19URVhUX0RBVEFfTEFOR1VBR0VfU1VQUE9SVCA9ICdqYXZhc2NyaXB0JyB8ICdodG1sJyB8ICdjc3MnIHwgJ21hcmtkb3duJyB8ICdqc29uJyB8ICdzcWwnIHwgJ3htbCcgfCAneWFtbCcgfCAncHl0aG9uJyB8ICdqYXZhJyB8ICdjcHAnIHwgJ3BocCcgfCAnZ28nIHwgJ3RleHQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElQcmV2aWV3VGV4dERhdGFDaGFuZ2Uge1xuICBjb250ZW50OiBzdHJpbmc7XG4gIGlzV3JhcDogYm9vbGVhbjtcbiAgbGFuZ3VhZ2U6IFBSRVZJRVdfVEVYVF9EQVRBX0xBTkdVQUdFX1NVUFBPUlQ7XG4gIGNvbnRleHRDaGFuZ2U6ICdjb250ZW50JyB8ICdsYW5ndWFnZScgfCAnaXNXcmFwJztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJTGFuZ3VhZ2VPcHRpb25zIHtcbiAgaWQ6IFBSRVZJRVdfVEVYVF9EQVRBX0xBTkdVQUdFX1NVUFBPUlQ7XG4gIGxhYmVsOiBzdHJpbmc7XG59XG4iXX0=
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy10ZXh0LWRhdGEuaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9wcmV2aWV3LXRleHQtZGF0YS9zcmMvcHJldmlldy10ZXh0LWRhdGEuaW50ZXJmYWNlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgUFJFVklFV19URVhUX0RBVEFfTEFOR1VBR0VfU1VQUE9SVCA9ICdqYXZhc2NyaXB0JyB8ICdodG1sJyB8ICdjc3MnIHwgJ21hcmtkb3duJyB8ICdqc29uJyB8ICdzcWwnIHwgJ3htbCcgfCAneWFtbCcgfCAncHl0aG9uJyB8ICdqYXZhJyB8ICdjcHAnIHwgJ3BocCcgfCAnZ28nIHwgJ3RleHQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElQcmV2aWV3VGV4dERhdGFDaGFuZ2Uge1xuICBjb250ZW50OiBzdHJpbmc7XG4gIGlzV3JhcDogYm9vbGVhbjtcbiAgbGFuZ3VhZ2U6IFBSRVZJRVdfVEVYVF9EQVRBX0xBTkdVQUdFX1NVUFBPUlQ7XG4gIGNvbnRleHRDaGFuZ2U6ICdjb250ZW50JyB8ICdsYW5ndWFnZScgfCAnaXNXcmFwJztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJTGFuZ3VhZ2VPcHRpb25zIHtcbiAgaWQ6IFBSRVZJRVdfVEVYVF9EQVRBX0xBTkdVQUdFX1NVUFBPUlQ7XG4gIGxhYmVsOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVByZXZpZXdUZXh0RGF0YUNvbXBsZXRpb25JdGVtIHtcbiAgbGFiZWw6IHN0cmluZztcbiAgLyoqIEBkZWZhdWx0ICd2YXJpYWJsZScgKi9cbiAgdHlwZT86ICd2YXJpYWJsZScgfCAncHJvcGVydHknIHwgJ2Z1bmN0aW9uJyB8ICdjbGFzcycgfCAnbWV0aG9kJyB8ICdrZXl3b3JkJyB8ICd0ZXh0JyB8ICdjb25zdGFudCcgfCAnaW50ZXJmYWNlJyB8ICd0eXBlJyB8ICdlbnVtJyB8ICdmaWVsZCcgfCAnbmFtZXNwYWNlJyB8ICdtb2R1bGUnO1xuICAvKiogU2hvcnQgdHlwZSBoaW50IHNob3duIG5leHQgdG8gdGhlIGxhYmVsLCBlLmcuIGBzdHJpbmdgLCBgKCkgPT4gdm9pZGAgKi9cbiAgZGV0YWlsPzogc3RyaW5nO1xuICAvKiogTG9uZ2VyIGRvY3VtZW50YXRpb24gc2hvd24gaW4gdGhlIHRvb2x0aXAgKi9cbiAgaW5mbz86IHN0cmluZztcbiAgLyoqIE5lc3RlZCBwcm9wZXJ0aWVzIOKAlCBhY2Nlc3NlZCB2aWEgZG90IG5vdGF0aW9uIChlLmcuIGBvYmoucHJvcGApICovXG4gIHByb3BlcnRpZXM/OiBJUHJldmlld1RleHREYXRhQ29tcGxldGlvbkl0ZW1bXTtcbn1cblxuLyoqXG4gKiBQYXR0ZXJuIGPhuqVtIOKAlCBjaHXhu5dpIGxpdGVyYWwgKHNvIGto4bubcCBjYXNlLWluc2Vuc2l0aXZlKSBob+G6t2MgUmVnRXhwIHTDuXkgY2jhu4luaC5cbiAqIETDuW5nIHbhu5tpIGlucHV0IGBbZm9yYmlkZGVuUGF0dGVybnNdYCDEkeG7gyBuZ8SDbiB1c2VyIG5o4bqtcCBtw6MgdmkgcGjhuqFtIGLhuqNvIG3huq10LlxuICovXG5leHBvcnQgdHlwZSBUX0ZvcmJpZGRlblBhdHRlcm4gPSBzdHJpbmcgfCBSZWdFeHA7XG5cbi8qKiBWaSBwaOG6oW0gxJHGsOG7o2MgcGjDoXQgaGnhu4duIHRyb25nIGVkaXRvciwgcGjDoXQgcmEgcXVhIG91dHB1dCBgKG91dFZpb2xhdGlvbnMpYCAqL1xuZXhwb3J0IGludGVyZmFjZSBJUHJldmlld1RleHREYXRhVmlvbGF0aW9uIHtcbiAgLyoqIFbhu4sgdHLDrSBi4bqvdCDEkeG6p3UgKGNoYXJhY3RlciBvZmZzZXQpICovXG4gIGZyb206IG51bWJlcjtcbiAgLyoqIFbhu4sgdHLDrSBr4bq/dCB0aMO6YyAoY2hhcmFjdGVyIG9mZnNldCkgKi9cbiAgdG86IG51bWJlcjtcbiAgLyoqIFPhu5EgZMOybmcgKDEtaW5kZXhlZCkgKi9cbiAgbGluZTogbnVtYmVyO1xuICAvKiogVMOqbi9tw7QgdOG6oyBj4bunYSBwYXR0ZXJuIMSRw6MgYuG7iyB2aSBwaOG6oW0gKi9cbiAgcGF0dGVybjogc3RyaW5nO1xuICAvKiogxJBv4bqhbiB0ZXh0IHRo4buxYyB04bq/IGLhu4sgbWF0Y2ggKi9cbiAgbWF0Y2hlZDogc3RyaW5nO1xufVxuIl19
@@ -1,8 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, inject, DestroyRef, computed, input, model, output, viewChild, effect, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { signal, inject, DestroyRef, computed, input, model, output, viewChild, effect, Component, ChangeDetectionStrategy } from '@angular/core';
3
+ import { autocompletion } from '@codemirror/autocomplete';
3
4
  import { syntaxTree } from '@codemirror/language';
4
5
  import { lintGutter, linter } from '@codemirror/lint';
5
- import { Compartment } from '@codemirror/state';
6
+ import { Compartment, Prec, EditorState, Transaction } from '@codemirror/state';
6
7
  import { EditorView, lineNumbers } from '@codemirror/view';
7
8
  import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
8
9
  import { LibsUiComponentsDropdownComponent } from '@libs-ui/components-dropdown';
@@ -32,7 +33,7 @@ const optionsLangData = [
32
33
  { id: 'go', label: 'Go' },
33
34
  ];
34
35
  const httpRequestConfigGetOptionsLang = (langsAccept, langsChangeLabel) => {
35
- const langs = [...optionsLangData].filter((item) => !langsAccept || !langsAccept.length || langsAccept.includes(item.id));
36
+ const langs = [...optionsLangData].filter((item) => !langsAccept?.length || langsAccept.includes(item.id));
36
37
  langs.forEach((item) => ({
37
38
  id: item.id,
38
39
  label: langsChangeLabel?.label || item.label,
@@ -107,6 +108,7 @@ const languageRegistry = {
107
108
  const { python } = await import('@codemirror/lang-python');
108
109
  return python();
109
110
  },
111
+ linter: async (component) => component.createPythonLinter(),
110
112
  },
111
113
  java: {
112
114
  loader: async () => {
@@ -133,6 +135,25 @@ const languageRegistry = {
133
135
  },
134
136
  },
135
137
  };
138
+ /**
139
+ * Bộ pattern bảo mật mặc định cho low-code platform.
140
+ * Chặn các API nguy hiểm: eval, network calls, storage, DOM injection...
141
+ */
142
+ const DEFAULT_SECURITY_PATTERNS = [
143
+ /eval\s*\(/i,
144
+ /new\s+Function\s*\(/i,
145
+ /document\.cookie/i,
146
+ /localStorage/i,
147
+ /sessionStorage/i,
148
+ /fetch\s*\(/i,
149
+ /new\s+XMLHttpRequest/i,
150
+ /require\s*\(/i,
151
+ /import\s*\(/i,
152
+ /process\.env/i,
153
+ /<script/i,
154
+ /document\.write\s*\(/i,
155
+ /window\.location\s*=/i,
156
+ ];
136
157
  /**
137
158
  * Tạo default language extension cho plain text
138
159
  * Sử dụng khi ngôn ngữ không được hỗ trợ
@@ -156,6 +177,8 @@ class LibsUiComponentsPreviewTextDataComponent {
156
177
  languageCompartment = new Compartment();
157
178
  lineNumberCompartment = new Compartment();
158
179
  linterCompartment = new Compartment();
180
+ completionsCompartment = new Compartment();
181
+ forbiddenCompartment = new Compartment();
159
182
  contentStateNoWrap = signal('');
160
183
  /** Cache để tránh load lại language đã load */
161
184
  languageCache = new Map();
@@ -170,7 +193,7 @@ class LibsUiComponentsPreviewTextDataComponent {
170
193
  // PROTECTED SIGNALS
171
194
  // ==========================================================================
172
195
  isWrap = signal(true);
173
- configLoadDataIsHttpConfig = signal(httpRequestConfigGetOptionsLang(undefined));
196
+ configLoadDataIsHttpConfig = signal(httpRequestConfigGetOptionsLang());
174
197
  labelLang = computed(() => optionsLangData.find((item) => item.id === this.langSelected())?.label);
175
198
  acceptChangeLang = computed(() => !(this.langSelected() && this.langsAccept()?.length === 1 && this.langsAccept()?.includes(this.langSelected())));
176
199
  // ==========================================================================
@@ -191,6 +214,26 @@ class LibsUiComponentsPreviewTextDataComponent {
191
214
  lintIgnorePatterns = input(['Cannot use import statement outside a module', 'Unexpected token export', 'import ', '@angular/core'], {
192
215
  transform: (value) => value ?? ['Cannot use import statement outside a module', 'Unexpected token export', 'import ', '@angular/core'],
193
216
  });
217
+ /**
218
+ * Danh sách đối tượng/biến gợi ý khi gõ — giống IntelliSense trong IDE.
219
+ * Hỗ trợ dot-notation: định nghĩa `properties` để gợi ý sau dấu `.`
220
+ * @example
221
+ * [completions]="[{ label: 'user', properties: [{ label: 'name', detail: 'string' }] }]"
222
+ */
223
+ completions = input([], {
224
+ transform: (value) => value ?? [],
225
+ });
226
+ /**
227
+ * Danh sách pattern cấm — chuỗi literal hoặc RegExp.
228
+ * Khi phát hiện vi phạm: highlight đỏ tại đúng vị trí + chặn paste + emit `(outViolations)`.
229
+ * Dùng `DEFAULT_SECURITY_PATTERNS` để áp dụng bộ quy tắc bảo mật mặc định cho low-code.
230
+ * @example
231
+ * [forbiddenPatterns]="defaultSecurityPatterns"
232
+ * [forbiddenPatterns]="[/eval\s*\(/, 'localStorage']"
233
+ */
234
+ forbiddenPatterns = input([], {
235
+ transform: (value) => value ?? [],
236
+ });
194
237
  background = input('#f8f9fa', {
195
238
  transform: (value) => value ?? '#f8f9fa',
196
239
  });
@@ -199,6 +242,7 @@ class LibsUiComponentsPreviewTextDataComponent {
199
242
  // ==========================================================================
200
243
  outChange = output();
201
244
  syntaxErrors = output();
245
+ outViolations = output();
202
246
  // ==========================================================================
203
247
  // VIEW CHILDREN
204
248
  // ==========================================================================
@@ -223,6 +267,24 @@ class LibsUiComponentsPreviewTextDataComponent {
223
267
  }
224
268
  }
225
269
  });
270
+ // Effect để cập nhật custom completions khi input thay đổi
271
+ effect(() => {
272
+ const items = this.completions();
273
+ if (!this.isInitialized || !this.editorViewInstance)
274
+ return;
275
+ this.editorViewInstance.dispatch({
276
+ effects: this.completionsCompartment.reconfigure(items.length ? this.buildCompletionExtension(items) : []),
277
+ });
278
+ });
279
+ // Effect để cập nhật forbidden patterns khi input thay đổi
280
+ effect(() => {
281
+ const patterns = this.forbiddenPatterns();
282
+ if (!this.isInitialized || !this.editorViewInstance)
283
+ return;
284
+ this.editorViewInstance.dispatch({
285
+ effects: this.forbiddenCompartment.reconfigure(patterns.length ? this.buildForbiddenExtension(patterns) : []),
286
+ });
287
+ });
226
288
  // Cleanup khi component bị destroy
227
289
  this.destroyRef.onDestroy(() => {
228
290
  this.editorViewInstance?.destroy();
@@ -261,10 +323,15 @@ class LibsUiComponentsPreviewTextDataComponent {
261
323
  * Tạo danh sách extensions cho editor
262
324
  */
263
325
  createExtensions(languageExtension, linterExtension) {
326
+ const initialCompletions = this.completions();
327
+ const initialPatterns = this.forbiddenPatterns();
264
328
  return [
265
329
  basicSetup,
266
330
  this.languageCompartment.of(languageExtension),
267
331
  this.linterCompartment.of(linterExtension),
332
+ // Compartment cho custom completions — Prec.highest để override basicSetup's autocompletion
333
+ Prec.highest(this.completionsCompartment.of(initialCompletions.length ? this.buildCompletionExtension(initialCompletions) : [])),
334
+ this.forbiddenCompartment.of(initialPatterns.length ? this.buildForbiddenExtension(initialPatterns) : []),
268
335
  this.createLightTheme(),
269
336
  EditorView.editable.of(this.editable()),
270
337
  this.wrapCompartment.of(EditorView.lineWrapping),
@@ -345,32 +412,83 @@ class LibsUiComponentsPreviewTextDataComponent {
345
412
  // PUBLIC METHODS - Linter factories (được gọi từ registry)
346
413
  // ==========================================================================
347
414
  /**
348
- * Tạo JavaScript linter
349
- * Sử dụng Function constructor để validate syntax
415
+ * Tạo JavaScript linter với 2-pass detection:
416
+ * 1. Text-based scan cho trailing dot (parser thường đặt error node sai vị trí với pattern này)
417
+ * 2. syntaxTree cho các lỗi thực sự khác, bỏ qua vùng bị ảnh hưởng bởi trailing dot
350
418
  */
351
419
  createJsLinter() {
352
420
  return linter((view) => {
353
- const text = view.state.doc.toString();
354
421
  const diagnostics = [];
355
- try {
356
- new Function(text);
422
+ const doc = view.state.doc;
423
+ // Pass 1: Text-based trailing dot detection — đặt diagnostic đúng tại vị trí dấu chấm
424
+ const trailingDotLines = new Set();
425
+ for (let lineNum = 1; lineNum <= doc.lines; lineNum++) {
426
+ const line = doc.line(lineNum);
427
+ const trimmed = line.text.trimEnd();
428
+ const match = /(\w+)\.\s*$/.exec(trimmed);
429
+ if (!match)
430
+ continue;
431
+ trailingDotLines.add(lineNum);
432
+ const dotPos = line.from + trimmed.lastIndexOf('.');
433
+ diagnostics.push({
434
+ from: dotPos,
435
+ to: dotPos + 1,
436
+ severity: 'error',
437
+ message: `Incomplete property access on "${match[1]}"`,
438
+ });
357
439
  }
358
- catch (err) {
359
- const message = get(err, 'message', '');
360
- const shouldIgnore = this.lintIgnorePatterns().some((pattern) => message.includes(pattern));
361
- if (!shouldIgnore) {
440
+ // Đánh dấu các dòng bị ảnh hưởng bởi trailing dot (trailing-dot line + 4 dòng tiếp theo)
441
+ // để lọc cascading errors từ syntaxTree
442
+ const taintedLines = new Set();
443
+ for (const lineNum of trailingDotLines) {
444
+ for (let i = lineNum; i <= Math.min(lineNum + 4, doc.lines); i++) {
445
+ taintedLines.add(i);
446
+ }
447
+ }
448
+ // Pass 2: syntaxTree cho các lỗi khác (chỉ non-empty range, bỏ qua vùng tainted)
449
+ const tree = syntaxTree(view.state);
450
+ tree.iterate({
451
+ enter: (node) => {
452
+ if (!node.type.isError)
453
+ return;
454
+ if (node.from === node.to)
455
+ return; // Bỏ qua empty-range node (cascading error)
456
+ const errorLineNum = doc.lineAt(node.from).number;
457
+ if (taintedLines.has(errorLineNum))
458
+ return;
362
459
  diagnostics.push({
363
- from: 0,
364
- to: text.length,
460
+ from: node.from,
461
+ to: Math.min(node.to, doc.length),
365
462
  severity: 'error',
366
- message,
463
+ message: this.buildJsErrorMessage(doc, node),
367
464
  });
368
- this.syntaxErrors.emit(diagnostics);
369
- }
370
- }
465
+ },
466
+ });
467
+ this.syntaxErrors.emit(diagnostics);
371
468
  return diagnostics;
372
469
  });
373
470
  }
471
+ buildJsErrorMessage(doc, node) {
472
+ const text = doc.sliceString(node.from, node.to).trim();
473
+ if (text)
474
+ return `JavaScript syntax error near "${text}"`;
475
+ const prevToken = this.getTokenBefore(doc, node.from);
476
+ if (!prevToken)
477
+ return 'JavaScript syntax error';
478
+ if (prevToken.endsWith('('))
479
+ return 'Missing closing ")"';
480
+ if (prevToken.endsWith('['))
481
+ return 'Missing closing "]"';
482
+ if (/^function$/i.test(prevToken))
483
+ return 'Expected function name or "("';
484
+ if (/^return$/i.test(prevToken))
485
+ return 'Invalid expression after "return"';
486
+ if (/^=>$/.test(prevToken))
487
+ return 'Expected function body after "=>"';
488
+ if (/^const$|^let$|^var$/i.test(prevToken))
489
+ return 'Expected variable name';
490
+ return `JavaScript syntax error near "${prevToken}"`;
491
+ }
374
492
  /**
375
493
  * Tạo JSON linter
376
494
  * Sử dụng JSON.parse để validate
@@ -436,7 +554,7 @@ class LibsUiComponentsPreviewTextDataComponent {
436
554
  if (/WHERE$/i.test(prevToken)) {
437
555
  return 'Expected condition after WHERE';
438
556
  }
439
- if (/\($/.test(prevToken)) {
557
+ if (prevToken.endsWith('(')) {
440
558
  return 'Missing closing ")"';
441
559
  }
442
560
  return `Unexpected end of SQL after "${prevToken}"`;
@@ -444,9 +562,185 @@ class LibsUiComponentsPreviewTextDataComponent {
444
562
  getTokenBefore(doc, pos) {
445
563
  const start = Math.max(0, pos - 30);
446
564
  const text = doc.sliceString(start, pos);
447
- const match = text.match(/(\S+)\s*$/);
565
+ const match = /(\S+)\s*$/.exec(text);
448
566
  return match?.[1] ?? '';
449
567
  }
568
+ /**
569
+ * Tạo Python linter dựa trên syntaxTree parse error — cùng approach với SQL linter.
570
+ * Phát hiện lỗi cú pháp mà CodeMirror Python parser đánh dấu là error node.
571
+ */
572
+ createPythonLinter() {
573
+ return linter((view) => {
574
+ const diagnostics = [];
575
+ const doc = view.state.doc;
576
+ const tree = syntaxTree(view.state);
577
+ tree.iterate({
578
+ enter: (node) => {
579
+ if (!node.type.isError)
580
+ return;
581
+ const from = Math.max(0, node.from - 1);
582
+ const to = node.from === node.to ? node.from + 1 : node.to;
583
+ diagnostics.push({
584
+ from,
585
+ to: Math.min(to, doc.length),
586
+ severity: 'error',
587
+ message: this.buildPythonErrorMessage(doc, node),
588
+ });
589
+ },
590
+ });
591
+ this.syntaxErrors.emit(diagnostics);
592
+ return diagnostics;
593
+ });
594
+ }
595
+ buildPythonErrorMessage(doc, node) {
596
+ if (node.from !== node.to) {
597
+ const text = doc.sliceString(node.from, node.to).trim();
598
+ const textSuffix = text ? ` near "${text}"` : '';
599
+ return `Python syntax error${textSuffix}`;
600
+ }
601
+ const prevToken = this.getTokenBefore(doc, node.from);
602
+ if (!prevToken) {
603
+ return 'Python syntax error';
604
+ }
605
+ if (/^def$/i.test(prevToken))
606
+ return 'Expected function name after "def"';
607
+ if (/^class$/i.test(prevToken))
608
+ return 'Expected class name after "class"';
609
+ if (/^return$/i.test(prevToken))
610
+ return 'Invalid expression after "return"';
611
+ if (/^import$/i.test(prevToken))
612
+ return 'Expected module name after "import"';
613
+ if (/^from$/i.test(prevToken))
614
+ return 'Expected module name after "from"';
615
+ if (/^if$/i.test(prevToken))
616
+ return 'Expected condition after "if"';
617
+ if (/^elif$/i.test(prevToken))
618
+ return 'Expected condition after "elif"';
619
+ if (/^while$/i.test(prevToken))
620
+ return 'Expected condition after "while"';
621
+ if (/^for$/i.test(prevToken))
622
+ return 'Expected variable after "for"';
623
+ if (prevToken.endsWith('.'))
624
+ return `Incomplete attribute access on "${prevToken.slice(0, -1)}"`;
625
+ if (prevToken.endsWith('('))
626
+ return 'Missing closing ")"';
627
+ if (prevToken.endsWith('['))
628
+ return 'Missing closing "]"';
629
+ return `Python syntax error near "${prevToken}"`;
630
+ }
631
+ /**
632
+ * Tạo CodeMirror extension cho custom completions từ danh sách input.
633
+ * Hỗ trợ 2 chế độ:
634
+ * 1. Gõ tên biến → gợi ý top-level items
635
+ * 2. Gõ `obj.` → gợi ý properties của obj
636
+ */
637
+ buildCompletionExtension(items) {
638
+ const completionSource = (context) => {
639
+ // Chế độ dot-notation: gõ "obj.prop" → gợi ý properties của obj
640
+ const dotMatch = context.matchBefore(/\w+\.\w*/);
641
+ if (dotMatch) {
642
+ const dotPos = dotMatch.text.indexOf('.');
643
+ const objectName = dotMatch.text.slice(0, dotPos);
644
+ const parent = items.find((i) => i.label === objectName);
645
+ if (parent?.properties?.length) {
646
+ return {
647
+ from: dotMatch.from + dotPos + 1,
648
+ options: parent.properties.map((p) => ({
649
+ label: p.label,
650
+ type: p.type ?? 'property',
651
+ detail: p.detail ?? '',
652
+ info: p.info ?? '',
653
+ })),
654
+ };
655
+ }
656
+ }
657
+ // Chế độ top-level: gợi ý tên biến/object khi gõ ký tự
658
+ const word = context.matchBefore(/\w*/);
659
+ if (!word || (word.from === word.to && !context.explicit))
660
+ return null;
661
+ return {
662
+ from: word.from,
663
+ options: items.map((item) => ({
664
+ label: item.label,
665
+ type: item.type ?? 'variable',
666
+ detail: item.detail ?? '',
667
+ info: item.info ?? '',
668
+ })),
669
+ };
670
+ };
671
+ return autocompletion({ override: [completionSource] });
672
+ }
673
+ /**
674
+ * Tạo extension bảo mật gồm 2 layer:
675
+ * 1. Linter: highlight đỏ tại đúng vị trí match + emit outViolations
676
+ * 2. Transaction filter: chặn paste nếu nội dung paste chứa pattern cấm
677
+ */
678
+ buildForbiddenExtension(patterns) {
679
+ const toGlobalRegex = (p) => {
680
+ if (p instanceof RegExp) {
681
+ const flags = p.flags.includes('g') ? p.flags : `${p.flags}g`;
682
+ return new RegExp(p.source, flags);
683
+ }
684
+ return new RegExp(this.escapeRegex(p), 'gi');
685
+ };
686
+ const forbiddenLinter = linter((view) => {
687
+ const diagnostics = [];
688
+ const violations = [];
689
+ const text = view.state.doc.toString();
690
+ const tree = syntaxTree(view.state);
691
+ // Build a Set of comment ranges từ AST để skip match nằm trong comment
692
+ const commentRanges = [];
693
+ tree.iterate({
694
+ enter: (node) => {
695
+ if (node.type.name.toLowerCase().includes('comment')) {
696
+ commentRanges.push({ from: node.from, to: node.to });
697
+ }
698
+ },
699
+ });
700
+ const isInComment = (from, to) => commentRanges.some((r) => from >= r.from && to <= r.to);
701
+ for (const pattern of patterns) {
702
+ const re = toGlobalRegex(pattern);
703
+ re.lastIndex = 0;
704
+ let match;
705
+ while ((match = re.exec(text)) !== null) {
706
+ const from = match.index;
707
+ const to = from + match[0].length;
708
+ if (isInComment(from, to))
709
+ continue;
710
+ const line = view.state.doc.lineAt(from).number;
711
+ const patternLabel = pattern instanceof RegExp ? pattern.source : pattern;
712
+ diagnostics.push({
713
+ from,
714
+ to,
715
+ severity: 'error',
716
+ message: `Mã bị cấm: "${match[0]}" — vi phạm chính sách bảo mật`,
717
+ });
718
+ violations.push({ from, to, line, pattern: patternLabel, matched: match[0] });
719
+ }
720
+ }
721
+ this.outViolations.emit(violations);
722
+ return diagnostics;
723
+ });
724
+ // Chặn paste nếu nội dung paste chứa bất kỳ pattern cấm nào
725
+ const pasteFilter = EditorState.transactionFilter.of((tr) => {
726
+ if (!tr.docChanged)
727
+ return tr;
728
+ if (!tr.annotation(Transaction.userEvent)?.startsWith('input.paste'))
729
+ return tr;
730
+ const newText = tr.newDoc.toString();
731
+ for (const pattern of patterns) {
732
+ const re = toGlobalRegex(pattern);
733
+ re.lastIndex = 0;
734
+ if (re.test(newText))
735
+ return []; // [] = block transaction
736
+ }
737
+ return tr;
738
+ });
739
+ return [forbiddenLinter, pasteFilter];
740
+ }
741
+ escapeRegex(str) {
742
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
743
+ }
450
744
  // ==========================================================================
451
745
  // PROTECTED METHODS - Event handlers
452
746
  // ==========================================================================
@@ -492,7 +786,7 @@ class LibsUiComponentsPreviewTextDataComponent {
492
786
  });
493
787
  }
494
788
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsPreviewTextDataComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
495
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsPreviewTextDataComponent, isStandalone: true, selector: "libs_ui-components-preview_text_data", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, langSelected: { classPropertyName: "langSelected", publicName: "langSelected", isSignal: true, isRequired: true, transformFunction: null }, langsAccept: { classPropertyName: "langsAccept", publicName: "langsAccept", isSignal: true, isRequired: false, transformFunction: null }, langsChangeLabel: { classPropertyName: "langsChangeLabel", publicName: "langsChangeLabel", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, hiddenAction: { classPropertyName: "hiddenAction", publicName: "hiddenAction", isSignal: true, isRequired: false, transformFunction: null }, lintIgnorePatterns: { classPropertyName: "lintIgnorePatterns", publicName: "lintIgnorePatterns", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { langSelected: "langSelectedChange", outChange: "outChange", syntaxErrors: "syntaxErrors" }, viewQueries: [{ propertyName: "containerPreview", first: true, predicate: ["containerPreview"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"libs-ui-preview-data-container flex flex-col w-full h-auto rounded-[8px] libs-ui-border-general px-[8px]\"\n [style.--background-color]=\"background()\"\n [class.pt-[8px]]=\"!hiddenAction()\">\n @if (!hiddenAction()) {\n <div class=\"flex items-center content-between color-[#6a7383]\">\n <libs_ui-components-dropdown\n classInclude=\"w-[200px]\"\n [listConfig]=\"configLoadDataIsHttpConfig()\"\n [listMaxItemShow]=\"5\"\n [isNgContent]=\"true\"\n [readonly]=\"!editable() || !acceptChangeLang()\"\n [listHasButtonUnSelectOption]=\"false\"\n (outSelectKey)=\"handlerSelectKey($event)\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-third'\"\n [label]=\"labelLang() || ''\"\n [sizeButton]=\"'small'\"\n [classIconRight]=\"editable() && acceptChangeLang() ? 'libs-ui-icon-move-right rotate-90' : ''\"\n [classInclude]=\"'!p-[0px]' + (editable() && acceptChangeLang() ? '' : '!pointer-events-none !cursor-default hover:!text-[#6A7383]')\" />\n </libs_ui-components-dropdown>\n <div class=\"flex items-center\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-third'\"\n [label]=\"isWrap() ? 'i18n_remove_line_wrap' : 'i18n_line_wrap'\"\n [sizeButton]=\"'small'\"\n [classIconLeft]=\"isWrap() ? 'libs-ui-icon-unwrap' : 'libs-ui-icon-wrap'\"\n [classInclude]=\"'mo-lib-p-0px mo-lib-mr-16px'\"\n (outClick)=\"handlerLineWrap()\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-third'\"\n [label]=\"'i18n_copy'\"\n [sizeButton]=\"'small'\"\n [classIconLeft]=\"'libs-ui-icon-copy'\"\n [classInclude]=\"'mo-lib-p-0px'\"\n (outClick)=\"handlerCopy()\" />\n </div>\n </div>\n }\n <div #containerPreview></div>\n</div>\n", styles: [":host ::ng-deep .libs-ui-preview-data-container{background-color:var(--background-color)!important}:host ::ng-deep .libs-ui-preview-data-container .cm-line{white-space:pre-wrap}:host ::ng-deep .libs-ui-preview-data-container .cm-lintRange-error{background-color:#ff323233;border-bottom:2px solid red}:host ::ng-deep .libs-ui-preview-data-container .cm-lintRange-warning{background-color:#ffc80026}:host ::ng-deep .libs-ui-preview-data-container .cm-tooltip-lint{background:#fff8f8;color:#d32f2f;border:1px solid #f44336;padding:8px 10px;font-size:13px;font-family:Inter,sans-serif;border-radius:6px;box-shadow:0 2px 8px #ff000026}:host ::ng-deep .libs-ui-preview-data-container .cm-focused{outline:none!important}:host ::ng-deep .libs-ui-preview-data-container .cm-gutters{background-color:var(--background-color)!important}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsDropdownComponent, selector: "libs_ui-components-dropdown", inputs: ["useXssFilter", "popoverElementRefCustom", "classInclude", "ignoreStopPropagationEvent", "flagMouse", "flagMouseContent", "popoverCustomConfig", "isNgContent", "zIndex", "convertItemSelected", "getPopoverItemSelected", "httpRequestDetailItemById", "lengthKeys", "textDisplayWhenNoSelect", "textDisplayWhenMultiSelect", "classIncludeTextDisplayWhenNoSelect", "fieldLabel", "fieldGetLabel", "labelPopoverConfig", "labelPopoverFullWidth", "hasContentUnitRight", "listSearchNoDataTemplateRef", "dropdownTemplateRefNotSearchNoData", "fieldGetImage", "imageSize", "typeShape", "fieldGetIcon", "fieldGetTextAvatar", "fieldGetColorAvatar", "classAvatarInclude", "getLastTextAfterSpace", "linkImageError", "showError", "showBorderError", "disable", "readonly", "labelConfig", "disableLabel", "listSearchConfig", "isSearchOnline", "listHiddenInputSearch", "listSearchPadding", "listKeySearch", "listDividerClassInclude", "listConfig", "listButtonsOther", "listHasButtonUnSelectOption", "listClickExactly", "listBackgroundCustom", "listMaxItemShow", "listKeySelected", "listMultiKeySelected", "listKeysDisable", "listKeysHidden", "validRequired", "validMaxItemSelected", "changeValidUndefinedResetError", "allowSelectItemMultiple", "focusInputSearch", "onlyEmitDataWhenReset", "resetKeyWhenSelectAllKey", "listConfigHasDivider", "classIncludeIcon", "classIncludeContent", "listIgnoreClassDisableDefaultWhenUseKeysDisableItem", "tabKeyActive", "tabsConfig", "ignoreBorderBottom"], outputs: ["flagMouseChange", "flagMouseContentChange", "lengthKeysChange", "showBorderErrorChange", "listKeySelectedChange", "listMultiKeySelectedChange", "tabKeyActiveChange", "outSelectKey", "outSelectMultiKey", "outFunctionsControl", "outValidEvent", "outChangStageFlagMouse", "outDataChange", "outClickButtonOther", "outShowList", "outChangeTabKeyActive"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
789
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsPreviewTextDataComponent, isStandalone: true, selector: "libs_ui-components-preview_text_data", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, langSelected: { classPropertyName: "langSelected", publicName: "langSelected", isSignal: true, isRequired: true, transformFunction: null }, langsAccept: { classPropertyName: "langsAccept", publicName: "langsAccept", isSignal: true, isRequired: false, transformFunction: null }, langsChangeLabel: { classPropertyName: "langsChangeLabel", publicName: "langsChangeLabel", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, hiddenAction: { classPropertyName: "hiddenAction", publicName: "hiddenAction", isSignal: true, isRequired: false, transformFunction: null }, lintIgnorePatterns: { classPropertyName: "lintIgnorePatterns", publicName: "lintIgnorePatterns", isSignal: true, isRequired: false, transformFunction: null }, completions: { classPropertyName: "completions", publicName: "completions", isSignal: true, isRequired: false, transformFunction: null }, forbiddenPatterns: { classPropertyName: "forbiddenPatterns", publicName: "forbiddenPatterns", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { langSelected: "langSelectedChange", outChange: "outChange", syntaxErrors: "syntaxErrors", outViolations: "outViolations" }, viewQueries: [{ propertyName: "containerPreview", first: true, predicate: ["containerPreview"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"libs-ui-preview-data-container flex flex-col w-full h-auto rounded-[8px] libs-ui-border-general px-[8px]\"\n [style.--background-color]=\"background()\"\n [class.pt-[8px]]=\"!hiddenAction()\">\n @if (!hiddenAction()) {\n <div class=\"flex items-center content-between color-[#6a7383]\">\n <libs_ui-components-dropdown\n classInclude=\"w-[200px]\"\n [listConfig]=\"configLoadDataIsHttpConfig()\"\n [listMaxItemShow]=\"5\"\n [isNgContent]=\"true\"\n [readonly]=\"!editable() || !acceptChangeLang()\"\n [listHasButtonUnSelectOption]=\"false\"\n (outSelectKey)=\"handlerSelectKey($event)\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-third'\"\n [label]=\"labelLang() || ''\"\n [sizeButton]=\"'small'\"\n [classIconRight]=\"editable() && acceptChangeLang() ? 'libs-ui-icon-move-right rotate-90' : ''\"\n [classInclude]=\"'!p-[0px]' + (editable() && acceptChangeLang() ? '' : '!pointer-events-none !cursor-default hover:!text-[#6A7383]')\" />\n </libs_ui-components-dropdown>\n <div class=\"flex items-center\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-third'\"\n [label]=\"isWrap() ? 'i18n_remove_line_wrap' : 'i18n_line_wrap'\"\n [sizeButton]=\"'small'\"\n [classIconLeft]=\"isWrap() ? 'libs-ui-icon-unwrap' : 'libs-ui-icon-wrap'\"\n [classInclude]=\"'mo-lib-p-0px mo-lib-mr-16px'\"\n (outClick)=\"handlerLineWrap()\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-third'\"\n [label]=\"'i18n_copy'\"\n [sizeButton]=\"'small'\"\n [classIconLeft]=\"'libs-ui-icon-copy'\"\n [classInclude]=\"'mo-lib-p-0px'\"\n (outClick)=\"handlerCopy()\" />\n </div>\n </div>\n }\n <div #containerPreview></div>\n</div>\n", styles: [":host ::ng-deep .libs-ui-preview-data-container{background-color:var(--background-color)!important}:host ::ng-deep .libs-ui-preview-data-container .cm-line{white-space:pre-wrap}:host ::ng-deep .libs-ui-preview-data-container .cm-lintRange-error{background-color:#ff323233;border-bottom:2px solid red}:host ::ng-deep .libs-ui-preview-data-container .cm-lintRange-warning{background-color:#ffc80026}:host ::ng-deep .libs-ui-preview-data-container .cm-tooltip-lint{background:#fff8f8;color:#d32f2f;border:1px solid #f44336;padding:8px 10px;font-size:13px;font-family:Inter,sans-serif;border-radius:6px;box-shadow:0 2px 8px #ff000026}:host ::ng-deep .libs-ui-preview-data-container .cm-focused{outline:none!important}:host ::ng-deep .libs-ui-preview-data-container .cm-gutters{background-color:var(--background-color)!important}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsDropdownComponent, selector: "libs_ui-components-dropdown", inputs: ["useXssFilter", "popoverElementRefCustom", "classInclude", "ignoreStopPropagationEvent", "flagMouse", "flagMouseContent", "popoverCustomConfig", "isNgContent", "zIndex", "convertItemSelected", "getPopoverItemSelected", "httpRequestDetailItemById", "lengthKeys", "textDisplayWhenNoSelect", "textDisplayWhenMultiSelect", "classIncludeTextDisplayWhenNoSelect", "fieldLabel", "fieldGetLabel", "labelPopoverConfig", "labelPopoverFullWidth", "hasContentUnitRight", "listSearchNoDataTemplateRef", "dropdownTemplateRefNotSearchNoData", "fieldGetImage", "imageSize", "typeShape", "fieldGetIcon", "fieldGetTextAvatar", "fieldGetColorAvatar", "classAvatarInclude", "getLastTextAfterSpace", "linkImageError", "showError", "showBorderError", "disable", "readonly", "labelConfig", "disableLabel", "listSearchConfig", "isSearchOnline", "listHiddenInputSearch", "listSearchPadding", "listKeySearch", "listDividerClassInclude", "listConfig", "listButtonsOther", "listHasButtonUnSelectOption", "listClickExactly", "listBackgroundCustom", "listMaxItemShow", "listKeySelected", "listMultiKeySelected", "listKeysDisable", "listKeysHidden", "validRequired", "validMaxItemSelected", "changeValidUndefinedResetError", "allowSelectItemMultiple", "focusInputSearch", "onlyEmitDataWhenReset", "resetKeyWhenSelectAllKey", "listConfigHasDivider", "classIncludeIcon", "classIncludeContent", "listIgnoreClassDisableDefaultWhenUseKeysDisableItem", "tabKeyActive", "tabsConfig", "ignoreBorderBottom"], outputs: ["flagMouseChange", "flagMouseContentChange", "lengthKeysChange", "showBorderErrorChange", "listKeySelectedChange", "listMultiKeySelectedChange", "tabKeyActiveChange", "outSelectKey", "outSelectMultiKey", "outFunctionsControl", "outValidEvent", "outChangStageFlagMouse", "outDataChange", "outClickButtonOther", "outShowList", "outChangeTabKeyActive"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
496
790
  }
497
791
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsPreviewTextDataComponent, decorators: [{
498
792
  type: Component,
@@ -503,5 +797,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
503
797
  * Generated bundle index. Do not edit.
504
798
  */
505
799
 
506
- export { LibsUiComponentsPreviewTextDataComponent, createDefaultLanguage, httpRequestConfigGetOptionsLang, languageRegistry, optionsLangData };
800
+ export { DEFAULT_SECURITY_PATTERNS, LibsUiComponentsPreviewTextDataComponent, createDefaultLanguage, httpRequestConfigGetOptionsLang, languageRegistry, optionsLangData };
507
801
  //# sourceMappingURL=libs-ui-components-preview-text-data.mjs.map