jsduck 0.6.1 → 2.0.pre

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 (453) hide show
  1. data/.gitignore +4 -0
  2. data/README.md +35 -13
  3. data/Rakefile +129 -0
  4. data/bin/jsduck +112 -20
  5. data/jsduck.gemspec +10 -7
  6. data/lib/jsduck/aggregator.rb +46 -20
  7. data/lib/jsduck/aliases.rb +39 -0
  8. data/lib/jsduck/app.rb +123 -51
  9. data/lib/jsduck/categories.rb +132 -0
  10. data/lib/jsduck/class.rb +71 -18
  11. data/lib/jsduck/doc_formatter.rb +61 -26
  12. data/lib/jsduck/doc_parser.rb +53 -2
  13. data/lib/jsduck/exporter.rb +14 -15
  14. data/lib/jsduck/guides.rb +110 -0
  15. data/lib/jsduck/js_parser.rb +18 -4
  16. data/lib/jsduck/jsonp.rb +17 -0
  17. data/lib/jsduck/logger.rb +36 -0
  18. data/lib/jsduck/merger.rb +69 -51
  19. data/lib/jsduck/page.rb +1 -1
  20. data/lib/jsduck/relations.rb +14 -3
  21. data/lib/jsduck/{members.rb → search_data.rb} +3 -28
  22. data/lib/jsduck/source_file.rb +4 -4
  23. data/lib/jsduck/source_writer.rb +2 -2
  24. data/lib/jsduck/timer.rb +6 -2
  25. data/lib/jsduck/tree.rb +29 -16
  26. data/lib/jsduck/tree_icons.rb +1 -1
  27. data/template/README.md +14 -0
  28. data/template/app.js +25 -0
  29. data/template/app/Application.js +53 -0
  30. data/template/app/Favorites.js +88 -0
  31. data/template/app/History.js +45 -0
  32. data/template/app/LocalStore.js +45 -0
  33. data/template/app/Settings.js +39 -0
  34. data/template/app/Syntax.js +20 -0
  35. data/template/app/controller/Classes.js +301 -0
  36. data/template/app/controller/Search.js +156 -0
  37. data/template/app/model/Favorite.js +11 -0
  38. data/template/app/model/Setting.js +11 -0
  39. data/template/app/store/Favorites.js +7 -0
  40. data/template/app/store/Search.js +14 -0
  41. data/template/app/store/Settings.js +7 -0
  42. data/template/app/view/ClassGrid.js +109 -0
  43. data/template/app/view/HoverMenu.js +59 -0
  44. data/template/app/view/HoverMenuButton.js +147 -0
  45. data/template/app/view/Viewport.js +240 -0
  46. data/template/app/view/cls/Header.js +47 -0
  47. data/template/app/view/cls/Overview.js +415 -0
  48. data/template/app/view/cls/Toolbar.js +199 -0
  49. data/template/app/view/index/Container.js +63 -0
  50. data/template/app/view/search/Dropdown.js +53 -0
  51. data/template/app/view/tree/Tree.js +133 -0
  52. data/template/favicon.ico +0 -0
  53. data/template/index.html +32 -37
  54. data/template/{resources/prettify → prettify}/prettify.css +0 -0
  55. data/template/{resources/prettify → prettify}/prettify.js +0 -0
  56. data/template/resources/images/class-m.png +0 -0
  57. data/template/resources/images/class-sm.png +0 -0
  58. data/template/resources/images/component-m.png +0 -0
  59. data/template/resources/images/configs.png +0 -0
  60. data/template/resources/images/data-package.png +0 -0
  61. data/template/resources/images/doc-m.png +0 -0
  62. data/template/resources/images/drag-bar-center.png +0 -0
  63. data/template/resources/{elbow-end.gif → images/elbow-end.gif} +0 -0
  64. data/template/resources/images/events.png +0 -0
  65. data/template/resources/images/expandcollapse.png +0 -0
  66. data/template/resources/images/guide-icon.png +0 -0
  67. data/template/resources/images/guides.png +0 -0
  68. data/template/resources/images/headBG.png +0 -0
  69. data/template/resources/images/header.gif +0 -0
  70. data/template/resources/images/icon.png +0 -0
  71. data/template/resources/images/icons.png +0 -0
  72. data/template/resources/images/loading-title.png +0 -0
  73. data/template/resources/images/loading.gif +0 -0
  74. data/template/resources/{member-collapsed.gif → images/member-collapsed.gif} +0 -0
  75. data/template/resources/{member-expanded.gif → images/member-expanded.gif} +0 -0
  76. data/template/resources/{member-hover.gif → images/member-hover.gif} +0 -0
  77. data/template/resources/images/methods.png +0 -0
  78. data/template/resources/images/model.png +0 -0
  79. data/template/resources/images/properties.png +0 -0
  80. data/template/resources/images/root-lines.png +0 -0
  81. data/template/resources/images/search-box.png +0 -0
  82. data/template/resources/images/singleton-m.png +0 -0
  83. data/template/resources/images/version-tabs.png +0 -0
  84. data/template/resources/images/x.png +0 -0
  85. data/template/resources/images/x12.png +0 -0
  86. metadata +84 -387
  87. data/lib/jsduck/cfg_table.rb +0 -21
  88. data/lib/jsduck/event_table.rb +0 -33
  89. data/lib/jsduck/inheritance_tree.rb +0 -42
  90. data/lib/jsduck/long_params.rb +0 -30
  91. data/lib/jsduck/method_table.rb +0 -45
  92. data/lib/jsduck/property_table.rb +0 -21
  93. data/lib/jsduck/short_params.rb +0 -24
  94. data/lib/jsduck/table.rb +0 -121
  95. data/template/resources/TabCloseMenu.js +0 -150
  96. data/template/resources/block-bottom.gif +0 -0
  97. data/template/resources/block-top.gif +0 -0
  98. data/template/resources/class.gif +0 -0
  99. data/template/resources/cmp.gif +0 -0
  100. data/template/resources/collapse-all.gif +0 -0
  101. data/template/resources/config.gif +0 -0
  102. data/template/resources/css/ext-all.css +0 -6993
  103. data/template/resources/css/xtheme-gray.css +0 -1654
  104. data/template/resources/docs.css +0 -361
  105. data/template/resources/docs.gif +0 -0
  106. data/template/resources/docs.js +0 -769
  107. data/template/resources/event.gif +0 -0
  108. data/template/resources/expand-all.gif +0 -0
  109. data/template/resources/expand-bg-over.gif +0 -0
  110. data/template/resources/expand-bg.gif +0 -0
  111. data/template/resources/expand-members.gif +0 -0
  112. data/template/resources/ext-all.js +0 -11
  113. data/template/resources/ext-base.js +0 -7
  114. data/template/resources/extanim32.gif +0 -0
  115. data/template/resources/fav.gif +0 -0
  116. data/template/resources/favicon.ico +0 -0
  117. data/template/resources/hd-bg.png +0 -0
  118. data/template/resources/hide-inherited.gif +0 -0
  119. data/template/resources/images/default/box/corners-blue.gif +0 -0
  120. data/template/resources/images/default/box/corners.gif +0 -0
  121. data/template/resources/images/default/box/l-blue.gif +0 -0
  122. data/template/resources/images/default/box/l.gif +0 -0
  123. data/template/resources/images/default/box/r-blue.gif +0 -0
  124. data/template/resources/images/default/box/r.gif +0 -0
  125. data/template/resources/images/default/box/tb-blue.gif +0 -0
  126. data/template/resources/images/default/box/tb.gif +0 -0
  127. data/template/resources/images/default/button/arrow.gif +0 -0
  128. data/template/resources/images/default/button/btn.gif +0 -0
  129. data/template/resources/images/default/button/group-cs.gif +0 -0
  130. data/template/resources/images/default/button/group-lr.gif +0 -0
  131. data/template/resources/images/default/button/group-tb.gif +0 -0
  132. data/template/resources/images/default/button/s-arrow-b-noline.gif +0 -0
  133. data/template/resources/images/default/button/s-arrow-b.gif +0 -0
  134. data/template/resources/images/default/button/s-arrow-bo.gif +0 -0
  135. data/template/resources/images/default/button/s-arrow-noline.gif +0 -0
  136. data/template/resources/images/default/button/s-arrow-o.gif +0 -0
  137. data/template/resources/images/default/button/s-arrow.gif +0 -0
  138. data/template/resources/images/default/dd/drop-add.gif +0 -0
  139. data/template/resources/images/default/dd/drop-no.gif +0 -0
  140. data/template/resources/images/default/dd/drop-yes.gif +0 -0
  141. data/template/resources/images/default/editor/tb-sprite.gif +0 -0
  142. data/template/resources/images/default/form/checkbox.gif +0 -0
  143. data/template/resources/images/default/form/clear-trigger.gif +0 -0
  144. data/template/resources/images/default/form/clear-trigger.psd +0 -0
  145. data/template/resources/images/default/form/date-trigger.gif +0 -0
  146. data/template/resources/images/default/form/date-trigger.psd +0 -0
  147. data/template/resources/images/default/form/error-tip-corners.gif +0 -0
  148. data/template/resources/images/default/form/exclamation.gif +0 -0
  149. data/template/resources/images/default/form/radio.gif +0 -0
  150. data/template/resources/images/default/form/search-trigger.gif +0 -0
  151. data/template/resources/images/default/form/search-trigger.psd +0 -0
  152. data/template/resources/images/default/form/text-bg.gif +0 -0
  153. data/template/resources/images/default/form/trigger-square.gif +0 -0
  154. data/template/resources/images/default/form/trigger-square.psd +0 -0
  155. data/template/resources/images/default/form/trigger-tpl.gif +0 -0
  156. data/template/resources/images/default/form/trigger.gif +0 -0
  157. data/template/resources/images/default/form/trigger.psd +0 -0
  158. data/template/resources/images/default/gradient-bg.gif +0 -0
  159. data/template/resources/images/default/grid/arrow-left-white.gif +0 -0
  160. data/template/resources/images/default/grid/arrow-right-white.gif +0 -0
  161. data/template/resources/images/default/grid/col-move-bottom.gif +0 -0
  162. data/template/resources/images/default/grid/col-move-top.gif +0 -0
  163. data/template/resources/images/default/grid/columns.gif +0 -0
  164. data/template/resources/images/default/grid/dirty.gif +0 -0
  165. data/template/resources/images/default/grid/done.gif +0 -0
  166. data/template/resources/images/default/grid/drop-no.gif +0 -0
  167. data/template/resources/images/default/grid/drop-yes.gif +0 -0
  168. data/template/resources/images/default/grid/footer-bg.gif +0 -0
  169. data/template/resources/images/default/grid/grid-blue-hd.gif +0 -0
  170. data/template/resources/images/default/grid/grid-blue-split.gif +0 -0
  171. data/template/resources/images/default/grid/grid-hrow.gif +0 -0
  172. data/template/resources/images/default/grid/grid-loading.gif +0 -0
  173. data/template/resources/images/default/grid/grid-split.gif +0 -0
  174. data/template/resources/images/default/grid/grid-vista-hd.gif +0 -0
  175. data/template/resources/images/default/grid/grid3-hd-btn.gif +0 -0
  176. data/template/resources/images/default/grid/grid3-hrow-over.gif +0 -0
  177. data/template/resources/images/default/grid/grid3-hrow.gif +0 -0
  178. data/template/resources/images/default/grid/grid3-special-col-bg.gif +0 -0
  179. data/template/resources/images/default/grid/grid3-special-col-sel-bg.gif +0 -0
  180. data/template/resources/images/default/grid/group-by.gif +0 -0
  181. data/template/resources/images/default/grid/group-collapse.gif +0 -0
  182. data/template/resources/images/default/grid/group-expand-sprite.gif +0 -0
  183. data/template/resources/images/default/grid/group-expand.gif +0 -0
  184. data/template/resources/images/default/grid/hd-pop.gif +0 -0
  185. data/template/resources/images/default/grid/hmenu-asc.gif +0 -0
  186. data/template/resources/images/default/grid/hmenu-desc.gif +0 -0
  187. data/template/resources/images/default/grid/hmenu-lock.gif +0 -0
  188. data/template/resources/images/default/grid/hmenu-lock.png +0 -0
  189. data/template/resources/images/default/grid/hmenu-unlock.gif +0 -0
  190. data/template/resources/images/default/grid/hmenu-unlock.png +0 -0
  191. data/template/resources/images/default/grid/invalid_line.gif +0 -0
  192. data/template/resources/images/default/grid/loading.gif +0 -0
  193. data/template/resources/images/default/grid/mso-hd.gif +0 -0
  194. data/template/resources/images/default/grid/nowait.gif +0 -0
  195. data/template/resources/images/default/grid/page-first-disabled.gif +0 -0
  196. data/template/resources/images/default/grid/page-first.gif +0 -0
  197. data/template/resources/images/default/grid/page-last-disabled.gif +0 -0
  198. data/template/resources/images/default/grid/page-last.gif +0 -0
  199. data/template/resources/images/default/grid/page-next-disabled.gif +0 -0
  200. data/template/resources/images/default/grid/page-next.gif +0 -0
  201. data/template/resources/images/default/grid/page-prev-disabled.gif +0 -0
  202. data/template/resources/images/default/grid/page-prev.gif +0 -0
  203. data/template/resources/images/default/grid/pick-button.gif +0 -0
  204. data/template/resources/images/default/grid/refresh.gif +0 -0
  205. data/template/resources/images/default/grid/row-check-sprite.gif +0 -0
  206. data/template/resources/images/default/grid/row-expand-sprite.gif +0 -0
  207. data/template/resources/images/default/grid/row-over.gif +0 -0
  208. data/template/resources/images/default/grid/row-sel.gif +0 -0
  209. data/template/resources/images/default/grid/sort-hd.gif +0 -0
  210. data/template/resources/images/default/grid/sort_asc.gif +0 -0
  211. data/template/resources/images/default/grid/sort_desc.gif +0 -0
  212. data/template/resources/images/default/grid/wait.gif +0 -0
  213. data/template/resources/images/default/layout/collapse.gif +0 -0
  214. data/template/resources/images/default/layout/expand.gif +0 -0
  215. data/template/resources/images/default/layout/gradient-bg.gif +0 -0
  216. data/template/resources/images/default/layout/mini-bottom.gif +0 -0
  217. data/template/resources/images/default/layout/mini-left.gif +0 -0
  218. data/template/resources/images/default/layout/mini-right.gif +0 -0
  219. data/template/resources/images/default/layout/mini-top.gif +0 -0
  220. data/template/resources/images/default/layout/ns-collapse.gif +0 -0
  221. data/template/resources/images/default/layout/ns-expand.gif +0 -0
  222. data/template/resources/images/default/layout/panel-close.gif +0 -0
  223. data/template/resources/images/default/layout/panel-title-bg.gif +0 -0
  224. data/template/resources/images/default/layout/panel-title-light-bg.gif +0 -0
  225. data/template/resources/images/default/layout/stick.gif +0 -0
  226. data/template/resources/images/default/layout/stuck.gif +0 -0
  227. data/template/resources/images/default/layout/tab-close-on.gif +0 -0
  228. data/template/resources/images/default/layout/tab-close.gif +0 -0
  229. data/template/resources/images/default/menu/checked.gif +0 -0
  230. data/template/resources/images/default/menu/group-checked.gif +0 -0
  231. data/template/resources/images/default/menu/item-over.gif +0 -0
  232. data/template/resources/images/default/menu/menu-parent.gif +0 -0
  233. data/template/resources/images/default/menu/menu.gif +0 -0
  234. data/template/resources/images/default/menu/unchecked.gif +0 -0
  235. data/template/resources/images/default/panel/corners-sprite.gif +0 -0
  236. data/template/resources/images/default/panel/left-right.gif +0 -0
  237. data/template/resources/images/default/panel/light-hd.gif +0 -0
  238. data/template/resources/images/default/panel/tool-sprite-tpl.gif +0 -0
  239. data/template/resources/images/default/panel/tool-sprites.gif +0 -0
  240. data/template/resources/images/default/panel/tools-sprites-trans.gif +0 -0
  241. data/template/resources/images/default/panel/top-bottom.gif +0 -0
  242. data/template/resources/images/default/panel/top-bottom.png +0 -0
  243. data/template/resources/images/default/panel/white-corners-sprite.gif +0 -0
  244. data/template/resources/images/default/panel/white-left-right.gif +0 -0
  245. data/template/resources/images/default/panel/white-top-bottom.gif +0 -0
  246. data/template/resources/images/default/progress/progress-bg.gif +0 -0
  247. data/template/resources/images/default/qtip/bg.gif +0 -0
  248. data/template/resources/images/default/qtip/close.gif +0 -0
  249. data/template/resources/images/default/qtip/tip-anchor-sprite.gif +0 -0
  250. data/template/resources/images/default/qtip/tip-sprite.gif +0 -0
  251. data/template/resources/images/default/s.gif +0 -0
  252. data/template/resources/images/default/shadow-c.png +0 -0
  253. data/template/resources/images/default/shadow-lr.png +0 -0
  254. data/template/resources/images/default/shadow.png +0 -0
  255. data/template/resources/images/default/shared/blue-loading.gif +0 -0
  256. data/template/resources/images/default/shared/calendar.gif +0 -0
  257. data/template/resources/images/default/shared/glass-bg.gif +0 -0
  258. data/template/resources/images/default/shared/hd-sprite.gif +0 -0
  259. data/template/resources/images/default/shared/large-loading.gif +0 -0
  260. data/template/resources/images/default/shared/left-btn.gif +0 -0
  261. data/template/resources/images/default/shared/loading-balls.gif +0 -0
  262. data/template/resources/images/default/shared/right-btn.gif +0 -0
  263. data/template/resources/images/default/shared/warning.gif +0 -0
  264. data/template/resources/images/default/sizer/e-handle-dark.gif +0 -0
  265. data/template/resources/images/default/sizer/e-handle.gif +0 -0
  266. data/template/resources/images/default/sizer/ne-handle-dark.gif +0 -0
  267. data/template/resources/images/default/sizer/ne-handle.gif +0 -0
  268. data/template/resources/images/default/sizer/nw-handle-dark.gif +0 -0
  269. data/template/resources/images/default/sizer/nw-handle.gif +0 -0
  270. data/template/resources/images/default/sizer/s-handle-dark.gif +0 -0
  271. data/template/resources/images/default/sizer/s-handle.gif +0 -0
  272. data/template/resources/images/default/sizer/se-handle-dark.gif +0 -0
  273. data/template/resources/images/default/sizer/se-handle.gif +0 -0
  274. data/template/resources/images/default/sizer/square.gif +0 -0
  275. data/template/resources/images/default/sizer/sw-handle-dark.gif +0 -0
  276. data/template/resources/images/default/sizer/sw-handle.gif +0 -0
  277. data/template/resources/images/default/slider/slider-bg.png +0 -0
  278. data/template/resources/images/default/slider/slider-thumb.png +0 -0
  279. data/template/resources/images/default/slider/slider-v-bg.png +0 -0
  280. data/template/resources/images/default/slider/slider-v-thumb.png +0 -0
  281. data/template/resources/images/default/tabs/scroll-left.gif +0 -0
  282. data/template/resources/images/default/tabs/scroll-right.gif +0 -0
  283. data/template/resources/images/default/tabs/scroller-bg.gif +0 -0
  284. data/template/resources/images/default/tabs/tab-btm-inactive-left-bg.gif +0 -0
  285. data/template/resources/images/default/tabs/tab-btm-inactive-right-bg.gif +0 -0
  286. data/template/resources/images/default/tabs/tab-btm-left-bg.gif +0 -0
  287. data/template/resources/images/default/tabs/tab-btm-over-left-bg.gif +0 -0
  288. data/template/resources/images/default/tabs/tab-btm-over-right-bg.gif +0 -0
  289. data/template/resources/images/default/tabs/tab-btm-right-bg.gif +0 -0
  290. data/template/resources/images/default/tabs/tab-close.gif +0 -0
  291. data/template/resources/images/default/tabs/tab-strip-bg.gif +0 -0
  292. data/template/resources/images/default/tabs/tab-strip-bg.png +0 -0
  293. data/template/resources/images/default/tabs/tab-strip-btm-bg.gif +0 -0
  294. data/template/resources/images/default/tabs/tabs-sprite.gif +0 -0
  295. data/template/resources/images/default/toolbar/bg.gif +0 -0
  296. data/template/resources/images/default/toolbar/btn-arrow-light.gif +0 -0
  297. data/template/resources/images/default/toolbar/btn-arrow.gif +0 -0
  298. data/template/resources/images/default/toolbar/btn-over-bg.gif +0 -0
  299. data/template/resources/images/default/toolbar/gray-bg.gif +0 -0
  300. data/template/resources/images/default/toolbar/more.gif +0 -0
  301. data/template/resources/images/default/toolbar/tb-bg.gif +0 -0
  302. data/template/resources/images/default/toolbar/tb-btn-sprite.gif +0 -0
  303. data/template/resources/images/default/toolbar/tb-xl-btn-sprite.gif +0 -0
  304. data/template/resources/images/default/toolbar/tb-xl-sep.gif +0 -0
  305. data/template/resources/images/default/tree/arrows.gif +0 -0
  306. data/template/resources/images/default/tree/drop-add.gif +0 -0
  307. data/template/resources/images/default/tree/drop-between.gif +0 -0
  308. data/template/resources/images/default/tree/drop-no.gif +0 -0
  309. data/template/resources/images/default/tree/drop-over.gif +0 -0
  310. data/template/resources/images/default/tree/drop-under.gif +0 -0
  311. data/template/resources/images/default/tree/drop-yes.gif +0 -0
  312. data/template/resources/images/default/tree/elbow-end-minus-nl.gif +0 -0
  313. data/template/resources/images/default/tree/elbow-end-minus.gif +0 -0
  314. data/template/resources/images/default/tree/elbow-end-plus-nl.gif +0 -0
  315. data/template/resources/images/default/tree/elbow-end-plus.gif +0 -0
  316. data/template/resources/images/default/tree/elbow-end.gif +0 -0
  317. data/template/resources/images/default/tree/elbow-line.gif +0 -0
  318. data/template/resources/images/default/tree/elbow-minus-nl.gif +0 -0
  319. data/template/resources/images/default/tree/elbow-minus.gif +0 -0
  320. data/template/resources/images/default/tree/elbow-plus-nl.gif +0 -0
  321. data/template/resources/images/default/tree/elbow-plus.gif +0 -0
  322. data/template/resources/images/default/tree/elbow.gif +0 -0
  323. data/template/resources/images/default/tree/folder-open.gif +0 -0
  324. data/template/resources/images/default/tree/folder.gif +0 -0
  325. data/template/resources/images/default/tree/leaf.gif +0 -0
  326. data/template/resources/images/default/tree/loading.gif +0 -0
  327. data/template/resources/images/default/tree/s.gif +0 -0
  328. data/template/resources/images/default/window/icon-error.gif +0 -0
  329. data/template/resources/images/default/window/icon-info.gif +0 -0
  330. data/template/resources/images/default/window/icon-question.gif +0 -0
  331. data/template/resources/images/default/window/icon-warning.gif +0 -0
  332. data/template/resources/images/default/window/left-corners.png +0 -0
  333. data/template/resources/images/default/window/left-corners.psd +0 -0
  334. data/template/resources/images/default/window/left-right.png +0 -0
  335. data/template/resources/images/default/window/left-right.psd +0 -0
  336. data/template/resources/images/default/window/right-corners.png +0 -0
  337. data/template/resources/images/default/window/right-corners.psd +0 -0
  338. data/template/resources/images/default/window/top-bottom.png +0 -0
  339. data/template/resources/images/default/window/top-bottom.psd +0 -0
  340. data/template/resources/images/gray/button/btn-arrow.gif +0 -0
  341. data/template/resources/images/gray/button/btn-sprite.gif +0 -0
  342. data/template/resources/images/gray/button/btn.gif +0 -0
  343. data/template/resources/images/gray/button/group-cs.gif +0 -0
  344. data/template/resources/images/gray/button/group-lr.gif +0 -0
  345. data/template/resources/images/gray/button/group-tb.gif +0 -0
  346. data/template/resources/images/gray/button/s-arrow-bo.gif +0 -0
  347. data/template/resources/images/gray/button/s-arrow-o.gif +0 -0
  348. data/template/resources/images/gray/form/clear-trigger.gif +0 -0
  349. data/template/resources/images/gray/form/date-trigger.gif +0 -0
  350. data/template/resources/images/gray/form/search-trigger.gif +0 -0
  351. data/template/resources/images/gray/form/trigger-square.gif +0 -0
  352. data/template/resources/images/gray/form/trigger.gif +0 -0
  353. data/template/resources/images/gray/gradient-bg.gif +0 -0
  354. data/template/resources/images/gray/grid/col-move-bottom.gif +0 -0
  355. data/template/resources/images/gray/grid/col-move-top.gif +0 -0
  356. data/template/resources/images/gray/grid/grid3-hd-btn.gif +0 -0
  357. data/template/resources/images/gray/grid/grid3-hrow-over.gif +0 -0
  358. data/template/resources/images/gray/grid/grid3-hrow-over2.gif +0 -0
  359. data/template/resources/images/gray/grid/grid3-hrow.gif +0 -0
  360. data/template/resources/images/gray/grid/grid3-hrow2.gif +0 -0
  361. data/template/resources/images/gray/grid/grid3-special-col-bg.gif +0 -0
  362. data/template/resources/images/gray/grid/grid3-special-col-bg2.gif +0 -0
  363. data/template/resources/images/gray/grid/grid3-special-col-sel-bg.gif +0 -0
  364. data/template/resources/images/gray/grid/group-collapse.gif +0 -0
  365. data/template/resources/images/gray/grid/group-expand-sprite.gif +0 -0
  366. data/template/resources/images/gray/grid/group-expand.gif +0 -0
  367. data/template/resources/images/gray/grid/page-first.gif +0 -0
  368. data/template/resources/images/gray/grid/page-last.gif +0 -0
  369. data/template/resources/images/gray/grid/page-next.gif +0 -0
  370. data/template/resources/images/gray/grid/page-prev.gif +0 -0
  371. data/template/resources/images/gray/grid/refresh.gif +0 -0
  372. data/template/resources/images/gray/grid/row-expand-sprite.gif +0 -0
  373. data/template/resources/images/gray/grid/sort_asc.gif +0 -0
  374. data/template/resources/images/gray/grid/sort_desc.gif +0 -0
  375. data/template/resources/images/gray/menu/group-checked.gif +0 -0
  376. data/template/resources/images/gray/menu/item-over-disabled.gif +0 -0
  377. data/template/resources/images/gray/menu/item-over.gif +0 -0
  378. data/template/resources/images/gray/menu/menu-parent.gif +0 -0
  379. data/template/resources/images/gray/panel/corners-sprite.gif +0 -0
  380. data/template/resources/images/gray/panel/left-right.gif +0 -0
  381. data/template/resources/images/gray/panel/light-hd.gif +0 -0
  382. data/template/resources/images/gray/panel/tool-sprite-tpl.gif +0 -0
  383. data/template/resources/images/gray/panel/tool-sprites.gif +0 -0
  384. data/template/resources/images/gray/panel/tools-sprites-trans.gif +0 -0
  385. data/template/resources/images/gray/panel/top-bottom.gif +0 -0
  386. data/template/resources/images/gray/panel/top-bottom.png +0 -0
  387. data/template/resources/images/gray/panel/white-corners-sprite.gif +0 -0
  388. data/template/resources/images/gray/panel/white-left-right.gif +0 -0
  389. data/template/resources/images/gray/panel/white-top-bottom.gif +0 -0
  390. data/template/resources/images/gray/progress/progress-bg.gif +0 -0
  391. data/template/resources/images/gray/qtip/bg.gif +0 -0
  392. data/template/resources/images/gray/qtip/close.gif +0 -0
  393. data/template/resources/images/gray/qtip/tip-anchor-sprite.gif +0 -0
  394. data/template/resources/images/gray/qtip/tip-sprite.gif +0 -0
  395. data/template/resources/images/gray/s.gif +0 -0
  396. data/template/resources/images/gray/shared/hd-sprite.gif +0 -0
  397. data/template/resources/images/gray/shared/left-btn.gif +0 -0
  398. data/template/resources/images/gray/shared/right-btn.gif +0 -0
  399. data/template/resources/images/gray/sizer/e-handle.gif +0 -0
  400. data/template/resources/images/gray/sizer/ne-handle.gif +0 -0
  401. data/template/resources/images/gray/sizer/nw-handle.gif +0 -0
  402. data/template/resources/images/gray/sizer/s-handle.gif +0 -0
  403. data/template/resources/images/gray/sizer/se-handle.gif +0 -0
  404. data/template/resources/images/gray/sizer/square.gif +0 -0
  405. data/template/resources/images/gray/sizer/sw-handle.gif +0 -0
  406. data/template/resources/images/gray/slider/slider-thumb.png +0 -0
  407. data/template/resources/images/gray/slider/slider-v-thumb.png +0 -0
  408. data/template/resources/images/gray/tabs/scroll-left.gif +0 -0
  409. data/template/resources/images/gray/tabs/scroll-right.gif +0 -0
  410. data/template/resources/images/gray/tabs/scroller-bg.gif +0 -0
  411. data/template/resources/images/gray/tabs/tab-btm-inactive-left-bg.gif +0 -0
  412. data/template/resources/images/gray/tabs/tab-btm-inactive-right-bg.gif +0 -0
  413. data/template/resources/images/gray/tabs/tab-btm-left-bg.gif +0 -0
  414. data/template/resources/images/gray/tabs/tab-btm-over-left-bg.gif +0 -0
  415. data/template/resources/images/gray/tabs/tab-btm-over-right-bg.gif +0 -0
  416. data/template/resources/images/gray/tabs/tab-btm-right-bg.gif +0 -0
  417. data/template/resources/images/gray/tabs/tab-close.gif +0 -0
  418. data/template/resources/images/gray/tabs/tab-strip-bg.gif +0 -0
  419. data/template/resources/images/gray/tabs/tab-strip-bg.png +0 -0
  420. data/template/resources/images/gray/tabs/tab-strip-btm-bg.gif +0 -0
  421. data/template/resources/images/gray/tabs/tabs-sprite.gif +0 -0
  422. data/template/resources/images/gray/toolbar/bg.gif +0 -0
  423. data/template/resources/images/gray/toolbar/btn-arrow-light.gif +0 -0
  424. data/template/resources/images/gray/toolbar/btn-arrow.gif +0 -0
  425. data/template/resources/images/gray/toolbar/btn-over-bg.gif +0 -0
  426. data/template/resources/images/gray/toolbar/gray-bg.gif +0 -0
  427. data/template/resources/images/gray/toolbar/more.gif +0 -0
  428. data/template/resources/images/gray/toolbar/tb-bg.gif +0 -0
  429. data/template/resources/images/gray/toolbar/tb-btn-sprite.gif +0 -0
  430. data/template/resources/images/gray/tree/arrows.gif +0 -0
  431. data/template/resources/images/gray/tree/elbow-end-minus-nl.gif +0 -0
  432. data/template/resources/images/gray/tree/elbow-end-minus.gif +0 -0
  433. data/template/resources/images/gray/tree/elbow-end-plus-nl.gif +0 -0
  434. data/template/resources/images/gray/tree/elbow-end-plus.gif +0 -0
  435. data/template/resources/images/gray/window/icon-error.gif +0 -0
  436. data/template/resources/images/gray/window/icon-info.gif +0 -0
  437. data/template/resources/images/gray/window/icon-question.gif +0 -0
  438. data/template/resources/images/gray/window/icon-warning.gif +0 -0
  439. data/template/resources/images/gray/window/left-corners.png +0 -0
  440. data/template/resources/images/gray/window/left-corners.pspimage +0 -0
  441. data/template/resources/images/gray/window/left-right.png +0 -0
  442. data/template/resources/images/gray/window/right-corners.png +0 -0
  443. data/template/resources/images/gray/window/top-bottom.png +0 -0
  444. data/template/resources/inherited.gif +0 -0
  445. data/template/resources/method.gif +0 -0
  446. data/template/resources/pkg-closed.gif +0 -0
  447. data/template/resources/pkg-open.gif +0 -0
  448. data/template/resources/pkg.gif +0 -0
  449. data/template/resources/prop.gif +0 -0
  450. data/template/resources/s.gif +0 -0
  451. data/template/resources/static.gif +0 -0
  452. data/template/resources/style.css +0 -291
  453. data/template/welcome.html +0 -45
@@ -0,0 +1,110 @@
1
+ require 'jsduck/jsonp'
2
+ require 'jsduck/logger'
3
+ require 'fileutils'
4
+
5
+ module JsDuck
6
+
7
+ # Reads in guides and converts them to JsonP files
8
+ class Guides
9
+ def initialize(formatter, order=nil)
10
+ @guides = []
11
+ @formatter = formatter
12
+ @order = order
13
+ end
14
+
15
+ # Looks for guide in each subdir of given directory.
16
+ def parse_dir(guides_dir)
17
+ Dir.glob(guides_dir + "/*").each do |dir|
18
+ if File.directory?(dir)
19
+ parse_guide(dir)
20
+ end
21
+ end
22
+
23
+ if @order
24
+ # When order specified, place guides into that order and
25
+ # exclude those guides that aren't listed in @order
26
+ @guides = @order.map {|name| @guides.find {|g| g[:name] =~ Regexp.new("^"+Regexp.escape(name)) } }
27
+ else
28
+ # Otherwise sort guides alphabetically
29
+ @guides.sort! {|a, b| a[:title] <=> b[:title] }
30
+ end
31
+ end
32
+
33
+ def parse_guide(dir)
34
+ guide_file = dir + "/README.md"
35
+ unless File.exists?(guide_file)
36
+ return Logger.instance.warn("README.md not found in #{dir}")
37
+ end
38
+
39
+ Logger.instance.log("Parsing guide #{guide_file} ...")
40
+ markdown = IO.read(guide_file)
41
+ name = File.basename(dir)
42
+ # Treat the first line of file as title
43
+ title = markdown.match(/^#\s*([^\n]*?)(\r?\n|$)/)[1]
44
+
45
+ @formatter.doc_context = {:filename => guide_file, :linenr => 0}
46
+ html = @formatter.format(markdown)
47
+ html.gsub!(/<img src="/, "<img src=\"guides/#{name}/")
48
+
49
+ @guides << {
50
+ :dir => dir,
51
+ :name => name,
52
+ :title => title,
53
+ :icon => File.exists?(dir+"/icon.png"),
54
+ :html => html,
55
+ }
56
+ end
57
+
58
+ # Writes all guides to given dir in JsonP format
59
+ def write(dir)
60
+ # Skip it all when we have no guides
61
+ FileUtils.mkdir(dir) if @guides.length > 0
62
+
63
+ @guides.each do |guide|
64
+ out_dir = dir+"/"+guide[:name]
65
+ FileUtils.cp_r(guide[:dir], out_dir)
66
+ # Write the JsonP file and remove the original Markdown file
67
+ JsonP.write(out_dir+"/README.js", guide[:name], {:guide => guide[:html]})
68
+ FileUtils.rm(out_dir + "/README.md")
69
+ end
70
+ end
71
+
72
+ # Returns HTML listing of guides
73
+ def to_html
74
+ return "" if @guides.length == 0
75
+
76
+ links = @guides.map do |g|
77
+ style = g[:icon] ? "style='background: url(guides/#{g[:name]}/icon.png) no-repeat'" : ""
78
+ "<a class='guide' rel='#{g[:name]}' #{style} href='#/guide/#{g[:name]}'>#{g[:title]}</a>"
79
+ end
80
+
81
+ # Divide to three columns: lft, mid, rgt
82
+ col_height = (links.length / 3).ceil
83
+ return <<-EOHTML
84
+ <div id='guides-content' style='display:none'>
85
+ <div class="lft">
86
+ #{links.slice(0, col_height).join("\n")}
87
+ </div>
88
+ <div class="mid">
89
+ #{links.slice(col_height, col_height).join("\n")}
90
+ </div>
91
+ <div class="rgt">
92
+ #{links.slice(col_height*2, col_height).join("\n")}
93
+ </div>
94
+ </div>
95
+ EOHTML
96
+ end
97
+
98
+ # Iterates over each guide
99
+ def each(&block)
100
+ @guides.each &block
101
+ end
102
+
103
+ # Returns number of guides
104
+ def length
105
+ @guides.length
106
+ end
107
+
108
+ end
109
+
110
+ end
@@ -195,7 +195,7 @@ module JsDuck
195
195
  cfg
196
196
  end
197
197
 
198
- # <ext-define-cfg> := "{" ( <extend> | <mixins> | <alternate-class-name> | <?> )*
198
+ # <ext-define-cfg> := "{" ( <extend> | <mixins> | <alternate-class-name> | <alias> | <?> )*
199
199
  def ext_define_cfg
200
200
  match("{")
201
201
  cfg = {}
@@ -209,7 +209,10 @@ module JsDuck
209
209
  cfg[:mixins] = ext_define_mixins
210
210
  found = true
211
211
  elsif look("alternateClassName", ":")
212
- cfg[:alternateClassNames] = ext_define_alternate_class_name
212
+ cfg[:alternateClassNames] = ext_define_alternate_class_names
213
+ found = true
214
+ elsif look("alias", ":")
215
+ cfg[:alias] = ext_define_alias
213
216
  found = true
214
217
  elsif look(:ident, ":")
215
218
  match(:ident, ":")
@@ -234,9 +237,20 @@ module JsDuck
234
237
  match("extend", ":", :string)
235
238
  end
236
239
 
237
- # <ext-define-alternate-class-name> := "alternateClassName" ":" ( <string> | <array-of-strings> )
238
- def ext_define_alternate_class_name
240
+ # <ext-define-alternate-class-names> := "alternateClassName" ":" <string-or-list>
241
+ def ext_define_alternate_class_names
239
242
  match("alternateClassName", ":")
243
+ string_or_list
244
+ end
245
+
246
+ # <ext-define-alias> := "alias" ":" <string-or-list>
247
+ def ext_define_alias
248
+ match("alias", ":")
249
+ string_or_list
250
+ end
251
+
252
+ # <string-or-list> := ( <string> | <array-of-strings> )
253
+ def string_or_list
240
254
  if look(:string)
241
255
  [ match(:string) ]
242
256
  elsif look("[")
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ module JsDuck
4
+
5
+ # Utility class for writing JsonP files
6
+ class JsonP
7
+
8
+ # Turns hash into JSON and writes inside JavaScript that calls the
9
+ # given callback name
10
+ def self.write(filename, callback_name, data)
11
+ jsonp = "Ext.data.JsonP." + callback_name + "(" + JSON.pretty_generate(data) + ");"
12
+ File.open(filename, 'w') {|f| f.write(jsonp) }
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,36 @@
1
+ require 'singleton'
2
+
3
+ module JsDuck
4
+
5
+ # Central logging of JsDuck
6
+ class Logger
7
+ include Singleton
8
+
9
+ attr_accessor :verbose
10
+ attr_accessor :warnings
11
+
12
+ def initialize
13
+ @verbose = false
14
+ @warnings = true
15
+ @shown_warnings = {}
16
+ end
17
+
18
+ # Prints log message
19
+ def log(msg)
20
+ puts msg if @verbose
21
+ end
22
+
23
+ # Prints warning message.
24
+ #
25
+ # Ignores duplicate warnings - only prints the first one.
26
+ # Works best when --processes=0, but it reduces the amount of
27
+ # warnings greatly also when run multiple processes.
28
+ def warn(msg)
29
+ if @warnings && !@shown_warnings[msg]
30
+ puts "Warning: " + msg
31
+ @shown_warnings[msg] = true
32
+ end
33
+ end
34
+ end
35
+
36
+ end
@@ -66,17 +66,8 @@ module JsDuck
66
66
  def create_class(docs, code)
67
67
  groups = group_class_docs(docs)
68
68
  result = create_bare_class(groups[:class], code)
69
- result[:cfg] = groups[:cfg].map { |tags| create_cfg(tags, {}, result[:name]) }
70
- result[:method] = []
71
- if groups[:constructor].length > 0
72
- constr = create_method(groups[:constructor], {})
73
- constr[:member] = result[:name]
74
- result[:method] << constr
75
- end
76
- result[:property] = []
77
- result[:event] = []
78
- result[:css_var] = []
79
- result[:css_mixin] = []
69
+ result[:members] = create_class_members(groups, result[:name])
70
+ result[:statics] = Class.default_members_hash
80
71
  result
81
72
  end
82
73
 
@@ -114,96 +105,111 @@ module JsDuck
114
105
 
115
106
  def create_bare_class(docs, code)
116
107
  doc_map = build_doc_map(docs)
117
- return {
108
+ return add_shared({
118
109
  :tagname => :class,
119
110
  :name => detect_name(:class, doc_map, code, :full_name),
120
111
  :doc => detect_doc(docs),
121
112
  :extends => detect_extends(doc_map, code),
122
113
  :mixins => detect_list(:mixins, doc_map, code),
123
114
  :alternateClassNames => detect_list(:alternateClassNames, doc_map, code),
124
- :xtype => detect_xtype(doc_map),
115
+ :xtypes => detect_xtypes(doc_map, code),
125
116
  :author => detect_author(doc_map),
126
117
  :docauthor => detect_docauthor(doc_map),
127
118
  :singleton => !!doc_map[:singleton],
128
- :private => !!doc_map[:private],
129
- }
119
+ # Used by Aggregator to determine if we're dealing with Ext4 code
120
+ :code_type => code[:type],
121
+ }, doc_map)
122
+ end
123
+
124
+ def create_class_members(groups, owner)
125
+ members = Class.default_members_hash
126
+ members[:cfg] = groups[:cfg].map { |tags| create_cfg(tags, {}, owner) }
127
+ if groups[:constructor].length > 0
128
+ constr = create_method(groups[:constructor], {})
129
+ constr[:owner] = owner
130
+ members[:method] << constr
131
+ end
132
+ members
130
133
  end
131
134
 
132
135
  def create_method(docs, code)
133
136
  doc_map = build_doc_map(docs)
134
- return {
137
+ name = detect_name(:method, doc_map, code)
138
+ return add_shared({
135
139
  :tagname => :method,
136
- :name => detect_name(:method, doc_map, code),
137
- :member => detect_member(doc_map),
140
+ :name => name,
141
+ :owner => detect_owner(doc_map),
138
142
  :doc => detect_doc(docs),
139
143
  :params => detect_params(docs, code),
140
- :return => detect_return(doc_map),
141
- :private => !!doc_map[:private],
142
- :static => !!doc_map[:static],
143
- }
144
+ :return => detect_return(doc_map, name == "constructor" ? "Object" : "void"),
145
+ }, doc_map)
144
146
  end
145
147
 
146
148
  def create_event(docs, code)
147
149
  doc_map = build_doc_map(docs)
148
- return {
150
+ return add_shared({
149
151
  :tagname => :event,
150
152
  :name => detect_name(:event, doc_map, code),
151
- :member => detect_member(doc_map),
153
+ :owner => detect_owner(doc_map),
152
154
  :doc => detect_doc(docs),
153
155
  :params => detect_params(docs, code),
154
- :private => !!doc_map[:private],
155
- }
156
+ }, doc_map)
156
157
  end
157
158
 
158
- def create_cfg(docs, code, member = nil)
159
+ def create_cfg(docs, code, owner = nil)
159
160
  doc_map = build_doc_map(docs)
160
- return {
161
+ return add_shared({
161
162
  :tagname => :cfg,
162
163
  :name => detect_name(:cfg, doc_map, code),
163
- :member => detect_member(doc_map) || member,
164
+ :owner => detect_owner(doc_map) || owner,
164
165
  :type => detect_type(:cfg, doc_map, code),
165
166
  :doc => detect_doc(docs),
166
- :private => !!doc_map[:private],
167
- }
167
+ }, doc_map)
168
168
  end
169
169
 
170
170
  def create_property(docs, code)
171
171
  doc_map = build_doc_map(docs)
172
- return {
172
+ return add_shared({
173
173
  :tagname => :property,
174
174
  :name => detect_name(:property, doc_map, code),
175
- :member => detect_member(doc_map),
175
+ :owner => detect_owner(doc_map),
176
176
  :type => detect_type(:property, doc_map, code),
177
177
  :doc => detect_doc(docs),
178
- :private => !!doc_map[:private],
179
- :static => !!doc_map[:static],
180
- }
178
+ }, doc_map)
181
179
  end
182
180
 
183
181
  def create_css_var(docs, code)
184
182
  doc_map = build_doc_map(docs)
185
- return {
183
+ return add_shared({
186
184
  :tagname => :css_var,
187
185
  :name => detect_name(:css_var, doc_map, code),
188
- :member => detect_member(doc_map),
186
+ :owner => detect_owner(doc_map),
189
187
  :type => detect_type(:css_var, doc_map, code),
190
188
  :doc => detect_doc(docs),
191
- :private => !!doc_map[:private],
192
- :static => !!doc_map[:static],
193
- }
189
+ }, doc_map)
194
190
  end
195
191
 
196
192
  def create_css_mixin(docs, code)
197
193
  doc_map = build_doc_map(docs)
198
- return {
194
+ return add_shared({
199
195
  :tagname => :css_mixin,
200
196
  :name => detect_name(:css_mixin, doc_map, code),
201
- :member => detect_member(doc_map),
197
+ :owner => detect_owner(doc_map),
202
198
  :doc => detect_doc(docs),
203
199
  :params => detect_params(docs, code),
200
+ }, doc_map)
201
+ end
202
+
203
+ # Detects properties common for each doc-object and adds them
204
+ def add_shared(hash, doc_map)
205
+ return hash.merge({
204
206
  :private => !!doc_map[:private],
207
+ :protected => !!doc_map[:protected],
205
208
  :static => !!doc_map[:static],
206
- }
209
+ :inheritable => !!doc_map[:inheritable],
210
+ :deprecated => detect_deprecated(doc_map),
211
+ :alias => doc_map[:alias] ? doc_map[:alias].first : nil,
212
+ })
207
213
  end
208
214
 
209
215
  def detect_name(tagname, doc_map, code, name_type = :last_name)
@@ -223,7 +229,7 @@ module JsDuck
223
229
  end
224
230
  end
225
231
 
226
- def detect_member(doc_map)
232
+ def detect_owner(doc_map)
227
233
  if doc_map[:member]
228
234
  doc_map[:member].first[:member]
229
235
  else
@@ -258,7 +264,8 @@ module JsDuck
258
264
  elsif code[:type] == :assignment && code[:right] && code[:right][:type] == :ext_extend
259
265
  code[:right][:extend].join(".")
260
266
  elsif code[:type] == :ext_define
261
- code[:extend]
267
+ # Classes defined with Ext.define will automatically inherit from Ext.Base
268
+ code[:extend] || "Ext.Base"
262
269
  end
263
270
  end
264
271
 
@@ -273,8 +280,14 @@ module JsDuck
273
280
  end
274
281
  end
275
282
 
276
- def detect_xtype(doc_map)
277
- doc_map[:xtype] ? doc_map[:xtype].first[:name] : nil
283
+ def detect_xtypes(doc_map, code)
284
+ if doc_map[:xtype]
285
+ doc_map[:xtype].map {|tag| tag[:name] }
286
+ elsif code[:alias]
287
+ code[:alias].find_all {|a| a =~ /^widget\./ }.map {|a| a.sub(/^widget\./, "") }
288
+ else
289
+ []
290
+ end
278
291
  end
279
292
 
280
293
  def detect_author(doc_map)
@@ -285,12 +298,17 @@ module JsDuck
285
298
  doc_map[:docauthor] ? doc_map[:docauthor].first[:name] : nil
286
299
  end
287
300
 
301
+ def detect_deprecated(doc_map)
302
+ doc_map[:deprecated] ? doc_map[:deprecated].first : nil
303
+ end
304
+
288
305
  def detect_params(docs, code)
289
306
  implicit = detect_implicit_params(code)
290
307
  explicit = detect_explicit_params(docs)
291
308
  # Override implicit parameters with explicit ones
309
+ # But if explicit ones exist, don't append the implicit ones.
292
310
  params = []
293
- [implicit.length, explicit.length].max.times do |i|
311
+ (explicit.length > 0 ? explicit.length : implicit.length).times do |i|
294
312
  im = implicit[i] || {}
295
313
  ex = explicit[i] || {}
296
314
  doc = ex[:doc] || im[:doc] || ""
@@ -319,10 +337,10 @@ module JsDuck
319
337
  docs.find_all {|tag| tag[:tagname] == :param}
320
338
  end
321
339
 
322
- def detect_return(doc_map)
340
+ def detect_return(doc_map, default_type="void")
323
341
  ret = doc_map[:return] ? doc_map[:return].first : {}
324
342
  return {
325
- :type => ret[:type] || "void",
343
+ :type => ret[:type] || default_type,
326
344
  :doc => ret[:doc] || "",
327
345
  }
328
346
  end
@@ -21,7 +21,7 @@ module JsDuck
21
21
  @relations = relations
22
22
  @cache = cache
23
23
  @formatter = DocFormatter.new
24
- @formatter.context = cls.full_name
24
+ @formatter.class_context = cls.full_name
25
25
  @formatter.link_tpl = '<a href="output/%c.html%M" rel="%c%M" class="docClass">%a</a>'
26
26
  @formatter.relations = relations
27
27
  end