@things-factory/shell 10.1.44 → 10.1.47
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/dist-server/middlewares/domain-middleware.d.ts +12 -0
- package/dist-server/middlewares/domain-middleware.js +19 -4
- package/dist-server/middlewares/domain-middleware.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/tests/domain-middleware-refusal.test.ts +44 -0
- package/tests/generator-list-page-template.test.ts +24 -0
- package/tests/undefined-custom-properties.test.ts +4 -13
- package/translations/en.json +17 -1
- package/translations/ja.json +17 -1
- package/translations/ko.json +20 -4
- package/translations/ms.json +17 -1
- package/translations/zh.json +17 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/shell",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.47",
|
|
4
4
|
"description": "Core module for framework",
|
|
5
5
|
"bin": {
|
|
6
6
|
"things-factory": "bin/things-factory",
|
|
@@ -126,5 +126,5 @@
|
|
|
126
126
|
"pg": "^8.7.3",
|
|
127
127
|
"sqlite3": "^5.0.8"
|
|
128
128
|
},
|
|
129
|
-
"gitHead": "
|
|
129
|
+
"gitHead": "185f20d7d9a15715a0ee2757a6a8189ec36cfb9d"
|
|
130
130
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* The domain is given in state, so the URL lookup is never reached - and importing it drags in every entity. */
|
|
2
|
+
jest.mock('../server/utils/get-domain', () => ({ getDomainFromURL: jest.fn() }))
|
|
3
|
+
|
|
4
|
+
import { domainMiddleware, REFUSAL_HEADER, REFUSED_ADDRESS } from '../server/middlewares/domain-middleware'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A request refused by the domain's IP lists says why (ADR README plan 3, left open there).
|
|
8
|
+
*
|
|
9
|
+
* The same 403 also means "no domain chosen", and the client answers that by sending the person to
|
|
10
|
+
* check-in. For a refused address check-in sends them straight back, so the client has to tell the
|
|
11
|
+
* two apart - the header is how. Anything that is not an address refusal carries no header.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
function run(iplist: any, ip: string) {
|
|
15
|
+
const headers: Record<string, string> = {}
|
|
16
|
+
const context: any = {
|
|
17
|
+
state: { domain: { id: 'd1', iplist } },
|
|
18
|
+
req: { headers: { 'x-client-ip': ip }, connection: {}, socket: {} },
|
|
19
|
+
status: 200,
|
|
20
|
+
set: (name: string, value: string) => (headers[name.toLowerCase()] = value)
|
|
21
|
+
}
|
|
22
|
+
let passed = false
|
|
23
|
+
return domainMiddleware(context, async () => {
|
|
24
|
+
passed = true
|
|
25
|
+
}).then(() => ({ status: context.status, headers, passed }))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('domain middleware - an address the domain does not let in', () => {
|
|
29
|
+
it('★ outside the whitelist: 403, and it says the address was refused', async () => {
|
|
30
|
+
const result = await run({ whitelist: ['^10\\.'] }, '192.168.0.9')
|
|
31
|
+
expect(result).toEqual({ status: 403, headers: { [REFUSAL_HEADER]: REFUSED_ADDRESS }, passed: false })
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('★ on the blacklist: 403, and it says the address was refused', async () => {
|
|
35
|
+
const result = await run({ blacklist: ['^192\\.168\\.'] }, '192.168.0.9')
|
|
36
|
+
expect(result).toEqual({ status: 403, headers: { [REFUSAL_HEADER]: REFUSED_ADDRESS }, passed: false })
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('★ an address that is let in passes with no refusal header', async () => {
|
|
40
|
+
expect(await run({ whitelist: ['^10\\.'] }, '10.0.0.1')).toEqual({ status: 200, headers: {}, passed: true })
|
|
41
|
+
expect(await run({ blacklist: ['^192\\.168\\.'] }, '10.0.0.1')).toEqual({ status: 200, headers: {}, passed: true })
|
|
42
|
+
expect(await run(undefined, '10.0.0.1')).toEqual({ status: 200, headers: {}, passed: true })
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readFileSync } from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The generator's list page does not stamp colours nothing uses.
|
|
6
|
+
*
|
|
7
|
+
* The template set `--grid-record-emphasized-background-color: #8B0000` and a `#FF6B6B` text on every
|
|
8
|
+
* generated list page. Emphasis only happens through a grid `classifier`, and the template has none,
|
|
9
|
+
* so 64 of the 66 pages that carry the pair never emphasize a row - and the two that declare a
|
|
10
|
+
* classifier leave it empty [확인함 2026-09-24]. The pair was also a contrast failure waiting to
|
|
11
|
+
* happen (about 3.6:1 against WCAG AA's 4.5) and ignored the dark theme. A page that does emphasize
|
|
12
|
+
* rows chooses its colours from the theme where it needs them.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const TEMPLATE = path.resolve(
|
|
16
|
+
__dirname,
|
|
17
|
+
'../../generator/templates/service/client/pages/entity/{{name}}-list-page.ts.hbs'
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
describe("the generator's list page template", () => {
|
|
21
|
+
it('★ stamps no emphasized-row colours', () => {
|
|
22
|
+
expect(readFileSync(TEMPLATE, 'utf-8')).not.toMatch(/--grid-record-emphasized-(background-)?color\s*:/)
|
|
23
|
+
})
|
|
24
|
+
})
|
|
@@ -91,8 +91,9 @@ const HOOKS = [
|
|
|
91
91
|
]
|
|
92
92
|
|
|
93
93
|
/*
|
|
94
|
-
* The installed operato components, as of @operato 10.
|
|
95
|
-
*
|
|
94
|
+
* The installed operato components, as of @operato 10.24-10.25 (process is not installed here). The ten
|
|
95
|
+
* typos fixed in 10.23 left this list with that install. What remains is read in operato and defined by
|
|
96
|
+
* no product we checked; a name leaves when something defines it or the read goes.
|
|
96
97
|
*/
|
|
97
98
|
const OPERATO_KNOWN = [
|
|
98
99
|
'--button-radius',
|
|
@@ -100,19 +101,9 @@ const OPERATO_KNOWN = [
|
|
|
100
101
|
'--component-detail-border-color',
|
|
101
102
|
'--form-input-width',
|
|
102
103
|
'--grid-record-focused-color',
|
|
103
|
-
'--legend-background-color',
|
|
104
|
-
'--legend-border',
|
|
105
|
-
'--legend-border-radius',
|
|
106
|
-
'--legend-margin',
|
|
107
|
-
'--md-sys-color-on-primary-container-rgb',
|
|
108
|
-
'--md-sys-on-color-secondary',
|
|
109
|
-
'--md-sys-shape-corner-tiny',
|
|
110
|
-
'--md-sys-typescale-label-medium-weight',
|
|
111
104
|
'--opacity-light-dark-color',
|
|
112
|
-
'--pading-default',
|
|
113
105
|
'--record-view-edit-border',
|
|
114
|
-
'--record-view-grid-field-border'
|
|
115
|
-
'--spacing-smail'
|
|
106
|
+
'--record-view-grid-field-border'
|
|
116
107
|
]
|
|
117
108
|
|
|
118
109
|
describe('custom properties read with no fallback are defined', () => {
|
package/translations/en.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"button.add": "Add",
|
|
3
|
+
"button.back": "back",
|
|
3
4
|
"button.cancel": "cancel",
|
|
4
5
|
"button.close": "Close",
|
|
6
|
+
"button.collapse": "collapse",
|
|
5
7
|
"button.confirm": "confirm",
|
|
6
8
|
"button.copy": "copy",
|
|
7
9
|
"button.copy to draft": "copy to draft",
|
|
@@ -12,6 +14,7 @@
|
|
|
12
14
|
"button.edit": "edit",
|
|
13
15
|
"button.edit-contact": "edit contact",
|
|
14
16
|
"button.empty": "empty",
|
|
17
|
+
"button.expand": "expand",
|
|
15
18
|
"button.export": "export",
|
|
16
19
|
"button.refresh": "refresh",
|
|
17
20
|
"button.register": "register",
|
|
@@ -109,6 +112,7 @@
|
|
|
109
112
|
"label.platform": "platform",
|
|
110
113
|
"label.please_select_a_country": "please select a country",
|
|
111
114
|
"label.please_select_a_platform": "please select a platform",
|
|
115
|
+
"label.resize": "resize",
|
|
112
116
|
"label.seconds": "seconds",
|
|
113
117
|
"label.state": "state",
|
|
114
118
|
"label.status": "Status",
|
|
@@ -127,6 +131,10 @@
|
|
|
127
131
|
"text.data_updated_successfully": "data updated successfully",
|
|
128
132
|
"text.data_uploaded_successfully": "data uploaded successfully",
|
|
129
133
|
"text.draft": "draft",
|
|
134
|
+
"text.entity360-not-yet": "there is no 360 for this kind yet.",
|
|
135
|
+
"text.entity360-none": "none",
|
|
136
|
+
"text.entity360-forbidden": "you may not see this",
|
|
137
|
+
"text.entity360-failed": "could not be read",
|
|
130
138
|
"text.error": "error",
|
|
131
139
|
"text.existing_item_found": "existing item found",
|
|
132
140
|
"text.failed": "failed",
|
|
@@ -161,5 +169,13 @@
|
|
|
161
169
|
"term.domain": "site",
|
|
162
170
|
"field.roles": "roles",
|
|
163
171
|
"label.released": "released",
|
|
164
|
-
"label.import": "import"
|
|
172
|
+
"label.import": "import",
|
|
173
|
+
"error.address-not-allowed": "this site does not accept connections from where you are. ask its administrator.",
|
|
174
|
+
"button.undo": "undo",
|
|
175
|
+
"button.redo": "redo",
|
|
176
|
+
"button.fit-view": "fit to view",
|
|
177
|
+
"button.hide-start-pane": "hide the left pane",
|
|
178
|
+
"button.show-start-pane": "show the left pane",
|
|
179
|
+
"button.hide-end-pane": "hide the right pane",
|
|
180
|
+
"button.show-end-pane": "show the right pane"
|
|
165
181
|
}
|
package/translations/ja.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"button.add": "追加",
|
|
3
|
+
"button.back": "戻る",
|
|
3
4
|
"button.cancel": "キャンセル",
|
|
4
5
|
"button.close": "閉じる",
|
|
6
|
+
"button.collapse": "縮める",
|
|
5
7
|
"button.confirm": "確認",
|
|
6
8
|
"button.copy": "コピー",
|
|
7
9
|
"button.copy to draft": "ドラフトにコピー",
|
|
@@ -12,6 +14,7 @@
|
|
|
12
14
|
"button.edit": "修正",
|
|
13
15
|
"button.edit-contact": "連絡先を編集",
|
|
14
16
|
"button.empty": "空にする",
|
|
17
|
+
"button.expand": "広げる",
|
|
15
18
|
"button.export": "エクスポート",
|
|
16
19
|
"button.refresh": "リロード",
|
|
17
20
|
"button.register": "登録",
|
|
@@ -109,6 +112,7 @@
|
|
|
109
112
|
"label.platform": "プラットフォーム",
|
|
110
113
|
"label.please_select_a_country": "国を選択してください",
|
|
111
114
|
"label.please_select_a_platform": "プラットフォームを選択してください",
|
|
115
|
+
"label.resize": "幅の調整",
|
|
112
116
|
"label.seconds": "秒",
|
|
113
117
|
"label.state": "状態",
|
|
114
118
|
"label.status": "状態",
|
|
@@ -127,6 +131,10 @@
|
|
|
127
131
|
"text.data_updated_successfully": "資料の修正に成功しました.",
|
|
128
132
|
"text.data_uploaded_successfully": "資料が正常に作成されました.",
|
|
129
133
|
"text.draft": "ドラフト保存",
|
|
134
|
+
"text.entity360-not-yet": "この種類の 360 はまだありません。",
|
|
135
|
+
"text.entity360-none": "なし",
|
|
136
|
+
"text.entity360-forbidden": "閲覧できません",
|
|
137
|
+
"text.entity360-failed": "読み込めませんでした",
|
|
130
138
|
"text.error": "エラー",
|
|
131
139
|
"text.existing_item_found": "既にある項目です",
|
|
132
140
|
"text.failed": "失敗",
|
|
@@ -161,5 +169,13 @@
|
|
|
161
169
|
"term.domain": "事業場",
|
|
162
170
|
"field.roles": "ロール",
|
|
163
171
|
"label.released": "公開済み",
|
|
164
|
-
"label.import": "インポート"
|
|
172
|
+
"label.import": "インポート",
|
|
173
|
+
"error.address-not-allowed": "この事業所は現在の場所からの接続を受け付けていません。事業所の管理者にお問い合わせください。",
|
|
174
|
+
"button.undo": "元に戻す",
|
|
175
|
+
"button.redo": "やり直す",
|
|
176
|
+
"button.fit-view": "画面に合わせる",
|
|
177
|
+
"button.hide-start-pane": "左のパネルを閉じる",
|
|
178
|
+
"button.show-start-pane": "左のパネルを開く",
|
|
179
|
+
"button.hide-end-pane": "右のパネルを閉じる",
|
|
180
|
+
"button.show-end-pane": "右のパネルを開く"
|
|
165
181
|
}
|
package/translations/ko.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"button.add": "추가",
|
|
3
|
+
"button.back": "뒤로",
|
|
3
4
|
"button.cancel": "취소",
|
|
4
5
|
"button.close": "닫기",
|
|
6
|
+
"button.collapse": "줄이기",
|
|
5
7
|
"button.confirm": "확인",
|
|
6
8
|
"button.copy": "복사",
|
|
7
|
-
"button.copy to draft": "
|
|
9
|
+
"button.copy to draft": "초안으로 복사",
|
|
8
10
|
"button.create": "생성",
|
|
9
11
|
"button.delete": "삭제",
|
|
10
12
|
"button.detail": "상세",
|
|
@@ -12,6 +14,7 @@
|
|
|
12
14
|
"button.edit": "수정",
|
|
13
15
|
"button.edit-contact": "연락처 편집",
|
|
14
16
|
"button.empty": "비우기",
|
|
17
|
+
"button.expand": "넓히기",
|
|
15
18
|
"button.export": "내보내기",
|
|
16
19
|
"button.refresh": "새로고침",
|
|
17
20
|
"button.register": "등록",
|
|
@@ -109,6 +112,7 @@
|
|
|
109
112
|
"label.platform": "플랫폼",
|
|
110
113
|
"label.please_select_a_country": "국가를 선택하세요",
|
|
111
114
|
"label.please_select_a_platform": "플랫폼을 선택하세요",
|
|
115
|
+
"label.resize": "폭 조절",
|
|
112
116
|
"label.seconds": "초",
|
|
113
117
|
"label.state": "상태",
|
|
114
118
|
"label.status": "상태",
|
|
@@ -127,6 +131,10 @@
|
|
|
127
131
|
"text.data_updated_successfully": "성공적으로 자료를 수정하였습니다.",
|
|
128
132
|
"text.data_uploaded_successfully": "성공적으로 자료를 업로드하였습니다.",
|
|
129
133
|
"text.draft": "초안저장",
|
|
134
|
+
"text.entity360-not-yet": "이 종류의 360 은 아직 없습니다.",
|
|
135
|
+
"text.entity360-none": "없음",
|
|
136
|
+
"text.entity360-forbidden": "볼 수 없음",
|
|
137
|
+
"text.entity360-failed": "읽지 못함",
|
|
130
138
|
"text.error": "오류",
|
|
131
139
|
"text.existing_item_found": "이미 있는 항목입니다",
|
|
132
140
|
"text.failed": "실패",
|
|
@@ -135,12 +143,12 @@
|
|
|
135
143
|
"text.initial version all new": "최초 버전 — 전체 신규",
|
|
136
144
|
"text.loading": "읽는 중…",
|
|
137
145
|
"text.no difference from previous": "앞 버전과 차이가 없습니다",
|
|
138
|
-
"text.no released version information available": "
|
|
146
|
+
"text.no released version information available": "발행된 버전이 없습니다",
|
|
139
147
|
"text.nothing_changed": "변경사항 없음",
|
|
140
148
|
"text.nothing_selected": "선택되지 않음",
|
|
141
149
|
"text.offline": "오프라인",
|
|
142
150
|
"text.online": "온라인",
|
|
143
|
-
"text.release comment optional": "
|
|
151
|
+
"text.release comment optional": "발행 메모(선택) — 비우면 자동으로 채웁니다",
|
|
144
152
|
"text.saved": "저장되었습니다",
|
|
145
153
|
"text.sure_to_x": "{x}하시겠습니까?",
|
|
146
154
|
"text.technical detail": "기술 정보",
|
|
@@ -161,5 +169,13 @@
|
|
|
161
169
|
"term.domain": "사업장",
|
|
162
170
|
"field.roles": "역할",
|
|
163
171
|
"label.released": "발행됨",
|
|
164
|
-
"label.import": "가져오기"
|
|
172
|
+
"label.import": "가져오기",
|
|
173
|
+
"error.address-not-allowed": "이 사업장은 지금 계신 곳에서의 접속을 받지 않습니다. 사업장 관리자에게 문의하십시오.",
|
|
174
|
+
"button.undo": "되돌리기",
|
|
175
|
+
"button.redo": "다시 실행",
|
|
176
|
+
"button.fit-view": "화면에 맞추기",
|
|
177
|
+
"button.hide-start-pane": "왼쪽 판 접기",
|
|
178
|
+
"button.show-start-pane": "왼쪽 판 펼치기",
|
|
179
|
+
"button.hide-end-pane": "오른쪽 판 접기",
|
|
180
|
+
"button.show-end-pane": "오른쪽 판 펼치기"
|
|
165
181
|
}
|
package/translations/ms.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"button.add": "Tambah",
|
|
3
|
+
"button.back": "kembali",
|
|
3
4
|
"button.cancel": "batal",
|
|
4
5
|
"button.close": "tutup",
|
|
6
|
+
"button.collapse": "kecilkan",
|
|
5
7
|
"button.confirm": "sahkan",
|
|
6
8
|
"button.copy": "salin",
|
|
7
9
|
"button.copy to draft": "salin ke draf",
|
|
@@ -12,6 +14,7 @@
|
|
|
12
14
|
"button.edit": "Edit",
|
|
13
15
|
"button.edit-contact": "edit kenalan",
|
|
14
16
|
"button.empty": "kosongkan",
|
|
17
|
+
"button.expand": "besarkan",
|
|
15
18
|
"button.export": "Eksport",
|
|
16
19
|
"button.refresh": "Segar Semula",
|
|
17
20
|
"button.register": "daftar",
|
|
@@ -109,6 +112,7 @@
|
|
|
109
112
|
"label.platform": "platform",
|
|
110
113
|
"label.please_select_a_country": "please select a country",
|
|
111
114
|
"label.please_select_a_platform": "please select a platform",
|
|
115
|
+
"label.resize": "ubah lebar",
|
|
112
116
|
"label.seconds": "saat",
|
|
113
117
|
"label.state": "negeri",
|
|
114
118
|
"label.status": "Status",
|
|
@@ -127,6 +131,10 @@
|
|
|
127
131
|
"text.data_updated_successfully": "data berjaya dikemaskini",
|
|
128
132
|
"text.data_uploaded_successfully": "data uploaded successfully",
|
|
129
133
|
"text.draft": "draf",
|
|
134
|
+
"text.entity360-not-yet": "belum ada 360 untuk jenis ini.",
|
|
135
|
+
"text.entity360-none": "tiada",
|
|
136
|
+
"text.entity360-forbidden": "anda tidak boleh melihat ini",
|
|
137
|
+
"text.entity360-failed": "tidak dapat dibaca",
|
|
130
138
|
"text.error": "Ralat",
|
|
131
139
|
"text.existing_item_found": "item ini sudah ada",
|
|
132
140
|
"text.failed": "gagal",
|
|
@@ -161,5 +169,13 @@
|
|
|
161
169
|
"term.domain": "tapak",
|
|
162
170
|
"field.roles": "peranan",
|
|
163
171
|
"label.released": "diterbitkan",
|
|
164
|
-
"label.import": "import"
|
|
172
|
+
"label.import": "import",
|
|
173
|
+
"error.address-not-allowed": "tapak ini tidak menerima sambungan dari lokasi anda. sila hubungi pentadbirnya.",
|
|
174
|
+
"button.undo": "buat asal",
|
|
175
|
+
"button.redo": "buat semula",
|
|
176
|
+
"button.fit-view": "muat ke paparan",
|
|
177
|
+
"button.hide-start-pane": "sembunyikan panel kiri",
|
|
178
|
+
"button.show-start-pane": "tunjukkan panel kiri",
|
|
179
|
+
"button.hide-end-pane": "sembunyikan panel kanan",
|
|
180
|
+
"button.show-end-pane": "tunjukkan panel kanan"
|
|
165
181
|
}
|
package/translations/zh.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"button.add": "添加",
|
|
3
|
+
"button.back": "返回",
|
|
3
4
|
"button.cancel": "取消",
|
|
4
5
|
"button.close": "关闭",
|
|
6
|
+
"button.collapse": "收起",
|
|
5
7
|
"button.confirm": "确认",
|
|
6
8
|
"button.copy": "复制",
|
|
7
9
|
"button.copy to draft": "复制到草稿",
|
|
@@ -12,6 +14,7 @@
|
|
|
12
14
|
"button.edit": "更改",
|
|
13
15
|
"button.edit-contact": "编辑联系人",
|
|
14
16
|
"button.empty": "清空",
|
|
17
|
+
"button.expand": "展开",
|
|
15
18
|
"button.export": "导出",
|
|
16
19
|
"button.refresh": "刷新",
|
|
17
20
|
"button.register": "注册",
|
|
@@ -109,6 +112,7 @@
|
|
|
109
112
|
"label.platform": "platform",
|
|
110
113
|
"label.please_select_a_country": "please select a country",
|
|
111
114
|
"label.please_select_a_platform": "please select a platform",
|
|
115
|
+
"label.resize": "调整宽度",
|
|
112
116
|
"label.seconds": "秒",
|
|
113
117
|
"label.state": "状态",
|
|
114
118
|
"label.status": "状态",
|
|
@@ -127,6 +131,10 @@
|
|
|
127
131
|
"text.data_updated_successfully": "数据更新成功。",
|
|
128
132
|
"text.data_uploaded_successfully": "数据上传成功。",
|
|
129
133
|
"text.draft": "草稿",
|
|
134
|
+
"text.entity360-not-yet": "此类暂无 360 视图。",
|
|
135
|
+
"text.entity360-none": "无",
|
|
136
|
+
"text.entity360-forbidden": "无权查看",
|
|
137
|
+
"text.entity360-failed": "无法读取",
|
|
130
138
|
"text.error": "错误",
|
|
131
139
|
"text.existing_item_found": "该项目已存在",
|
|
132
140
|
"text.failed": "失败",
|
|
@@ -161,5 +169,13 @@
|
|
|
161
169
|
"field.roles": "角色",
|
|
162
170
|
"term.domain": "站点",
|
|
163
171
|
"label.released": "已发布",
|
|
164
|
-
"label.import": "导入"
|
|
172
|
+
"label.import": "导入",
|
|
173
|
+
"error.address-not-allowed": "此站点不接受来自您当前位置的连接。请联系站点管理员。",
|
|
174
|
+
"button.undo": "撤销",
|
|
175
|
+
"button.redo": "重做",
|
|
176
|
+
"button.fit-view": "适应视图",
|
|
177
|
+
"button.hide-start-pane": "收起左侧面板",
|
|
178
|
+
"button.show-start-pane": "展开左侧面板",
|
|
179
|
+
"button.hide-end-pane": "收起右侧面板",
|
|
180
|
+
"button.show-end-pane": "展开右侧面板"
|
|
165
181
|
}
|