@liujitcn/kratos-admin-system 0.0.20 → 0.0.21

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.
Files changed (86) hide show
  1. package/README.md +51 -50
  2. package/dist/package/declarations/src/api/system/base_language.d.ts +51 -0
  3. package/dist/package/declarations/src/api/system/base_translation.d.ts +7 -0
  4. package/dist/package/declarations/src/api/system/code_gen_i18n.d.ts +8 -0
  5. package/dist/package/declarations/src/components/DynamicTranslationCell.vue.d.ts +39 -0
  6. package/dist/package/declarations/src/components/DynamicTranslationEditor.vue.d.ts +23 -0
  7. package/dist/package/declarations/src/components/dynamicTranslation.d.ts +44 -0
  8. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +5 -0
  9. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +79 -0
  10. package/dist/package/declarations/src/rpc/system/admin/v1/base_language.d.ts +114 -0
  11. package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +40 -0
  12. package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +102 -0
  13. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +2 -0
  14. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_column.d.ts +7 -0
  15. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +13 -0
  16. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts +23 -0
  17. package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +7 -7
  18. package/dist/package/declarations/src/views/tool/language/index.vue.d.ts +3 -0
  19. package/dist/package/src/api/base/ai_message.ts +7 -12
  20. package/dist/package/src/api/base/sse.ts +3 -1
  21. package/dist/package/src/api/system/base_language.ts +137 -0
  22. package/dist/package/src/api/system/base_translation.ts +22 -0
  23. package/dist/package/src/api/system/code_gen_column.ts +17 -3
  24. package/dist/package/src/api/system/code_gen_i18n.ts +18 -0
  25. package/dist/package/src/api/system/code_gen_table.ts +12 -4
  26. package/dist/package/src/components/DynamicTranslationCell.vue +176 -0
  27. package/dist/package/src/components/DynamicTranslationEditor.vue +166 -0
  28. package/dist/package/src/components/dynamicTranslation.ts +86 -0
  29. package/dist/package/src/locales/README.md +28 -0
  30. package/dist/package/src/locales/en-US.json +929 -0
  31. package/dist/package/src/locales/es-ES.json +928 -0
  32. package/dist/package/src/locales/fr-FR.json +928 -0
  33. package/dist/package/src/locales/ja-JP.json +929 -0
  34. package/dist/package/src/locales/ko-KR.json +928 -0
  35. package/dist/package/src/locales/zh-CN.json +929 -0
  36. package/dist/package/src/locales/zh-TW.json +928 -0
  37. package/dist/package/src/module.ts +19 -1
  38. package/dist/package/src/rpc/system/admin/v1/base_config.ts +5 -0
  39. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +81 -0
  40. package/dist/package/src/rpc/system/admin/v1/base_language.ts +135 -0
  41. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +41 -0
  42. package/dist/package/src/rpc/system/admin/v1/base_translation.ts +117 -0
  43. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +5 -1
  44. package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +8 -0
  45. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +15 -0
  46. package/dist/package/src/views/ai/chat/components/AiMarkdown.vue +1 -6
  47. package/dist/package/src/views/ai/chat/components/ChatPanel.vue +70 -53
  48. package/dist/package/src/views/ai/chat/components/SessionPanel.vue +20 -9
  49. package/dist/package/src/views/ai/chat/components/XSender.vue +36 -23
  50. package/dist/package/src/views/ai/chat/index.vue +55 -39
  51. package/dist/package/src/views/ai/chat/message.ts +18 -17
  52. package/dist/package/src/views/base/api/index.vue +121 -83
  53. package/dist/package/src/views/base/area/index.vue +81 -31
  54. package/dist/package/src/views/base/config/index.vue +272 -78
  55. package/dist/package/src/views/base/dept/index.vue +110 -61
  56. package/dist/package/src/views/base/dict/index.vue +137 -58
  57. package/dist/package/src/views/base/dict/item.vue +147 -61
  58. package/dist/package/src/views/base/job/index.vue +134 -81
  59. package/dist/package/src/views/base/job/log.vue +21 -22
  60. package/dist/package/src/views/base/log/index.vue +68 -46
  61. package/dist/package/src/views/base/menu/index.vue +257 -156
  62. package/dist/package/src/views/base/migration/index.vue +49 -29
  63. package/dist/package/src/views/base/post/index.vue +128 -59
  64. package/dist/package/src/views/base/role/index.vue +145 -78
  65. package/dist/package/src/views/base/tenant/index.vue +132 -63
  66. package/dist/package/src/views/base/user/components/dept-tree.vue +2 -1
  67. package/dist/package/src/views/base/user/index.vue +192 -112
  68. package/dist/package/src/views/profile/components/base.vue +44 -27
  69. package/dist/package/src/views/profile/components/password.vue +43 -27
  70. package/dist/package/src/views/profile/components/security.vue +89 -53
  71. package/dist/package/src/views/profile/index.vue +10 -9
  72. package/dist/package/src/views/tool/api-doc/index.vue +6 -2
  73. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +30 -14
  74. package/dist/package/src/views/tool/code-gen/columns/index.vue +382 -273
  75. package/dist/package/src/views/tool/code-gen/columns/option-copy.ts +1 -6
  76. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +118 -0
  77. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +65 -36
  78. package/dist/package/src/views/tool/code-gen/components/CodePreviewPane.vue +8 -5
  79. package/dist/package/src/views/tool/code-gen/config.ts +114 -77
  80. package/dist/package/src/views/tool/code-gen/preview/data.ts +19 -17
  81. package/dist/package/src/views/tool/code-gen/preview/index.vue +96 -58
  82. package/dist/package/src/views/tool/code-gen/proto/index.vue +110 -62
  83. package/dist/package/src/views/tool/code-gen/table/index.vue +197 -117
  84. package/dist/package/src/views/tool/language/index.vue +256 -0
  85. package/dist/package/src/views/tool/project-doc/index.vue +17 -15
  86. package/package.json +6 -2
@@ -16,7 +16,7 @@
16
16
  <FormDialog
17
17
  v-model="dialog.visible"
18
18
  ref="formDialogRef"
19
- :title="dialog.title"
19
+ :title="t(dialog.titleKey, { resource: t('system.dept.resource') })"
20
20
  width="600px"
21
21
  :model="formData"
22
22
  :fields="formFields"
@@ -45,6 +45,7 @@ import type { SelectOptionResponse_Option, TreeOptionResponse_Option } from "@li
45
45
  import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
46
46
  import { normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
47
47
  import { DEFAULT_TENANT_CODE, requestTenantOptions } from "@liujitcn/kratos-admin-core/tenant";
48
+ import { t } from "@liujitcn/kratos-admin-core";
48
49
 
49
50
  defineOptions({
50
51
  name: "BaseDept",
@@ -63,17 +64,17 @@ const proTable = ref<ProTableInstance>();
63
64
  const formDialogRef = ref<InstanceType<typeof FormDialog>>();
64
65
 
65
66
  const dialog = reactive({
66
- title: "",
67
+ titleKey: "system.common.action.createResource",
67
68
  visible: false
68
69
  });
69
70
 
70
71
  const deptOptions = ref<TreeOptionResponse_Option[]>([]);
71
72
  const tenantOptions = ref<SelectOptionResponse_Option[]>([]);
72
73
  const currentTenantId = ref<number | undefined>();
73
- const statusOptions: ProFormOption[] = [
74
- { label: "启用", value: Status.ENABLE },
75
- { label: "禁用", value: Status.DISABLE }
76
- ];
74
+ const statusOptions = computed<ProFormOption[]>(() => [
75
+ { label: t("common.status.enabled"), value: Status.ENABLE },
76
+ { label: t("common.status.disabled"), value: Status.DISABLE }
77
+ ]);
77
78
 
78
79
  const formData = reactive<BaseDeptFormState>({
79
80
  /** 部门ID */
@@ -92,16 +93,42 @@ const formData = reactive<BaseDeptFormState>({
92
93
  remark: ""
93
94
  });
94
95
 
95
- const rules = reactive({
96
- tenant_id: [{ required: true, message: "所属租户不能为空", trigger: "change" }],
97
- parent_id: [{ required: true, message: "上级部门不能为空", trigger: "change" }],
96
+ const rules = computed(() => ({
97
+ tenant_id: [
98
+ {
99
+ required: true,
100
+ message: t("system.common.validation.requiredSelect", { field: t("system.common.field.tenant") }),
101
+ trigger: "change"
102
+ }
103
+ ],
104
+ parent_id: [
105
+ {
106
+ required: true,
107
+ message: t("system.common.validation.requiredSelect", { field: t("system.dept.field.parent") }),
108
+ trigger: "change"
109
+ }
110
+ ],
98
111
  name: [
99
- { required: true, message: "部门名称不能为空", trigger: "blur" },
100
- { max: 255, message: "部门名称不能超过 255 个字符", trigger: "blur" }
112
+ {
113
+ required: true,
114
+ message: t("system.common.validation.requiredInput", { field: t("system.dept.field.name") }),
115
+ trigger: "blur"
116
+ },
117
+ {
118
+ max: 255,
119
+ message: t("system.common.validation.maxLength", { field: t("system.dept.field.name"), max: 255 }),
120
+ trigger: "blur"
121
+ }
101
122
  ],
102
- sort: [{ required: true, type: "number", min: 1, message: "排序必须大于 0", trigger: "blur" }],
103
- status: [{ required: true, message: "状态不能为空", trigger: "change" }]
104
- });
123
+ sort: [{ required: true, type: "number", min: 1, message: t("system.common.validation.sortPositive"), trigger: "blur" }],
124
+ status: [
125
+ {
126
+ required: true,
127
+ message: t("system.common.validation.requiredSelect", { field: t("system.common.field.status") }),
128
+ trigger: "change"
129
+ }
130
+ ]
131
+ }));
105
132
 
106
133
  /** 当前登录账号是否默认租户。 */
107
134
  const isDefaultTenant = computed(() => userStore.userInfo.tenant_code === DEFAULT_TENANT_CODE);
@@ -110,10 +137,10 @@ const isDefaultTenant = computed(() => userStore.userInfo.tenant_code === DEFAUL
110
137
  const formFields = computed<ProFormField[]>(() => [
111
138
  {
112
139
  prop: "tenant_id",
113
- label: "所属租户",
140
+ label: t("system.common.field.tenant"),
114
141
  component: "select",
115
142
  props: {
116
- placeholder: "请选择所属租户",
143
+ placeholder: t("system.common.validation.requiredSelect", { field: t("system.common.field.tenant") }),
117
144
  filterable: true,
118
145
  disabled: Boolean(formData.id),
119
146
  onChange: handleFormTenantChange
@@ -123,26 +150,36 @@ const formFields = computed<ProFormField[]>(() => [
123
150
  },
124
151
  {
125
152
  prop: "parent_id",
126
- label: "上级部门",
153
+ label: t("system.dept.field.parent"),
127
154
  component: "tree-select",
128
155
  options: deptOptions.value,
129
156
  props: {
130
- placeholder: "选择上级部门",
157
+ placeholder: t("system.common.validation.requiredSelect", { field: t("system.dept.field.parent") }),
131
158
  filterable: true,
132
159
  checkStrictly: true,
133
160
  renderAfterExpand: false,
134
161
  style: { width: "100%" }
135
162
  }
136
163
  },
137
- { prop: "name", label: "部门名称", component: "input", props: { placeholder: "请输入部门名称" } },
164
+ {
165
+ prop: "name",
166
+ label: t("system.dept.field.name"),
167
+ component: "input",
168
+ props: { placeholder: t("system.common.validation.requiredInput", { field: t("system.dept.field.name") }) }
169
+ },
138
170
  {
139
171
  prop: "sort",
140
- label: "排序",
172
+ label: t("system.common.field.sort"),
141
173
  component: "input-number",
142
174
  props: { min: 1, precision: 0, step: 1, controlsPosition: "right", style: { width: "100%" } }
143
175
  },
144
- { prop: "remark", label: "备注", component: "textarea", props: { placeholder: "请输入备注" } },
145
- { prop: "status", label: "状态", component: "radio-group", options: statusOptions }
176
+ {
177
+ prop: "remark",
178
+ label: t("system.common.field.remark"),
179
+ component: "textarea",
180
+ props: { placeholder: t("system.common.placeholder.remark") }
181
+ },
182
+ { prop: "status", label: t("system.common.field.status"), component: "radio-group", options: statusOptions.value }
146
183
  ]);
147
184
 
148
185
  /** 部门树表格列配置。 */
@@ -152,7 +189,7 @@ const columns = computed<ColumnProps[]>(() => [
152
189
  ? ([
153
190
  {
154
191
  prop: "tenant_id",
155
- label: "租户",
192
+ label: t("system.common.field.tenant"),
156
193
  minWidth: 140,
157
194
  showOverflowTooltip: true,
158
195
  search: { el: "select", key: "tenant_id", props: { filterable: true }, order: 1 },
@@ -160,35 +197,35 @@ const columns = computed<ColumnProps[]>(() => [
160
197
  }
161
198
  ] satisfies ColumnProps[])
162
199
  : []),
163
- { prop: "name", label: "部门名称", minWidth: 140, align: "left", search: { el: "input" } },
164
- { prop: "remark", label: "备注", minWidth: 160, search: { el: "input" } },
165
- { prop: "sort", label: "排序", minWidth: 90, align: "right" },
200
+ { prop: "name", label: t("system.dept.field.name"), minWidth: 140, align: "left", search: { el: "input" } },
201
+ { prop: "remark", label: t("system.common.field.remark"), minWidth: 160, search: { el: "input" } },
202
+ { prop: "sort", label: t("system.common.field.sort"), minWidth: 90, align: "right" },
166
203
  {
167
204
  prop: "status",
168
- label: "状态",
205
+ label: t("system.common.field.status"),
169
206
  minWidth: 100,
170
207
  search: { el: "select" },
171
208
  cellType: "status",
172
209
  statusProps: {
173
210
  activeValue: Status.ENABLE,
174
211
  inactiveValue: Status.DISABLE,
175
- activeText: "启用",
176
- inactiveText: "禁用",
212
+ activeText: t("common.status.enabled"),
213
+ inactiveText: t("common.status.disabled"),
177
214
  disabled: () => !BUTTONS.value["base:dept:status"],
178
215
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseDept)
179
216
  }
180
217
  },
181
- { prop: "created_at", label: "创建时间", minWidth: 180 },
182
- { prop: "updated_at", label: "更新时间", minWidth: 180 },
218
+ { prop: "created_at", label: t("system.common.field.createdAt"), minWidth: 180 },
219
+ { prop: "updated_at", label: t("system.common.field.updatedAt"), minWidth: 180 },
183
220
  {
184
221
  prop: "operation",
185
- label: "操作",
222
+ label: t("system.common.field.operation"),
186
223
  width: 220,
187
224
  fixed: "right",
188
225
  cellType: "actions",
189
226
  actions: [
190
227
  {
191
- label: "新增",
228
+ label: t("common.action.create"),
192
229
  type: "primary",
193
230
  link: true,
194
231
  icon: CirclePlus,
@@ -198,7 +235,7 @@ const columns = computed<ColumnProps[]>(() => [
198
235
  handleOpenDialog((params?.parent_id as number | undefined) ?? 0, undefined, params?.tenantId as number | undefined)
199
236
  },
200
237
  {
201
- label: "编辑",
238
+ label: t("common.action.edit"),
202
239
  type: "primary",
203
240
  link: true,
204
241
  icon: EditPen,
@@ -210,7 +247,7 @@ const columns = computed<ColumnProps[]>(() => [
210
247
  onClick: (_, params) => handleOpenDialog(params?.parent_id as number | undefined, params?.deptId as number | undefined)
211
248
  },
212
249
  {
213
- label: "删除",
250
+ label: t("common.action.delete"),
214
251
  type: "danger",
215
252
  link: true,
216
253
  icon: Delete,
@@ -222,23 +259,23 @@ const columns = computed<ColumnProps[]>(() => [
222
259
  ]);
223
260
 
224
261
  /** 部门顶部按钮配置。 */
225
- const headerActions: HeaderActionProps[] = [
262
+ const headerActions = computed<HeaderActionProps[]>(() => [
226
263
  {
227
- label: "新增",
264
+ label: t("common.action.create"),
228
265
  type: "success",
229
266
  icon: CirclePlus,
230
267
  hidden: () => !BUTTONS.value["base:dept:create"],
231
268
  onClick: () => handleOpenDialog(0)
232
269
  },
233
270
  {
234
- label: "删除",
271
+ label: t("common.action.delete"),
235
272
  type: "danger",
236
273
  icon: Delete,
237
274
  hidden: () => !BUTTONS.value["base:dept:delete"],
238
275
  disabled: scope => !scope.selectedList.length,
239
276
  onClick: scope => handleDelete(scope.selectedList as BaseDept[])
240
277
  }
241
- ];
278
+ ]);
242
279
 
243
280
  /**
244
281
  * 按搜索条件递归过滤部门树,命中父节点或子节点时保留当前节点。
@@ -295,7 +332,7 @@ function refreshTable() {
295
332
  async function loadDeptOptions() {
296
333
  // 默认租户未选择目标租户时仅保留顶级部门,避免混入其他租户的部门树。
297
334
  if (isDefaultTenant.value && !formData.tenant_id) {
298
- deptOptions.value = [{ value: 0, label: "顶级部门", disabled: false, has_children: true, children: [] }];
335
+ deptOptions.value = [{ value: 0, label: t("system.dept.value.root"), disabled: false, has_children: true, children: [] }];
299
336
  return;
300
337
  }
301
338
  const optionBaseDeptResponse = await defBaseDeptService.OptionBaseDept({
@@ -304,7 +341,7 @@ async function loadDeptOptions() {
304
341
  deptOptions.value = [
305
342
  {
306
343
  value: 0,
307
- label: "顶级部门",
344
+ label: t("system.dept.value.root"),
308
345
  disabled: false,
309
346
  has_children: true,
310
347
  children: optionBaseDeptResponse.list
@@ -336,7 +373,7 @@ async function handleOpenDialog(parent_id?: number, deptId?: number, tenantId?:
336
373
  resetForm();
337
374
  await loadTenantOptions();
338
375
  if (deptId) {
339
- dialog.title = "修改部门";
376
+ dialog.titleKey = "system.common.action.editResource";
340
377
  dialog.visible = true;
341
378
  defBaseDeptService.GetBaseDept({ id: deptId }).then(async data => {
342
379
  Object.assign(formData, data);
@@ -348,7 +385,7 @@ async function handleOpenDialog(parent_id?: number, deptId?: number, tenantId?:
348
385
  // 从部门行新增子部门时,继承父部门租户并加载同租户上级部门树。
349
386
  formData.tenant_id = tenantId;
350
387
  await loadDeptOptions();
351
- dialog.title = "新增部门";
388
+ dialog.titleKey = "system.common.action.createResource";
352
389
  dialog.visible = true;
353
390
  formData.parent_id = parent_id ?? 0;
354
391
  }
@@ -389,7 +426,11 @@ function handleSubmit() {
389
426
  ? defBaseDeptService.UpdateBaseDept({ base_dept: submitData })
390
427
  : defBaseDeptService.CreateBaseDept({ base_dept: submitData });
391
428
  request.then(() => {
392
- ElMessage.success(submitData.id ? "修改部门成功" : "新增部门成功");
429
+ ElMessage.success(
430
+ t(submitData.id ? "system.common.message.updateSuccess" : "system.common.message.createSuccess", {
431
+ resource: t("system.dept.resource")
432
+ })
433
+ );
393
434
  handleCloseDialog();
394
435
  refreshTable();
395
436
  });
@@ -401,16 +442,25 @@ function handleSubmit() {
401
442
  */
402
443
  async function handleBeforeSetStatus(row: BaseDept) {
403
444
  const nextStatus = row.status === Status.ENABLE ? Status.DISABLE : Status.ENABLE;
404
- const text = nextStatus === Status.ENABLE ? "启用" : "禁用";
445
+ const text = t(nextStatus === Status.ENABLE ? "common.status.enabled" : "common.status.disabled");
405
446
  const deptName = row.name || `ID:${row.id}`;
406
447
  try {
407
- await ElMessageBox.confirm(`是否确定${text}部门?\n部门名称:${deptName}`, "提示", {
408
- confirmButtonText: "确认",
409
- cancelButtonText: "取消",
410
- type: "warning"
411
- });
448
+ await ElMessageBox.confirm(
449
+ t("system.common.dialog.statusChange", {
450
+ action: text,
451
+ resource: t("system.dept.resource"),
452
+ field: t("system.dept.field.name"),
453
+ value: deptName
454
+ }),
455
+ t("common.title.notice"),
456
+ {
457
+ confirmButtonText: t("common.action.confirm"),
458
+ cancelButtonText: t("common.action.cancel"),
459
+ type: "warning"
460
+ }
461
+ );
412
462
  await defBaseDeptService.SetBaseDeptStatus({ id: row.id, status: nextStatus });
413
- ElMessage.success(`${text}成功`);
463
+ ElMessage.success(t("system.common.message.statusSuccess", { action: text }));
414
464
  refreshTable();
415
465
  return true;
416
466
  } catch {
@@ -431,31 +481,30 @@ function handleDelete(selected?: number | string | Array<number | string> | Base
431
481
  deptList.length ? deptList.map(item => item.id) : normalizeSelectedIds(selected as number | string | Array<number | string>)
432
482
  ).join(",");
433
483
  if (!deptIds) {
434
- ElMessage.warning("请勾选删除项");
484
+ ElMessage.warning(t("system.common.message.selectDeleteItem"));
435
485
  return;
436
486
  }
437
487
 
438
488
  const confirmMessage = deptList.length
439
489
  ? deptList.length === 1
440
- ? `是否确定删除部门?\n部门名称:${deptList[0].name || `ID:${deptList[0].id}`}`
441
- : `确认删除已选中的 ${deptList.length} 个部门吗?`
442
- : "确认删除已选中的部门吗?";
490
+ ? `${t("system.common.dialog.deleteSingle", { resource: t("system.dept.resource") })}\n${t("system.common.dialog.resourceField", { field: t("system.dept.field.name"), value: deptList[0].name || `ID:${deptList[0].id}` })}`
491
+ : t("system.common.dialog.deleteBatch", { count: deptList.length, unit: "", resource: t("system.dept.resource") })
492
+ : t("system.common.dialog.deleteSelected", { resource: t("system.dept.resource") });
443
493
 
444
- ElMessageBox.confirm(confirmMessage, "警告", {
445
- confirmButtonText: "确定",
446
- cancelButtonText: "取消",
494
+ ElMessageBox.confirm(confirmMessage, t("common.title.warning"), {
495
+ confirmButtonText: t("common.action.confirm"),
496
+ cancelButtonText: t("common.action.cancel"),
447
497
  type: "warning"
448
498
  }).then(
449
499
  () => {
450
500
  defBaseDeptService.DeleteBaseDept({ id: deptIds }).then(() => {
451
- ElMessage.success("删除部门成功");
501
+ ElMessage.success(t("system.common.message.deleteSuccess", { resource: t("system.dept.resource") }));
452
502
  refreshTable();
453
503
  });
454
504
  },
455
505
  () => {
456
- ElMessage.info("已取消删除部门");
506
+ ElMessage.info(t("system.common.dialog.cancelDelete", { resource: t("system.dept.resource") }));
457
507
  }
458
508
  );
459
509
  }
460
-
461
510
  </script>