From a1e1d1b8b61948bce3be39e7e748dbbfd4c3c0c1 Mon Sep 17 00:00:00 2001
From: Guillaume Weghsteen
Date: Wed, 18 Dec 2024 01:15:57 -0800
Subject: [PATCH] No public description
PiperOrigin-RevId: 707444715
---
VERSION | 1 +
fixup.sh | 16 +-
integration_tests/basic_import/package.json | 3 -
integration_tests/jest/package.json | 1 -
package.json | 2 +-
.../html_sanitizer/html_sanitizer_test.ts | 49 +-
test/testing/testvectors/html_test_vectors.ts | 24485 ----------------
7 files changed, 51 insertions(+), 24506 deletions(-)
create mode 100644 VERSION
delete mode 100644 test/testing/testvectors/html_test_vectors.ts
diff --git a/VERSION b/VERSION
new file mode 100644
index 00000000..afaf360d
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+1.0.0
\ No newline at end of file
diff --git a/fixup.sh b/fixup.sh
index 8299d8c5..b370311b 100755
--- a/fixup.sh
+++ b/fixup.sh
@@ -1,13 +1,17 @@
#!/bin/bash
# Adds package.json files to cjs/mjs subtrees
-echo '{
- "type": "commonjs"
-}' > dist/cjs/package.json
+VERSION=$(cat VERSION)
-echo '{
- "type": "module"
-}' > dist/mjs/package.json
+echo "{
+ \"type\": \"commonjs\",
+ \"version\": \"${VERSION}\"
+}" > dist/cjs/package.json
+
+echo "{
+ \"type\": \"module\",
+ \"version\": \"${VERSION}\"
+}" > dist/mjs/package.json
rm -rf dist/mjs/test
mv dist/mjs/src/* dist/mjs
diff --git a/integration_tests/basic_import/package.json b/integration_tests/basic_import/package.json
index 7f1181db..b02845c8 100644
--- a/integration_tests/basic_import/package.json
+++ b/integration_tests/basic_import/package.json
@@ -29,8 +29,5 @@
"karma-typescript": "^5.2.0",
"typescript": "^4.1.2",
"karma-typescript-es6-transform": "*"
- },
- "dependencies": {
- "safevalues": "^0.3.1"
}
}
diff --git a/integration_tests/jest/package.json b/integration_tests/jest/package.json
index 0ce962a6..4c3eda38 100644
--- a/integration_tests/jest/package.json
+++ b/integration_tests/jest/package.json
@@ -27,7 +27,6 @@
"@types/jest": "^27.0.0",
"babel-jest": "^27.0.6",
"jest": "^27.0.0",
- "safevalues": "^0.3.1",
"ts-jest": "^27.0.0",
"typescript": "^3.9.10"
}
diff --git a/package.json b/package.json
index a4bac441..09732498 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "safevalues",
- "version": "1.0.0-rc.1",
+ "version": "1.0.0",
"description": "Safe builders for Trusted Types values",
"repository": "https://github.com/google/safevalues",
"author": "ISE Web Hardening Team",
diff --git a/test/builders/html_sanitizer/html_sanitizer_test.ts b/test/builders/html_sanitizer/html_sanitizer_test.ts
index b6ca4254..4fd66597 100644
--- a/test/builders/html_sanitizer/html_sanitizer_test.ts
+++ b/test/builders/html_sanitizer/html_sanitizer_test.ts
@@ -5,7 +5,6 @@
*/
import {secretToken} from '../../../src/internals/secrets';
-import {HTML_TEST_VECTORS} from '../../testing/testvectors/html_test_vectors';
import {
CssSanitizationFn,
@@ -51,16 +50,46 @@ function sanitizeAssertUnchanged(table: SanitizerTable, html: string): string {
.toString();
}
-describe('HtmlSanitizer', () => {
- describe('using test vectors', () => {
- for (const v of HTML_TEST_VECTORS) {
- it(`passes testVector[${v.name}]`, () => {
- const sanitized = sanitizeHtml(v.input).toString();
- expect(v.acceptable).toContain(sanitized);
- });
- }
- });
+describe('sanitizeHtml', () => {
+ interface TestCase {
+ html: string;
+ expected: string;
+ }
+ const testCases: TestCase[] = [
+ {
+ html: '',
+ expected: '',
+ },
+ {
+ html: 'abcd',
+ expected: 'abcd',
+ },
+ {
+ html: 'abcd',
+ expected: 'abcd',
+ },
+ {
+ html: '',
+ expected: '',
+ },
+ {
+ html: '
',
+ expected: '
',
+ },
+ {
+ html: '',
+ expected: '',
+ },
+ ];
+ for (const testCase of testCases) {
+ it(`sanitizes ${JSON.stringify(testCase.html)} correctly`, () => {
+ const sanitized = sanitizeHtml(testCase.html).toString();
+ expect(sanitized).toEqual(testCase.expected);
+ });
+ }
+});
+describe('HtmlSanitizer', () => {
it('drops unknown elements', () => {
const emptyTable = new SanitizerTable(
new Set(),
diff --git a/test/testing/testvectors/html_test_vectors.ts b/test/testing/testvectors/html_test_vectors.ts
deleted file mode 100644
index 76c6e633..00000000
--- a/test/testing/testvectors/html_test_vectors.ts
+++ /dev/null
@@ -1,24485 +0,0 @@
-/**
- * @license
- * Copyright Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-interface TestVector {
- readonly input: string;
- readonly acceptable: string[];
- readonly name: string;
-}
-
-/**
- * AUTOGENERATED. DO NOT EDIT.
- * Test vectors for HTML sanitizer.
- */
-export const HTML_TEST_VECTORS: TestVector[] = [
- {
- input: 'foo',
- acceptable: [
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- ],
- name: 'a',
- },
- {
- input: 'foo',
- acceptable: [
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- ],
- name: 'a_quot',
- },
- {
- input: 'foo',
- acceptable: [
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- 'foo',
- ],
- name: 'a_tab',
- },
- {input: "", acceptable: [''], name: 'body_onload'},
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'clobbering_children',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'clobbering_firstchild',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'clobbering_proto',
- },
- {
- input: '',
- acceptable: ['', ''],
- name: 'clobbering_tagname',
- },
- {
- input: '',
- acceptable: [
- '',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ],
- name: 'details',
- },
- {
- input: '',
- '',
- '',
- ' ',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_html_action',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- acceptable: ['', '', ''],
- name: 'contract_body_plain',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'contract_body_scriptinside',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_html_method',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_html_formaction',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_html_formmethod',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_html_pattern',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_html_readonly',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_html_accept',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_html_defer',
- },
- {
- input: '
',
- acceptable: ['', '', ''],
- name: 'contract_head_plain',
- },
- {
- input: '
',
- acceptable: ['', '', ''],
- name: 'contract_head_scriptinside',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_srcdoc',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_action',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_method',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_formaction',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_formmethod',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_pattern',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_readonly',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_accept',
- },
- {
- input: '
',
- acceptable: [
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '
',
- '',
- '',
- '',
- ],
- name: 'contract_head_defer',
- },
- {
- input: '
',
- acceptable: ['', '', ''],
- name: 'contract_title_plain',
- },
- {
- input: '
',
- acceptable: ['', '', ''],
- name: 'contract_title_scriptinside',
- },
- {
- input: '
',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_srcdoc',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_action',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_method',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_formaction',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_formmethod',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_pattern',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_readonly',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_accept',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_title_defer',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'contract_base_plain',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'contract_base_scriptinside',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_srcdoc',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_action',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_method',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_formaction',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_formmethod',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_pattern',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_readonly',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_accept',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_base_defer',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'contract_meta_plain',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'contract_meta_scriptinside',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_srcdoc',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_action',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_method',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_formaction',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_formmethod',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_pattern',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_readonly',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_accept',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_meta_defer',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'contract_style_plain',
- },
- {
- input: '',
- acceptable: ['', '', ''],
- name: 'contract_style_scriptinside',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_srcdoc',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_action',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_method',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_formaction',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_formmethod',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_pattern',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_readonly',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_accept',
- },
- {
- input: '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_style_defer',
- },
- {
- input: '',
- '
',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_srcdoc',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_action',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_method',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_formaction',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_formmethod',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_pattern',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_readonly',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_accept',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '
',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_body_defer',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_plain',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_scriptinside',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_srcdoc',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_action',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_method',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_formaction',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_formmethod',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_pattern',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_readonly',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_accept',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_article_defer',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_plain',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_scriptinside',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_srcdoc',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_action',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_method',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_formaction',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_formmethod',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_pattern',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_readonly',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_accept',
- },
- {
- input: '',
- acceptable: [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ],
- name: 'contract_section_defer',
- },
- {
- input: '',
- acceptable: [
- '