lutaml 0.9.43 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (583) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +63 -0
  3. data/.github/workflows/links.yml +99 -0
  4. data/.github/workflows/rake.yml +13 -2
  5. data/.github/workflows/release.yml +12 -6
  6. data/.gitignore +3 -0
  7. data/.rubocop.yml +11 -3
  8. data/.rubocop_todo.yml +336 -0
  9. data/Gemfile +18 -7
  10. data/README.adoc +1854 -21
  11. data/Rakefile +7 -1
  12. data/bin/plantuml2lutaml +3 -3
  13. data/bin/yaml2lutaml +2 -2
  14. data/config/diagram_styles.yml +200 -0
  15. data/config/model_transformations.yml +266 -0
  16. data/config/package_metadata.example.yml +58 -0
  17. data/config/qea_schema.yml +1024 -0
  18. data/config/static_site.yml +166 -0
  19. data/docs/.github/workflows/docs.yml +66 -0
  20. data/docs/.github/workflows/links.yml +78 -0
  21. data/docs/CONTINUATION_PLAN.md +168 -0
  22. data/docs/Gemfile +13 -0
  23. data/docs/MIGRATION_GUIDE.md +202 -0
  24. data/docs/README.md +252 -0
  25. data/docs/REFACTOR_PLAN.md +214 -0
  26. data/docs/_config.yml +144 -0
  27. data/docs/_guides/diagram-generation.adoc +316 -0
  28. data/docs/_guides/index.adoc +135 -0
  29. data/docs/{lutaml-express.adoc → _guides/parsing/express-parsing.adoc} +7 -0
  30. data/docs/_guides/parsing/index.adoc +77 -0
  31. data/docs/{lutaml-xmi.adoc → _guides/parsing/xmi-parsing.adoc} +7 -0
  32. data/docs/_guides/sysml-modeling.adoc +37 -0
  33. data/docs/{lutaml-uml.adoc → _guides/uml-modeling.adoc} +8 -2
  34. data/docs/_pages/concepts/diagram-generation.adoc +337 -0
  35. data/docs/_pages/concepts/lur-format.adoc +711 -0
  36. data/docs/_pages/concepts/qea-parsing.adoc +418 -0
  37. data/docs/_pages/core/architecture.adoc +329 -0
  38. data/docs/_pages/core/installation.adoc +321 -0
  39. data/docs/_pages/core/overview.adoc +197 -0
  40. data/docs/_pages/index.adoc +48 -0
  41. data/docs/_pages/uml-syntax.adoc +995 -0
  42. data/docs/_references/configuration/diagram-styles.adoc +716 -0
  43. data/docs/_references/configuration/index.adoc +52 -0
  44. data/docs/_references/configuration/package-metadata.adoc +416 -0
  45. data/docs/_references/formats/index.adoc +42 -0
  46. data/docs/{lutaml_syntax.adoc → _references/formats/lutaml-syntax.adoc} +7 -0
  47. data/docs/_references/formats/qea-structure.adoc +1364 -0
  48. data/docs/_references/index.adoc +197 -0
  49. data/docs/_tutorials/index.adoc +109 -0
  50. data/docs/index.adoc +64 -0
  51. data/docs/lychee.toml +83 -0
  52. data/examples/UML_EA.DTD +6856 -0
  53. data/examples/lur/20251010_current_plateau_v5.1.lur +0 -0
  54. data/examples/lur/basic.lur +0 -0
  55. data/examples/lur/test-output.lur +0 -0
  56. data/examples/lur/test.lur +0 -0
  57. data/examples/lur_basic_usage.rb +220 -0
  58. data/examples/lur_cli_workflow.rb +262 -0
  59. data/examples/lur_statistics.rb +325 -0
  60. data/examples/qea/20251010_current_plateau_v5.1.qea +0 -0
  61. data/examples/qea/ArcGISWorkspace_template.qea +0 -0
  62. data/examples/qea/README_qea_parser.adoc +230 -0
  63. data/examples/qea/UmlModel_template.qea +0 -0
  64. data/examples/qea/basic.qea +0 -0
  65. data/examples/qea/simple.qea +0 -0
  66. data/examples/qea/simple_example.qea +0 -0
  67. data/examples/qea/test.qea +0 -0
  68. data/examples/xmi/20251010_current_plateau_v5.1.xmi +118121 -0
  69. data/examples/xmi/ArcGISWorkspace_template.xmi +1467 -0
  70. data/examples/xmi/Images/EAID_0016F797_D055_4717_AF1A_606413D0A166.svg +158 -0
  71. data/examples/xmi/Images/EAID_00C5C772_5A03_434f_BF30_AC37542A1AAC.svg +659 -0
  72. data/examples/xmi/Images/EAID_0114FD24_9E58_4664_98CD_71305B59AD11.svg +411 -0
  73. data/examples/xmi/Images/EAID_01661E1B_31B6_4167_BCCF_A00678FB4EA2.svg +102 -0
  74. data/examples/xmi/Images/EAID_039FE004_5408_4fc0_89AA_EB319E4F61C7.svg +169 -0
  75. data/examples/xmi/Images/EAID_04EE9625_17A0_4721_BC71_21756DB21D06.svg +403 -0
  76. data/examples/xmi/Images/EAID_05FF9417_1619_4170_B0C9_55AA6B988EF1.svg +175 -0
  77. data/examples/xmi/Images/EAID_09853FB2_AF8A_432f_94C5_6C47461BD937.svg +360 -0
  78. data/examples/xmi/Images/EAID_09927B7F_A657_4819_99E5_AC9DC99227D9.svg +195 -0
  79. data/examples/xmi/Images/EAID_09AF6B8A_557C_43bc_BBB0_47C1E9401EF3.svg +218 -0
  80. data/examples/xmi/Images/EAID_0BE81AC5_031B_4973_A9A0_223CCD92BAA1.svg +471 -0
  81. data/examples/xmi/Images/EAID_0EDEA6EF_4DC8_4979_BB80_28B1B9EBD1D4.svg +56 -0
  82. data/examples/xmi/Images/EAID_0F413534_6AD2_48bc_B4AF_8699D530D91D.svg +262 -0
  83. data/examples/xmi/Images/EAID_1321F39B_AD67_47b5_B5C3_3A42BBFCBDF9.svg +286 -0
  84. data/examples/xmi/Images/EAID_13E09C71_99E7_40b4_B72D_48AF6379BC2E.svg +164 -0
  85. data/examples/xmi/Images/EAID_144955D8_CB4E_4b59_BB0C_E549F7F84943.svg +66 -0
  86. data/examples/xmi/Images/EAID_14E9F5FD_F6CD_4f48_B1CD_F5A40C6D8E83.svg +95 -0
  87. data/examples/xmi/Images/EAID_157826AA_96A7_4278_89A6_94BD0F31409A.svg +63 -0
  88. data/examples/xmi/Images/EAID_159E9DA0_7A54_4817_B72A_401C750F675D.svg +306 -0
  89. data/examples/xmi/Images/EAID_17BC8309_8051_492b_BE87_61CCFE83DB16.svg +45 -0
  90. data/examples/xmi/Images/EAID_1A10EB6D_E2E5_42a6_A31E_B293D93FD07E.svg +193 -0
  91. data/examples/xmi/Images/EAID_1A290AFD_CE96_46a2_8351_A986D77CC727.svg +444 -0
  92. data/examples/xmi/Images/EAID_1B2D9309_C66B_492a_995C_95B2B02E0D7C.svg +168 -0
  93. data/examples/xmi/Images/EAID_1DE6B973_CE8A_416f_909B_54CEA1E5944E.svg +10 -0
  94. data/examples/xmi/Images/EAID_204F4ACC_2230_4c8d_9861_EF5A6844B712.svg +60 -0
  95. data/examples/xmi/Images/EAID_227300E2_4F4B_4955_83B9_FA626CE8680B.svg +188 -0
  96. data/examples/xmi/Images/EAID_22C24D4C_4894_480a_B113_0CB034CB59E9.svg +426 -0
  97. data/examples/xmi/Images/EAID_234BC4F5_8100_4969_BDCB_A24E0E641F23.svg +169 -0
  98. data/examples/xmi/Images/EAID_24446BFC_9FEB_4935_8970_65A4C562A93F.svg +277 -0
  99. data/examples/xmi/Images/EAID_24E8A45C_C99F_49b7_860A_9CF65FF76C76.svg +575 -0
  100. data/examples/xmi/Images/EAID_272F3181_4300_48b7_98A0_A8CFD12B1A72.svg +255 -0
  101. data/examples/xmi/Images/EAID_292E0D94_392C_4da6_A0B5_841501FAE50A.svg +183 -0
  102. data/examples/xmi/Images/EAID_29DD0967_ADAB_4abb_99C5_544821F5E7DA.svg +10 -0
  103. data/examples/xmi/Images/EAID_2A339928_E5EF_4ed2_9E5D_CC2CA5CF248B.svg +310 -0
  104. data/examples/xmi/Images/EAID_2A5E0832_06BE_4381_85D4_9B00E4F95575.svg +155 -0
  105. data/examples/xmi/Images/EAID_2AAB709F_EFCE_496f_8AFE_92809D66A0A9.svg +81 -0
  106. data/examples/xmi/Images/EAID_2C8DD882_8DEA_4065_89F8_DDA796AA0C85.svg +520 -0
  107. data/examples/xmi/Images/EAID_2E98EA19_37D8_4b70_BDCE_CFEE4FA800B0.svg +173 -0
  108. data/examples/xmi/Images/EAID_30D62231_110F_44e8_9C06_6FCDCBA53A09.svg +722 -0
  109. data/examples/xmi/Images/EAID_3206D3FD_1FC4_41c7_8D00_36DB908E9319.svg +181 -0
  110. data/examples/xmi/Images/EAID_3452CC53_9ACB_44eb_9C9D_B90CF862F284.svg +92 -0
  111. data/examples/xmi/Images/EAID_348EE46E_ABD9_40b0_82A1_0285E75BDC52.svg +187 -0
  112. data/examples/xmi/Images/EAID_34FF671B_CFDC_47ad_91DF_ECA6D8358180.svg +217 -0
  113. data/examples/xmi/Images/EAID_359DD694_0100_4bdf_AD5F_712D97E9C69B.svg +157 -0
  114. data/examples/xmi/Images/EAID_35DE714C_49A8_490e_913A_56F39EF317F9.svg +180 -0
  115. data/examples/xmi/Images/EAID_360C79F1_8EDF_41db_A069_DECDC55625BC.svg +31 -0
  116. data/examples/xmi/Images/EAID_36913C58_FF35_4ba2_A04B_9A4824E24609.svg +166 -0
  117. data/examples/xmi/Images/EAID_372F7F7B_57ED_469a_A640_70DB578B3C56.svg +361 -0
  118. data/examples/xmi/Images/EAID_37AC19B9_8433_4fee_A326_763170D54D06.svg +32 -0
  119. data/examples/xmi/Images/EAID_38170608_32B5_4a6f_A68D_A0D7C0C9D019.svg +234 -0
  120. data/examples/xmi/Images/EAID_3A77A5D0_4E1B_4116_8AAD_407FC422B47F.svg +183 -0
  121. data/examples/xmi/Images/EAID_3B8BD087_1683_46b1_8D0D_6F839C46C578.svg +42 -0
  122. data/examples/xmi/Images/EAID_3DC20801_AE8B_4e76_B08C_F574E8A90E13.svg +192 -0
  123. data/examples/xmi/Images/EAID_3DE28C70_C6D4_406c_B49F_EEF52148C8C1.svg +124 -0
  124. data/examples/xmi/Images/EAID_458E093C_BA2B_4292_BEC4_37511C163DDC.svg +140 -0
  125. data/examples/xmi/Images/EAID_45F9B1F7_E568_47c9_B229_953BC2E707E4.svg +266 -0
  126. data/examples/xmi/Images/EAID_46B3041A_8C23_46e6_8E14_ADE7012274C5.svg +80 -0
  127. data/examples/xmi/Images/EAID_47E4600F_CEC9_4245_9BF5_EE38007A9DDB.svg +584 -0
  128. data/examples/xmi/Images/EAID_4881CEEE_792C_4cb0_BEA7_54333B643D0A.svg +155 -0
  129. data/examples/xmi/Images/EAID_48D364F0_DCA4_41e8_B4D4_509B3023B969.svg +17 -0
  130. data/examples/xmi/Images/EAID_4DBDAB9E_4C1C_4cb1_A767_06BD743A50A7.svg +78 -0
  131. data/examples/xmi/Images/EAID_4EB75007_B31D_4f2c_8855_7E9D3A3B17F4.svg +454 -0
  132. data/examples/xmi/Images/EAID_4F421236_FCF3_4aae_B22A_C7E6A5EFBAC7.svg +81 -0
  133. data/examples/xmi/Images/EAID_4FC1D352_2102_4b73_BCB0_1410B29C6BD7.svg +379 -0
  134. data/examples/xmi/Images/EAID_4FE346EA_01E1_4b30_8BE6_BB32EA191E47.svg +126 -0
  135. data/examples/xmi/Images/EAID_5038EEE3_7DD0_4cca_9829_364E044D37E8.svg +199 -0
  136. data/examples/xmi/Images/EAID_508A37DC_9378_4f5a_BD96_48F4D24E03A5.svg +162 -0
  137. data/examples/xmi/Images/EAID_516DA1A2_F0EC_415c_9664_E4CA54E7F05C.svg +136 -0
  138. data/examples/xmi/Images/EAID_52A1DBD3_D3DA_4b6d_8F96_FC6F39F64242.svg +161 -0
  139. data/examples/xmi/Images/EAID_575E87BA_32E9_4a84_AA4E_0EFDFC5D4C07.svg +71 -0
  140. data/examples/xmi/Images/EAID_57E0F1A0_6C72_47ef_B922_B806F9A875E8.svg +209 -0
  141. data/examples/xmi/Images/EAID_5957C373_3FC1_482f_8F35_D809153A17F5.svg +123 -0
  142. data/examples/xmi/Images/EAID_59A66AE2_412C_48a6_BFC7_EA56CF11D269.svg +218 -0
  143. data/examples/xmi/Images/EAID_5A43833E_680B_4a90_8931_0C902304E029.svg +236 -0
  144. data/examples/xmi/Images/EAID_5D6DB5A0_5047_4bac_9E60_69904A60B56D.svg +353 -0
  145. data/examples/xmi/Images/EAID_5DA1E7A7_8E59_4803_A831_E9F3EC27328F.svg +242 -0
  146. data/examples/xmi/Images/EAID_5E2C1E2A_82A8_47f4_B2ED_1398D72BFCFD.svg +246 -0
  147. data/examples/xmi/Images/EAID_6052620C_4BD5_49f6_A21C_AD7E6DCA2795.svg +290 -0
  148. data/examples/xmi/Images/EAID_6481E2CC_35A6_43b0_88D4_10A667A2BC2D.svg +60 -0
  149. data/examples/xmi/Images/EAID_660C7D03_A26C_4977_A7BA_9D0A773DA811.svg +318 -0
  150. data/examples/xmi/Images/EAID_671F3C3D_35B6_4514_B5B6_DD7E84925493.svg +24 -0
  151. data/examples/xmi/Images/EAID_676B9C9A_D85F_4d2f_A46B_73F02090DC87.svg +127 -0
  152. data/examples/xmi/Images/EAID_6797FEFA_5801_48e4_8B9C_3C824C0E165D.svg +412 -0
  153. data/examples/xmi/Images/EAID_6807F4EE_18EF_4e7e_ACCF_D5BD323AFDE9.svg +130 -0
  154. data/examples/xmi/Images/EAID_69E81E34_CF28_4c7f_A48F_5941BA85CEE3.svg +96 -0
  155. data/examples/xmi/Images/EAID_6A3C55E8_3C3C_4f3a_8AAC_0299C5B23070.svg +10 -0
  156. data/examples/xmi/Images/EAID_6BAC333E_E2C2_42c7_8DDF_6B4FA0FFC03B.svg +143 -0
  157. data/examples/xmi/Images/EAID_6D0349D5_3F1B_4b28_82D2_910743DEB5E5.svg +114 -0
  158. data/examples/xmi/Images/EAID_6E95B74E_8A09_4698_9E9E_23BCFD2CE194.svg +37 -0
  159. data/examples/xmi/Images/EAID_70C77F92_5614_4b22_8C8E_67859F59D8FD.svg +254 -0
  160. data/examples/xmi/Images/EAID_71F9216B_E7A7_4083_B08E_6C71B57F3A1F.svg +187 -0
  161. data/examples/xmi/Images/EAID_73025C5A_08FC_47ff_AB2F_C7F79CF54B41.svg +145 -0
  162. data/examples/xmi/Images/EAID_74C974B6_6D07_425d_B7AC_C8899E3B4967.svg +76 -0
  163. data/examples/xmi/Images/EAID_7504FCD2_524C_4e7d_BAE4_4E58A8A8A12C.svg +196 -0
  164. data/examples/xmi/Images/EAID_78030266_3603_4747_9D75_03D16614BE7D.svg +35 -0
  165. data/examples/xmi/Images/EAID_785226C1_12B1_4104_A4C1_F19B70B9FB71.svg +348 -0
  166. data/examples/xmi/Images/EAID_7854470F_26B8_4d3c_AFDF_C05BCE6ED0CD.svg +72 -0
  167. data/examples/xmi/Images/EAID_794F4A8F_18CA_4e9f_8477_A6F0E5ED22D4.svg +187 -0
  168. data/examples/xmi/Images/EAID_7A24839E_C8AE_424d_B7D2_6DA16DC813E7.svg +114 -0
  169. data/examples/xmi/Images/EAID_7A3649FD_E960_4ae6_B9B1_A9001C066AE7.svg +181 -0
  170. data/examples/xmi/Images/EAID_7B2C6765_AB68_439a_87F3_DAC323CB2AF5.svg +196 -0
  171. data/examples/xmi/Images/EAID_7C44AC09_27C1_47b3_9A85_88EC71C081FF.svg +55 -0
  172. data/examples/xmi/Images/EAID_7CE102CA_97C1_4cac_BD3B_0500D3712D2A.svg +195 -0
  173. data/examples/xmi/Images/EAID_7D960BD8_65D8_4934_9C11_4EF860DD8FBA.svg +90 -0
  174. data/examples/xmi/Images/EAID_80939C98_A456_48c3_BCEA_4B72851F2DF6.svg +174 -0
  175. data/examples/xmi/Images/EAID_812FE862_76ED_44f0_B678_7A4601B395CF.svg +142 -0
  176. data/examples/xmi/Images/EAID_81B76F5B_9D64_4bbf_8AC8_34234FB87533.svg +740 -0
  177. data/examples/xmi/Images/EAID_84352F1A_195B_411b_9552_5BFC40BF90B5.svg +105 -0
  178. data/examples/xmi/Images/EAID_846DD800_139C_4d47_A1DF_3FB1AC5D130F.svg +554 -0
  179. data/examples/xmi/Images/EAID_84A9C65B_FD6D_4bb5_818F_E8C35FF5BCD1.svg +228 -0
  180. data/examples/xmi/Images/EAID_853674F5_7DC9_4aae_809B_5728098B5D5B.svg +154 -0
  181. data/examples/xmi/Images/EAID_860CBBFB_2F27_408f_9144_751F9D1F487F.svg +273 -0
  182. data/examples/xmi/Images/EAID_87476527_7B9B_4b92_967E_3D38365470CA.svg +239 -0
  183. data/examples/xmi/Images/EAID_87DAE930_5069_4c58_AC65_4B0B2C0F32C8.svg +10 -0
  184. data/examples/xmi/Images/EAID_88AF6BD7_BC34_406f_BB59_47CFAB4A7D5D.svg +116 -0
  185. data/examples/xmi/Images/EAID_88D0CB44_20D0_44fc_A6E3_B663332EF401.svg +200 -0
  186. data/examples/xmi/Images/EAID_8BB1CA0C_C003_4678_973B_A1C3308E021D.svg +136 -0
  187. data/examples/xmi/Images/EAID_8DAB169F_D189_4320_A0F5_4443E3297F0E.svg +181 -0
  188. data/examples/xmi/Images/EAID_8FD488EF_BAAB_40ec_A7ED_F7CC831D546E.svg +324 -0
  189. data/examples/xmi/Images/EAID_90BCA409_BB45_42c5_AFA5_45FE3D995904.svg +342 -0
  190. data/examples/xmi/Images/EAID_926AFE38_01FA_469e_B6AA_ED5F4D62B66F.svg +105 -0
  191. data/examples/xmi/Images/EAID_92AB0FD0_B0FB_4ceb_8EAE_66B6600D31D7.svg +681 -0
  192. data/examples/xmi/Images/EAID_92C43670_3057_47f1_A576_C60843FF3D26.svg +136 -0
  193. data/examples/xmi/Images/EAID_93F63576_BE01_4cd8_8A91_C674FF77FC3D.svg +718 -0
  194. data/examples/xmi/Images/EAID_9400D9BC_05A5_41fc_83F7_02E5C67F9718.svg +487 -0
  195. data/examples/xmi/Images/EAID_95246DCF_1C09_4a16_9512_98000F56B3D8.svg +292 -0
  196. data/examples/xmi/Images/EAID_9994BF62_51E2_42cd_BB35_16C537B6718A.svg +715 -0
  197. data/examples/xmi/Images/EAID_9AAD6C21_B1E7_4472_B64A_FB5E3569D970.svg +116 -0
  198. data/examples/xmi/Images/EAID_9BD7189A_877B_4ca9_B42C_817DEF144FB2.svg +284 -0
  199. data/examples/xmi/Images/EAID_9DA6C553_94FC_4204_83AD_ECC4B45A53EF.svg +159 -0
  200. data/examples/xmi/Images/EAID_9EE6A41B_5FAA_4c89_B98F_732059778630.svg +10 -0
  201. data/examples/xmi/Images/EAID_9F1A4B54_46F6_435c_9529_E43E54CF6050.svg +172 -0
  202. data/examples/xmi/Images/EAID_9FE1EA7B_4CEF_4976_A281_93A94315BD84.svg +153 -0
  203. data/examples/xmi/Images/EAID_A0695647_6172_4262_8C30_67441399609C.svg +290 -0
  204. data/examples/xmi/Images/EAID_A081C63E_D6F2_41a7_A99C_307836754AFA.svg +149 -0
  205. data/examples/xmi/Images/EAID_A24E2778_5AD9_44f2_AB8F_5CD3913477D6.svg +194 -0
  206. data/examples/xmi/Images/EAID_A264F089_F9B3_406c_A3A8_FF34903797D3.svg +143 -0
  207. data/examples/xmi/Images/EAID_A282E5D1_2A13_4e7f_BC76_5D086DD4A577.svg +357 -0
  208. data/examples/xmi/Images/EAID_A3BCE1D6_9DB5_4272_A020_4C0E194B99CC.svg +171 -0
  209. data/examples/xmi/Images/EAID_A56E3818_D1B8_4b63_B69E_FBAC4A8AF482.svg +218 -0
  210. data/examples/xmi/Images/EAID_A57215D5_75C5_4532_BCF4_264A77CD62F1.svg +204 -0
  211. data/examples/xmi/Images/EAID_A59065AF_9669_486c_9582_9693177CFC7F.svg +263 -0
  212. data/examples/xmi/Images/EAID_A759374D_589A_488c_99EF_537ACB9B1FF9.svg +398 -0
  213. data/examples/xmi/Images/EAID_A7B25F46_F18A_4373_B16D_8C6AC0B868B0.svg +174 -0
  214. data/examples/xmi/Images/EAID_A9FE9E6F_A5F4_47e5_A6BA_26E22C7346B6.svg +310 -0
  215. data/examples/xmi/Images/EAID_AA62CDEB_55EC_498d_B326_4AA2C9AF6A05.svg +144 -0
  216. data/examples/xmi/Images/EAID_AAF52AF6_F7F9_4005_AE46_8920847BEA03.svg +144 -0
  217. data/examples/xmi/Images/EAID_AB281AC1_7CB8_404a_8124_34343DDD84E2.svg +198 -0
  218. data/examples/xmi/Images/EAID_AB7F1FDF_A66B_42a1_B8A3_7F594BAAD508.svg +143 -0
  219. data/examples/xmi/Images/EAID_AC2191E3_76E3_40b2_9E21_0E0B9B5277D2.svg +114 -0
  220. data/examples/xmi/Images/EAID_AD451676_A7C8_4c6a_A925_A9B9CA344142.svg +339 -0
  221. data/examples/xmi/Images/EAID_ADBA40A1_9375_4c1b_9938_0990612EB615.svg +429 -0
  222. data/examples/xmi/Images/EAID_ADC8773C_1B27_48ac_BAC1_14C1C919FAF6.svg +245 -0
  223. data/examples/xmi/Images/EAID_AE0718DF_AF69_4ea1_A099_E20028FE40A1.svg +173 -0
  224. data/examples/xmi/Images/EAID_B0DDB85D_A00C_4a7f_8C06_CCA15E5E4FE5.svg +31 -0
  225. data/examples/xmi/Images/EAID_B27ED282_D5E5_4f33_8AC1_62802F9E0B35.svg +256 -0
  226. data/examples/xmi/Images/EAID_B3AFECCB_17DD_44d6_8A44_2C38D9A64C0B.svg +95 -0
  227. data/examples/xmi/Images/EAID_B3B6C5B1_278E_4714_8244_B6C28B66AB50.svg +176 -0
  228. data/examples/xmi/Images/EAID_B53E76CD_A0F2_4e2f_B3AB_796D85964EF2.svg +179 -0
  229. data/examples/xmi/Images/EAID_B55D6E67_0BDD_4163_B359_11A6FBA89C74.svg +207 -0
  230. data/examples/xmi/Images/EAID_B58D1A53_E860_41a3_8352_11C274093E83.svg +189 -0
  231. data/examples/xmi/Images/EAID_B62C02B3_69DB_49e9_8089_4EE398BDE666.svg +165 -0
  232. data/examples/xmi/Images/EAID_BC008774_B539_4150_8174_B675989053D0.svg +22 -0
  233. data/examples/xmi/Images/EAID_BC1F7E00_082D_4a26_922B_3967A8D66859.svg +266 -0
  234. data/examples/xmi/Images/EAID_BDA613D8_402A_475a_AA15_683D88FD3D23.svg +183 -0
  235. data/examples/xmi/Images/EAID_C028B286_4C85_47d8_B6D5_80B28F556E82.svg +303 -0
  236. data/examples/xmi/Images/EAID_C173A6F4_1D1B_400e_AD8C_64FFF7CD5BE5.svg +178 -0
  237. data/examples/xmi/Images/EAID_C1834072_CADC_4ce4_B0FC_8284AE5CF4A4.svg +158 -0
  238. data/examples/xmi/Images/EAID_C1EC985B_5CBD_4e91_8661_EB4EF23781D9.svg +286 -0
  239. data/examples/xmi/Images/EAID_C31C1314_B679_4413_B8FE_A2CD584FC128.svg +305 -0
  240. data/examples/xmi/Images/EAID_C37CFBD6_69BA_42fb_9AC7_2D329D931BCF.svg +171 -0
  241. data/examples/xmi/Images/EAID_C857C934_306F_463a_87D5_257CB225ECFE.svg +174 -0
  242. data/examples/xmi/Images/EAID_C96797DE_2238_42d3_896A_9F92500270ED.svg +180 -0
  243. data/examples/xmi/Images/EAID_C96CBC24_B20E_459a_8F9D_75B61CDCB89F.svg +656 -0
  244. data/examples/xmi/Images/EAID_CACB523D_56A5_4f05_B3C2_51BB18F380FD.svg +158 -0
  245. data/examples/xmi/Images/EAID_CB34B578_101B_48b4_9271_214FFEA6A83A.svg +409 -0
  246. data/examples/xmi/Images/EAID_CBBD6CF4_0A1E_4406_9930_89DE43527910.svg +361 -0
  247. data/examples/xmi/Images/EAID_CC06A828_3750_472f_8DB2_C2E0863FCE17.svg +96 -0
  248. data/examples/xmi/Images/EAID_CD5CF053_1772_4a0f_962D_B17054D8EEAA.svg +173 -0
  249. data/examples/xmi/Images/EAID_CE440B5A_9534_4c75_9BA5_50862BB396C2.svg +97 -0
  250. data/examples/xmi/Images/EAID_CE4734FC_7986_4b3a_807F_A5B2C7EDE9E4.svg +193 -0
  251. data/examples/xmi/Images/EAID_D14AA320_9D41_4366_8739_9C2C21F96AE1.svg +32 -0
  252. data/examples/xmi/Images/EAID_D2FA55D3_C733_4a4d_92D0_0BC7AC0BB5BC.svg +108 -0
  253. data/examples/xmi/Images/EAID_D351FC34_FB03_488d_ADA4_BDB93DA9CB02.svg +49 -0
  254. data/examples/xmi/Images/EAID_D368FDF3_BDC5_4718_A701_351C8587A376.svg +592 -0
  255. data/examples/xmi/Images/EAID_D4DA8C48_3998_450d_87C4_9D65C9FECDB4.svg +42 -0
  256. data/examples/xmi/Images/EAID_D5464ECF_290E_4b2b_A6C4_25BE80F886CB.svg +76 -0
  257. data/examples/xmi/Images/EAID_D55235B0_61E9_461a_8379_2B8BF2403BE2.svg +147 -0
  258. data/examples/xmi/Images/EAID_D555ED73_F010_45d7_8A53_45A33C64C249.svg +318 -0
  259. data/examples/xmi/Images/EAID_D7AAC526_267E_45a0_A853_3207F02363F8.svg +45 -0
  260. data/examples/xmi/Images/EAID_D998B20D_A875_4ef8_A9CE_996BE56602BD.svg +158 -0
  261. data/examples/xmi/Images/EAID_DBFA8B39_F5B7_4c0e_9552_19AEAE5BA64E.svg +200 -0
  262. data/examples/xmi/Images/EAID_DE47A47D_E7BE_4e6f_BA81_F789EE8CFE72.svg +61 -0
  263. data/examples/xmi/Images/EAID_DFBB1072_8EC5_4384_8241_7EDF4B6B888B.svg +78 -0
  264. data/examples/xmi/Images/EAID_E325B9D8_E955_4aed_8125_63167BD40320.svg +67 -0
  265. data/examples/xmi/Images/EAID_E32D9D02_CAE9_4a47_92A8_3290EDCD6E6D.svg +79 -0
  266. data/examples/xmi/Images/EAID_E3B28611_7857_458a_B0BC_736E777B88EC.svg +194 -0
  267. data/examples/xmi/Images/EAID_E43C37EC_1176_4d2e_8B98_B6F3DFF6A092.svg +96 -0
  268. data/examples/xmi/Images/EAID_E591C1CF_7F35_4160_8A72_DFA097AD5811.svg +271 -0
  269. data/examples/xmi/Images/EAID_E77C66A2_2E94_4196_BFC6_662FE5AEEB6F.svg +332 -0
  270. data/examples/xmi/Images/EAID_E7AABA98_2450_4986_9736_DCCAF0108C50.svg +639 -0
  271. data/examples/xmi/Images/EAID_E7D9A2C4_72D6_40b9_8EB8_6B35476246B3.svg +134 -0
  272. data/examples/xmi/Images/EAID_E9CDAD85_ECF1_43de_819F_30A0D01785E6.svg +193 -0
  273. data/examples/xmi/Images/EAID_EC8AF507_F441_4e8a_B8A7_C1690F3C7D0B.svg +58 -0
  274. data/examples/xmi/Images/EAID_ED501058_D540_47ac_8EBC_5921E8C0BF57.svg +384 -0
  275. data/examples/xmi/Images/EAID_EFBF5F0F_DF74_4944_8791_114F5637C335.svg +590 -0
  276. data/examples/xmi/Images/EAID_EFFFA027_2A1F_425c_8437_BF89AADC8893.svg +365 -0
  277. data/examples/xmi/Images/EAID_F07E7718_B2C2_4a65_B5DD_477CB73E971E.svg +165 -0
  278. data/examples/xmi/Images/EAID_F0F20BDF_C729_47f7_B6FC_25ED2C4609CA.svg +61 -0
  279. data/examples/xmi/Images/EAID_F32E5AFE_8605_4c77_AE69_D0D0A6E380AC.svg +76 -0
  280. data/examples/xmi/Images/EAID_F3F00F45_CD37_46fd_B521_D1040EB2FB16.svg +123 -0
  281. data/examples/xmi/Images/EAID_F46E8F19_D8F1_4a3d_B87B_B0BAB4F50F50.svg +202 -0
  282. data/examples/xmi/Images/EAID_F48E5F6E_2411_4635_9315_3EAA4CFA29F7.svg +351 -0
  283. data/examples/xmi/Images/EAID_F4C23F9E_DD74_4fed_B75D_AD3C6448BA24.svg +189 -0
  284. data/examples/xmi/Images/EAID_F853B3C4_B145_4ef0_B261_C3CC0475B6D2.svg +215 -0
  285. data/examples/xmi/Images/EAID_F8BE68CA_1F8F_47e5_9454_01A2EB7D388A.svg +124 -0
  286. data/examples/xmi/Images/EAID_F92A6A28_612E_468e_9E39_D7AE7D24E24D.svg +208 -0
  287. data/examples/xmi/Images/EAID_F995FA49_B86E_4c94_BE5E_C928FB6B87D0.svg +302 -0
  288. data/examples/xmi/Images/EAID_FEAE013A_A4E4_4283_A491_1FEB8D0EBA28.svg +524 -0
  289. data/examples/xmi/Images/EAID_FEBE5726_3751_470b_9023_8C569202E97E.svg +730 -0
  290. data/examples/xmi/UML_EA.DTD +6856 -0
  291. data/examples/xmi/UmlModel_template.xmi +23 -0
  292. data/examples/xmi/basic.xmi +9086 -0
  293. data/examples/xmi/simple.xmi +655 -0
  294. data/examples/xmi/simple_example.xmi +23 -0
  295. data/examples/xmi/test.xmi +1703 -0
  296. data/exe/lutaml +2 -16
  297. data/exe/lutaml-wsd2uml +3 -3
  298. data/exe/lutaml-yaml2uml +2 -2
  299. data/lib/lutaml/cli/commands/base_command.rb +118 -0
  300. data/lib/lutaml/cli/element_identifier.rb +165 -0
  301. data/lib/lutaml/cli/enhanced_formatter.rb +502 -0
  302. data/lib/lutaml/cli/interactive_shell.rb +911 -0
  303. data/lib/lutaml/cli/lml_commands.rb +201 -0
  304. data/lib/lutaml/cli/output_formatter.rb +348 -0
  305. data/lib/lutaml/cli/resource_registry.rb +127 -0
  306. data/lib/lutaml/cli/tree_view_formatter.rb +308 -0
  307. data/lib/lutaml/cli/uml/build_command.rb +538 -0
  308. data/lib/lutaml/cli/uml/diagram_command.rb +421 -0
  309. data/lib/lutaml/cli/uml/export_command.rb +78 -0
  310. data/lib/lutaml/cli/uml/find_command.rb +122 -0
  311. data/lib/lutaml/cli/uml/info_command.rb +104 -0
  312. data/lib/lutaml/cli/uml/inspect_command.rb +88 -0
  313. data/lib/lutaml/cli/uml/ls_command.rb +105 -0
  314. data/lib/lutaml/cli/uml/repl_command.rb +50 -0
  315. data/lib/lutaml/cli/uml/search_command.rb +88 -0
  316. data/lib/lutaml/cli/uml/serve_command.rb +59 -0
  317. data/lib/lutaml/cli/uml/shared_helpers.rb +51 -0
  318. data/lib/lutaml/cli/uml/spa_command.rb +209 -0
  319. data/lib/lutaml/cli/uml/stats_command.rb +60 -0
  320. data/lib/lutaml/cli/uml/tree_command.rb +85 -0
  321. data/lib/lutaml/cli/uml/validate_command.rb +195 -0
  322. data/lib/lutaml/cli/uml/verify_command.rb +107 -0
  323. data/lib/lutaml/cli/uml_commands.rb +163 -0
  324. data/lib/lutaml/cli.rb +72 -0
  325. data/lib/lutaml/command_line.rb +8 -6
  326. data/lib/lutaml/converter/dsl_to_uml.rb +2 -0
  327. data/lib/lutaml/converter/xmi_to_uml.rb +40 -19
  328. data/lib/lutaml/ea/diagram/configuration.rb +379 -0
  329. data/lib/lutaml/ea/diagram/element_renderers/base_renderer.rb +81 -0
  330. data/lib/lutaml/ea/diagram/element_renderers/class_renderer.rb +330 -0
  331. data/lib/lutaml/ea/diagram/element_renderers/connector_renderer.rb +55 -0
  332. data/lib/lutaml/ea/diagram/element_renderers/package_renderer.rb +69 -0
  333. data/lib/lutaml/ea/diagram/extractor.rb +559 -0
  334. data/lib/lutaml/ea/diagram/layout_engine.rb +251 -0
  335. data/lib/lutaml/ea/diagram/path_builder.rb +258 -0
  336. data/lib/lutaml/ea/diagram/style_parser.rb +315 -0
  337. data/lib/lutaml/ea/diagram/style_resolver.rb +291 -0
  338. data/lib/lutaml/ea/diagram/svg_renderer.rb +285 -0
  339. data/lib/lutaml/ea/diagram/util.rb +69 -0
  340. data/lib/lutaml/ea/diagram.rb +77 -0
  341. data/lib/lutaml/express/parsers/exp.rb +1 -1
  342. data/lib/lutaml/express.rb +4 -2
  343. data/lib/lutaml/formatter/base.rb +6 -6
  344. data/lib/lutaml/formatter/graphviz.rb +10 -8
  345. data/lib/lutaml/formatter.rb +3 -0
  346. data/lib/lutaml/layout/engine.rb +9 -7
  347. data/lib/lutaml/layout/graph_viz_engine.rb +2 -1
  348. data/lib/lutaml/layout.rb +8 -0
  349. data/lib/lutaml/model_transformations/configuration.rb +333 -0
  350. data/lib/lutaml/model_transformations/format_registry.rb +394 -0
  351. data/lib/lutaml/model_transformations/parsers/base_parser.rb +389 -0
  352. data/lib/lutaml/model_transformations/parsers/qea_parser.rb +455 -0
  353. data/lib/lutaml/model_transformations/parsers/xmi_parser.rb +301 -0
  354. data/lib/lutaml/model_transformations/transformation_engine.rb +409 -0
  355. data/lib/lutaml/model_transformations.rb +143 -0
  356. data/lib/lutaml/parser.rb +15 -7
  357. data/lib/lutaml/qea/benchmark.rb +212 -0
  358. data/lib/lutaml/qea/database.rb +324 -0
  359. data/lib/lutaml/qea/factory/association_transformer.rb +115 -0
  360. data/lib/lutaml/qea/factory/attribute_tag_transformer.rb +60 -0
  361. data/lib/lutaml/qea/factory/attribute_transformer.rb +103 -0
  362. data/lib/lutaml/qea/factory/base_transformer.rb +132 -0
  363. data/lib/lutaml/qea/factory/class_transformer.rb +734 -0
  364. data/lib/lutaml/qea/factory/constraint_transformer.rb +78 -0
  365. data/lib/lutaml/qea/factory/data_type_transformer.rb +162 -0
  366. data/lib/lutaml/qea/factory/diagram_transformer.rb +182 -0
  367. data/lib/lutaml/qea/factory/document_builder.rb +275 -0
  368. data/lib/lutaml/qea/factory/ea_to_uml_factory.rb +260 -0
  369. data/lib/lutaml/qea/factory/enum_transformer.rb +87 -0
  370. data/lib/lutaml/qea/factory/generalization_transformer.rb +106 -0
  371. data/lib/lutaml/qea/factory/instance_transformer.rb +96 -0
  372. data/lib/lutaml/qea/factory/object_property_transformer.rb +61 -0
  373. data/lib/lutaml/qea/factory/operation_transformer.rb +75 -0
  374. data/lib/lutaml/qea/factory/package_transformer.rb +199 -0
  375. data/lib/lutaml/qea/factory/reference_resolver.rb +99 -0
  376. data/lib/lutaml/qea/factory/tagged_value_transformer.rb +41 -0
  377. data/lib/lutaml/qea/factory/transformer_registry.rb +85 -0
  378. data/lib/lutaml/qea/file_detector.rb +178 -0
  379. data/lib/lutaml/qea/infrastructure/database_connection.rb +100 -0
  380. data/lib/lutaml/qea/infrastructure/schema_reader.rb +136 -0
  381. data/lib/lutaml/qea/infrastructure/table_reader.rb +224 -0
  382. data/lib/lutaml/qea/models/base_model.rb +48 -0
  383. data/lib/lutaml/qea/models/ea_attribute.rb +135 -0
  384. data/lib/lutaml/qea/models/ea_attribute_tag.rb +109 -0
  385. data/lib/lutaml/qea/models/ea_complexity_type.rb +81 -0
  386. data/lib/lutaml/qea/models/ea_connector.rb +162 -0
  387. data/lib/lutaml/qea/models/ea_connector_type.rb +62 -0
  388. data/lib/lutaml/qea/models/ea_constraint_type.rb +65 -0
  389. data/lib/lutaml/qea/models/ea_datatype.rb +108 -0
  390. data/lib/lutaml/qea/models/ea_diagram.rb +117 -0
  391. data/lib/lutaml/qea/models/ea_diagram_link.rb +80 -0
  392. data/lib/lutaml/qea/models/ea_diagram_object.rb +86 -0
  393. data/lib/lutaml/qea/models/ea_diagram_type.rb +58 -0
  394. data/lib/lutaml/qea/models/ea_document.rb +68 -0
  395. data/lib/lutaml/qea/models/ea_object.rb +208 -0
  396. data/lib/lutaml/qea/models/ea_object_constraint.rb +62 -0
  397. data/lib/lutaml/qea/models/ea_object_property.rb +96 -0
  398. data/lib/lutaml/qea/models/ea_object_type.rb +75 -0
  399. data/lib/lutaml/qea/models/ea_operation.rb +153 -0
  400. data/lib/lutaml/qea/models/ea_operation_param.rb +73 -0
  401. data/lib/lutaml/qea/models/ea_package.rb +75 -0
  402. data/lib/lutaml/qea/models/ea_script.rb +69 -0
  403. data/lib/lutaml/qea/models/ea_status_type.rb +68 -0
  404. data/lib/lutaml/qea/models/ea_stereotype.rb +59 -0
  405. data/lib/lutaml/qea/models/ea_tagged_value.rb +105 -0
  406. data/lib/lutaml/qea/models/ea_xref.rb +174 -0
  407. data/lib/lutaml/qea/parser.rb +61 -0
  408. data/lib/lutaml/qea/repositories/base_repository.rb +215 -0
  409. data/lib/lutaml/qea/repositories/object_repository.rb +221 -0
  410. data/lib/lutaml/qea/services/configuration.rb +211 -0
  411. data/lib/lutaml/qea/services/database_loader.rb +215 -0
  412. data/lib/lutaml/qea/validation/association_validator.rb +75 -0
  413. data/lib/lutaml/qea/validation/attribute_validator.rb +103 -0
  414. data/lib/lutaml/qea/validation/base_validator.rb +305 -0
  415. data/lib/lutaml/qea/validation/class_validator.rb +123 -0
  416. data/lib/lutaml/qea/validation/database/circular_reference_validator.rb +111 -0
  417. data/lib/lutaml/qea/validation/database/orphan_validator.rb +155 -0
  418. data/lib/lutaml/qea/validation/database/referential_integrity_validator.rb +130 -0
  419. data/lib/lutaml/qea/validation/diagram_validator.rb +114 -0
  420. data/lib/lutaml/qea/validation/formatters/json_formatter.rb +137 -0
  421. data/lib/lutaml/qea/validation/formatters/text_formatter.rb +235 -0
  422. data/lib/lutaml/qea/validation/operation_validator.rb +81 -0
  423. data/lib/lutaml/qea/validation/package_validator.rb +113 -0
  424. data/lib/lutaml/qea/validation/validation_engine.rb +497 -0
  425. data/lib/lutaml/qea/validation/validation_message.rb +144 -0
  426. data/lib/lutaml/qea/validation/validation_result.rb +212 -0
  427. data/lib/lutaml/qea/validation/validator_registry.rb +134 -0
  428. data/lib/lutaml/qea/verification/comparison_result.rb +264 -0
  429. data/lib/lutaml/qea/verification/document_normalizer.rb +177 -0
  430. data/lib/lutaml/qea/verification/document_verifier.rb +320 -0
  431. data/lib/lutaml/qea/verification/element_comparator.rb +306 -0
  432. data/lib/lutaml/qea/verification/structure_matcher.rb +287 -0
  433. data/lib/lutaml/qea.rb +226 -0
  434. data/lib/lutaml/sysml/allocate.rb +2 -0
  435. data/lib/lutaml/sysml/allocated.rb +2 -0
  436. data/lib/lutaml/sysml/binding_connector.rb +2 -0
  437. data/lib/lutaml/sysml/block.rb +2 -0
  438. data/lib/lutaml/sysml/constraint_block.rb +2 -0
  439. data/lib/lutaml/sysml/copy.rb +2 -0
  440. data/lib/lutaml/sysml/derive_requirement.rb +2 -0
  441. data/lib/lutaml/sysml/nested_connector_end.rb +2 -0
  442. data/lib/lutaml/sysml/refine.rb +2 -0
  443. data/lib/lutaml/sysml/requirement.rb +2 -0
  444. data/lib/lutaml/sysml/requirement_related.rb +2 -0
  445. data/lib/lutaml/sysml/satisfy.rb +2 -0
  446. data/lib/lutaml/sysml/test_case.rb +2 -0
  447. data/lib/lutaml/sysml/trace.rb +2 -0
  448. data/lib/lutaml/sysml/verify.rb +2 -0
  449. data/lib/lutaml/sysml/xmi_file.rb +2 -0
  450. data/lib/lutaml/sysml.rb +3 -1
  451. data/lib/lutaml/uml/association.rb +4 -0
  452. data/lib/lutaml/uml/class.rb +11 -9
  453. data/lib/lutaml/uml/classifier.rb +3 -0
  454. data/lib/lutaml/uml/comment.rb +13 -0
  455. data/lib/lutaml/uml/data_type.rb +7 -6
  456. data/lib/lutaml/uml/diagram.rb +12 -0
  457. data/lib/lutaml/uml/diagram_link.rb +26 -0
  458. data/lib/lutaml/uml/diagram_object.rb +30 -0
  459. data/lib/lutaml/uml/document.rb +18 -0
  460. data/lib/lutaml/uml/enum.rb +4 -3
  461. data/lib/lutaml/uml/fontname.rb +13 -0
  462. data/lib/lutaml/uml/generalization.rb +2 -0
  463. data/lib/lutaml/uml/group.rb +2 -0
  464. data/lib/lutaml/uml/namespace.rb +2 -2
  465. data/lib/lutaml/uml/node/{field.rb → attribute.rb} +4 -4
  466. data/lib/lutaml/uml/node/base.rb +1 -1
  467. data/lib/lutaml/uml/node/class_node.rb +12 -12
  468. data/lib/lutaml/uml/node/class_relationship.rb +2 -2
  469. data/lib/lutaml/uml/node/document.rb +2 -2
  470. data/lib/lutaml/uml/node/method_argument.rb +3 -3
  471. data/lib/lutaml/uml/node/{method.rb → operation.rb} +4 -4
  472. data/lib/lutaml/uml/node/relationship.rb +3 -3
  473. data/lib/lutaml/uml/package.rb +7 -4
  474. data/lib/lutaml/uml/package_path.rb +235 -0
  475. data/lib/lutaml/uml/parsers/attribute.rb +2 -2
  476. data/lib/lutaml/uml/parsers/dsl.rb +3 -4
  477. data/lib/lutaml/uml/parsers/yaml.rb +1 -1
  478. data/lib/lutaml/uml/qualified_name.rb +178 -0
  479. data/lib/lutaml/uml/tagged_value.rb +21 -0
  480. data/lib/lutaml/uml/top_element.rb +7 -1
  481. data/lib/lutaml/uml/top_element_attribute.rb +4 -0
  482. data/lib/lutaml/uml/validation/document_structure_validator.rb +389 -0
  483. data/lib/lutaml/uml.rb +89 -45
  484. data/lib/lutaml/uml_repository/error_handler.rb +203 -0
  485. data/lib/lutaml/uml_repository/exporters/base_exporter.rb +61 -0
  486. data/lib/lutaml/uml_repository/exporters/json_exporter.rb +344 -0
  487. data/lib/lutaml/uml_repository/exporters/markdown_exporter.rb +598 -0
  488. data/lib/lutaml/uml_repository/index_builder.rb +460 -0
  489. data/lib/lutaml/uml_repository/lazy_repository.rb +238 -0
  490. data/lib/lutaml/uml_repository/package_exporter.rb +336 -0
  491. data/lib/lutaml/uml_repository/package_loader.rb +220 -0
  492. data/lib/lutaml/uml_repository/package_metadata.rb +77 -0
  493. data/lib/lutaml/uml_repository/presenters/association_presenter.rb +86 -0
  494. data/lib/lutaml/uml_repository/presenters/attribute_presenter.rb +101 -0
  495. data/lib/lutaml/uml_repository/presenters/class_presenter.rb +75 -0
  496. data/lib/lutaml/uml_repository/presenters/datatype_presenter.rb +108 -0
  497. data/lib/lutaml/uml_repository/presenters/diagram_presenter.rb +508 -0
  498. data/lib/lutaml/uml_repository/presenters/element_presenter.rb +92 -0
  499. data/lib/lutaml/uml_repository/presenters/enum_presenter.rb +83 -0
  500. data/lib/lutaml/uml_repository/presenters/package_presenter.rb +48 -0
  501. data/lib/lutaml/uml_repository/presenters/presenter_factory.rb +76 -0
  502. data/lib/lutaml/uml_repository/queries/association_query.rb +187 -0
  503. data/lib/lutaml/uml_repository/queries/base_query.rb +45 -0
  504. data/lib/lutaml/uml_repository/queries/class_query.rb +117 -0
  505. data/lib/lutaml/uml_repository/queries/diagram_query.rb +111 -0
  506. data/lib/lutaml/uml_repository/queries/inheritance_query.rb +259 -0
  507. data/lib/lutaml/uml_repository/queries/package_query.rb +239 -0
  508. data/lib/lutaml/uml_repository/queries/search_query.rb +357 -0
  509. data/lib/lutaml/uml_repository/query_dsl/conditions/base_condition.rb +28 -0
  510. data/lib/lutaml/uml_repository/query_dsl/conditions/block_condition.rb +46 -0
  511. data/lib/lutaml/uml_repository/query_dsl/conditions/hash_condition.rb +84 -0
  512. data/lib/lutaml/uml_repository/query_dsl/conditions/package_condition.rb +84 -0
  513. data/lib/lutaml/uml_repository/query_dsl/order.rb +90 -0
  514. data/lib/lutaml/uml_repository/query_dsl/query_builder.rb +296 -0
  515. data/lib/lutaml/uml_repository/repository.rb +764 -0
  516. data/lib/lutaml/uml_repository/repository_enhanced.rb +439 -0
  517. data/lib/lutaml/uml_repository/search_result.rb +86 -0
  518. data/lib/lutaml/uml_repository/static_site/configuration.rb +270 -0
  519. data/lib/lutaml/uml_repository/static_site/data_transformer.rb +967 -0
  520. data/lib/lutaml/uml_repository/static_site/generator.rb +401 -0
  521. data/lib/lutaml/uml_repository/static_site/id_generator.rb +115 -0
  522. data/lib/lutaml/uml_repository/static_site/search_index_builder.rb +317 -0
  523. data/lib/lutaml/uml_repository/static_site.rb +88 -0
  524. data/lib/lutaml/uml_repository/statistics_calculator.rb +334 -0
  525. data/lib/lutaml/uml_repository/validators/repository_validator.rb +404 -0
  526. data/lib/lutaml/uml_repository/web_ui/app.rb +144 -0
  527. data/lib/lutaml/uml_repository/web_ui/public/app.js +452 -0
  528. data/lib/lutaml/uml_repository/web_ui/public/styles.css +381 -0
  529. data/lib/lutaml/uml_repository/web_ui/views/index.erb +40 -0
  530. data/lib/lutaml/uml_repository.rb +97 -0
  531. data/lib/lutaml/version.rb +3 -1
  532. data/lib/lutaml/xmi/liquid_drops/association_drop.rb +60 -58
  533. data/lib/lutaml/xmi/liquid_drops/attribute_drop.rb +55 -53
  534. data/lib/lutaml/xmi/liquid_drops/cardinality_drop.rb +15 -13
  535. data/lib/lutaml/xmi/liquid_drops/connector_drop.rb +50 -46
  536. data/lib/lutaml/xmi/liquid_drops/constraint_drop.rb +19 -17
  537. data/lib/lutaml/xmi/liquid_drops/data_type_drop.rb +93 -90
  538. data/lib/lutaml/xmi/liquid_drops/dependency_drop.rb +26 -24
  539. data/lib/lutaml/xmi/liquid_drops/diagram_drop.rb +26 -24
  540. data/lib/lutaml/xmi/liquid_drops/enum_drop.rb +40 -37
  541. data/lib/lutaml/xmi/liquid_drops/enum_owned_literal_drop.rb +20 -18
  542. data/lib/lutaml/xmi/liquid_drops/generalization_attribute_drop.rb +64 -62
  543. data/lib/lutaml/xmi/liquid_drops/generalization_drop.rb +142 -140
  544. data/lib/lutaml/xmi/liquid_drops/klass_drop.rb +174 -170
  545. data/lib/lutaml/xmi/liquid_drops/operation_drop.rb +23 -21
  546. data/lib/lutaml/xmi/liquid_drops/package_drop.rb +95 -93
  547. data/lib/lutaml/xmi/liquid_drops/root_drop.rb +28 -25
  548. data/lib/lutaml/xmi/liquid_drops/source_target_drop.rb +39 -37
  549. data/lib/lutaml/xmi/parsers/xmi_base.rb +27 -17
  550. data/lib/lutaml/xmi/parsers/xml.rb +9 -9
  551. data/lib/lutaml/xmi.rb +37 -6
  552. data/lib/lutaml/xml/parsers/xml.rb +3 -1
  553. data/lib/lutaml/xml.rb +3 -1
  554. data/lib/lutaml.rb +14 -2
  555. data/lutaml.gemspec +16 -8
  556. data/plateau_all_packages.lur +0 -0
  557. data/templates/static_site/assets/scripts/app.js +45 -0
  558. data/templates/static_site/assets/scripts/core/state.js +419 -0
  559. data/templates/static_site/assets/scripts/core/utils.js +133 -0
  560. data/templates/static_site/assets/scripts/ui/details.js +74 -0
  561. data/templates/static_site/assets/scripts/ui/diagrams.js +345 -0
  562. data/templates/static_site/assets/scripts/ui/search.js +187 -0
  563. data/templates/static_site/assets/scripts/ui/sidebar.js +214 -0
  564. data/templates/static_site/assets/styles/00-variables.css +144 -0
  565. data/templates/static_site/assets/styles/01-reset.css +79 -0
  566. data/templates/static_site/assets/styles/02-base.css +149 -0
  567. data/templates/static_site/assets/styles/03-layout.css +171 -0
  568. data/templates/static_site/assets/styles/04-components.css +856 -0
  569. data/templates/static_site/assets/styles/05-utilities.css +89 -0
  570. data/templates/static_site/assets/styles/06-diagrams.css +277 -0
  571. data/templates/static_site/components/class_details.liquid +328 -0
  572. data/templates/static_site/components/content.liquid +508 -0
  573. data/templates/static_site/components/diagram_list.liquid +52 -0
  574. data/templates/static_site/components/diagram_viewer.liquid +71 -0
  575. data/templates/static_site/components/header.liquid +134 -0
  576. data/templates/static_site/components/package_details.liquid +119 -0
  577. data/templates/static_site/components/sidebar.liquid +46 -0
  578. data/templates/static_site/components/tree_node.liquid +81 -0
  579. data/templates/static_site/multi_file.liquid +46 -0
  580. data/templates/static_site/single_file.liquid +52 -0
  581. metadata +604 -31
  582. data/CODE_OF_CONDUCT.md +0 -74
  583. data/docs/lutaml-sysml.adoc +0 -10
@@ -0,0 +1,911 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "readline"
4
+ require "pathname"
5
+ require_relative "enhanced_formatter"
6
+ require_relative "../uml_repository/repository"
7
+
8
+ module Lutaml
9
+ module Cli
10
+ # InteractiveShell provides a full-featured REPL for
11
+ # exploring UML repositories
12
+ #
13
+ # Features:
14
+ # - Readline integration with history
15
+ # - Tab completion for commands and paths
16
+ # - Colorized prompts and output
17
+ # - Navigation commands (cd, pwd, ls, tree, up, root, back)
18
+ # - Query commands (find, show, search)
19
+ # - Bookmark management
20
+ # - Results management
21
+ # - Command history persistence
22
+ class InteractiveShell
23
+ HISTORY_FILE = File.expand_path("~/.lutaml-xmi-history")
24
+ MAX_HISTORY = 1000
25
+
26
+ attr_reader :repository, :current_path, :config, :bookmarks,
27
+ :last_results, :path_history
28
+
29
+ # Initialize the interactive shell
30
+ #
31
+ # @param lur_path_or_repo [String, UmlRepository] Path to LUR file or
32
+ # repository
33
+ # @param config [Hash] Configuration options
34
+ # @option config [Boolean] :color Enable colored output
35
+ # @option config [Boolean] :icons Enable icons in output
36
+ def initialize(lur_path_or_repo, config: nil) # rubocop:disable Metrics/MethodLength
37
+ @config = {
38
+ color: true,
39
+ icons: true,
40
+ show_counts: true,
41
+ page_size: 50,
42
+ }.merge(config || {})
43
+
44
+ # Load repository
45
+ if lur_path_or_repo.is_a?(String)
46
+ OutputFormatter.progress("Loading repository")
47
+ @repository = Lutaml::UmlRepository::Repository.from_package(lur_path_or_repo)
48
+ OutputFormatter.progress_done
49
+ else
50
+ @repository = lur_path_or_repo
51
+ end
52
+
53
+ # Initialize state
54
+ @current_path = "ModelRoot"
55
+ @bookmarks = {}
56
+ @last_results = nil
57
+ @path_history = ["ModelRoot"]
58
+ @running = false
59
+
60
+ setup_readline
61
+ load_history
62
+ end
63
+
64
+ # Start the REPL loop
65
+ #
66
+ # @return [void]
67
+ def start # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
68
+ @running = true
69
+ display_welcome
70
+
71
+ while @running
72
+ begin
73
+ input = Readline.readline(prompt, true)
74
+
75
+ # Exit on Ctrl+D or nil input
76
+ break if input.nil?
77
+
78
+ # Skip empty lines
79
+ next if input.strip.empty?
80
+
81
+ # Don't save duplicates in history
82
+ if Readline::HISTORY.length > 1 &&
83
+ Readline::HISTORY[-2] == input
84
+ Readline::HISTORY.pop
85
+ end
86
+
87
+ execute_command(input.strip)
88
+ rescue Interrupt
89
+ puts "\nUse 'exit' or 'quit' to exit the shell"
90
+ rescue StandardError => e
91
+ puts OutputFormatter.error("Error: #{e.message}")
92
+ puts e.backtrace.first(3).join("\n") if ENV["DEBUG"]
93
+ end
94
+ end
95
+
96
+ save_history
97
+ puts "\nGoodbye!"
98
+ end
99
+
100
+ private
101
+
102
+ # Generate contextual prompt
103
+ #
104
+ # @return [String] Formatted prompt
105
+ def prompt
106
+ path_display = @current_path == "ModelRoot" ? "/" : "/#{@current_path}"
107
+ prompt_text = "lutaml[#{path_display}]> "
108
+
109
+ if @config[:color] && $stdout.tty?
110
+ OutputFormatter.colorize(prompt_text, :green)
111
+ else
112
+ prompt_text
113
+ end
114
+ end
115
+
116
+ # Setup readline with tab completion and history
117
+ #
118
+ # @return [void]
119
+ def setup_readline
120
+ # Tab completion
121
+ Readline.completion_proc = proc do |word|
122
+ complete_command(word)
123
+ end
124
+
125
+ Readline.completion_append_character = " "
126
+ end
127
+
128
+ # Load command history from file
129
+ #
130
+ # @return [void]
131
+ def load_history
132
+ return unless File.exist?(HISTORY_FILE)
133
+
134
+ File.readlines(HISTORY_FILE).each do |line|
135
+ Readline::HISTORY.push(line.chomp)
136
+ end
137
+ rescue StandardError => e
138
+ # Silently ignore history load errors
139
+ warn "Warning: Could not load history: #{e.message}" if ENV["DEBUG"]
140
+ end
141
+
142
+ # Save command history to file
143
+ #
144
+ # @return [void]
145
+ def save_history
146
+ history_lines = Readline::HISTORY.to_a.last(MAX_HISTORY)
147
+ File.write(HISTORY_FILE, history_lines.join("\n"))
148
+ rescue StandardError => e
149
+ warn "Warning: Could not save history: #{e.message}"
150
+ end
151
+
152
+ # Display welcome message
153
+ #
154
+ # @return [void]
155
+ def display_welcome # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
156
+ puts OutputFormatter.colorize(
157
+ "╔═══════════════════════════════════════╗", :cyan
158
+ )
159
+ puts OutputFormatter.colorize(
160
+ "║ LutaML Interactive Shell (REPL) ║", :cyan
161
+ )
162
+ puts OutputFormatter.colorize(
163
+ "╚═══════════════════════════════════════╝", :cyan
164
+ )
165
+ puts ""
166
+ puts "Type 'help' for available commands, 'exit' to quit"
167
+ puts ""
168
+
169
+ # Show quick stats
170
+ stats = @repository.statistics
171
+ puts "Repository loaded:"
172
+ puts " #{stats[:total_packages]} packages, " \
173
+ "#{stats[:total_classes]} classes"
174
+ puts ""
175
+ end
176
+
177
+ # Execute a command
178
+ #
179
+ # @param input [String] User input
180
+ # @return [void]
181
+ def execute_command(input) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
182
+ parts = input.split(/\s+/)
183
+ command = parts[0].downcase
184
+ args = parts[1..]
185
+
186
+ case command
187
+ # Navigation
188
+ when "cd"
189
+ cmd_cd(args)
190
+ when "pwd"
191
+ cmd_pwd(args)
192
+ when "ls", "list"
193
+ cmd_ls(args)
194
+ when "tree"
195
+ cmd_tree(args)
196
+ when "up"
197
+ cmd_up(args)
198
+ when "root"
199
+ cmd_root(args)
200
+ when "back"
201
+ cmd_back(args)
202
+
203
+ # Query
204
+ when "find", "f"
205
+ cmd_find(args)
206
+ when "show", "s"
207
+ cmd_show(args)
208
+ when "search", "?"
209
+ cmd_search(args)
210
+
211
+ # Bookmarks
212
+ when "bookmark", "bm"
213
+ cmd_bookmark(args)
214
+
215
+ # Results
216
+ when "results"
217
+ cmd_results(args)
218
+ when "export"
219
+ cmd_export(args)
220
+
221
+ # Utilities
222
+ when "help", "h"
223
+ cmd_help(args)
224
+ when "history"
225
+ cmd_history(args)
226
+ when "clear", "cls"
227
+ cmd_clear(args)
228
+ when "config"
229
+ cmd_config(args)
230
+ when "stats"
231
+ cmd_stats(args)
232
+ when "exit", "quit", "q"
233
+ @running = false
234
+
235
+ else
236
+ puts OutputFormatter.warning("Unknown command: #{command}")
237
+ puts "Type 'help' for available commands"
238
+ end
239
+ end
240
+
241
+ # Tab completion for commands
242
+ #
243
+ # @param word [String] Word to complete
244
+ # @return [Array<String>] Completion options
245
+ def complete_command(word)
246
+ commands = %w[
247
+ cd pwd ls list tree up root back
248
+ find show search
249
+ bookmark bm
250
+ results export
251
+ help history clear config stats exit quit
252
+ ]
253
+
254
+ commands.grep(/^#{Regexp.escape(word)}/)
255
+ end
256
+
257
+ # Navigation: Change directory
258
+ #
259
+ # @param args [Array<String>] Command arguments
260
+ # @return [void]
261
+ def cmd_cd(args) # rubocop:disable Metrics/MethodLength
262
+ if args.empty?
263
+ puts OutputFormatter.warning("Usage: cd PATH")
264
+ return
265
+ end
266
+
267
+ path = resolve_path(args[0])
268
+ pkg = @repository.find_package(path)
269
+
270
+ if pkg
271
+ unless @path_history.last == @current_path
272
+ @path_history << @current_path
273
+ end
274
+ @current_path = path
275
+ puts "Changed to: #{path}"
276
+ else
277
+ puts OutputFormatter.error("Package not found: #{path}")
278
+ end
279
+ end
280
+
281
+ # Navigation: Print working directory
282
+ #
283
+ # @param _args [Array<String>] Command arguments (unused)
284
+ # @return [void]
285
+ def cmd_pwd(_args)
286
+ puts @current_path
287
+ end
288
+
289
+ # Navigation: List packages
290
+ #
291
+ # @param args [Array<String>] Command arguments
292
+ # @return [void]
293
+ def cmd_ls(args) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/PerceivedComplexity
294
+ path = args.empty? ? @current_path : resolve_path(args[0])
295
+ recursive = args.include?("-r") || args.include?("--recursive")
296
+
297
+ packages = @repository.list_packages(path, recursive: recursive)
298
+
299
+ if packages.empty?
300
+ puts OutputFormatter.warning("No packages found at #{path}")
301
+ else
302
+ packages.each do |pkg|
303
+ icon = if @config[:icons]
304
+ "#{EnhancedFormatter::ICONS[:package]} "
305
+ else
306
+ ""
307
+ end
308
+ puts "#{icon}#{pkg.name}"
309
+ end
310
+ puts ""
311
+ puts "Total: #{packages.size} package(s)"
312
+ end
313
+ end
314
+
315
+ # Navigation: Show tree
316
+ #
317
+ # @param args [Array<String>] Command arguments
318
+ # @return [void]
319
+ def cmd_tree(args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
320
+ path = args.empty? ? @current_path : resolve_path(args[0])
321
+
322
+ # Parse depth option
323
+ max_depth = nil
324
+ args.each_with_index do |arg, i|
325
+ if arg == "-d" && args[i + 1]
326
+ max_depth = args[i + 1].to_i
327
+ end
328
+ end
329
+
330
+ tree_data = @repository.package_tree(path, max_depth: max_depth)
331
+
332
+ unless tree_data
333
+ puts OutputFormatter.error("Package not found: #{path}")
334
+ return
335
+ end
336
+
337
+ if @config[:icons]
338
+ puts EnhancedFormatter.format_tree_with_icons(tree_data, @config)
339
+ else
340
+ puts OutputFormatter.format_tree(tree_data)
341
+ end
342
+ end
343
+
344
+ # Navigation: Go up one level
345
+ #
346
+ # @param _args [Array<String>] Command arguments (unused)
347
+ # @return [void]
348
+ def cmd_up(_args) # rubocop:disable Metrics/MethodLength
349
+ if @current_path == "ModelRoot"
350
+ puts OutputFormatter.warning("Already at root")
351
+ return
352
+ end
353
+
354
+ parts = @current_path.split("::")
355
+ parts.pop
356
+ new_path = parts.empty? ? "ModelRoot" : parts.join("::")
357
+
358
+ unless @path_history.last == @current_path
359
+ @path_history << @current_path
360
+ end
361
+ @current_path = new_path
362
+ puts "Changed to: #{@current_path}"
363
+ end
364
+
365
+ # Navigation: Go to root
366
+ #
367
+ # @param _args [Array<String>] Command arguments (unused)
368
+ # @return [void]
369
+ def cmd_root(_args)
370
+ if @current_path == "ModelRoot"
371
+ puts "Already at root"
372
+ else
373
+ unless @path_history.last == @current_path
374
+ @path_history << @current_path
375
+ end
376
+ @current_path = "ModelRoot"
377
+ puts "Changed to: ModelRoot"
378
+ end
379
+ end
380
+
381
+ # Navigation: Go back to previous location
382
+ #
383
+ # @param _args [Array<String>] Command arguments (unused)
384
+ # @return [void]
385
+ def cmd_back(_args)
386
+ if @path_history.size > 1
387
+ @path_history.pop
388
+ @current_path = @path_history.last
389
+ puts "Changed to: #{@current_path}"
390
+ else
391
+ puts OutputFormatter.warning("No previous location")
392
+ end
393
+ end
394
+
395
+ # Query: Find class by name
396
+ #
397
+ # @param args [Array<String>] Command arguments
398
+ # @return [void]
399
+ def cmd_find(args) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
400
+ if args.empty?
401
+ puts OutputFormatter.warning("Usage: find CLASS_NAME")
402
+ return
403
+ end
404
+
405
+ query = args.join(" ")
406
+ results = @repository.search(query, types: [:class])
407
+
408
+ if results[:class].empty?
409
+ puts OutputFormatter.warning("No classes found matching '#{query}'")
410
+ else
411
+ @last_results = results[:class]
412
+
413
+ puts OutputFormatter.colorize(
414
+ "Found #{@last_results.size} class(es):", :cyan
415
+ )
416
+ @last_results.each_with_index do |qname, i|
417
+ puts " #{i + 1}. #{qname}"
418
+ end
419
+ puts ""
420
+ puts "Use 'show NUMBER' to view details"
421
+ end
422
+ end
423
+
424
+ # Query: Show details
425
+ #
426
+ # @param args [Array<String>] Command arguments
427
+ # @return [void]
428
+ def cmd_show(args) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
429
+ if args.empty?
430
+ puts OutputFormatter.warning(
431
+ "Usage: show class QNAME | show package PATH | show NUMBER",
432
+ )
433
+ return
434
+ end
435
+
436
+ subcommand = args[0].downcase
437
+
438
+ case subcommand
439
+ when "class"
440
+ show_class(args[1..].join(" "))
441
+ when "package"
442
+ show_package(args[1..].join(" "))
443
+ when /^\d+$/
444
+ show_numbered_result(subcommand.to_i)
445
+ else
446
+ # Try as class name
447
+ show_class(args.join(" "))
448
+ end
449
+ end
450
+
451
+ # Query: Full-text search
452
+ #
453
+ # @param args [Array<String>] Command arguments
454
+ # @return [void]
455
+ def cmd_search(args) # rubocop:disable Metrics/MethodLength
456
+ if args.empty?
457
+ puts OutputFormatter.warning("Usage: search QUERY")
458
+ return
459
+ end
460
+
461
+ query = args.join(" ")
462
+ results = @repository.search(query)
463
+
464
+ if results.values.all?(&:empty?)
465
+ puts OutputFormatter.warning("No results found for '#{query}'")
466
+ else
467
+ display_search_results(results)
468
+ end
469
+ end
470
+
471
+ # Bookmarks: Manage bookmarks
472
+ #
473
+ # @param args [Array<String>] Command arguments
474
+ # @return [void]
475
+ def cmd_bookmark(args) # rubocop:disable Metrics/MethodLength
476
+ return bookmark_list if args.empty?
477
+
478
+ subcommand = args[0].downcase
479
+
480
+ case subcommand
481
+ when "add"
482
+ bookmark_add(args[1])
483
+ when "list"
484
+ bookmark_list
485
+ when "go"
486
+ bookmark_go(args[1])
487
+ when "rm", "remove"
488
+ bookmark_remove(args[1])
489
+ else
490
+ # Quick jump
491
+ bookmark_go(subcommand)
492
+ end
493
+ end
494
+
495
+ # Results: Show last search results
496
+ #
497
+ # @param _args [Array<String>] Command arguments (unused)
498
+ # @return [void]
499
+ def cmd_results(_args)
500
+ if @last_results.nil? || @last_results.empty?
501
+ puts OutputFormatter.warning("No previous results")
502
+ else
503
+ puts OutputFormatter.colorize(
504
+ "Last results (#{@last_results.size}):", :cyan
505
+ )
506
+ @last_results.each_with_index do |item, i|
507
+ puts " #{i + 1}. #{item}"
508
+ end
509
+ end
510
+ end
511
+
512
+ # Export: Export results
513
+ #
514
+ # @param args [Array<String>] Command arguments
515
+ # @return [void]
516
+ def cmd_export(args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
517
+ if @last_results.nil? || @last_results.empty?
518
+ puts OutputFormatter.warning("No results to export")
519
+ return
520
+ end
521
+
522
+ if args.size < 3 || args[0] != "last"
523
+ puts OutputFormatter.warning("Usage: export last FORMAT FILE")
524
+ return
525
+ end
526
+
527
+ format = args[1].downcase
528
+ file_path = args[2]
529
+
530
+ case format
531
+ when "csv"
532
+ export_csv(file_path)
533
+ when "json"
534
+ export_json(file_path)
535
+ when "yaml"
536
+ export_yaml(file_path)
537
+ else
538
+ puts OutputFormatter.error("Unsupported format: #{format}")
539
+ end
540
+ end
541
+
542
+ # Utilities: Show help
543
+ #
544
+ # @param args [Array<String>] Command arguments
545
+ # @return [void]
546
+ def cmd_help(args)
547
+ if args.empty?
548
+ display_general_help
549
+ else
550
+ display_command_help(args[0])
551
+ end
552
+ end
553
+
554
+ # Utilities: Show command history
555
+ #
556
+ # @param _args [Array<String>] Command arguments (unused)
557
+ # @return [void]
558
+ def cmd_history(_args)
559
+ history = Readline::HISTORY.to_a.last(20)
560
+ history.each_with_index do |line, i|
561
+ puts "#{i + 1}. #{line}"
562
+ end
563
+ end
564
+
565
+ # Utilities: Clear screen
566
+ #
567
+ # @param _args [Array<String>] Command arguments (unused)
568
+ # @return [void]
569
+ def cmd_clear(_args)
570
+ print "\e[2J\e[H"
571
+ end
572
+
573
+ # Utilities: Show configuration
574
+ #
575
+ # @param _args [Array<String>] Command arguments (unused)
576
+ # @return [void]
577
+ def cmd_config(_args)
578
+ puts OutputFormatter.colorize("Current Configuration:", :cyan)
579
+ @config.each do |key, value|
580
+ puts " #{key}: #{value}"
581
+ end
582
+ end
583
+
584
+ # Utilities: Show quick statistics
585
+ #
586
+ # @param _args [Array<String>] Command arguments (unused)
587
+ # @return [void]
588
+ def cmd_stats(_args)
589
+ stats = @repository.statistics
590
+
591
+ if @config[:icons]
592
+ puts EnhancedFormatter.format_stats_enhanced(stats)
593
+ else
594
+ puts OutputFormatter.format_stats(stats, detailed: false)
595
+ end
596
+ end
597
+
598
+ # Show class details
599
+ #
600
+ # @param qname [String] Qualified class name
601
+ # @return [void]
602
+ def show_class(qname) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
603
+ cls = @repository.find_class(qname)
604
+
605
+ unless cls
606
+ puts OutputFormatter.error("Class not found: #{qname}")
607
+ return
608
+ end
609
+
610
+ if @config[:icons]
611
+ puts EnhancedFormatter.format_class_details_enhanced(cls)
612
+ else
613
+ puts OutputFormatter.colorize("Class: #{qname}", :cyan)
614
+ puts "=" * 50
615
+ puts ""
616
+ puts "Name: #{cls.name}"
617
+
618
+ if cls.respond_to?(:attributes) && cls.attributes &&
619
+ !cls.attributes.empty?
620
+ puts ""
621
+ puts OutputFormatter.colorize("Attributes:", :yellow)
622
+ cls.attributes.each do |attr|
623
+ puts " - #{attr.name}: #{attr.type}"
624
+ end
625
+ end
626
+ end
627
+ end
628
+
629
+ # Show package details
630
+ #
631
+ # @param path [String] Package path
632
+ # @return [void]
633
+ def show_package(path) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
634
+ path = resolve_path(path)
635
+ pkg = @repository.find_package(path)
636
+
637
+ unless pkg
638
+ puts OutputFormatter.error("Package not found: #{path}")
639
+ return
640
+ end
641
+
642
+ puts OutputFormatter.colorize("Package: #{path}", :cyan)
643
+ puts "=" * 50
644
+ puts ""
645
+ puts "Name: #{pkg.name}"
646
+ puts ""
647
+
648
+ classes = @repository.classes_in_package(path)
649
+ puts OutputFormatter.colorize("Classes (#{classes.size}):", :yellow)
650
+ classes.each do |cls|
651
+ icon = @config[:icons] ? "#{EnhancedFormatter::ICONS[:class]} " : ""
652
+ puts " #{icon}#{cls.name}"
653
+ end
654
+ end
655
+
656
+ # Show numbered result from last search
657
+ #
658
+ # @param number [Integer] Result number (1-indexed)
659
+ # @return [void]
660
+ def show_numbered_result(number) # rubocop:disable Metrics/MethodLength
661
+ if @last_results.nil? || @last_results.empty?
662
+ puts OutputFormatter.warning("No previous results")
663
+ return
664
+ end
665
+
666
+ index = number - 1
667
+ if index.negative? || index >= @last_results.size
668
+ puts OutputFormatter.error("Invalid result number: #{number}")
669
+ return
670
+ end
671
+
672
+ item = @last_results[index]
673
+ show_class(item)
674
+ end
675
+
676
+ # Display search results
677
+ #
678
+ # @param results [Hash] Search results by type
679
+ # @return [void]
680
+ def display_search_results(results) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
681
+ results.each do |type, items| # rubocop:disable Metrics/BlockLength
682
+ next if items.empty?
683
+
684
+ puts ""
685
+ puts OutputFormatter.colorize(
686
+ "#{type.to_s.capitalize} Results (#{items.size}):", :cyan
687
+ )
688
+
689
+ case type
690
+ when :class
691
+ @last_results = items
692
+ items.each_with_index do |qname, i|
693
+ icon = if @config[:icons]
694
+ "#{EnhancedFormatter::ICONS[:class]} "
695
+ else
696
+ ""
697
+ end
698
+ puts " #{i + 1}. #{icon}#{qname}"
699
+ end
700
+ puts ""
701
+ puts "Use 'show NUMBER' to view details"
702
+ when :attribute
703
+ items.each do |item|
704
+ puts " - #{item[:class_name]}::#{item[:attribute_name]} : " \
705
+ "#{item[:type]}"
706
+ end
707
+ when :association
708
+ items.each do |item|
709
+ icon = if @config[:icons]
710
+ "#{EnhancedFormatter::ICONS[:association]} "
711
+ else
712
+ ""
713
+ end
714
+ puts " #{icon}#{item[:source]} → #{item[:target]}"
715
+ end
716
+ end
717
+ end
718
+ end
719
+
720
+ # Add bookmark
721
+ #
722
+ # @param name [String] Bookmark name
723
+ # @return [void]
724
+ def bookmark_add(name)
725
+ if name.nil? || name.empty?
726
+ puts OutputFormatter.warning("Usage: bookmark add NAME")
727
+ return
728
+ end
729
+
730
+ target = @last_results&.first || @current_path
731
+ @bookmarks[name] = target
732
+ puts OutputFormatter.success("Bookmark '#{name}' added: #{target}")
733
+ end
734
+
735
+ # List bookmarks
736
+ #
737
+ # @return [void]
738
+ def bookmark_list # rubocop:disable Metrics/MethodLength
739
+ if @bookmarks.empty?
740
+ puts "No bookmarks"
741
+ else
742
+ puts OutputFormatter.colorize("Bookmarks:", :cyan)
743
+ @bookmarks.each do |name, target|
744
+ icon = if @config[:icons]
745
+ "#{EnhancedFormatter::ICONS[:favorite]} "
746
+ else
747
+ ""
748
+ end
749
+ puts " #{icon}#{name} → #{target}"
750
+ end
751
+ end
752
+ end
753
+
754
+ # Jump to bookmark
755
+ #
756
+ # @param name [String] Bookmark name
757
+ # @return [void]
758
+ def bookmark_go(name) # rubocop:disable Metrics/MethodLength
759
+ unless @bookmarks.key?(name)
760
+ puts OutputFormatter.error("Bookmark not found: #{name}")
761
+ return
762
+ end
763
+
764
+ target = @bookmarks[name]
765
+ if @repository.find_package(target)
766
+ unless @path_history.last == @current_path
767
+ @path_history << @current_path
768
+ end
769
+ @current_path = target
770
+ puts "Changed to: #{target}"
771
+ else
772
+ puts OutputFormatter.warning(
773
+ "Bookmark target no longer exists: #{target}",
774
+ )
775
+ end
776
+ end
777
+
778
+ # Remove bookmark
779
+ #
780
+ # @param name [String] Bookmark name
781
+ # @return [void]
782
+ def bookmark_remove(name)
783
+ if @bookmarks.delete(name)
784
+ puts OutputFormatter.success("Bookmark '#{name}' removed")
785
+ else
786
+ puts OutputFormatter.error("Bookmark not found: #{name}")
787
+ end
788
+ end
789
+
790
+ # Export results to CSV
791
+ #
792
+ # @param file_path [String] Output file path
793
+ # @return [void]
794
+ def export_csv(file_path)
795
+ require "csv"
796
+
797
+ CSV.open(file_path, "w") do |csv|
798
+ csv << ["Qualified Name"]
799
+ @last_results.each do |qname|
800
+ csv << [qname]
801
+ end
802
+ end
803
+
804
+ puts OutputFormatter.success("Exported #{@last_results.size} " \
805
+ "results to #{file_path}")
806
+ end
807
+
808
+ # Export results to JSON
809
+ #
810
+ # @param file_path [String] Output file path
811
+ # @return [void]
812
+ def export_json(file_path)
813
+ require "json"
814
+
815
+ File.write(file_path, JSON.pretty_generate(@last_results))
816
+ puts OutputFormatter.success("Exported #{@last_results.size} " \
817
+ "results to #{file_path}")
818
+ end
819
+
820
+ # Export results to YAML
821
+ #
822
+ # @param file_path [String] Output file path
823
+ # @return [void]
824
+ def export_yaml(file_path)
825
+ require "yaml"
826
+
827
+ File.write(file_path, @last_results.to_yaml)
828
+ puts OutputFormatter.success("Exported #{@last_results.size} " \
829
+ "results to #{file_path}")
830
+ end
831
+
832
+ # Display general help
833
+ #
834
+ # @return [void]
835
+ def display_general_help # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
836
+ puts OutputFormatter.colorize("Available Commands:", :cyan)
837
+ puts ""
838
+
839
+ puts OutputFormatter.colorize("Navigation:", :yellow)
840
+ puts " cd PATH Change to package path"
841
+ puts " pwd Print current path"
842
+ puts " ls [PATH] List packages"
843
+ puts " tree [PATH] Show package tree"
844
+ puts " up Go to parent package"
845
+ puts " root Go to ModelRoot"
846
+ puts " back Go to previous location"
847
+ puts ""
848
+
849
+ puts OutputFormatter.colorize("Query:", :yellow)
850
+ puts " find CLASS Find class (fuzzy search)"
851
+ puts " show class QNAME Show class details"
852
+ puts " show package PATH Show package details"
853
+ puts " show NUMBER Show numbered result"
854
+ puts " search QUERY Full-text search"
855
+ puts " ? QUERY Alias for search"
856
+ puts ""
857
+
858
+ puts OutputFormatter.colorize("Bookmarks:", :yellow)
859
+ puts " bookmark add NAME Bookmark current location"
860
+ puts " bookmark list List bookmarks"
861
+ puts " bookmark go NAME Jump to bookmark"
862
+ puts " bookmark rm NAME Remove bookmark"
863
+ puts " bm NAME Quick jump"
864
+ puts ""
865
+
866
+ puts OutputFormatter.colorize("Utilities:", :yellow)
867
+ puts " help [COMMAND] Show help"
868
+ puts " history Show command history"
869
+ puts " clear Clear screen"
870
+ puts " config Show configuration"
871
+ puts " stats Show statistics"
872
+ puts " exit, quit, q Exit shell"
873
+ end
874
+
875
+ # Display command-specific help
876
+ #
877
+ # @param command [String] Command name
878
+ # @return [void]
879
+ def display_command_help(command)
880
+ # Command-specific help would go here
881
+ puts "Help for '#{command}' not yet implemented"
882
+ puts "Use 'help' for general help"
883
+ end
884
+
885
+ # Resolve path relative to current location
886
+ #
887
+ # @param path [String] Path to resolve
888
+ # @return [String] Resolved path
889
+ def resolve_path(path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
890
+ return path if path.start_with?("ModelRoot")
891
+ return @current_path if path == "."
892
+ return "ModelRoot" if path == "/"
893
+
894
+ if path.start_with?("../")
895
+ # Go up and then navigate
896
+ parts = @current_path.split("::")
897
+ path.scan("../").each { parts.pop }
898
+ remaining = path.gsub(/^(\.\.\/)+/, "")
899
+ new_path = parts + remaining.split("/")
900
+ new_path.join("::")
901
+ elsif path.start_with?("./")
902
+ # Relative to current
903
+ "#{@current_path}::#{path[2..]}"
904
+ else
905
+ # Append to current
906
+ @current_path == "ModelRoot" ? path : "#{@current_path}::#{path}"
907
+ end
908
+ end
909
+ end
910
+ end
911
+ end