@baravak/risloo-profile-cli 3.1.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 (200) hide show
  1. package/.github/workflows/push.yml +14 -0
  2. package/.prettierrc +16 -0
  3. package/.yarn/releases/yarn-1.22.19.cjs +147529 -0
  4. package/.yarnrc.yml +1 -0
  5. package/README.md +98 -0
  6. package/bin/risloo.js +9 -0
  7. package/package.json +44 -0
  8. package/src/Gift.js +29 -0
  9. package/src/Profile.js +405 -0
  10. package/src/cli-commands/Executor.js +118 -0
  11. package/src/cli-commands/ExtractExecutor.js +194 -0
  12. package/src/cli-commands/GiftExecutor.js +56 -0
  13. package/src/cli-commands/utilities/BaseOps.js +71 -0
  14. package/src/cli-commands/utilities/Benchmarker.js +88 -0
  15. package/src/cli-commands/utilities/CustomErrors.js +14 -0
  16. package/src/cli-commands/utilities/Response.js +59 -0
  17. package/src/cli-commands/utilities/STATUSES.js +16 -0
  18. package/src/cli-commands/utilities/Status.js +9 -0
  19. package/src/cli.js +125 -0
  20. package/src/handlebars/helpers/abs.js +8 -0
  21. package/src/handlebars/helpers/addCommas.js +8 -0
  22. package/src/handlebars/helpers/array.js +8 -0
  23. package/src/handlebars/helpers/assignGlobal.js +9 -0
  24. package/src/handlebars/helpers/boolean.js +19 -0
  25. package/src/handlebars/helpers/ceil.js +8 -0
  26. package/src/handlebars/helpers/concat.js +8 -0
  27. package/src/handlebars/helpers/cos.js +8 -0
  28. package/src/handlebars/helpers/displacePoint.js +11 -0
  29. package/src/handlebars/helpers/ellipsisChars.js +10 -0
  30. package/src/handlebars/helpers/ellipsisLines.js +11 -0
  31. package/src/handlebars/helpers/first.js +11 -0
  32. package/src/handlebars/helpers/floor.js +8 -0
  33. package/src/handlebars/helpers/forLoop.js +15 -0
  34. package/src/handlebars/helpers/getArrOfProp.js +8 -0
  35. package/src/handlebars/helpers/isArray.js +8 -0
  36. package/src/handlebars/helpers/join.js +10 -0
  37. package/src/handlebars/helpers/last.js +11 -0
  38. package/src/handlebars/helpers/lineWrap.js +28 -0
  39. package/src/handlebars/helpers/math.js +24 -0
  40. package/src/handlebars/helpers/modulo.js +8 -0
  41. package/src/handlebars/helpers/normalizeAngle.js +7 -0
  42. package/src/handlebars/helpers/object.js +8 -0
  43. package/src/handlebars/helpers/objectEntries.js +8 -0
  44. package/src/handlebars/helpers/polarToCartesian.js +14 -0
  45. package/src/handlebars/helpers/prepend.js +10 -0
  46. package/src/handlebars/helpers/profiles/bar.js +45 -0
  47. package/src/handlebars/helpers/profiles/calcGaugeSidePoints.js +34 -0
  48. package/src/handlebars/helpers/profiles/gauge.js +61 -0
  49. package/src/handlebars/helpers/profiles/polygon.js +40 -0
  50. package/src/handlebars/helpers/reverse.js +9 -0
  51. package/src/handlebars/helpers/roundToTwo.js +8 -0
  52. package/src/handlebars/helpers/setVar.js +8 -0
  53. package/src/handlebars/helpers/sin.js +8 -0
  54. package/src/handlebars/helpers/split.js +8 -0
  55. package/src/handlebars/helpers/tan.js +8 -0
  56. package/src/handlebars/helpers/ternary.js +9 -0
  57. package/src/handlebars/helpers/toDeg.js +8 -0
  58. package/src/handlebars/helpers/toRad.js +8 -0
  59. package/src/handlebars/helpers/withGroup.js +20 -0
  60. package/src/handlebars/helpers/wrapOnNewline.js +11 -0
  61. package/src/handlebars/helpers.js +86 -0
  62. package/src/handlebars/importPartials.js +40 -0
  63. package/src/handlebars/init.js +15 -0
  64. package/src/publish/bot.js +91 -0
  65. package/src/publish/json/gift/gift.json +16 -0
  66. package/src/publish/json/profiles/16PF93.json +201 -0
  67. package/src/publish/json/profiles/AEQ93.json +96 -0
  68. package/src/publish/json/profiles/AMS93.json +102 -0
  69. package/src/publish/json/profiles/AMS9A.json +102 -0
  70. package/src/publish/json/profiles/BAOMEIS93.json +99 -0
  71. package/src/publish/json/profiles/BEQI93.json +1589 -0
  72. package/src/publish/json/profiles/CAATS93.json +11355 -0
  73. package/src/publish/json/profiles/CADS93.json +351 -0
  74. package/src/publish/json/profiles/CARSP93.json +96 -0
  75. package/src/publish/json/profiles/CERQ93.json +106 -0
  76. package/src/publish/json/profiles/CRAAS93.json +98 -0
  77. package/src/publish/json/profiles/CSI93.json +143 -0
  78. package/src/publish/json/profiles/DSWLS93.json +93 -0
  79. package/src/publish/json/profiles/EMSS93.json +116 -0
  80. package/src/publish/json/profiles/FACES93.json +106 -0
  81. package/src/publish/json/profiles/FTEPT93.json +102 -0
  82. package/src/publish/json/profiles/GMIT93.json +98 -0
  83. package/src/publish/json/profiles/HPL93.json +102 -0
  84. package/src/publish/json/profiles/IBT93.json +106 -0
  85. package/src/publish/json/profiles/IUS93.json +93 -0
  86. package/src/publish/json/profiles/JCSI93.json +102 -0
  87. package/src/publish/json/profiles/JPFQ93.json +1 -0
  88. package/src/publish/json/profiles/KJGI93.json +100 -0
  89. package/src/publish/json/profiles/LMIQ93.json +109 -0
  90. package/src/publish/json/profiles/MMFAD93.json +103 -0
  91. package/src/publish/json/profiles/MMFAD9A.json +103 -0
  92. package/src/publish/json/profiles/MOCI93.json +100 -0
  93. package/src/publish/json/profiles/OBQ4493.json +96 -0
  94. package/src/publish/json/profiles/PIES93.json +104 -0
  95. package/src/publish/json/profiles/PIES9A.json +104 -0
  96. package/src/publish/json/profiles/PMCIEF93.json +1 -0
  97. package/src/publish/json/profiles/PSWQ93.json +97 -0
  98. package/src/publish/json/profiles/RIASEC93.json +2511 -0
  99. package/src/publish/json/profiles/SAFE93.json +110 -0
  100. package/src/publish/json/profiles/SASQ93.json +92 -0
  101. package/src/publish/json/profiles/SCASP93.json +611 -0
  102. package/src/publish/json/profiles/SDCAQ93.json +96 -0
  103. package/src/publish/json/profiles/STAIY93.json +98 -0
  104. package/src/publish/json/profiles/WAQ93.json +100 -0
  105. package/src/publish/json/profiles/YBOCS93.json +1322 -0
  106. package/src/publish/json/profiles/empty.json +139 -0
  107. package/src/publish/new-version.hbs +11 -0
  108. package/src/publish/test.js +109 -0
  109. package/src/qrcode/qrCodeGenerator.js +14 -0
  110. package/src/qrcode/qrRender.js +229 -0
  111. package/src/samples/16PF93.js +158 -0
  112. package/src/samples/AEQ93.js +121 -0
  113. package/src/samples/AMS93.js +139 -0
  114. package/src/samples/AMS9A.js +9 -0
  115. package/src/samples/BAOMEIS93.js +146 -0
  116. package/src/samples/BEQI93.js +255 -0
  117. package/src/samples/CAATS93.js +218 -0
  118. package/src/samples/CADS93.js +161 -0
  119. package/src/samples/CARSP93.js +134 -0
  120. package/src/samples/CERQ93.js +195 -0
  121. package/src/samples/CRAAS93.js +141 -0
  122. package/src/samples/CSI93.js +315 -0
  123. package/src/samples/DSWLS93.js +112 -0
  124. package/src/samples/EMSS93.js +178 -0
  125. package/src/samples/FACES93.js +225 -0
  126. package/src/samples/FTEPT93.js +167 -0
  127. package/src/samples/GMIT93.js +142 -0
  128. package/src/samples/HPL93.js +132 -0
  129. package/src/samples/IBT93.js +99 -0
  130. package/src/samples/IUS93.js +204 -0
  131. package/src/samples/JCSI93.js +174 -0
  132. package/src/samples/JPFQ93.js +74 -0
  133. package/src/samples/KJGI93.js +136 -0
  134. package/src/samples/LMIQ93.js +188 -0
  135. package/src/samples/MMFAD93.js +135 -0
  136. package/src/samples/MMFAD9A.js +31 -0
  137. package/src/samples/MOCI93.js +128 -0
  138. package/src/samples/OBQ4493.js +132 -0
  139. package/src/samples/PIES93.js +228 -0
  140. package/src/samples/PIES9A.js +32 -0
  141. package/src/samples/PMCIEF93.js +64 -0
  142. package/src/samples/PSWQ93.js +126 -0
  143. package/src/samples/RIASEC93.js +144 -0
  144. package/src/samples/SAFE93.js +64 -0
  145. package/src/samples/SASQ93.js +130 -0
  146. package/src/samples/SCASP93.js +207 -0
  147. package/src/samples/SDCAQ93.js +174 -0
  148. package/src/samples/STAIY93.js +159 -0
  149. package/src/samples/WAQ93.js +208 -0
  150. package/src/samples/YBOCS93.js +583 -0
  151. package/src/samples/empty.js +53 -0
  152. package/views/gift.hbs +160 -0
  153. package/views/profiles/fonts.css +18 -0
  154. package/views/profiles/layout.hbs +27 -0
  155. package/views/profiles/samples/16PF93.hbs +54 -0
  156. package/views/profiles/samples/AEQ93.hbs +31 -0
  157. package/views/profiles/samples/AMS93.hbs +97 -0
  158. package/views/profiles/samples/AMS9A.hbs +1 -0
  159. package/views/profiles/samples/BAOMEIS93.hbs +48 -0
  160. package/views/profiles/samples/BEQI93.hbs +118 -0
  161. package/views/profiles/samples/CAATS93.hbs +251 -0
  162. package/views/profiles/samples/CADS93.hbs +104 -0
  163. package/views/profiles/samples/CARSP93.hbs +26 -0
  164. package/views/profiles/samples/CERQ93.hbs +115 -0
  165. package/views/profiles/samples/CRAAS93.hbs +88 -0
  166. package/views/profiles/samples/CSI93_1.hbs +110 -0
  167. package/views/profiles/samples/CSI93_2.hbs +76 -0
  168. package/views/profiles/samples/DSWLS93.hbs +26 -0
  169. package/views/profiles/samples/EMSS93.hbs +101 -0
  170. package/views/profiles/samples/FACES93_1.hbs +107 -0
  171. package/views/profiles/samples/FACES93_2.hbs +51 -0
  172. package/views/profiles/samples/FTEPT93.hbs +67 -0
  173. package/views/profiles/samples/GMIT93.hbs +45 -0
  174. package/views/profiles/samples/HPL93.hbs +36 -0
  175. package/views/profiles/samples/IBT93.hbs +67 -0
  176. package/views/profiles/samples/IUS93.hbs +123 -0
  177. package/views/profiles/samples/JCSI93.hbs +65 -0
  178. package/views/profiles/samples/JPFQ93.hbs +44 -0
  179. package/views/profiles/samples/KJGI93.hbs +57 -0
  180. package/views/profiles/samples/LMIQ93.hbs +82 -0
  181. package/views/profiles/samples/MMFAD93.hbs +35 -0
  182. package/views/profiles/samples/MMFAD9A.hbs +1 -0
  183. package/views/profiles/samples/MOCI93.hbs +60 -0
  184. package/views/profiles/samples/OBQ4493.hbs +61 -0
  185. package/views/profiles/samples/PIES93.hbs +67 -0
  186. package/views/profiles/samples/PIES9A.hbs +1 -0
  187. package/views/profiles/samples/PMCIEF93.hbs +8 -0
  188. package/views/profiles/samples/PSWQ93.hbs +32 -0
  189. package/views/profiles/samples/RIASEC93.hbs +38 -0
  190. package/views/profiles/samples/SAFE93.hbs +118 -0
  191. package/views/profiles/samples/SASQ93.hbs +45 -0
  192. package/views/profiles/samples/SCASP93.hbs +94 -0
  193. package/views/profiles/samples/SDCAQ93.hbs +68 -0
  194. package/views/profiles/samples/STAIY93.hbs +67 -0
  195. package/views/profiles/samples/WAQ93.hbs +74 -0
  196. package/views/profiles/samples/YBOCS93_1.hbs +96 -0
  197. package/views/profiles/samples/YBOCS93_2.hbs +115 -0
  198. package/views/profiles/samples/YBOCS93_3.hbs +93 -0
  199. package/views/profiles/samples/empty.hbs +10 -0
  200. package/views/profiles/sidebar.hbs +193 -0
@@ -0,0 +1,174 @@
1
+ const { Profile } = require("../Profile");
2
+
3
+ class JCSI93 extends Profile {
4
+ // Number of pages
5
+ static pages = 1;
6
+
7
+ // Labels of the sample
8
+ labels = {
9
+ L1: { eng: "raw", fr: "نمره کل" },
10
+ L2: { eng: "listening", fr: "گوش دادن" },
11
+ L3: { eng: "emotion_regulation", fr: "تنظیم عواطف" },
12
+ L4: { eng: "understanding_message", fr: "درک پیام" },
13
+ L5: { eng: "awareness", fr: "بینش" },
14
+ L6: { eng: "assertiveness", fr: "قاطعیت" },
15
+ L7: { eng: "interpretation", fr: "تفسیر" },
16
+ };
17
+
18
+ profileSpec = {
19
+ /* "sample" determines some important info about the sample and profile */
20
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
21
+ /* "prerequisites" is synonym to "fields" in our program */
22
+ sample: {
23
+ name: "پرسشنامه مهارت‌های ارتباطی جرابک" /* Name of the sample */,
24
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
25
+ questions: false /* Determines whether to get questions from inital dataset or not */,
26
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
27
+ fields: ["marital_status"] /* In case you want to get some additional fields and show in the profile */,
28
+ },
29
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
30
+ /* calculating its dimensions carefully is of great importance */
31
+ profile: {
32
+ get dimensions() {
33
+ return {
34
+ width: 690 + 2 * this.padding.x,
35
+ height: 641.5 + 2 * this.padding.y,
36
+ }
37
+ },
38
+ padding: {
39
+ x: 0,
40
+ y: 37.75,
41
+ },
42
+ },
43
+ /* "raw" is the general term used for total data element in the profile */
44
+ raw: {
45
+ maxValue: 170 /* Maximum value of raw mark provided by the dataset */,
46
+ offsetY: 135 /* Vertical offset from items */,
47
+ rect: {
48
+ base: {
49
+ width: 680 /* Width of the base rectangle of the raw */,
50
+ height: 4 /* Height of the base rectangle of the raw */,
51
+ br: 2 /* Border radius of the base rectangle of the raw */,
52
+ },
53
+ body: {
54
+ height: 20 /* Height of the body rectangle of the raw */,
55
+ br: 8 /* Border radius of the body rectangle of the raw */,
56
+ },
57
+ },
58
+ widthCoeff: 4 /* Used for converting mark to the width */,
59
+ stops: [33, 68, 102, 170] /* Stops array for the raw mark */,
60
+ interprets: [
61
+ { fill: "#EF4444", eng: "mild", fr: "ضعیف" },
62
+ { fill: "#FBBF24", eng: "moderate", fr: "متوسط" },
63
+ { fill: "#22C55E", eng: "severe", fr: "قوی" },
64
+ ] /* Interprets array for the raw mark */,
65
+ label: {
66
+ stops: {
67
+ line: {
68
+ offsetY: 5.5,
69
+ length: 16,
70
+ },
71
+ number: {
72
+ offsetY: 15,
73
+ },
74
+ },
75
+ shape: {
76
+ width: 50,
77
+ height: 42.6,
78
+ offsetY: 35,
79
+ },
80
+ },
81
+ },
82
+ /* "items" is the general term used for independent data elements to be drawn in the profile */
83
+ items: {
84
+ baseline: {
85
+ width: 680 /* Width of the baseline below items */,
86
+ },
87
+ maxValues: {
88
+ [this.labels.L2.eng]: 35,
89
+ [this.labels.L3.eng]: 40,
90
+ [this.labels.L4.eng]: 45,
91
+ [this.labels.L5.eng]: 25,
92
+ [this.labels.L6.eng]: 25,
93
+ } /* Maximum values of items marks provided by the dataset */,
94
+ topPos: 430 /* Top position of the baseline of items */,
95
+ offsetX: 100 /* Horizontal offset between two consecutive item */,
96
+ get distanceX() {
97
+ return this.offsetX + this.rect.body.width;
98
+ } /* Horizontal distance between two consecutive item */,
99
+ rect: {
100
+ base: {
101
+ width: 4 /* Width of the base rectangle of items */,
102
+ br: 2 /* Border radius of the base rectangle of items */,
103
+ color: "#E4E4E7" /* Fill of the base rectangle */,
104
+ },
105
+ body: {
106
+ width: 35 /* Width of the body rectangle of items */,
107
+ height: 8 /* Height of the body rectangle parts of items */,
108
+ offsetY: 1 /* Vertical offset between two parts of body rectangles */,
109
+ get distanceY() {
110
+ return this.height + this.offsetY;
111
+ } /* Vertical distance between two parts of body rectangles */,
112
+ br: 4 /* Border radius of the body rectangle of items */,
113
+ colors: [
114
+ "#C026D3",
115
+ "#EC4899",
116
+ "#3B82F6",
117
+ "#14B8A6",
118
+ "#65A30D",
119
+ ] /* Colors used for theming items body parts */,
120
+ },
121
+ heightCoeff: 9 /* Used to convert mark to height for base rectangle of items */,
122
+ },
123
+ },
124
+ /* "labels" part which has to be provided for each profile */
125
+ labels: Object.values(this.labels),
126
+ };
127
+
128
+ constructor(dataset, options, config = {}) {
129
+ super();
130
+ this._init(dataset, options, config);
131
+ }
132
+
133
+ _calcContext() {
134
+ const {
135
+ spec: { parameters: spec },
136
+ dataset,
137
+ } = this;
138
+
139
+ const { raw: rawSpec, items: itemsSpec } = spec;
140
+
141
+ // Separate Raw Data from the Dataset
142
+ let rawData = dataset.score.shift();
143
+
144
+ // Separate Interpretation from the Dataset
145
+ let interpret = dataset.score.pop().mark;
146
+
147
+ // Gather Required Info for Raw
148
+ const raw = {
149
+ mark: rawData.mark,
150
+ label: rawData.label,
151
+ width: rawData.mark * rawSpec.widthCoeff,
152
+ interpret: rawSpec.interprets.find((interpretation) => interpretation.eng === interpret),
153
+ stops: rawSpec.stops.map((stop) => ({
154
+ mark: stop,
155
+ width: stop * rawSpec.widthCoeff,
156
+ })),
157
+ };
158
+
159
+ // Gather Required Info for Items
160
+ const items = dataset.score.map((data, index) => ({
161
+ label: data.label,
162
+ mark: data.mark,
163
+ maxValue: itemsSpec.maxValues[data.label.eng],
164
+ height: {
165
+ base: itemsSpec.maxValues[data.label.eng] * itemsSpec.rect.heightCoeff + 5,
166
+ },
167
+ fill: itemsSpec.rect.body.colors[index],
168
+ }));
169
+
170
+ return [{ raw, items }];
171
+ }
172
+ }
173
+
174
+ module.exports = JCSI93;
@@ -0,0 +1,74 @@
1
+ const { Profile, FS } = require("../Profile");
2
+
3
+ class JPFQ93 extends Profile {
4
+ // Number of pages
5
+ static pages = 1;
6
+
7
+ // Labels of the sample
8
+ labels = {
9
+ L1: { eng: "identity", fr: "هویت", fill:"#8B5CF6 ", background:"#EDE9FE", width: 69},
10
+ L2: { eng: "intimacy", fr: "صمیمیت" , fill:"#8B5CF6 ", background:"#EDE9FE", width: 33},
11
+ L3: { eng: "empathy", fr: "همدلی" , fill:"#8B5CF6 ", background:"#EDE9FE", width: 33},
12
+ L4: { eng: "self_direction", fr: "خودراهبری" , fill:"#8B5CF6 ", background:"#EDE9FE", width: 30},
13
+
14
+ L5: { eng: "psychoticism", fr: "سایکوزگرایی", fill:"#EC4899 ", background:"#FCE7F3", width: 33},
15
+ L6: { eng: "detachment", fr: "دل‌بریدگی", fill:"#EC4899 ", background:"#FCE7F3", width: 27},
16
+ L7: { eng: "disinhibition", fr: "مهارگسیختگی", fill:"#EC4899 ", background:"#FCE7F3", width: 66},
17
+ L8: { eng: "negative_affectivity", fr: "عاطفه‌پذیری منفی", fill:"#EC4899 ", background:"#FCE7F3", width: 45},
18
+ L9: { eng: "antagonism", fr: "تضادورزی", fill:"#EC4899 ", background:"#FCE7F3", width: 42},
19
+ };
20
+
21
+ profileSpec = {
22
+ /* "sample" determines some important info about the sample and profile */
23
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
24
+ /* "prerequisites" is synonym to "fields" in our program */
25
+ sample: {
26
+ name: "کارکردهای شخصیت - جان‌بزرگی" /* Name of the sample */,
27
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
28
+ questions: false /* Determines whether to get questions from inital dataset or not */,
29
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
30
+ fields: [] /* In case you want to get some additional fields and show in the profile */,
31
+ },
32
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
33
+ /* calculating its dimensions carefully is of great importance */
34
+ profile: {
35
+ get dimensions() {
36
+ return {
37
+ width: 702 + 2 * this.padding.x,
38
+ height: 450 + 2 * this.padding.y,
39
+ };
40
+ },
41
+ padding: {
42
+ x: 120.5,
43
+ y: 152,
44
+ },
45
+ },
46
+ /* "labels" part which has to be provided for each profile */
47
+ labels: Object.values(this.labels),
48
+ };
49
+
50
+ constructor(dataset, options, config = {}) {
51
+ super();
52
+ this._init(dataset, options, config);
53
+ }
54
+
55
+ _calcContext() {
56
+ const { dataset } = this;
57
+ let markSum = 0
58
+ dataset.score.forEach(score => {
59
+ markSum += score.mark
60
+ })
61
+ // const items = dataset.score.map((data) => ({
62
+ // label: data.label,
63
+ // mark: data.mark,
64
+ // coordinates: {
65
+ // x: (data.mark.interaction - 6) * 25,
66
+ // y: (data.mark.structure - 6) * 25,
67
+ // },
68
+ // }));
69
+ // markSum = 378
70
+ return [{ markSum: markSum }];
71
+ }
72
+ }
73
+
74
+ module.exports = JPFQ93;
@@ -0,0 +1,136 @@
1
+ const { Profile, FS } = require("../Profile");
2
+
3
+ class KJGI93 extends Profile {
4
+ // Number of pages
5
+ static pages = 1;
6
+
7
+ // Labels of the sample
8
+ labels = {
9
+ L1: { eng: "raw", fr: "نمره کل" },
10
+ L2: { eng: "moral_standards", fr: "معیارهای اخلاقی" },
11
+ L3: { eng: "state_guilt", fr: "حالت گناه" },
12
+ L4: { eng: "trait_guilt", fr: "خصیصه گناه" },
13
+ L5: { eng: "interpretation", fr: "تفسیر" },
14
+ };
15
+
16
+ profileSpec = {
17
+ /* "sample" determines some important info about the sample and profile */
18
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
19
+ /* "prerequisites" is synonym to "fields" in our program */
20
+ sample: {
21
+ name: "پرسشنامه احساس گناه گوکلر و جونز" /* Name of the sample */,
22
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
23
+ questions: false /* Determines whether to get questions from inital dataset or not */,
24
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
25
+ fields: ["marital_status"] /* In case you want to get some additional fields and show in the profile */,
26
+ },
27
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
28
+ /* calculating its dimensions carefully is of great importance */
29
+ profile: {
30
+ get dimensions() {
31
+ return {
32
+ width: 500 + 2 * this.padding.x,
33
+ height: 785 + 2 * this.padding.y,
34
+ }
35
+ },
36
+ padding: {
37
+ x: 10,
38
+ y: 35,
39
+ },
40
+ },
41
+ /* "raw" is the general term used for total data element in the profile */
42
+ raw: {
43
+ maxValue: 225 /* Maximum value of raw mark */,
44
+ markToRadius: FS.createLine(
45
+ { x: 45, y: 90 },
46
+ { x: 225, y: 225 }
47
+ ) /* The function used for converting mark to the radius of the circle */,
48
+ get maxRadius() {
49
+ return this.markToRadius(this.maxValue);
50
+ } /* Maximum radius of raw circle */,
51
+ },
52
+ /* "items" is the general term used for independent data elements to be drawn in the profile */
53
+ items: {
54
+ maxValue: 225 /* Maximum value of items mark */,
55
+ markToRadius: FS.createLine(
56
+ { x: 45, y: 50 },
57
+ { x: 225, y: 80 }
58
+ ) /* The function used for converting mark to the radius of the circle */,
59
+ get maxRadius() {
60
+ return this.markToRadius(this.maxValue);
61
+ } /* Maximum radius of items circle */,
62
+ offset: {
63
+ x: 10 /* Horizontal offset between items */,
64
+ y: 10 /* Vertical offset between items and their labels */,
65
+ },
66
+ get distance() {
67
+ return {
68
+ x: this.offset.x + 2 * this.markToRadius(this.maxValue),
69
+ y: this.offset.y + this.markToRadius(this.maxValue),
70
+ };
71
+ },
72
+ },
73
+ interpretRects: {
74
+ width: 160 /* Width of interpretation rectangles */,
75
+ height: 40 /* Height of interpretation rectangles */,
76
+ borderRadius: 4 /* Border Radius of interpretation rectangles */,
77
+ offsetX: 10 /* Horizontal offset between two adjacent interpretation rectangles */,
78
+ offsetY1: 80 /* Vertical offset between raw circle and interpretation rectangles */,
79
+ offsetY2: 25 /* Vertical offset between interpretation rectangles and items circles */,
80
+ get distanceX() {
81
+ return this.width + this.offsetX;
82
+ } /* Horizontal distance between two adjacent interpretation rectangles */,
83
+ labels: [
84
+ { eng: "mild", fr: "احساس گناه کم" },
85
+ { eng: "moderate", fr: "احساس گناه متوسط" },
86
+ { eng: "severe", fr: "احساس گناه زیاد" },
87
+ ] /* labels of interpretation rectangles */,
88
+ },
89
+ /* "labels" part which has to be provided for each profile */
90
+ labels: Object.values(this.labels),
91
+ };
92
+
93
+ constructor(dataset, options, config = {}) {
94
+ super();
95
+ this._init(dataset, options, config);
96
+ }
97
+
98
+ _calcContext() {
99
+ const {
100
+ spec: { parameters: spec },
101
+ dataset,
102
+ } = this;
103
+
104
+ // Deconstructing the Spec of the Profile
105
+ let { raw: rawSpec, items: itemsSpec } = spec;
106
+
107
+ // Separate Raw Data from the Dataset
108
+ let rawData = dataset.score.shift();
109
+
110
+ // Separate Interpretation from the Dataset
111
+ let interpret = dataset.score.pop().mark;
112
+
113
+ // Gather Required Info for Raw
114
+ const raw = {
115
+ mark: rawData.mark,
116
+ radius: FS.roundTo2(rawSpec.markToRadius(rawData.mark)),
117
+ };
118
+
119
+ // Gather Required Info for Items
120
+ const items = dataset.score.map((data) => ({
121
+ label: data.label.fr,
122
+ mark: data.mark,
123
+ radius: FS.roundTo2(itemsSpec.markToRadius(data.mark)),
124
+ }));
125
+
126
+ return [
127
+ {
128
+ raw,
129
+ interpret,
130
+ items,
131
+ },
132
+ ];
133
+ }
134
+ }
135
+
136
+ module.exports = KJGI93;
@@ -0,0 +1,188 @@
1
+ const { Profile, FS, Mappings } = require("../Profile");
2
+
3
+ class LMIQ93 extends Profile {
4
+ // Number of pages
5
+ static pages = 1;
6
+
7
+ // Labels of the sample
8
+ labels = {
9
+ L1: { eng: "1", fr: "عمل کردن مبتنی بر اصول، ارزش‌ها و باورها" },
10
+ L2: { eng: "2", fr: "راستگویی" },
11
+ L3: { eng: "3", fr: "استقامت و پافشاری برای حق" },
12
+ L4: { eng: "4", fr: "وفای به عهد" },
13
+ L5: { eng: "5", fr: "مسئولیت‌پذیری برای تصمیمات شخصی" },
14
+ L6: { eng: "6", fr: "اقرار به اشتباهات و شکست‌ها" },
15
+ L7: { eng: "7", fr: "قبول مسئولیت برای خدمت به دیگران" },
16
+ L8: { eng: "8", fr: "فعالانه علاقه‌مند بودن به دیگران" },
17
+ L9: { eng: "9", fr: "توانایی در بخشش اشتباهات خود" },
18
+ L10: { eng: "10", fr: "توانایی در بخشش اشتباهات دیگران" },
19
+ L11: { eng: "normalized_honesty", fr: "درستکاری" },
20
+ L12: { eng: "normalized_responsibility", fr: "مسئولیت‌پذیری" },
21
+ L13: { eng: "normalized_forgiveness", fr: "بخشش" },
22
+ L14: { eng: "normalized_emphaty", fr: "همدلی" },
23
+ L15: { eng: "honesty", fr: "درستکاری" },
24
+ L16: { eng: "responsibility", fr: "مسئولیت‌پذیری" },
25
+ L17: { eng: "forgiveness", fr: "بخشش" },
26
+ L18: { eng: "emphaty", fr: "همدلی" },
27
+ L19: { eng: "raw", fr: "توانایی در بخشش اشتباهات دیگران" },
28
+ };
29
+
30
+ profileSpec = {
31
+ /* "sample" determines some important info about the sample and profile */
32
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
33
+ /* "prerequisites" is synonym to "fields" in our program */
34
+ sample: {
35
+ name: "پرسشنامه هوش اخلاقی" /* Name of the sample */,
36
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
37
+ questions: false /* Determines whether to get questions from inital dataset or not */,
38
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
39
+ fields: ["marital_status"] /* In case you want to get some additional fields and show in the profile */,
40
+ },
41
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
42
+ /* calculating its dimensions carefully is of great importance */
43
+ profile: {
44
+ get dimensions() {
45
+ return {
46
+ width: 835 + 2 * this.padding.x,
47
+ height: 597 + 2 * this.padding.y,
48
+ };
49
+ },
50
+ padding: {
51
+ x: 35,
52
+ y: 0,
53
+ },
54
+ },
55
+ /* "raw" is the general term used for total data element in the profile */
56
+ raw: {
57
+ minValue: 40 /* Minimum values of raw marks provided by the dataset */,
58
+ maxValue: 200 /* Maximum values of raw marks provided by the dataset */,
59
+ offsetX: 120 /* Horizontal offset from items */,
60
+ ticks: {
61
+ arr: [40, 200],
62
+ line: {
63
+ width: 10 /* Width of the tick line */,
64
+ offsetX: 7 /* Horizontal offset from the rectangle */,
65
+ },
66
+ number: {
67
+ offsetX: 3 /* Horizontal Offset from the line */,
68
+ },
69
+ },
70
+ rect: {
71
+ width: 35 /* Width of the raw rectangle */,
72
+ get borderRadius() {
73
+ return this.width / 2;
74
+ } /* Border radius of the raw rectangle */,
75
+ },
76
+ heightCoeff: 2 /* Used for converting mark to the height */,
77
+ },
78
+ /* "items" is the general term used for independent data elements to be drawn in the profile */
79
+ items: {
80
+ minValue: 4 /* Minimum value of items mark provided by the dataset */,
81
+ maxValue: 20 /* Maximum value of items mark provided by the dataset */,
82
+ overallMarksMaxValues: [80, 60, 40, 20],
83
+ offsetX: 240 /* Horizontal offset between items and left side of profile */,
84
+ offsetY1: 8 /* Vertical offset between two consecutive item in the profile */,
85
+ offsetY2: 32 /* Vertical offset between two categories of items */,
86
+ get distanceY() {
87
+ return this.offsetY1 + this.rect.height;
88
+ } /* Distance between two consecutive item in the profile */,
89
+ totalHeights: [] /* To be calculated in the class with the function provided */,
90
+ calcTotalHeight: function (n) {
91
+ return this.distanceY * (n - 1) + this.rect.height;
92
+ } /* Method for calculating the total height of items */,
93
+ ticks: {
94
+ num: 5 /* Number of ticks */,
95
+ heightOffset: 45 /* Half length that the ticks lines of items is greater than items total heigth */,
96
+ numberOffset: {
97
+ x: 10 /* Horizontal distance from the line */,
98
+ y: 10 /* Vertical distance from the line */,
99
+ },
100
+ },
101
+ rect: {
102
+ height: 30 /* Height of the items rectangle */,
103
+ get borderRadius() {
104
+ return this.height / 2;
105
+ } /* Border Radius of the items rectangle */,
106
+ colors: ["#8B5CF6", "#EC4899"] /* Colors used for theming items body parts */,
107
+ opacityMappings: new Mappings()
108
+ .addMapping("4-7", 0.7)
109
+ .addMapping("8-11", 0.8)
110
+ .addMapping("12-15", 0.9)
111
+ .addMapping("16-20", 1) /* Opacity mapping for marks */,
112
+ },
113
+ widthCoeff: 20 /* Used for converting mark to the width */,
114
+ label: {
115
+ offsetX: 9 /* Horizontal offset of label from item */,
116
+ },
117
+ },
118
+ /* "labels" part which has to be provided for each profile */
119
+ labels: Object.values(this.labels),
120
+ };
121
+
122
+ constructor(dataset, options, config = {}) {
123
+ super();
124
+ this._init(dataset, options, config);
125
+ }
126
+
127
+ _calcContext() {
128
+ const {
129
+ spec: { parameters: spec },
130
+ dataset,
131
+ } = this;
132
+
133
+ const { items: itemsSpec, raw: rawSpec } = spec;
134
+
135
+ // Remove Last Element to Separate Raw Data
136
+ const rawData = dataset.score.pop();
137
+
138
+ // Categorize Items Dataset
139
+ const itemsDatasets = [dataset.score.slice(0, 10), dataset.score.slice(10, 14)];
140
+ const overallData = dataset.score.slice(14);
141
+
142
+ // ّInit Spec
143
+ spec.items.totalHeights = itemsDatasets.map((dataset) => spec.items.calcTotalHeight(dataset.length));
144
+
145
+ // Gather Required Info for Items
146
+ const items = itemsDatasets.map((dataset, datasetIndex) =>
147
+ dataset.map((data, index) => ({
148
+ label: data.label,
149
+ mark: data.mark,
150
+ ...(datasetIndex === 1 && {
151
+ overallMark: { mark: overallData[index].mark, maxValue: itemsSpec.overallMarksMaxValues[index] },
152
+ }),
153
+ width: data.mark * itemsSpec.widthCoeff,
154
+ fill: itemsSpec.rect.colors[datasetIndex],
155
+ opacity: itemsSpec.rect.opacityMappings.map(data.mark),
156
+ }))
157
+ );
158
+
159
+ const raw = {
160
+ label: rawData.label,
161
+ mark: rawData.mark,
162
+ height: rawData.mark * rawSpec.heightCoeff,
163
+ };
164
+
165
+ // Calculate Ticks Numbers Array for Items
166
+ const itemsTicksNumbers = FS.createArithmeticSequence(
167
+ itemsSpec.minValue,
168
+ (itemsSpec.maxValue - itemsSpec.minValue) / (itemsSpec.ticks.num - 1),
169
+ itemsSpec.ticks.num
170
+ );
171
+
172
+ // Gather Required Info for Items Ticks
173
+ const itemsTicks = itemsTicksNumbers.map((tick) => ({
174
+ number: tick,
175
+ leftPos: tick * itemsSpec.widthCoeff,
176
+ }));
177
+
178
+ // Gather Required Info for Raw Ticks
179
+ const rawTicks = rawSpec.ticks.arr.map((tick) => ({
180
+ number: tick,
181
+ bottomPos: tick * rawSpec.heightCoeff,
182
+ }));
183
+
184
+ return [{ items, itemsTicks, raw, rawTicks }];
185
+ }
186
+ }
187
+
188
+ module.exports = LMIQ93;