@things-factory/board-ui 10.0.0-beta.8 → 10.0.0-beta.80

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 (104) hide show
  1. package/dist-client/apptools/favorite-tool.js +5 -5
  2. package/dist-client/apptools/favorite-tool.js.map +1 -1
  3. package/dist-client/board-list/board-tile-list.d.ts +6 -3
  4. package/dist-client/board-list/board-tile-list.js +316 -62
  5. package/dist-client/board-list/board-tile-list.js.map +1 -1
  6. package/dist-client/board-list/group-bar.js +3 -3
  7. package/dist-client/board-list/group-bar.js.map +1 -1
  8. package/dist-client/board-list/play-group-bar.d.ts +0 -1
  9. package/dist-client/board-list/play-group-bar.js +3 -6
  10. package/dist-client/board-list/play-group-bar.js.map +1 -1
  11. package/dist-client/board-provider.js +20 -8
  12. package/dist-client/board-provider.js.map +1 -1
  13. package/dist-client/data-grist/board-editor.js +4 -4
  14. package/dist-client/data-grist/board-editor.js.map +1 -1
  15. package/dist-client/data-grist/board-renderer.js +4 -4
  16. package/dist-client/data-grist/board-renderer.js.map +1 -1
  17. package/dist-client/graphql/attachment.d.ts +33 -0
  18. package/dist-client/graphql/attachment.js +87 -0
  19. package/dist-client/graphql/attachment.js.map +1 -0
  20. package/dist-client/graphql/board-import.d.ts +45 -0
  21. package/dist-client/graphql/board-import.js +104 -0
  22. package/dist-client/graphql/board-import.js.map +1 -0
  23. package/dist-client/graphql/board-template.js +1 -1
  24. package/dist-client/graphql/board-template.js.map +1 -1
  25. package/dist-client/graphql/board.d.ts +1 -0
  26. package/dist-client/graphql/board.js +28 -2
  27. package/dist-client/graphql/board.js.map +1 -1
  28. package/dist-client/graphql/group.js +1 -1
  29. package/dist-client/graphql/group.js.map +1 -1
  30. package/dist-client/graphql/play-group.js +3 -3
  31. package/dist-client/graphql/play-group.js.map +1 -1
  32. package/dist-client/pages/attachment-list-page.d.ts +16 -0
  33. package/dist-client/pages/attachment-list-page.js +63 -2
  34. package/dist-client/pages/attachment-list-page.js.map +1 -1
  35. package/dist-client/pages/board-action-dispatch.d.ts +31 -0
  36. package/dist-client/pages/board-action-dispatch.js +80 -0
  37. package/dist-client/pages/board-action-dispatch.js.map +1 -0
  38. package/dist-client/pages/board-action-dispatch.test.d.ts +1 -0
  39. package/dist-client/pages/board-action-dispatch.test.js +235 -0
  40. package/dist-client/pages/board-action-dispatch.test.js.map +1 -0
  41. package/dist-client/pages/board-create-wizard-page.d.ts +157 -0
  42. package/dist-client/pages/board-create-wizard-page.js +2176 -0
  43. package/dist-client/pages/board-create-wizard-page.js.map +1 -0
  44. package/dist-client/pages/board-edit-dispatch.d.ts +74 -0
  45. package/dist-client/pages/board-edit-dispatch.js +299 -0
  46. package/dist-client/pages/board-edit-dispatch.js.map +1 -0
  47. package/dist-client/pages/board-edit-dispatch.test.d.ts +1 -0
  48. package/dist-client/pages/board-edit-dispatch.test.js +858 -0
  49. package/dist-client/pages/board-edit-dispatch.test.js.map +1 -0
  50. package/dist-client/pages/board-list-page.d.ts +23 -3
  51. package/dist-client/pages/board-list-page.js +165 -77
  52. package/dist-client/pages/board-list-page.js.map +1 -1
  53. package/dist-client/pages/board-modeller-page.d.ts +134 -0
  54. package/dist-client/pages/board-modeller-page.js +725 -54
  55. package/dist-client/pages/board-modeller-page.js.map +1 -1
  56. package/dist-client/pages/board-player-by-name-page.js.map +1 -1
  57. package/dist-client/pages/board-player-page.js +14 -26
  58. package/dist-client/pages/board-player-page.js.map +1 -1
  59. package/dist-client/pages/board-viewer-by-name-page.d.ts +8 -1
  60. package/dist-client/pages/board-viewer-by-name-page.js +9 -1
  61. package/dist-client/pages/board-viewer-by-name-page.js.map +1 -1
  62. package/dist-client/pages/board-viewer-page.d.ts +2 -1
  63. package/dist-client/pages/board-viewer-page.js +52 -48
  64. package/dist-client/pages/board-viewer-page.js.map +1 -1
  65. package/dist-client/pages/play-list-page.d.ts +0 -1
  66. package/dist-client/pages/play-list-page.js +26 -33
  67. package/dist-client/pages/play-list-page.js.map +1 -1
  68. package/dist-client/pages/printable-board-viewer-page.js +2 -2
  69. package/dist-client/pages/printable-board-viewer-page.js.map +1 -1
  70. package/dist-client/route.d.ts +1 -1
  71. package/dist-client/route.js +3 -0
  72. package/dist-client/route.js.map +1 -1
  73. package/dist-client/setting-let/board-view-setting-let.js +1 -1
  74. package/dist-client/setting-let/board-view-setting-let.js.map +1 -1
  75. package/dist-client/tsconfig.tsbuildinfo +1 -1
  76. package/dist-client/utils/notify-helper.d.ts +7 -0
  77. package/dist-client/utils/notify-helper.js +28 -0
  78. package/dist-client/utils/notify-helper.js.map +1 -0
  79. package/dist-client/utils/query-utils.d.ts +1 -0
  80. package/dist-client/utils/query-utils.js +20 -0
  81. package/dist-client/utils/query-utils.js.map +1 -0
  82. package/dist-client/viewparts/board-basic-info.js +9 -13
  83. package/dist-client/viewparts/board-basic-info.js.map +1 -1
  84. package/dist-client/viewparts/board-template-info.d.ts +0 -1
  85. package/dist-client/viewparts/board-template-info.js +5 -13
  86. package/dist-client/viewparts/board-template-info.js.map +1 -1
  87. package/dist-client/viewparts/board-versions.js +1 -1
  88. package/dist-client/viewparts/board-versions.js.map +1 -1
  89. package/dist-client/viewparts/group-info-basic.js +2 -2
  90. package/dist-client/viewparts/group-info-basic.js.map +1 -1
  91. package/dist-client/viewparts/group-info-import.js +2 -2
  92. package/dist-client/viewparts/group-info-import.js.map +1 -1
  93. package/dist-client/viewparts/link-builder.js +1 -1
  94. package/dist-client/viewparts/link-builder.js.map +1 -1
  95. package/dist-client/viewparts/play-group-info-basic.js +2 -2
  96. package/dist-client/viewparts/play-group-info-basic.js.map +1 -1
  97. package/dist-server/tsconfig.tsbuildinfo +1 -1
  98. package/package.json +5 -4
  99. package/things-factory.config.js +1 -0
  100. package/translations/en.json +71 -30
  101. package/translations/ja.json +3 -29
  102. package/translations/ko.json +71 -30
  103. package/translations/ms.json +3 -29
  104. package/translations/zh.json +3 -29
@@ -1 +1 @@
1
- {"version":3,"file":"board-modeller-page.js","sourceRoot":"","sources":["../../client/pages/board-modeller-page.ts"],"names":[],"mappings":"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","sourcesContent":["import './things-scene-components.import'\nimport '@operato/board/ox-board-modeller.js'\nimport '@operato/oops'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { BoardModeller } from '@operato/board/ox-board-modeller.js'\nimport { OxPropertyEditor } from '@operato/property-editor'\nimport { PageView, FontController } from '@operato/shell'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client/index.js'\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\n\nimport { provider } from '../board-provider.js'\nimport components from './things-scene-components-with-tools.import'\n\nconst NOOP = () => {}\n\n@customElement('board-modeller-page')\nexport class BoardModellerPage extends PageView {\n constructor() {\n super()\n\n components.forEach(({ templates = [], groups = [] }) => {\n groups.forEach(group => BoardModeller.registerGroup(group))\n BoardModeller.registerTemplate(templates)\n })\n\n /* 컴포넌트에서 정의된 에디터들을 MODELLER_EDITORS에 등록 */\n var addedEditors = {}\n for (let component in components) {\n let { editors } = components[component]\n\n editors &&\n editors.forEach(editor => {\n let { type, element } = editor\n\n addedEditors[type] = element\n })\n }\n\n OxPropertyEditor.register(addedEditors)\n }\n\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n overflow: hidden;\n position: relative;\n }\n\n ox-board-modeller {\n flex: 1;\n }\n\n ox-oops-note {\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n `\n ]\n\n @property({ type: String }) boardId?: string | null\n @property({ type: String }) boardName?: string = ''\n @property({ type: Object }) model: any = null\n @property({ type: Array }) selected: any = []\n @property({ type: Number }) mode?: number = 1\n @property({ type: Boolean }) hideProperty?: boolean = false\n @property({ type: String }) overlay?: string | null = null\n @property({ type: Object }) scene: any = null\n @property({ type: Array }) componentGroupList?: any[] = BoardModeller.groups\n @property({ type: Array }) propertyEditor: any\n @property({ type: Boolean }) preparing?: boolean\n\n private board: any = null\n private _fontCtrl = new FontController(this)\n @query('ox-board-modeller') modeller?: BoardModeller\n\n get context() {\n return {\n title: this.board ? this.boardName : this.preparing ? 'Fetching board...' : 'Board Not Found',\n help: 'board-modeller/modeller',\n widebleed: true\n }\n }\n\n get oopsNote() {\n return {\n icon: 'color_lens',\n title: 'EMPTY BOARD',\n description: 'There are no board to be designed'\n }\n }\n\n async refresh() {\n if (!this.boardId) {\n this.board = null\n this.model = null\n\n return\n }\n try {\n this.preparing = true\n this.updateContext()\n\n var response = await client.query({\n query: gql`\n query FetchBoardById($id: String!) {\n board(id: $id) {\n id\n name\n model\n }\n }\n `,\n variables: { id: this.boardId },\n context: gqlContext()\n })\n\n var board = response.data.board\n\n if (!board) {\n this.board = null\n throw 'board not found'\n }\n\n this.board = {\n ...board,\n model: JSON.parse(board.model)\n }\n\n this.boardName = this.board.name\n this.model = {\n ...this.board.model\n }\n } catch (ex) {\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: ex,\n ex\n }\n })\n )\n } finally {\n this.preparing = false\n this.updateContext()\n }\n }\n\n async updated(changes) {\n if (changes.has('boardId')) {\n if (await hasPrivilege({ privilege: 'mutation', category: 'board' })) {\n this.refresh()\n } else {\n this.boardId = null\n this.model = null\n this.modeller?.close()\n }\n }\n }\n\n pageUpdated(changes, lifecycle) {\n if (this.active) {\n this.boardId = lifecycle.resourceId\n } else {\n this.boardId = null\n this.model = null\n this.modeller?.close()\n }\n }\n\n render() {\n var oops = !this.preparing && !this.model && this.oopsNote\n\n return oops\n ? html` <ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note> `\n : html`\n <ox-board-modeller\n .mode=${this.mode}\n @mode-changed=${e => {\n this.mode = e.detail.value\n }}\n .model=${this.model}\n @model-changed=${e => {\n this.model = e.detail.value\n }}\n .scene=${this.scene}\n @scene-changed=${e => {\n this.scene = e.detail.value\n }}\n .selected=${this.selected}\n @selected-changed=${e => {\n this.selected = e.detail.value\n }}\n .provider=${provider}\n @save-model=${e => this.saveBoard()}\n .componentGroupList=${this.componentGroupList}\n .fonts=${this._fontCtrl.fonts}\n .hideProperty=${this.hideProperty}\n >\n </ox-board-modeller>\n `\n }\n\n async updateBoard() {\n try {\n this.preparing = true\n\n var { id, name, description, groupId } = this.board\n var model = JSON.stringify(this.scene.model)\n\n await client.mutate({\n mutation: gql`\n mutation UpdateBoard($id: String!, $patch: BoardPatch!) {\n updateBoard(id: $id, patch: $patch) {\n id\n }\n }\n `,\n variables: {\n id,\n patch: { name, description, model, groupId }\n },\n context: gqlContext()\n })\n\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'info',\n message: i18next.t('text.saved')\n }\n })\n )\n } catch (ex) {\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: ex,\n ex: ex\n }\n })\n )\n } finally {\n this.preparing = false\n }\n\n this.updateContext()\n }\n\n async saveBoard() {\n await this.updateBoard()\n this.modeller?.preserve()\n }\n\n async canDeactivate(): Promise<boolean> {\n if (this.modeller?.hasUnpreservedChanges()) {\n return await OxPrompt.open({\n title: i18next.t('text.are_you_sure'),\n text: i18next.t('prompt.sure to navigate away?'),\n confirmButton: { text: i18next.t('button.confirm') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n }\n\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"board-modeller-page.js","sourceRoot":"","sources":["../../client/pages/board-modeller-page.ts"],"names":[],"mappings":";AAAA,OAAO,kCAAkC,CAAA;AACzC,OAAO,qCAAqC,CAAA;AAC5C,OAAO,eAAe,CAAA;AACtB,OAAO,0BAA0B,CAAA;AAEjC,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAA;AACnE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,gDAAgD,CAAA;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AAErE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,UAAU,MAAM,6CAA6C,CAAA;AACpE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAE7B,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAErB,oDAAoD;AACpD,MAAM,qBAAqB,GAAG,GAAG,CAAA;;;;CAIhC,CAAA;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,QAAa,EAAE,QAAa;IACrD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAA;IAChE,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAA;IAChE,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAA;IACjF,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAA;IAEvE,MAAM,GAAG,GAAQ,EAAE,GAAG,QAAQ,EAAE,CAAA;IAChC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,EAAE,GAAI,QAAgB,CAAC,GAAG,CAAC,CAAA;QACjC,MAAM,EAAE,GAAI,QAAgB,CAAC,GAAG,CAAC,CAAA;QACjC,IACE,EAAE,KAAK,IAAI;YACX,EAAE,KAAK,IAAI;YACX,OAAO,EAAE,KAAK,QAAQ;YACtB,OAAO,EAAE,KAAK,QAAQ;YACtB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAClB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAClB,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QACtC,CAAC;aAAM,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YAC5B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;QACf,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAGM,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,QAAQ;IAC7C;QACE,KAAK,EAAE,CAAA;QA8FmB,cAAS,GAAY,EAAE,CAAA;QACvB,UAAK,GAAQ,IAAI,CAAA;QAClB,aAAQ,GAAQ,EAAE,CAAA;QACjB,SAAI,GAAY,CAAC,CAAA;QAChB,iBAAY,GAAa,KAAK,CAAA;QAC/B,YAAO,GAAmB,IAAI,CAAA;QAC9B,UAAK,GAAQ,IAAI,CAAA;QAClB,uBAAkB,GAAW,aAAa,CAAC,MAAM,CAAA;QAO5E,mCAAmC;QAC1B,iBAAY,GAA6D,EAAE,CAAA;QAEpF,6BAA6B;QACpB,gBAAW,GAAG,KAAK,CAAA;QAE5B;;;;;;WAMG;QACK,kBAAa,GAAG,IAAI,GAAG,EAAyB,CAAA;QA+HhD,UAAK,GAAQ,IAAI,CAAA;QAEjB,cAAS,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAA;QAkJ5C;kFAC0E;QAClE,+BAA0B,GAAG,KAAK,EACxC,KAAa,EACkD,EAAE;YACjE,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;oBAChC,KAAK,EAAE,GAAG,CAAA;;;;;;;;SAQT;oBACD,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;oBAC9C,OAAO,EAAE,UAAU,EAAE;oBACrB,WAAW,EAAE,aAAa;iBAC3B,CAAC,CAAA;gBACF,OAAO,MAAM,CAAC,IAAI,EAAE,qBAAqB,IAAI,EAAE,CAAA;YACjD,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,8BAA8B;gBAC9B,OAAO,CAAC,IAAI,CAAC,0DAA0D,EAAE,EAAE,CAAC,CAAA;gBAC5E,OAAO,EAAE,CAAA;YACX,CAAC;QACH,CAAC,CAAA;QAED,8BAA8B;QACtB,wBAAmB,GAAG,CAAC,CAAc,EAAE,EAAE;YAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,CAAA;YACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC9D,IAAI,CAAC,aAAa,GAAG,KAAK,CAAA;YAC5B,CAAC;QACH,CAAC,CAAA;QAED,yCAAyC;QACjC,wBAAmB,GAAG,KAAK,IAAI,EAAE;YACvC,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,OAAM;YACzB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;oBAClC,QAAQ,EAAE,GAAG,CAAA;;;;;;;;SAQZ;oBACD,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE;oBAChD,OAAO,EAAE,UAAU,EAAE;iBACtB,CAAC,CAAA;gBACF,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,iBAAiB,CAAA;gBACzC,IAAI,CAAC,EAAE,CAAC;oBACN,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;oBAC7C,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,CAAA;gBAC3B,CAAC;YACH,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,WAAW,CAAC,EAAE,CAAC,CAAA;YACjB,CAAC;QACH,CAAC,CAAA;QAoBD;;;;;;;;;WASG;QACK,0BAAqB,GAAG,CAAC,GAAG,EAAE;YACpC,MAAM,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAA;YACtC,OAAO,CAAC,KAAa,EAAS,EAAE;gBAC9B,MAAM,IAAI,GAAI,IAAI,CAAC,KAAa,EAAE,IAAI,CAAA;gBACtC,IAAI,CAAC,IAAI;oBAAE,OAAO,EAAE,CAAA;gBACpB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;gBAC1C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;oBACrB,MAAM,CAAC,GAAQ,CAAC,CAAC,SAAS,CAAA;oBAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;oBACtE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;oBAChE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;oBACpE,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;oBAClE,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;oBACpE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;oBACpE,OAAO;wBACL,SAAS,EAAE;4BACT,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;4BACpD,KAAK,EAAE,EAAE,IAAI,IAAI,IAAI,SAAS;4BAC9B,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;4BACjD,EAAE,EAAE,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;4BACjD,GAAG,EAAE,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;4BACrD,KAAK,EAAE,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;4BACvD,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;yBAC1D;wBACD,SAAS,EAAE,CAAC,CAAC,SAAS;wBACtB,UAAU,EAAE,CAAC,CAAC,UAAU;qBACzB,CAAA;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC,CAAA;QACH,CAAC,CAAC,EAAE,CAAA;QAsBJ;;;;;;;;;;WAUG;QACK,qBAAgB,GAAG,CAAC,CAAc,EAAE,EAAE;YAC5C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAA;YACzC,IAAI,CAAC,KAAK;gBAAE,OAAM;YAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAY,CAAA;YAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,WAAW,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAA;gBAC/C,OAAM;YACR,CAAC;YAED,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAe,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,CAAA;YACnF,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;gBACxC,OAAM;YACR,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,MAAM,GAAkB,EAAE,CAAA;gBAChC,2DAA2D;gBAC3D,iDAAiD;gBACjD,MAAM,UAAU,GAAkB,EAAE,CAAA;gBACpC,MAAM,SAAS,GAAG,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAA;gBAExD,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,GAAoB,EAAE,CAAC;oBAC5C,MAAM,CAAC,GAAG,mBAAmB,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;oBACvD,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;wBACd,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAA;oBAClC,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;oBACjB,CAAC;gBACH,CAAC;gBAED,wCAAwC;gBACxC,IAAI,OAAO,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACrC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;gBAC7C,CAAC;gBAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,MAAM,UAAU,GAAG,MAAM;yBACtB,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE;wBACf,IAAI,EAAE,CAAC,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,EAAE,KAAK,QAAQ;4BAAE,OAAO,SAAS,EAAE,CAAC,KAAK,EAAE,CAAA;wBACxE,IAAI,EAAE,CAAC,EAAE,KAAK,aAAa;4BAAE,OAAO,sCAAsC,CAAA;wBAC1E,OAAO,EAAE,CAAC,EAAE,CAAA;oBACd,CAAC,CAAC;yBACD,IAAI,CAAC,IAAI,CAAC,CAAA;oBACb,MAAM,CACJ,MAAM,EACN,QAAQ,MAAM,CAAC,MAAM,4BAA4B,UAAU,EAAE,CAC9D,CAAA;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,WAAW,CAAC,EAAE,CAAC,CAAA;YACjB,CAAC;QACH,CAAC,CAAA;QAmCD;;;;;;;WAOG;QACK,sBAAiB,GAAG,KAAK,EAAE,CAAc,EAAE,EAAE;YACnD,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAA;YAClC,IAAI,CAAC,OAAO;gBAAE,OAAM;YACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAChD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvC,MAAM,CACJ,MAAM,EACN,gEAAgE,CACjE,CAAA;gBACD,OAAM;YACR,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAY,CAAA;YAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,WAAW,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAA;gBAC/C,OAAM;YACR,CAAC;YAED,IAAI,CAAC;gBACH,gDAAgD;gBAChD,qDAAqD;gBACrD,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAA;gBACxC,MAAM,gBAAgB,GAAmB;oBACvC,GAAG,EAAE,QAAQ;oBACb,OAAO,EAAE,QAAQ;oBACjB,UAAU,EAAE,CAAC;iBACd,CAAA;gBACD,sEAAsE;gBACtE,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,CAAA;gBAC3D,IAAI,UAAU,EAAE,CAAC;oBACf,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAA;gBAC5C,CAAC;qBAAM,CAAC;oBACN,qEAAqE;oBACrE,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;gBAC9C,CAAC;gBAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBAClC,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAA;YAC1C,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,WAAW,CAAC,EAAE,CAAC,CAAA;YACjB,CAAC;QACH,CAAC,CAAA;QAsBD;;;;;WAKG;QACK,yBAAoB,GAAG,CAAC,CAAc,EAAE,EAAE;YAChD,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAA;YAClC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAM;YAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAY,CAAA;YAC/B,IAAI,CAAC,KAAK;gBAAE,OAAM;YAElB,IAAI,WAAW,GAAG,KAAK,CAAA;YACvB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,CAAC;oBACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;oBAClC,IAAI,MAAM,EAAE,MAAM,KAAK,cAAc;wBAAE,WAAW,GAAG,IAAI,CAAA;gBAC3D,CAAC;gBAAC,OAAO,EAAO,EAAE,CAAC;oBACjB,OAAO,CAAC,IAAI,CAAC,yCAAyC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA;gBACpF,CAAC;YACH,CAAC;YACD,oEAAoE;YACpE,IAAI,WAAW;gBAAE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;QACzC,CAAC,CAAA;QAxtBC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,EAAE,EAAE;YACrD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;YAC3D,aAAa,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAA;QAC3C,CAAC,CAAC,CAAA;QAEF,2CAA2C;QAC3C,MAAM,YAAY,GAAG,EAAE,CAAA;QACvB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;YAEvC,OAAO;gBACL,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;oBACvB,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;oBAE9B,YAAY,CAAC,IAAI,CAAC,GAAG,OAAO,CAAA;gBAC9B,CAAC,CAAC,CAAA;QACN,CAAC;QAED,gBAAgB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;IACzC,CAAC;aAEM,WAAM,GAAG;QACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkEF;KACF,AApEY,CAoEZ;IAqCD,IAAY,UAAU;QACpB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;YAC/B,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;gBAC/C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;oBACtC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;wBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;gBACxD,CAAC;YACH,CAAC;YACD,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;QAClD,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAA;IAC9B,CAAC;IAED,IAAY,eAAe;QACzB,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;YAC9B,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;gBAC/C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;oBACtC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;wBAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;gBACzD,CAAC;YACH,CAAC;YACD,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;QACtD,CAAC;QACD,OAAO,IAAI,CAAC,qBAAqB,CAAA;IACnC,CAAC;IAkBD,IAAY,gBAAgB;QAC1B,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC;YACjC,MAAM,GAAG,GAMJ,EAAE,CAAA;YACP,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;YAC1D,sCAAsC;YACtC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;gBAC5B,MAAM;gBACN,KAAK;gBACL,OAAO;gBACP,QAAQ;gBACR,GAAG;gBACH,GAAG;gBACH,IAAI;gBACJ,IAAI;gBACJ,OAAO;gBACP,QAAQ;gBACR,IAAI;gBACJ,IAAI;gBACJ,QAAQ;gBACR,UAAU;gBACV,WAAW;gBACX,OAAO;gBACP,QAAQ;gBACR,MAAM;gBACN,UAAU;gBACV,WAAW;gBACX,QAAQ;gBACR,QAAQ;gBACR,MAAM;gBACN,MAAM;gBACN,YAAY;gBACZ,UAAU;aACX,CAAC,CAAA;YACF,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;gBAC/C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;oBACtC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;wBAAE,SAAQ;oBAC9C,MAAM,UAAU,GAAwB,EAAE,CAAA;oBAC1C,MAAM,YAAY,GAAa,EAAE,CAAA;oBACjC,MAAM,KAAK,GAAQ,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;oBAChC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;wBACrC,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;4BAAE,SAAQ;wBAChC,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;4BAC3B,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;4BACtB,SAAQ;wBACV,CAAC;wBACD,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;wBACpB,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;4BACpD,UAAU,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,CAClC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;iCACX,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;iCACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CACvB,CAAA;wBACH,CAAC;6BAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC5B,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;wBACtB,CAAC;6BAAM,CAAC;4BACN,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;wBACrB,CAAC;oBACH,CAAC;oBACD,GAAG,CAAC,IAAI,CAAC;wBACP,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,SAAS;wBACvC,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,SAAS;wBAC3B,YAAY,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;wBAChE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;qBACxE,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;YACD,IAAI,CAAC,sBAAsB,GAAG,GAAG,CAAA;QACnC,CAAC;QACD,OAAO,IAAI,CAAC,sBAAsB,CAAA;IACpC,CAAC;IAOD,IAAI,OAAO;QACT,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE;YAC9E,IAAI,EAAE,yBAAyB;YAC/B,SAAS,EAAE,IAAI;SAChB,CAAA;IACH,CAAC;IAED,IAAI,QAAQ;QACV,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,aAAa;YACpB,WAAW,EAAE,mCAAmC;SACjD,CAAA;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;YACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;YAEjB,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,gBAAgB;YAChB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;YACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;YACjB,IAAI,CAAC,YAAY,GAAG,IAAI,WAAW,EAAE,CAAA;YACrC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YACnC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;YACrB,IAAI,CAAC,aAAa,EAAE,CAAA;YAEpB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;gBAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;SAQT;gBACD,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE;gBAC/B,OAAO,EAAE,UAAU,EAAE;aACtB,CAAC,CAAA;YAEF,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;YAEpC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAA;YAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;gBACjB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;YACpC,CAAC;YAED,IAAI,CAAC,KAAK,GAAG;gBACX,GAAG,KAAK;gBACR,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;aAC/B,CAAA;YAED,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAA;YAChC,IAAI,CAAC,KAAK,GAAG;gBACX,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK;aACpB,CAAA;YAED,yDAAyD;YACzD,iEAAiE;YACjE,wEAAwE;YACxE,IAAI,CAAC,aAAa,GAAG,SAAS,CAAA;YAC9B,IAAI,CAAC,YAAY,GAAG,EAAE,CAAA;YACtB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACrC,IAAI,CAAC,iBAAiB,EAAE,CAAA;YAC1B,CAAC;QACH,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,WAAW,CAAC,EAAE,CAAC,CAAA;QACjB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;YACtB,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC;IACH,CAAC;IAED,8DAA8D;IACtD,KAAK,CAAC,aAAa;QACzB,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,WAAW,CAAA;QAClC,IAAI,QAAQ,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAA;QAChC,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAA;IAC7B,CAAC;IAED;;;4CAGwC;IAChC,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAM;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;gBAChC,KAAK,EAAE,GAAG,CAAA;;;;;;;;SAQT;gBACD,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;gBACpC,OAAO,EAAE,UAAU,EAAE;gBACrB,WAAW,EAAE,cAAc;aAC5B,CAAC,CAAA;YACF,IAAI,QAAQ,GACV,MAAM,CAAC,IAAI,EAAE,mBAAmB,IAAI,EAAE,CAAA;YAExC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,2BAA2B;gBAC3B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;oBAClC,QAAQ,EAAE,GAAG,CAAA;;;;;;;;WAQZ;oBACD,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;oBACpC,OAAO,EAAE,UAAU,EAAE;iBACtB,CAAC,CAAA;gBACF,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAA;gBAC3C,IAAI,CAAC;oBAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAA;YACvB,CAAC;YAED,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAA;YAC5B,iDAAiD;YACjD,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC5E,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;YACtC,CAAC;QACH,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,WAAW,CAAC,EAAE,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAiED;;;;;;OAMG;IACK,qBAAqB;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAA;QAC/B,OAAO,GAAG;aACP,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;YACd,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU;gBAAE,OAAO,IAAI,CAAA;YAClD,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;QAC3E,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAgB,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;IAC1D,CAAC;IA2CD;;;;;;;;;;;OAWG;IACK,YAAY;QAClB,MAAM,UAAU,GAAI,IAAI,CAAC,KAAa,EAAE,KAAK,CAAA;QAC7C,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAA;QAC/C,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAmED;;;;;;;OAOG;IACK,mBAAmB,CAAC,KAAqB,EAAE,OAAgB;QACjE,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;YACrC,MAAM,UAAU,GAAkB,SAAS;gBACzC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;gBACnE,CAAC,CAAC,EAAE,CAAA;YACN,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YAC3D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAY,CAAA;YAChC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAM;YACvC,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAA;YACtF,IAAI,CAAC,KAAK,GAAG;gBACX,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;gBACpB,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACtD,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzD,UAAU,EAAE,UAAU;aACvB,CAAA;YACD,IAAI,OAAO,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;YAC7C,CAAC;YACD,MAAM,CAAC,MAAM,EAAE,yCAAyC,CAAC,CAAA;QAC3D,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,WAAW,CAAC,EAAE,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAqDD;;;OAGG;IACK,sBAAsB,CAAC,KAAU,EAAE,GAAkB;QAC3D,MAAM,SAAS,GAAG,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAA;QACxD,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,mBAAmB,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC;IAED,qEAAqE;IAC7D,KAAK,CAAC,oBAAoB,CAAC,OAAe;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,qBAAqB,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QAClF,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,qDAAqD,EAAE,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,CAAA;QACtF,CAAC;IACH,CAAC;IA2BD;;;;;OAKG;IACK,kBAAkB,CAAC,CAAM;QAC/B,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAA;QACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QAChD,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK;YAAE,OAAO,CAAC,CAAA;QAC1C,OAAO,iBAAiB,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAC7C,CAAC;IAEO,kBAAkB,CAAC,IAAY;QACrC,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YAC/C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;oBAAE,OAAO,CAAC,CAAA;YACpC,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAO;QACnB,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,IAAI,MAAM,YAAY,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;oBACrE,IAAI,CAAC,OAAO,EAAE,CAAA;gBAChB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;oBACnB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;oBACjB,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAA;gBACxB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;gBACnB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;gBACjB,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAA;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,WAAW,CAAC,OAAO,EAAE,SAAS;QAC5B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,UAAU,CAAA;QACrC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;YACnB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;YACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;YACjB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;YACtB,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAA;YACtB,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC;IACH,CAAC;IAED,MAAM;QACJ,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAA;QAE5D,OAAO,IAAI,CAAA;;UAEL,IAAI;YACJ,CAAC,CAAC,IAAI,CAAA,sBAAsB,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,KAAK,gBAAgB,IAAI,CAAC,WAAW,kBAAkB;YAC3G,CAAC,CAAC,IAAI,CAAA;;wBAEQ,IAAI,CAAC,IAAI;+BACF,IAAI,CAAC,YAAY;gCAChB,CAAC,CAAC,EAAE;gBAClB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;YAC5B,CAAC;yBACQ,IAAI,CAAC,KAAK;iCACF,CAAC,CAAC,EAAE;gBACnB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;YAC7B,CAAC;yBACQ,IAAI,CAAC,KAAK;iCACF,CAAC,CAAC,EAAE;gBACnB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;YAC7B,CAAC;4BACW,IAAI,CAAC,QAAQ;oCACL,CAAC,CAAC,EAAE;gBACtB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;YAChC,CAAC;4BACW,QAAQ;8BACN,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE;sCACb,IAAI,CAAC,kBAAkB;yBACpC,IAAI,CAAC,SAAS,CAAC,KAAK;gCACb,IAAI,CAAC,YAAY;;;aAGpC;UACH,IAAI,CAAC,OAAO;YACZ,CAAC,CAAC,IAAI,CAAA;;mCAEmB,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;yBACxC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,cAAc;yBAChD,IAAI,CAAC,aAAa;kBACzB,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;;aAEvC;YACH,CAAC,CAAC,OAAO;;QAEX,IAAI,CAAC,WAAW;YAChB,CAAC,CAAC,IAAI,CAAA;;;6BAGe,IAAI,CAAC,aAAa;4BACnB,IAAI,CAAC,YAAY;gCACb,IAAI,CAAC,KAAK;iCACT,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE;kCACxB,IAAI,CAAC,qBAAqB;gCAC5B,IAAI,CAAC,0BAA0B;8BACjC,IAAI,CAAC,UAAU;8BACf,IAAI,CAAC,eAAe;oCACd,IAAI,CAAC,gBAAgB;kCACvB,IAAI,CAAC,qBAAqB,EAAE;kCAC5B,IAAI,CAAC,mBAAmB;kCACxB,IAAI,CAAC,mBAAmB;oCACtB,IAAI,CAAC,gBAAgB;qCACpB,IAAI,CAAC,iBAAiB;wCACnB,IAAI,CAAC,oBAAoB;;;WAGtD;YACH,CAAC,CAAC,OAAO;KACZ,CAAA;IACH,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;YAErB,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;YACrD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAE9C,MAAM,MAAM,CAAC,MAAM,CAAC;gBAClB,QAAQ,EAAE,GAAG,CAAA;;;;;;SAMZ;gBACD,SAAS,EAAE;oBACT,EAAE;oBACF,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE;iBAC7C;gBACD,OAAO,EAAE,UAAU,EAAE;aACtB,CAAC,CAAA;YAEF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;QACzC,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,WAAW,CAAC,EAAE,CAAC,CAAA;QACjB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACxB,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;QACxB,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,IAAI,CAAC,QAAQ,EAAE,qBAAqB,EAAE,EAAE,CAAC;YAC3C,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC;gBACzB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;gBACrC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,+BAA+B,CAAC;gBAChD,aAAa,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE;gBACpD,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE;aACnD,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;;AA3yB2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;kDAAwB;AACvB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;oDAAwB;AACvB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;gDAAkB;AAClB;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;mDAAmB;AACjB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;+CAAkB;AAChB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;;uDAA+B;AAC/B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;kDAA+B;AAC9B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;gDAAkB;AAClB;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;6DAAkD;AACjD;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;yDAAoB;AACjB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;;oDAAoB;AAGvC;IAAR,KAAK,EAAE;;wDAAuB;AAGtB;IAAR,KAAK,EAAE;8BAAe,KAAK;uDAAwD;AAG3E;IAAR,KAAK,EAAE;;sDAAoB;AA2IA;IAA3B,KAAK,CAAC,mBAAmB,CAAC;8BAAY,aAAa;mDAAA;AA7PzC,iBAAiB;IAD7B,aAAa,CAAC,qBAAqB,CAAC;;GACxB,iBAAiB,CA24B7B","sourcesContent":["import './things-scene-components.import'\nimport '@operato/board/ox-board-modeller.js'\nimport '@operato/oops'\nimport '@things-factory/board-ai'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { BoardModeller } from '@operato/board/ox-board-modeller.js'\nimport { LoadTracker, SceneSearchEngine } from '@hatiolab/things-scene'\nimport { OxPropertyEditor } from '@operato/property-editor'\nimport { PageView, FontController } from '@operato/shell'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client/index.js'\nimport { applyBoardEditPatchVerbose } from '@things-factory/board-ai'\nimport type { BoardEditOp, BoardEditPatch } from '@things-factory/board-ai'\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\n\nimport { provider } from '../board-provider.js'\nimport components from './things-scene-components-with-tools.import'\nimport { notify, notifyError } from '../utils/notify-helper.js'\nimport { findSceneComponent, dispatchBoardAction } from './board-action-dispatch.js'\nimport { dispatchBoardEditOp } from './board-edit-dispatch.js'\n\nexport { findSceneComponent }\n\nconst NOOP = () => {}\n\n/** 서버 PatchEntry.reverted=true 플래그 영속용 mutation. */\nconst REVERT_PATCH_MUTATION = gql`\n mutation RevertPatch($patchId: String!) {\n revertPatch(patchId: $patchId)\n }\n`\n\n/**\n * default 위에 override 를 깊게 merge.\n * - override 의 키 값이 undefined 가 아닌 경우 우선 적용\n * - override 의 nested object 는 default 와 deep merge\n * - array / primitive 는 override 가 그대로 우선\n */\nfunction mergeDefaultsDeep(defaults: any, override: any): any {\n if (defaults === null || defaults === undefined) return override\n if (override === null || override === undefined) return defaults\n if (typeof defaults !== 'object' || typeof override !== 'object') return override\n if (Array.isArray(defaults) || Array.isArray(override)) return override\n\n const out: any = { ...defaults }\n for (const key of Object.keys(override)) {\n const dv = (defaults as any)[key]\n const ov = (override as any)[key]\n if (\n dv !== null &&\n ov !== null &&\n typeof dv === 'object' &&\n typeof ov === 'object' &&\n !Array.isArray(dv) &&\n !Array.isArray(ov)\n ) {\n out[key] = mergeDefaultsDeep(dv, ov)\n } else if (ov !== undefined) {\n out[key] = ov\n }\n }\n return out\n}\n\n@customElement('board-modeller-page')\nexport class BoardModellerPage extends PageView {\n constructor() {\n super()\n\n components.forEach(({ templates = [], groups = [] }) => {\n groups.forEach(group => BoardModeller.registerGroup(group))\n BoardModeller.registerTemplate(templates)\n })\n\n /* 컴포넌트에서 정의된 에디터들을 MODELLER_EDITORS에 등록 */\n const addedEditors = {}\n for (const component in components) {\n let { editors } = components[component]\n\n editors &&\n editors.forEach(editor => {\n let { type, element } = editor\n\n addedEditors[type] = element\n })\n }\n\n OxPropertyEditor.register(addedEditors)\n }\n\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: row;\n\n overflow: hidden;\n position: relative;\n }\n\n .modeller-area {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n position: relative;\n }\n\n ox-board-modeller {\n flex: 1;\n }\n\n .ai-toggle {\n position: absolute;\n right: 12px;\n bottom: 12px;\n z-index: 10;\n padding: 8px 14px;\n border: 0;\n border-radius: 24px;\n background: #2563eb;\n color: #fff;\n font: 500 13px/1.4 system-ui, -apple-system, sans-serif;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(37, 99, 235, 0.35);\n transition: background 0.15s, transform 0.1s;\n }\n .ai-toggle:hover { background: #1d4ed8; }\n .ai-toggle:active { transform: scale(0.97); }\n .ai-toggle.open { background: #475569; }\n .ai-toggle.open:hover { background: #334155; }\n\n .ai-panel {\n flex: 0 0 320px;\n display: flex;\n border-left: 1px solid #e2e8f0;\n background: #ffffff;\n }\n\n ox-board-ai-chat { flex: 1; }\n\n ox-oops-note {\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n @media (max-width: 900px) {\n .ai-panel {\n flex-basis: 100%;\n position: absolute;\n inset: 0;\n z-index: 20;\n }\n }\n `\n ]\n\n @property({ type: String }) boardId?: string | null\n @property({ type: String }) boardName?: string = ''\n @property({ type: Object }) model: any = null\n @property({ type: Array }) selected: any = []\n @property({ type: Number }) mode?: number = 1\n @property({ type: Boolean }) hideProperty?: boolean = false\n @property({ type: String }) overlay?: string | null = null\n @property({ type: Object }) scene: any = null\n @property({ type: Array }) componentGroupList?: any[] = BoardModeller.groups\n @property({ type: Array }) propertyEditor: any\n @property({ type: Boolean }) preparing?: boolean\n\n /** AI 협력 세션 id — 현재 활성 세션. boardId 변경 시 자동 ensure. 다중 세션 시 활성 1개. */\n @state() chatSessionId?: string\n\n /** 보드의 모든 ChatSession (탭으로 표시). */\n @state() chatSessions: Array<{ id: string; name?: string; createdAt?: string }> = []\n\n /** AI 채팅 패널 열림 상태 (기본 닫힘) */\n @state() aiPanelOpen = false\n\n /**\n * 적용된 patch 별 inverse op 시퀀스 — Revert 기능용.\n *\n * Map<patchId, inverseOps[]>: 각 patch 적용 시점에 계산해 저장. revert 클릭\n * 시 역순 in-place 적용. 페이지 reload 시 손실 — reload 후 revert 시도는\n * notify 로 안내 (메모리 외 영속은 별개 작업).\n */\n private patchInverses = new Map<string, BoardEditOp[]>()\n\n /** 모델러에 등록된 컴포넌트 type 목록 — chat 호출 시 LLM 에 전달 (lazy cache) */\n private _knownTypesCache?: string[]\n /** 등록된 type 의 group 분류 — categories 로 LLM 에 전달 */\n private _knownCategoriesCache?: string[]\n\n private get knownTypes(): string[] {\n if (!this._knownTypesCache) {\n const types = new Set<string>()\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && typeof t.type === 'string') types.add(t.type)\n }\n }\n this._knownTypesCache = Array.from(types).sort()\n }\n return this._knownTypesCache\n }\n\n private get knownCategories(): string[] {\n if (!this._knownCategoriesCache) {\n const cats = new Set<string>()\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && typeof t.group === 'string') cats.add(t.group)\n }\n }\n this._knownCategoriesCache = Array.from(cats).sort()\n }\n return this._knownCategoriesCache\n }\n\n /**\n * type 별 유효 속성 스킴 — LLM 이 정확한 컴포넌트를 만들도록 (lazy cache).\n *\n * 핵심: 좌표 표현은 type 마다 다르다 (left/top vs cx/cy vs points 등).\n * 따라서 OMIT 하지 않고 `geometryKeys` 로 별도 노출 → LLM 이 type 별 좌표 키 사용 가능.\n */\n private _componentSchemasCache?: Array<{\n type: string\n description?: string\n group?: string\n /** template.model 의 좌표/크기 관련 키들 — type 별 다름 */\n geometryKeys?: string[]\n /** 좌표 외 type 특화 속성 (default 값 또는 nested 키 목록) */\n properties?: Record<string, any>\n }>\n\n private get componentSchemas() {\n if (!this._componentSchemasCache) {\n const out: Array<{\n type: string\n description?: string\n group?: string\n geometryKeys?: string[]\n properties?: Record<string, any>\n }> = []\n const NON_PROPS = new Set(['type', 'id', 'name', 'class'])\n // 좌표/크기/경로 관련 키들 — type 마다 다른 조합으로 사용\n const GEOMETRY_KEYS = new Set([\n 'left',\n 'top',\n 'right',\n 'bottom',\n 'x',\n 'y',\n 'cx',\n 'cy',\n 'width',\n 'height',\n 'rx',\n 'ry',\n 'radius',\n 'rotation',\n 'translate',\n 'scale',\n 'points',\n 'path',\n 'vertices',\n 'verticles',\n 'startX',\n 'startY',\n 'endX',\n 'endY',\n 'startPoint',\n 'endPoint'\n ])\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (!t || typeof t.type !== 'string') continue\n const properties: Record<string, any> = {}\n const geometryKeys: string[] = []\n const model: any = t.model || {}\n for (const key of Object.keys(model)) {\n if (NON_PROPS.has(key)) continue\n if (GEOMETRY_KEYS.has(key)) {\n geometryKeys.push(key)\n continue\n }\n const v = model[key]\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n properties[key] = Object.fromEntries(\n Object.keys(v)\n .slice(0, 8)\n .map(k => [k, null])\n )\n } else if (Array.isArray(v)) {\n properties[key] = []\n } else {\n properties[key] = v\n }\n }\n out.push({\n type: t.type,\n description: t.description || undefined,\n group: t.group || undefined,\n geometryKeys: geometryKeys.length > 0 ? geometryKeys : undefined,\n properties: Object.keys(properties).length > 0 ? properties : undefined\n })\n }\n }\n this._componentSchemasCache = out\n }\n return this._componentSchemasCache\n }\n\n private board: any = null\n private _loadTracker?: LoadTracker\n private _fontCtrl = new FontController(this)\n @query('ox-board-modeller') modeller?: BoardModeller\n\n get context() {\n return {\n title: this.board ? this.boardName : this.preparing ? 'Fetching board...' : '',\n help: 'board-modeller/modeller',\n widebleed: true\n }\n }\n\n get oopsNote() {\n return {\n icon: 'color_lens',\n title: 'EMPTY BOARD',\n description: 'There are no board to be designed'\n }\n }\n\n async refresh() {\n if (!this.boardId) {\n this.board = null\n this.model = null\n\n return\n }\n try {\n // 이전 보드 완전히 클리어\n this.board = null\n this.model = null\n this._loadTracker = new LoadTracker()\n this._loadTracker.setPhase('fetch')\n this.preparing = true\n this.updateContext()\n\n const response = await client.query({\n query: gql`\n query FetchBoardById($id: String!) {\n board(id: $id) {\n id\n name\n model\n }\n }\n `,\n variables: { id: this.boardId },\n context: gqlContext()\n })\n\n this._loadTracker?.setPhase('parse')\n\n const board = response.data.board\n\n if (!board) {\n this.board = null\n throw new Error('board not found')\n }\n\n this.board = {\n ...board,\n model: JSON.parse(board.model)\n }\n\n this.boardName = this.board.name\n this.model = {\n ...this.board.model\n }\n\n // AI 협력 세션 — 보드 전환 시 이전 보드의 세션 / 세션 리스트 정리 (chat panel 의\n // sessionId/sessions 변화 감지 → history 비우고 새로 로드). 패널 열린 채 보드 옮겼다면\n // 새 보드의 세션 리스트를 즉시 ensure (fire-and-forget — 에러는 ensureChatSession 처리).\n this.chatSessionId = undefined\n this.chatSessions = []\n if (this.aiPanelOpen && this.boardId) {\n this.ensureChatSession()\n }\n } catch (ex) {\n notifyError(ex)\n } finally {\n this.preparing = false\n this.updateContext()\n }\n }\n\n /** 패널 토글 시 호출 — 열 때만 chatSession 보장 (세션 리스트 로드 + 활성 세션 결정) */\n private async toggleAIPanel() {\n const willOpen = !this.aiPanelOpen\n if (willOpen && this.boardId) {\n await this.ensureChatSession()\n }\n this.aiPanelOpen = willOpen\n }\n\n /** 보드의 모든 ChatSession 목록을 로드 + 활성 세션 보장.\n * - 세션이 0 개면 startBoardAISession 으로 첫 세션 생성 (단일 세션 UX 호환)\n * - 활성 세션 미설정 시 첫 번째 세션을 활성으로\n * - 이미 활성 세션 set 돼있고 list 에 포함되면 유지 */\n private async ensureChatSession() {\n if (!this.boardId) return\n try {\n const result = await client.query({\n query: gql`\n query ChatSessionsByBoard($boardId: String!) {\n chatSessionsByBoard(boardId: $boardId) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId },\n context: gqlContext(),\n fetchPolicy: 'network-only'\n })\n let sessions: Array<{ id: string; name?: string; createdAt?: string }> =\n result.data?.chatSessionsByBoard ?? []\n\n if (sessions.length === 0) {\n // 첫 세션 ensure (idempotent)\n const created = await client.mutate({\n mutation: gql`\n mutation StartBoardAISession($boardId: String!) {\n startBoardAISession(boardId: $boardId) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId },\n context: gqlContext()\n })\n const s = created.data?.startBoardAISession\n if (s) sessions = [s]\n }\n\n this.chatSessions = sessions\n // 활성 세션 결정 — 기존 active 가 list 에 있으면 유지, 아니면 첫 번째\n if (!this.chatSessionId || !sessions.some(s => s.id === this.chatSessionId)) {\n this.chatSessionId = sessions[0]?.id\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /** `@` mention popup 의 도메인 사용자 후보 — chat 의 userProvider prop 으로 wire.\n * query 변할 때마다 호출되므로 server query (`domainUsersForMention`) 를 그대로 위임. */\n private fetchDomainUsersForMention = async (\n query: string\n ): Promise<Array<{ id: string; name?: string; email?: string }>> => {\n try {\n const result = await client.query({\n query: gql`\n query DomainUsersForMention($query: String, $limit: Int) {\n domainUsersForMention(query: $query, limit: $limit) {\n id\n name\n email\n }\n }\n `,\n variables: { query: query || null, limit: 50 },\n context: gqlContext(),\n fetchPolicy: 'cache-first'\n })\n return result.data?.domainUsersForMention ?? []\n } catch (ex) {\n // 조용히 — chat panel 이 빈 결과로 처리\n console.warn('[board-modeller-page] fetchDomainUsersForMention failed:', ex)\n return []\n }\n }\n\n /** 채팅 패널의 탭 클릭 — 활성 세션 전환. */\n private onChatSessionSwitch = (e: CustomEvent) => {\n const newId = e.detail?.sessionId\n if (typeof newId === 'string' && newId !== this.chatSessionId) {\n this.chatSessionId = newId\n }\n }\n\n /** 채팅 패널의 \"+\" 버튼 — 새 세션 생성 후 활성으로 전환. */\n private onChatSessionCreate = async () => {\n if (!this.boardId) return\n try {\n const created = await client.mutate({\n mutation: gql`\n mutation CreateChatSession($boardId: String!, $name: String) {\n createChatSession(boardId: $boardId, name: $name) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId, name: null },\n context: gqlContext()\n })\n const s = created.data?.createChatSession\n if (s) {\n this.chatSessions = [...this.chatSessions, s]\n this.chatSessionId = s.id\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * 모델러의 selected (things-scene Component 인스턴스 배열) 에서 refid 추출.\n *\n * refid 는 things-scene 이 모든 컴포넌트에 자동 발급하는 universal numeric handle.\n * AI 의 selection 표현은 항상 refid 기반 (id 는 데이터 바인딩 이름이며 unique 가\n * 아니라 targeting 에 부적합).\n */\n private extractSelectedRefids(): number[] {\n const sel = this.selected || []\n return sel\n .map((c: any) => {\n if (!c || typeof c.get !== 'function') return null\n const refid = c.get('refid')\n return typeof refid === 'number' && Number.isFinite(refid) ? refid : null\n })\n .filter((x: number | null): x is number => x !== null)\n }\n\n /**\n * AI 채팅 mention popup (`#`) 검색 위임 — things-scene SceneSearchEngine 으로 wrap.\n *\n * F-key Finder 와 동일한 검색 룰 (id → name → tag → type → class → text → data → property)\n * 을 그대로 mention popup 에 재사용. 컴포넌트 트리를 직접 순회하므로 model JSON 으로\n * 변환할 필요 없음 — 일관성 + 성능 이점.\n *\n * 반환 구조 (FilterResult) 는 chat 의 mention-popup 표시 모델. host 는 things-scene\n * Component 에서 refid/id/type/tag/class/text 를 뽑아 candidate 로 채워 넘긴다.\n */\n private searchSceneForMention = (() => {\n const engine = new SceneSearchEngine()\n return (query: string): any[] => {\n const root = (this.scene as any)?.root\n if (!root) return []\n const results = engine.search(root, query)\n return results.map(r => {\n const c: any = r.component\n const refid = typeof c.get === 'function' ? c.get('refid') : undefined\n const id = typeof c.get === 'function' ? c.get('id') : undefined\n const type = typeof c.get === 'function' ? c.get('type') : undefined\n const tag = typeof c.get === 'function' ? c.get('tag') : undefined\n const cls = typeof c.get === 'function' ? c.get('class') : undefined\n const text = typeof c.get === 'function' ? c.get('text') : undefined\n return {\n candidate: {\n refid: typeof refid === 'number' ? refid : undefined,\n label: id || type || 'unknown',\n type: typeof type === 'string' ? type : 'unknown',\n id: typeof id === 'string' && id ? id : undefined,\n tag: typeof tag === 'string' && tag ? tag : undefined,\n class: typeof cls === 'string' && cls ? cls : undefined,\n text: typeof text === 'string' && text ? text : undefined\n },\n matchType: r.matchType,\n matchValue: r.matchValue\n }\n })\n }\n })()\n\n /**\n * 라이브 보드 모델 — things-scene 캔버스가 들고 있는 가장 최신 상태의 deep clone.\n *\n * 사용자 수작업 편집은 scene.model 에만 반영되고 this.model property 에는 자동\n * 동기화되지 않는다. AI 한테 보드 상태를 넘기거나 patch 를 적용할 때는 반드시\n * 이쪽을 쓴다.\n *\n * id 와 refid 는 별개 필드 — 컴포넌트는 model.id (선택, 사용자/AI 가 명시 설정)\n * 와 model.refid (필수, things-scene 자동 발급) 를 둘 다 가질 수 있고 AI 가\n * 양쪽을 구별해서 다룬다 (tool 인자가 분리됨). 따라서 여기서는 model 을 mutate\n * 하지 않고 raw deep clone 만 반환.\n */\n private getLiveBoard(): any {\n const sceneModel = (this.scene as any)?.model\n if (sceneModel) {\n return JSON.parse(JSON.stringify(sceneModel))\n }\n return this.model\n }\n\n /**\n * 채팅에서 patch 도착 — things-scene 에 in-place 적용.\n *\n * 핵심: `this.model = next` 로 모델을 통째 교체하면 ox-scene-viewer 가 scene 을\n * dispose → 재생성 → undo 히스토리/dirty 플래그가 모두 초기화된다.\n * 따라서 일반 add/modify/remove 는 scene 의 in-place mutation API 로 적용 →\n * commander 가 자동으로 snapshot push → CMD+Z 와 저장 안내 팝업이 정상 동작.\n *\n * 'replace' op (보드 전체 교체) 만은 부득이 wholesale 경로로 빠진다 — 이 경우는\n * 사용자에게 명시적으로 안내 후 진행.\n */\n private onBoardEditPatch = (e: CustomEvent) => {\n const { patch, patchId } = e.detail || {}\n if (!patch) return\n const scene = this.scene as any\n if (!scene) {\n notifyError(new Error('Scene not initialized'))\n return\n }\n\n const hasReplace = (patch.ops || []).some((op: BoardEditOp) => op.op === 'replace')\n if (hasReplace) {\n this.applyPatchWholesale(patch, patchId)\n return\n }\n\n try {\n const missed: BoardEditOp[] = []\n // 각 op 의 inverse — dispatcher 가 적용 직전/직후 scene 상태로 계산해 반환.\n // 누적했다가 onBoardEditRevert 가 역순 in-place 적용으로 복원.\n const inverseOps: BoardEditOp[] = []\n const normalize = (c: any) => this.normalizeComponent(c)\n\n for (const op of patch.ops as BoardEditOp[]) {\n const r = dispatchBoardEditOp(scene, op, { normalize })\n if (r.applied) {\n inverseOps.push(...r.inverseOps)\n } else {\n missed.push(op)\n }\n }\n\n // patch 단위로 inverse 보관 — Revert 시 역순 적용\n if (patchId && inverseOps.length > 0) {\n this.patchInverses.set(patchId, inverseOps)\n }\n\n if (missed.length > 0) {\n const missedDesc = missed\n .map((op: any) => {\n if (op.op === 'modify' || op.op === 'remove') return `refid=${op.refid}`\n if (op.op === 'modifyBoard') return 'modifyBoard (scene root unavailable)'\n return op.op\n })\n .join(', ')\n notify(\n 'warn',\n `AI 가 ${missed.length}개의 변경을 시도했지만 적용되지 않았습니다: ${missedDesc}`\n )\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * 'replace' op 적용 — scene 통째로 재생성 (undo 히스토리 초기화).\n *\n * AI 가 보드 전체 재구성을 요청한 경우. 사용자에게 history 손실 안내.\n * board-import 데이터 wholesale 적용 등 드문 케이스에 한정.\n *\n * Revert 지원 — replace 직전 보드 model 을 inverse 로 보관 (또 다른 replace).\n */\n private applyPatchWholesale(patch: BoardEditPatch, patchId?: string) {\n try {\n const baseBoard = this.getLiveBoard()\n const inverseOps: BoardEditOp[] = baseBoard\n ? [{ op: 'replace', board: JSON.parse(JSON.stringify(baseBoard)) }]\n : []\n const report = applyBoardEditPatchVerbose(baseBoard, patch)\n const next = report.board as any\n if (report.applied.length === 0) return\n const normalized = (next.components || []).map((c: any) => this.normalizeComponent(c))\n this.model = {\n ...(baseBoard || {}),\n ...(next.width !== undefined && { width: next.width }),\n ...(next.height !== undefined && { height: next.height }),\n components: normalized\n }\n if (patchId && inverseOps.length > 0) {\n this.patchInverses.set(patchId, inverseOps)\n }\n notify('info', '보드 전체가 교체되어 실행 취소(undo) 히스토리가 초기화되었습니다.')\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * 채팅에서 board-edit-revert 도착 — 누적된 inverse 를 역순 in-place 적용.\n *\n * - 메모리상 patchInverses Map 만 본다. 페이지 reload 후엔 inverse 가 없어\n * 되돌릴 수 없음 (사용자에게 안내).\n * - 성공 시 서버 revertPatch mutation 호출 → PatchEntry.reverted=true 영속.\n * - in-place 적용이라 undo/dirty/selection 보존 (chatViaTools 의 모든 강점 그대로).\n */\n private onBoardEditRevert = async (e: CustomEvent) => {\n const { patchId } = e.detail || {}\n if (!patchId) return\n const inverses = this.patchInverses.get(patchId)\n if (!inverses || inverses.length === 0) {\n notify(\n 'warn',\n '이 변경은 자동 되돌릴 수 없습니다 (페이지 새로고침 이후 적용된 변경은 메모리에 inverse 가 없습니다).'\n )\n return\n }\n\n const scene = this.scene as any\n if (!scene) {\n notifyError(new Error('Scene not initialized'))\n return\n }\n\n try {\n // 역순 적용 — 마지막 op 부터 되돌림. 단일 patch 안에서도 순서 의미 있음\n // (예: add 후 modify 한 시퀀스를 되돌리려면 modify(원본) 후 remove)\n const reversed = [...inverses].reverse()\n const reverseFakePatch: BoardEditPatch = {\n ops: reversed,\n summary: 'revert',\n confidence: 1\n }\n // hasReplace 면 wholesale, 그렇지 않으면 in-place — 일반 onBoardEditPatch 와 동일\n const hasReplace = reversed.some(op => op.op === 'replace')\n if (hasReplace) {\n this.applyPatchWholesale(reverseFakePatch)\n } else {\n // in-place 직접 적용 — 새 inverse 누적은 안 함 (revert 의 revert 는 redo, 별개 기능)\n this.applyInverseOpsInPlace(scene, reversed)\n }\n\n this.patchInverses.delete(patchId)\n await this.recordRevertOnServer(patchId)\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * inverse op 시퀀스를 things-scene 위에 in-place 적용 (snapshot/undo 보존).\n * dispatcher 재사용 — inverse 누적은 무시 (revert 의 revert 는 redo, 별개 기능).\n */\n private applyInverseOpsInPlace(scene: any, ops: BoardEditOp[]): void {\n const normalize = (c: any) => this.normalizeComponent(c)\n for (const op of ops) {\n dispatchBoardEditOp(scene, op, { normalize })\n }\n }\n\n /** 서버 PatchEntry.reverted=true 영속 — fail 해도 UI 는 이미 되돌렸으니 warn 만. */\n private async recordRevertOnServer(patchId: string): Promise<void> {\n try {\n await client.mutate({ mutation: REVERT_PATCH_MUTATION, variables: { patchId } })\n } catch (e: any) {\n console.warn('[board-modeller] revertPatch server persist failed:', e?.message ?? e)\n }\n }\n\n /**\n * AI 가 ephemeral scene action (selection / view / mode) 을 실행하라고 요청.\n *\n * board-edit-patch 와 별개 채널 — 모델 변경 X, undo 영향 X, dirty flag 무관.\n * things-scene API 직접 호출. 잘못된 action / 누락된 컴포넌트는 console.warn 만.\n */\n private onBoardActionExecute = (e: CustomEvent) => {\n const { actions } = e.detail || {}\n if (!Array.isArray(actions) || actions.length === 0) return\n const scene = this.scene as any\n if (!scene) return\n\n let modeChanged = false\n for (const action of actions) {\n try {\n dispatchBoardAction(scene, action)\n if (action?.action === 'setSceneMode') modeChanged = true\n } catch (ex: any) {\n console.warn('[board-modeller] action execute failed:', action, ex?.message ?? ex)\n }\n }\n // setSceneMode 가 있었으면 page 의 reactive mode 도 동기 (Lit re-render 트리거)\n if (modeChanged) this.mode = scene.mode\n }\n\n /**\n * AI 가 만든 컴포넌트를 things-scene 이 기대하는 완전한 형태로 normalize.\n * BoardModeller 에 등록된 template.model (default 값) 위에 AI 응답을 덮어쓴다.\n * 이 단계 없이 things-scene 에 넣으면 필수 속성 누락 시 render 에서 crash 가능\n * (예: gauge-circle 의 value 가 undefined → toString() TypeError).\n */\n private normalizeComponent(c: any): any {\n if (!c || typeof c !== 'object' || typeof c.type !== 'string') return c\n const template = this.findTemplateByType(c.type)\n if (!template || !template.model) return c\n return mergeDefaultsDeep(template.model, c)\n }\n\n private findTemplateByType(type: string): any {\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && t.type === type) return t\n }\n }\n return undefined\n }\n\n async updated(changes) {\n if (changes.has('boardId')) {\n try {\n if (await hasPrivilege({ privilege: 'mutation', category: 'board' })) {\n this.refresh()\n } else {\n this.boardId = null\n this.model = null\n this.modeller?.close()\n }\n } catch {\n this.boardId = null\n this.model = null\n this.modeller?.close()\n }\n }\n }\n\n pageUpdated(changes, lifecycle) {\n if (this.active) {\n this.boardId = lifecycle.resourceId\n } else {\n this.boardId = null\n this.board = null\n this.model = null\n this.preparing = false\n this.modeller?.close()\n this.updateContext()\n }\n }\n\n render() {\n const oops = !this.preparing && !this.model && this.oopsNote\n\n return html`\n <div class=\"modeller-area\">\n ${oops\n ? html`<ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note>`\n : html`\n <ox-board-modeller\n .mode=${this.mode}\n .loadTracker=${this._loadTracker}\n @mode-changed=${e => {\n this.mode = e.detail.value\n }}\n .model=${this.model}\n @model-changed=${e => {\n this.model = e.detail.value\n }}\n .scene=${this.scene}\n @scene-changed=${e => {\n this.scene = e.detail.value\n }}\n .selected=${this.selected}\n @selected-changed=${e => {\n this.selected = e.detail.value\n }}\n .provider=${provider}\n @save-model=${e => this.saveBoard()}\n .componentGroupList=${this.componentGroupList}\n .fonts=${this._fontCtrl.fonts}\n .hideProperty=${this.hideProperty}\n >\n </ox-board-modeller>\n `}\n ${this.boardId\n ? html`\n <button\n class=\"ai-toggle ${this.aiPanelOpen ? 'open' : ''}\"\n title=\"${i18next.t('text.ai_assistant') || 'AI Assistant'}\"\n @click=${this.toggleAIPanel}>\n ${this.aiPanelOpen ? '✕ AI' : '✨ AI'}\n </button>\n `\n : nothing}\n </div>\n ${this.aiPanelOpen\n ? html`\n <div class=\"ai-panel\">\n <ox-board-ai-chat\n .sessionId=${this.chatSessionId}\n .sessions=${this.chatSessions}\n .currentBoard=${this.model}\n .boardProvider=${() => this.getLiveBoard()}\n .searchProvider=${this.searchSceneForMention}\n .userProvider=${this.fetchDomainUsersForMention}\n .knownTypes=${this.knownTypes}\n .categories=${this.knownCategories}\n .componentSchemas=${this.componentSchemas}\n .selectedRefids=${this.extractSelectedRefids()}\n @session-switch=${this.onChatSessionSwitch}\n @session-create=${this.onChatSessionCreate}\n @board-edit-patch=${this.onBoardEditPatch}\n @board-edit-revert=${this.onBoardEditRevert}\n @board-action-execute=${this.onBoardActionExecute}>\n </ox-board-ai-chat>\n </div>\n `\n : nothing}\n `\n }\n\n async updateBoard() {\n try {\n this.preparing = true\n\n const { id, name, description, groupId } = this.board\n const model = JSON.stringify(this.scene.model)\n\n await client.mutate({\n mutation: gql`\n mutation UpdateBoard($id: String!, $patch: BoardPatch!) {\n updateBoard(id: $id, patch: $patch) {\n id\n }\n }\n `,\n variables: {\n id,\n patch: { name, description, model, groupId }\n },\n context: gqlContext()\n })\n\n notify('info', i18next.t('text.saved'))\n } catch (ex) {\n notifyError(ex)\n } finally {\n this.preparing = false\n }\n\n this.updateContext()\n }\n\n async saveBoard() {\n await this.updateBoard()\n this.modeller?.preserve()\n }\n\n async canDeactivate(): Promise<boolean> {\n if (this.modeller?.hasUnpreservedChanges()) {\n return await OxPrompt.open({\n title: i18next.t('text.are_you_sure'),\n text: i18next.t('prompt.sure to navigate away?'),\n confirmButton: { text: i18next.t('button.confirm') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n }\n\n return true\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"board-player-by-name-page.js","sourceRoot":"","sources":["../../client/pages/board-player-by-name-page.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAA;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAGjD,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,eAAe;IACxD,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC;YACxB,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;OAYT;YACD,SAAS,EAAE;gBACT,IAAI;aACL;SACF,CAAC,CAAA;IACJ,CAAC;CACF,CAAA;AArBY,qBAAqB;IADjC,aAAa,CAAC,2BAA2B,CAAC;GAC9B,qBAAqB,CAqBjC","sourcesContent":["import gql from 'graphql-tag'\nimport { customElement } from 'lit/decorators.js'\nimport { client, gqlContext } from '@operato/graphql'\nimport { ApolloQueryResult } from '@apollo/client'\n\nimport { BoardPlayerPage } from './board-player-page.js'\n\n@customElement('board-player-by-name-page')\nexport class BoardPlayerByNamePage extends BoardPlayerPage {\n async fetch(name: string): Promise<ApolloQueryResult<any>> {\n return await client.query({\n query: gql`\n query ($name: String!) {\n response: playGroupByName(name: $name) {\n id\n name\n description\n boards {\n id\n model\n }\n }\n }\n `,\n variables: {\n name\n }\n })\n }\n}\n"]}
1
+ {"version":3,"file":"board-player-by-name-page.js","sourceRoot":"","sources":["../../client/pages/board-player-by-name-page.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAGzC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAGjD,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,eAAe;IACxD,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC;YACxB,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;OAYT;YACD,SAAS,EAAE;gBACT,IAAI;aACL;SACF,CAAC,CAAA;IACJ,CAAC;CACF,CAAA;AArBY,qBAAqB;IADjC,aAAa,CAAC,2BAA2B,CAAC;GAC9B,qBAAqB,CAqBjC","sourcesContent":["import gql from 'graphql-tag'\nimport { customElement } from 'lit/decorators.js'\nimport { client } from '@operato/graphql'\nimport { ApolloQueryResult } from '@apollo/client'\n\nimport { BoardPlayerPage } from './board-player-page.js'\n\n@customElement('board-player-by-name-page')\nexport class BoardPlayerByNamePage extends BoardPlayerPage {\n async fetch(name: string): Promise<ApolloQueryResult<any>> {\n return await client.query({\n query: gql`\n query ($name: String!) {\n response: playGroupByName(name: $name) {\n id\n name\n description\n boards {\n id\n model\n }\n }\n }\n `,\n variables: {\n name\n }\n })\n }\n}\n"]}
@@ -10,19 +10,8 @@ import { PageView } from '@operato/shell';
10
10
  import { clientSettingStore } from '@operato/shell/object-store.js';
11
11
  import { client, subscribe } from '@operato/graphql';
12
12
  import { BoardPlayer } from '@operato/board/ox-board-player.js';
13
- function parseQuery(query) {
14
- for (const key in query) {
15
- if (query.hasOwnProperty(key)) {
16
- try {
17
- query[key] = JSON.parse(query[key]);
18
- }
19
- catch (error) {
20
- // do nothing
21
- }
22
- }
23
- }
24
- return query;
25
- }
13
+ import { parseQuery } from '../utils/query-utils.js';
14
+ import { notifyError } from '../utils/notify-helper.js';
26
15
  let BoardPlayerPage = class BoardPlayerPage extends PageView {
27
16
  static { this.styles = [
28
17
  css `
@@ -100,29 +89,28 @@ let BoardPlayerPage = class BoardPlayerPage extends PageView {
100
89
  const response = await this.fetch(this.playGroupId);
101
90
  this.playGroup = response.data.response;
102
91
  if (!this.playGroup) {
103
- throw 'playgroup not found';
92
+ throw new Error('playgroup not found');
104
93
  }
105
94
  this.boards = this.playGroup.boards;
106
95
  }
107
96
  catch (ex) {
108
- document.dispatchEvent(new CustomEvent('notify', {
109
- detail: {
110
- level: 'error',
111
- message: ex,
112
- ex
113
- }
114
- }));
97
+ notifyError(ex);
115
98
  }
116
99
  finally {
117
100
  this.showSpinner = false;
118
101
  this.updateContext();
119
- const { autoRefresh = true } = (await clientSettingStore.get('board-view'))?.value || {};
120
- autoRefresh && this.startSubscribingForAutoRefresh();
102
+ try {
103
+ const { autoRefresh = true } = (await clientSettingStore.get('board-view'))?.value || {};
104
+ autoRefresh && this.startSubscribingForAutoRefresh();
105
+ }
106
+ catch {
107
+ this.startSubscribingForAutoRefresh();
108
+ }
121
109
  }
122
110
  }
123
111
  updated(changes) {
124
112
  if (changes.has('playGroupId')) {
125
- this.boardPlayer.stop();
113
+ this.boardPlayer?.stop();
126
114
  this.refresh();
127
115
  }
128
116
  }
@@ -139,7 +127,7 @@ let BoardPlayerPage = class BoardPlayerPage extends PageView {
139
127
  };
140
128
  }
141
129
  render() {
142
- var oops = !this.showSpinner && !this.playGroup && this.oopsNote;
130
+ const oops = !this.showSpinner && !this.playGroup && this.oopsNote;
143
131
  return oops
144
132
  ? html ` <ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note> `
145
133
  : html `
@@ -156,7 +144,7 @@ let BoardPlayerPage = class BoardPlayerPage extends PageView {
156
144
  else {
157
145
  this.stopSubscribing();
158
146
  this.playGroupId = null;
159
- this.boardPlayer.stop();
147
+ this.boardPlayer?.stop();
160
148
  }
161
149
  }
162
150
  async startSubscribingForAutoRefresh() {
@@ -1 +1 @@
1
- {"version":3,"file":"board-player-page.js","sourceRoot":"","sources":["../../client/pages/board-player-page.ts"],"names":[],"mappings":";AAAA,OAAO,kCAAkC,CAAA;AACzC,OAAO,mCAAmC,CAAA;AAC1C,OAAO,eAAe,CAAA;AAEtB,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;AAE/D,SAAS,UAAU,CAAC,KAAU;IAC5B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;YACrC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,aAAa;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAGM,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,QAAQ;aACpC,WAAM,GAAG;QACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkCF;KACF,AApCY,CAoCZ;IAaD,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAA;QAEzB,IAAI,CAAC,QAAQ,GAAG,mBAAmB,EAAE,CAAA;IACvC,CAAC;IAED,oBAAoB;QAClB,KAAK,CAAC,oBAAoB,EAAE,CAAA;QAE5B,IAAI,CAAC,QAAS,CAAC,OAAQ,EAAE,CAAA;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,EAAU;QACpB,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC;YACxB,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;OAYT;YACD,SAAS,EAAE;gBACT,EAAE;aACH;SACF,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;YACvB,IAAI,CAAC,aAAa,EAAE,CAAA;YAEpB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAEnD,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAA;YAEvC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,MAAM,qBAAqB,CAAA;YAC7B,CAAC;YAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAA;QACrC,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE;gBACxB,MAAM,EAAE;oBACN,KAAK,EAAE,OAAO;oBACd,OAAO,EAAE,EAAE;oBACX,EAAE;iBACH;aACF,CAAC,CACH,CAAA;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,WAAW,GAAG,KAAK,CAAA;YACxB,IAAI,CAAC,aAAa,EAAE,CAAA;YAEpB,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,GAAG,CAAC,MAAM,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,CAAA;YACxF,WAAW,IAAI,IAAI,CAAC,8BAA8B,EAAE,CAAA;QACtD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,OAAO;QACb,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,WAAY,CAAC,IAAI,EAAE,CAAA;YACxB,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC;IACH,CAAC;IAED,IAAI,QAAQ;QACV,OAAO;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,iBAAiB;YACxB,WAAW,EAAE,gCAAgC;SAC9C,CAAA;IACH,CAAC;IAED,IAAI,OAAO;QACT,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB;SACjH,CAAA;IACH,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAA;QAEhE,OAAO,IAAI;YACT,CAAC,CAAC,IAAI,CAAA,uBAAuB,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,KAAK,gBAAgB,IAAI,CAAC,WAAW,mBAAmB;YAC7G,CAAC,CAAC,IAAI,CAAA;qCACyB,IAAI,CAAC,MAAM,UAAU,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,QAAQ;mCAC3D,IAAI,CAAC,WAAW;SAC1C,CAAA;IACP,CAAC;IAED,WAAW,CAAC,OAAO,EAAE,SAAS;QAC5B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,UAAU,CAAA;YACvC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;YAE/C,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,EAAE,CAAA;YAEtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;YACvB,IAAI,CAAC,WAAY,CAAC,IAAI,EAAE,CAAA;QAC1B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,8BAA8B;QAClC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QAED,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;QAE5B,IAAI,CAAC,0BAA0B,GAAG,MAAM,SAAS,CAC/C;YACE,KAAK,EAAE,GAAG,CAAA;;;;;;SAMT;YACD,SAAS,EAAE;gBACT,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE;aACtB;SACF,EACD;YACE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBACvB,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;gBAE5B,oBAAoB;gBACpB,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,CAAC,OAAO,EAAE,CAAA;gBAChB,CAAC;YACH,CAAC;SACF,CACF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,0BAA0B,EAAE,WAAW,EAAE,CAAA;QACpD,OAAO,IAAI,CAAC,0BAA0B,CAAA;IACxC,CAAC;;AApKQ;IAAR,KAAK,EAAE;;6CAAU;AACT;IAAR,KAAK,EAAE;;kDAAe;AACd;IAAR,KAAK,EAAE;;oDAA4B;AAC3B;IAAR,KAAK,EAAE;;+CAAY;AACX;IAAR,KAAK,EAAE;;oDAAsB;AAKJ;IAAzB,KAAK,CAAC,iBAAiB,CAAC;8BAAe,WAAW;oDAAA;AAhDxC,eAAe;IAD3B,aAAa,CAAC,mBAAmB,CAAC;GACtB,eAAe,CA4M3B","sourcesContent":["import './things-scene-components.import'\nimport '@operato/board/ox-board-player.js'\nimport '@operato/oops'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, state, query } from 'lit/decorators.js'\nimport { createBoardProvider } from '../board-provider.js'\nimport { PageView } from '@operato/shell'\nimport { clientSettingStore } from '@operato/shell/object-store.js'\nimport { client, subscribe } from '@operato/graphql'\nimport { ReferenceMap } from '@hatiolab/things-scene'\nimport { BoardPlayer } from '@operato/board/ox-board-player.js'\nimport { ApolloQueryResult } from '@apollo/client'\nfunction parseQuery(query: any) {\n for (const key in query) {\n if (query.hasOwnProperty(key)) {\n try {\n query[key] = JSON.parse(query[key])\n } catch (error) {\n // do nothing\n }\n }\n }\n\n return query\n}\n\n@customElement('board-player-page')\nexport class BoardPlayerPage extends PageView {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n\n overflow: hidden;\n position: relative;\n }\n\n ox-board-player {\n flex: 1;\n }\n\n ox-oops-spinner {\n display: none;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n ox-oops-spinner[show] {\n display: block;\n }\n\n ox-oops-note {\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n `\n ]\n\n @state() data: any\n @state() playGroup: any\n @state() playGroupId?: string | null\n @state() boards: any\n @state() showSpinner?: boolean\n\n private provider?: ReferenceMap & { dispose?: () => void }\n private subscriptionForAutoRefresh\n\n @query('ox-board-player') boardPlayer?: BoardPlayer\n\n connectedCallback() {\n super.connectedCallback()\n\n this.provider = createBoardProvider()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.provider!.dispose!()\n delete this.provider\n }\n\n async fetch(id: string): Promise<ApolloQueryResult<any>> {\n return await client.query({\n query: gql`\n query ($id: String!) {\n response: playGroup(id: $id) {\n id\n name\n description\n boards {\n id\n model\n }\n }\n }\n `,\n variables: {\n id\n }\n })\n }\n\n async refresh() {\n if (!this.playGroupId) {\n return\n }\n\n try {\n this.showSpinner = true\n this.updateContext()\n\n const response = await this.fetch(this.playGroupId)\n\n this.playGroup = response.data.response\n\n if (!this.playGroup) {\n throw 'playgroup not found'\n }\n\n this.boards = this.playGroup.boards\n } catch (ex) {\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: ex,\n ex\n }\n })\n )\n } finally {\n this.showSpinner = false\n this.updateContext()\n\n const { autoRefresh = true } = (await clientSettingStore.get('board-view'))?.value || {}\n autoRefresh && this.startSubscribingForAutoRefresh()\n }\n }\n\n updated(changes) {\n if (changes.has('playGroupId')) {\n this.boardPlayer!.stop()\n this.refresh()\n }\n }\n\n get oopsNote() {\n return {\n icon: 'style',\n title: 'EMPTY PLAYGROUP',\n description: 'There are no board to be shown'\n }\n }\n\n get context() {\n return {\n title: this.playGroup ? this.playGroup.name : this.showSpinner ? 'Fetching playgroup...' : 'Playgroup Not Found'\n }\n }\n\n render() {\n var oops = !this.showSpinner && !this.playGroup && this.oopsNote\n\n return oops\n ? html` <ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note> `\n : html`\n <ox-board-player .boards=${this.boards} .data=${this.data} .provider=${this.provider}></ox-board-player>\n <ox-oops-spinner ?show=${this.showSpinner}></ox-oops-spinner>\n `\n }\n\n pageUpdated(changes, lifecycle) {\n if (this.active) {\n this.playGroupId = lifecycle.resourceId\n this.data = parseQuery({ ...lifecycle.params })\n\n this.refresh()\n } else {\n this.stopSubscribing()\n\n this.playGroupId = null\n this.boardPlayer!.stop()\n }\n }\n\n async startSubscribingForAutoRefresh() {\n if (!this.playGroup) {\n return\n }\n\n await this.stopSubscribing()\n\n this.subscriptionForAutoRefresh = await subscribe(\n {\n query: gql`\n subscription ($id: String!) {\n playGroup(id: $id) {\n id\n }\n }\n `,\n variables: {\n id: this.playGroup.id\n }\n },\n {\n next: async ({ data }) => {\n await this.stopSubscribing()\n\n // location.reload()\n if (data) {\n this.refresh()\n }\n }\n }\n )\n }\n\n async stopSubscribing() {\n await this.subscriptionForAutoRefresh?.unsubscribe()\n delete this.subscriptionForAutoRefresh\n }\n}\n"]}
1
+ {"version":3,"file":"board-player-page.js","sourceRoot":"","sources":["../../client/pages/board-player-page.ts"],"names":[],"mappings":"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","sourcesContent":["import './things-scene-components.import'\nimport '@operato/board/ox-board-player.js'\nimport '@operato/oops'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, state, query } from 'lit/decorators.js'\nimport { createBoardProvider } from '../board-provider.js'\nimport { PageView } from '@operato/shell'\nimport { clientSettingStore } from '@operato/shell/object-store.js'\nimport { client, subscribe } from '@operato/graphql'\nimport { ReferenceMap } from '@hatiolab/things-scene'\nimport { BoardPlayer } from '@operato/board/ox-board-player.js'\nimport { ApolloQueryResult } from '@apollo/client'\nimport { parseQuery } from '../utils/query-utils.js'\nimport { notifyError } from '../utils/notify-helper.js'\n\n@customElement('board-player-page')\nexport class BoardPlayerPage extends PageView {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n\n overflow: hidden;\n position: relative;\n }\n\n ox-board-player {\n flex: 1;\n }\n\n ox-oops-spinner {\n display: none;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n ox-oops-spinner[show] {\n display: block;\n }\n\n ox-oops-note {\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n `\n ]\n\n @state() data: any\n @state() playGroup: any\n @state() playGroupId?: string | null\n @state() boards: any\n @state() showSpinner?: boolean\n\n private provider?: ReferenceMap & { dispose?: () => void }\n private subscriptionForAutoRefresh\n\n @query('ox-board-player') boardPlayer?: BoardPlayer\n\n connectedCallback() {\n super.connectedCallback()\n\n this.provider = createBoardProvider()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.provider!.dispose!()\n delete this.provider\n }\n\n async fetch(id: string): Promise<ApolloQueryResult<any>> {\n return await client.query({\n query: gql`\n query ($id: String!) {\n response: playGroup(id: $id) {\n id\n name\n description\n boards {\n id\n model\n }\n }\n }\n `,\n variables: {\n id\n }\n })\n }\n\n async refresh() {\n if (!this.playGroupId) {\n return\n }\n\n try {\n this.showSpinner = true\n this.updateContext()\n\n const response = await this.fetch(this.playGroupId)\n\n this.playGroup = response.data.response\n\n if (!this.playGroup) {\n throw new Error('playgroup not found')\n }\n\n this.boards = this.playGroup.boards\n } catch (ex) {\n notifyError(ex)\n } finally {\n this.showSpinner = false\n this.updateContext()\n\n try {\n const { autoRefresh = true } = (await clientSettingStore.get('board-view'))?.value || {}\n autoRefresh && this.startSubscribingForAutoRefresh()\n } catch {\n this.startSubscribingForAutoRefresh()\n }\n }\n }\n\n updated(changes) {\n if (changes.has('playGroupId')) {\n this.boardPlayer?.stop()\n this.refresh()\n }\n }\n\n get oopsNote() {\n return {\n icon: 'style',\n title: 'EMPTY PLAYGROUP',\n description: 'There are no board to be shown'\n }\n }\n\n get context() {\n return {\n title: this.playGroup ? this.playGroup.name : this.showSpinner ? 'Fetching playgroup...' : 'Playgroup Not Found'\n }\n }\n\n render() {\n const oops = !this.showSpinner && !this.playGroup && this.oopsNote\n\n return oops\n ? html` <ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note> `\n : html`\n <ox-board-player .boards=${this.boards} .data=${this.data} .provider=${this.provider}></ox-board-player>\n <ox-oops-spinner ?show=${this.showSpinner}></ox-oops-spinner>\n `\n }\n\n pageUpdated(changes, lifecycle) {\n if (this.active) {\n this.playGroupId = lifecycle.resourceId\n this.data = parseQuery({ ...lifecycle.params })\n\n this.refresh()\n } else {\n this.stopSubscribing()\n\n this.playGroupId = null\n this.boardPlayer?.stop()\n }\n }\n\n async startSubscribingForAutoRefresh() {\n if (!this.playGroup) {\n return\n }\n\n await this.stopSubscribing()\n\n this.subscriptionForAutoRefresh = await subscribe(\n {\n query: gql`\n subscription ($id: String!) {\n playGroup(id: $id) {\n id\n }\n }\n `,\n variables: {\n id: this.playGroup.id\n }\n },\n {\n next: async ({ data }) => {\n await this.stopSubscribing()\n\n // location.reload()\n if (data) {\n this.refresh()\n }\n }\n }\n )\n }\n\n async stopSubscribing() {\n await this.subscriptionForAutoRefresh?.unsubscribe()\n delete this.subscriptionForAutoRefresh\n }\n}\n"]}
@@ -1,5 +1,12 @@
1
1
  import { ApolloQueryResult } from '@apollo/client';
2
2
  import { BoardViewerPage } from './board-viewer-page.js';
3
+ /**
4
+ * 이름으로 보드를 조회하는 뷰어 페이지.
5
+ *
6
+ * BoardModelCache는 id 기반이므로 name 기반 조회에서는 캐시 활용 불가.
7
+ * (name → id 매핑 캐시를 별도 구현하면 가능하지만, 사용 빈도가 낮아 미적용)
8
+ * cachedUpdatedAt 파라미터를 전달하지 않으므로 항상 full model을 반환받는다.
9
+ */
3
10
  export declare class BoardViewerByNamePage extends BoardViewerPage {
4
- fetch(name: string): Promise<ApolloQueryResult<any>>;
11
+ fetch(name: string, _cachedUpdatedAt?: string): Promise<ApolloQueryResult<any>>;
5
12
  }
@@ -3,8 +3,15 @@ import gql from 'graphql-tag';
3
3
  import { customElement } from 'lit/decorators.js';
4
4
  import { client, gqlContext } from '@operato/graphql';
5
5
  import { BoardViewerPage } from './board-viewer-page.js';
6
+ /**
7
+ * 이름으로 보드를 조회하는 뷰어 페이지.
8
+ *
9
+ * BoardModelCache는 id 기반이므로 name 기반 조회에서는 캐시 활용 불가.
10
+ * (name → id 매핑 캐시를 별도 구현하면 가능하지만, 사용 빈도가 낮아 미적용)
11
+ * cachedUpdatedAt 파라미터를 전달하지 않으므로 항상 full model을 반환받는다.
12
+ */
6
13
  let BoardViewerByNamePage = class BoardViewerByNamePage extends BoardViewerPage {
7
- async fetch(name) {
14
+ async fetch(name, _cachedUpdatedAt) {
8
15
  return await client.query({
9
16
  query: gql `
10
17
  query FetchBoardByName($name: String!) {
@@ -12,6 +19,7 @@ let BoardViewerByNamePage = class BoardViewerByNamePage extends BoardViewerPage
12
19
  id
13
20
  name
14
21
  model
22
+ updatedAt
15
23
  }
16
24
  }
17
25
  `,
@@ -1 +1 @@
1
- {"version":3,"file":"board-viewer-by-name-page.js","sourceRoot":"","sources":["../../client/pages/board-viewer-by-name-page.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAGjD,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,eAAe;IACxD,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC;YACxB,KAAK,EAAE,GAAG,CAAA;;;;;;;;OAQT;YACD,SAAS,EAAE,EAAE,IAAI,EAAE;YACnB,OAAO,EAAE,UAAU,EAAE;SACtB,CAAC,CAAA;IACJ,CAAC;CACF,CAAA;AAhBY,qBAAqB;IADjC,aAAa,CAAC,2BAA2B,CAAC;GAC9B,qBAAqB,CAgBjC","sourcesContent":["import gql from 'graphql-tag'\nimport { customElement } from 'lit/decorators.js'\nimport { client, gqlContext } from '@operato/graphql'\nimport { ApolloQueryResult } from '@apollo/client'\nimport { BoardViewerPage } from './board-viewer-page.js'\n\n@customElement('board-viewer-by-name-page')\nexport class BoardViewerByNamePage extends BoardViewerPage {\n async fetch(name: string): Promise<ApolloQueryResult<any>> {\n return await client.query({\n query: gql`\n query FetchBoardByName($name: String!) {\n response: boardByName(name: $name) {\n id\n name\n model\n }\n }\n `,\n variables: { name },\n context: gqlContext()\n })\n }\n}\n"]}
1
+ {"version":3,"file":"board-viewer-by-name-page.js","sourceRoot":"","sources":["../../client/pages/board-viewer-by-name-page.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD;;;;;;GAMG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,eAAe;IACxD,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,gBAAyB;QACjD,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC;YACxB,KAAK,EAAE,GAAG,CAAA;;;;;;;;;OAST;YACD,SAAS,EAAE,EAAE,IAAI,EAAE;YACnB,OAAO,EAAE,UAAU,EAAE;SACtB,CAAC,CAAA;IACJ,CAAC;CACF,CAAA;AAjBY,qBAAqB;IADjC,aAAa,CAAC,2BAA2B,CAAC;GAC9B,qBAAqB,CAiBjC","sourcesContent":["import gql from 'graphql-tag'\nimport { customElement } from 'lit/decorators.js'\nimport { client, gqlContext } from '@operato/graphql'\nimport { ApolloQueryResult } from '@apollo/client'\nimport { BoardViewerPage } from './board-viewer-page.js'\n\n/**\n * 이름으로 보드를 조회하는 뷰어 페이지.\n *\n * BoardModelCache는 id 기반이므로 name 기반 조회에서는 캐시 활용 불가.\n * (name → id 매핑 캐시를 별도 구현하면 가능하지만, 사용 빈도가 낮아 미적용)\n * cachedUpdatedAt 파라미터를 전달하지 않으므로 항상 full model을 반환받는다.\n */\n@customElement('board-viewer-by-name-page')\nexport class BoardViewerByNamePage extends BoardViewerPage {\n async fetch(name: string, _cachedUpdatedAt?: string): Promise<ApolloQueryResult<any>> {\n return await client.query({\n query: gql`\n query FetchBoardByName($name: String!) {\n response: boardByName(name: $name) {\n id\n name\n model\n updatedAt\n }\n }\n `,\n variables: { name },\n context: gqlContext()\n })\n }\n}\n"]}
@@ -12,6 +12,7 @@ export declare class BoardViewerPage extends PageView {
12
12
  _interactive?: boolean;
13
13
  _showSpinner?: boolean;
14
14
  data: any;
15
+ private _loadTracker?;
15
16
  subscriptionForAutoRefresh: any;
16
17
  boardViewer: BoardViewer;
17
18
  get oopsNote(): {
@@ -26,7 +27,7 @@ export declare class BoardViewerPage extends PageView {
26
27
  render(): import("lit-html").TemplateResult<1>;
27
28
  updated(changes: any): void;
28
29
  pageUpdated(changes: any, lifecycle: any): void;
29
- fetch(id: string): Promise<ApolloQueryResult<any> | undefined>;
30
+ fetch(id: string, cachedUpdatedAt?: string): Promise<ApolloQueryResult<any> | undefined>;
30
31
  refresh(): Promise<void>;
31
32
  startSubscribingForAutoRefresh(): Promise<void>;
32
33
  stopSubscribing(): Promise<void>;
@@ -6,25 +6,14 @@ import gql from 'graphql-tag';
6
6
  import { css, html } from 'lit';
7
7
  import { customElement, property, query, state } from 'lit/decorators.js';
8
8
  import { buildLabelPrintCommand } from '@operato/barcode';
9
- import { BoardViewer } from '@operato/board';
9
+ import { BoardModelCache, BoardViewer } from '@operato/board';
10
+ import { LoadTracker } from '@hatiolab/things-scene';
10
11
  import { PageView } from '@operato/shell';
11
12
  import { client, gqlContext, subscribe } from '@operato/graphql';
12
13
  import { clientSettingStore } from '@operato/shell/object-store.js';
13
14
  import { provider } from '../board-provider.js';
14
- const NOOP = () => { };
15
- function parseQuery(query) {
16
- for (const key in query) {
17
- if (query.hasOwnProperty(key)) {
18
- try {
19
- query[key] = JSON.parse(query[key]);
20
- }
21
- catch (error) {
22
- // do nothing
23
- }
24
- }
25
- }
26
- return query;
27
- }
15
+ import { parseQuery } from '../utils/query-utils.js';
16
+ import { notifyError } from '../utils/notify-helper.js';
28
17
  let BoardViewerPage = class BoardViewerPage extends PageView {
29
18
  static { this.styles = [
30
19
  css `
@@ -73,14 +62,13 @@ let BoardViewerPage = class BoardViewerPage extends PageView {
73
62
  }
74
63
  get context() {
75
64
  return {
76
- /* can set the page title with the 'title' parameter. */
77
65
  title: this.lifecycle.params['title'] ||
78
- (this._board ? this._board.name : this._showSpinner ? 'Fetching board...' : 'Board Not Found'),
66
+ (this._board ? this._board.name : this._showSpinner ? 'Fetching board...' : ''),
79
67
  help: this._help
80
68
  };
81
69
  }
82
70
  render() {
83
- var oops = !this._showSpinner && !this._board && this.oopsNote;
71
+ const oops = !this._showSpinner && !this._board && this.oopsNote;
84
72
  return oops
85
73
  ? html ` <ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note> `
86
74
  : html `
@@ -90,6 +78,7 @@ let BoardViewerPage = class BoardViewerPage extends PageView {
90
78
  ?hide-fullscreen=${this._interactive}
91
79
  ?hide-navigation=${this._interactive}
92
80
  .data=${this.data}
81
+ .loadTracker=${this._loadTracker}
93
82
  history
94
83
  ></ox-board-viewer>
95
84
  <ox-oops-spinner ?show=${this._showSpinner}></ox-oops-spinner>
@@ -108,34 +97,35 @@ let BoardViewerPage = class BoardViewerPage extends PageView {
108
97
  this.data = parseQuery({ ...lifecycle.params });
109
98
  }
110
99
  else {
111
- /*
112
- * 비활성화된 페이지에서 render update가 발생하지 않으므로, 강제로 scene을 close 한다.
113
- * 화면이 inactive 될 때, 굳이 scene을 close하는 이유는,
114
- * 새로운 board가 선택되어 뷰어가 열릴 때, 기존 보드 잔상이 보이지 않도록 하기위해서이다.
115
- */
100
+ // 비활성 — 철저히 클리어
116
101
  this.stopSubscribing();
117
- if (this._boardId) {
118
- let boardViewer = this.boardViewer;
119
- boardViewer && boardViewer.closeScene();
102
+ const boardViewer = this.boardViewer;
103
+ if (boardViewer) {
104
+ boardViewer.closeScene();
120
105
  }
121
106
  this._boardId = '';
107
+ this._board = null;
108
+ this._loadTracker = undefined;
109
+ this._showSpinner = false;
110
+ this.updateContext();
122
111
  }
123
112
  }
124
- async fetch(id) {
113
+ async fetch(id, cachedUpdatedAt) {
125
114
  if (!id) {
126
115
  return;
127
116
  }
128
117
  return await client.query({
129
118
  query: gql `
130
- query ($id: String!) {
131
- response: board(id: $id) {
119
+ query ($id: String!, $cachedUpdatedAt: String) {
120
+ response: board(id: $id, cachedUpdatedAt: $cachedUpdatedAt) {
132
121
  id
133
122
  name
134
123
  model
124
+ updatedAt
135
125
  }
136
126
  }
137
127
  `,
138
- variables: { id },
128
+ variables: { id, cachedUpdatedAt },
139
129
  context: gqlContext()
140
130
  });
141
131
  }
@@ -145,34 +135,48 @@ let BoardViewerPage = class BoardViewerPage extends PageView {
145
135
  return;
146
136
  }
147
137
  try {
138
+ // 이전 보드 완전히 클리어
139
+ this._board = null;
140
+ this._loadTracker = new LoadTracker();
141
+ this._loadTracker.setPhase('fetch');
148
142
  this._showSpinner = true;
149
143
  this.updateContext();
150
- var { data, errors } = (await this.fetch(this._boardId)) || {};
151
- var board = data?.response;
144
+ // 캐시의 updatedAt을 서버에 전달 동일하면 model 생략됨
145
+ const cached = await BoardModelCache.get(this._boardId);
146
+ const { data, errors } = (await this.fetch(this._boardId, cached?.updatedAt)) || {};
147
+ this._loadTracker.setPhase('parse');
148
+ const board = data?.response;
152
149
  if (!board) {
153
150
  this._board = null;
154
151
  const message = errors?.map(error => error.message).join('\n');
155
152
  throw message || 'board not found';
156
153
  }
157
- this._board = {
158
- ...board,
159
- model: JSON.parse(board.model)
160
- };
154
+ if (board.model === null && cached) {
155
+ // 서버가 model 생략 → 캐시 유효, 캐시 모델 사용
156
+ this._board = cached;
157
+ }
158
+ else {
159
+ // 새 모델 또는 첫 로드 → 캐시 갱신
160
+ await BoardModelCache.put(board.id, board.name, board.model, board.updatedAt);
161
+ this._board = {
162
+ ...board,
163
+ model: JSON.parse(board.model)
164
+ };
165
+ }
161
166
  }
162
167
  catch (ex) {
163
- document.dispatchEvent(new CustomEvent('notify', {
164
- detail: {
165
- level: 'error',
166
- message: ex,
167
- ex
168
- }
169
- }));
168
+ notifyError(ex);
170
169
  }
171
170
  finally {
172
171
  this._showSpinner = false;
173
172
  this.updateContext();
174
- const { autoRefresh = true } = (await clientSettingStore.get('board-view'))?.value || {};
175
- autoRefresh && this.startSubscribingForAutoRefresh();
173
+ try {
174
+ const { autoRefresh = true } = (await clientSettingStore.get('board-view'))?.value || {};
175
+ autoRefresh && this.startSubscribingForAutoRefresh();
176
+ }
177
+ catch { /* clientSettingStore 접근 실패 시 기본값으로 autoRefresh */
178
+ this.startSubscribingForAutoRefresh();
179
+ }
176
180
  }
177
181
  }
178
182
  async startSubscribingForAutoRefresh() {
@@ -205,10 +209,10 @@ let BoardViewerPage = class BoardViewerPage extends PageView {
205
209
  delete this.subscriptionForAutoRefresh;
206
210
  }
207
211
  async getGrf() {
208
- var { labelRotation } = this._board.model;
209
- var { width, height, data } = (await this.boardViewer.getSceneImageData()) || {};
212
+ const { labelRotation } = this._board.model;
213
+ const { width, height, data } = (await this.boardViewer.getSceneImageData()) || {};
210
214
  if (!width || !data) {
211
- throw 'Cannot get SceneImageData...';
215
+ throw new Error('Cannot get SceneImageData...');
212
216
  }
213
217
  return buildLabelPrintCommand(data, width, height, labelRotation, false, false);
214
218
  }