@baravak/risloo-profile-cli 4.32.3 → 4.34.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.
@@ -0,0 +1,99 @@
1
+ const gauge = require("../helpers/gauge");
2
+ const { Profile } = require("../Profile");
3
+
4
+ class JMIB93 extends Profile {
5
+ // Number of pages
6
+ static pages = 1;
7
+
8
+ // Labels of the sample
9
+ labels = {
10
+ L1_1: { eng: "unrealistic_expectations_raw", max: 76, title: 'توقعات نامعقول'},
11
+ L1_2: { eng: "unrealistic_expectations_percentage"},
12
+
13
+ L2_1: { eng: "negative_thinking_raw", max: 32, title: 'منفی‌بافی'},
14
+ L2_2: { eng: "negative_thinking_percentage"},
15
+
16
+ L3_1: { eng: "excessive_optimism_raw", max: 52, title: 'خوش‌بینی افراطی'},
17
+ L3_2: { eng: "excessive_optimism_percentage"},
18
+
19
+ L4_1: { eng: "perfectionism_raw", max: 36, title: 'کامل‌خواهی'},
20
+ L4_2: { eng: "perfectionism_percentage"},
21
+
22
+ L5_1: { eng: "negative_self_belief_raw", max: 20, title: 'خودباوری منفی'},
23
+ L5_2: { eng: "negative_self_belief_percentage"},
24
+
25
+ L6_1: { eng: "total_raw", max: 216, title: 'نمره کل'},
26
+ L6_2: { eng: "total_percentage"},
27
+ };
28
+
29
+ profileSpec = {
30
+ /* "sample" determines some important info about the sample and profile */
31
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
32
+ /* "prerequisites" is synonym to "fields" in our program */
33
+ sample: {
34
+ name: "پرسشنامه رها - آشکارسازی" /* Name of the sample */,
35
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
36
+ questions: false /* Determines whether to get questions from inital dataset or not */,
37
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
38
+ fields: [] /* In case you want to get some additional fields and show in the profile */,
39
+ },
40
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
41
+ /* calculating its dimensions carefully is of great importance */
42
+ profile: {
43
+ get dimensions() {
44
+ return {
45
+ width: 706 + 2 * this.padding.x,
46
+ height: 245 + 2 * this.padding.y,
47
+ };
48
+ },
49
+ padding: {
50
+ x: 99,
51
+ y: 235,
52
+ },
53
+ },
54
+ /* "labels" part which has to be provided for each profile */
55
+ labels: Object.values(this.labels),
56
+ };
57
+
58
+ constructor(dataset, options, config = {}) {
59
+ super();
60
+ this._init(dataset, options, config);
61
+ }
62
+
63
+ _calcContext() {
64
+ const {
65
+ dataset,
66
+ } = this;
67
+ // dataset.score[0].mark = 7
68
+ // dataset.score[1].mark = dataset.score[0].mark / dataset.score[0].label.max
69
+
70
+ // dataset.score[2].mark = 32
71
+ // dataset.score[3].mark = dataset.score[2].mark / dataset.score[2].label.max
72
+
73
+ const factors = [
74
+ packItem(dataset.score[0], dataset.score[1]),
75
+ packItem(dataset.score[2], dataset.score[3]),
76
+ packItem(dataset.score[4], dataset.score[5]),
77
+ packItem(dataset.score[6], dataset.score[7]),
78
+ packItem(dataset.score[8], dataset.score[9]),
79
+ ]
80
+ const total = packItem(dataset.score[10], dataset.score[11])
81
+ total.transform = `translate(0, ${217 - total.p * 217})`
82
+ return [{ factors, total }];
83
+ }
84
+ }
85
+
86
+ function packItem(raw, percentage){
87
+ return {
88
+ ...raw,
89
+ label: {
90
+ ...raw.label,
91
+ eng: raw.label.eng.replace('_raw', '')
92
+ },
93
+ mark: raw.mark ?? 0,
94
+ percentage: Math.round((percentage.mark ?? 0) * 100),
95
+ p: percentage.mark ?? 0
96
+ }
97
+ }
98
+
99
+ module.exports = JMIB93;
@@ -0,0 +1,96 @@
1
+ const { Profile } = require("../Profile");
2
+ const answers = [4,5,1,2,6,3,6,2,1,3,4,5,2,6,1,2,1,3,5,6,4,3,4,5,8,2,3,8,7,4,5,1,7,6,1,2,3,4,3,7,8,6,5,4,1,2,5,6,7,6,8,2,1,5,1,6,3,2,4,5]
3
+ const setGroup = ['A', 'B', 'C', 'D', 'E']
4
+ const levels = {
5
+ 'Very superior' : {title: 'خیلی سرآمد', min: 149, color: ['#059669', '#10B981']},
6
+ 'Superior' : {title: 'سرآمد', min: 125, max: 148, color: ['#059669', '#10B981']},
7
+ 'High average' : {title: 'متوسط بالا', min: 113, max: 124, color: ['#059669', '#10B981']},
8
+ 'Average' : {title: 'متوسط (بهنجار)', min: 89, max: 112, color: ['#475569', '#64748B']},
9
+ 'Low average' : {title: 'متوسط پایین', min: 77, max: 88, color: ['#E11D48', '#F43F5E']},
10
+ 'Borderline' : {title: 'مرزی', min: 65, max: 76, color: ['#E11D48', '#F43F5E']},
11
+ 'Extremely low' : {title: 'بسیار پایین', min: 0, max: 64, color: ['#E11D48', '#F43F5E']},
12
+ }
13
+
14
+ class Raven93 extends Profile {
15
+ // Number of pages
16
+ static pages = 1;
17
+
18
+ // Labels of the sample
19
+ labels = {
20
+ L1: { eng: "raw"},
21
+ L2: { eng: "iq"},
22
+ L3: { eng: "percentile"},
23
+ L9: { eng: "report"},
24
+ };
25
+
26
+ profileSpec = {
27
+ /* "sample" determines some important info about the sample and profile */
28
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
29
+ /* "prerequisites" is synonym to "fields" in our program */
30
+ sample: {
31
+ name: "آزمون ریون استاندارد" /* Name of the sample */,
32
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
33
+ questions: true /* Determines whether to get questions from inital dataset or not */,
34
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
35
+ fields: [] /* In case you want to get some additional fields and show in the profile */,
36
+ },
37
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
38
+ /* calculating its dimensions carefully is of great importance */
39
+ profile: {
40
+ get dimensions() {
41
+ return {
42
+ width: 815 + 2 * this.padding.x,
43
+ height: 618 + 2 * this.padding.y,
44
+ };
45
+ },
46
+ padding: {
47
+ x: 44,
48
+ y: 48,
49
+ },
50
+ },
51
+ /* "labels" part which has to be provided for each profile */
52
+ labels: Object.values(this.labels),
53
+ };
54
+
55
+ constructor(dataset, options, config = {}) {
56
+ super();
57
+ this._init(dataset, options, config);
58
+ }
59
+
60
+ _calcContext() {
61
+ const {
62
+ dataset,
63
+ } = this;
64
+ const report = dataset.score[3]
65
+ const iq = dataset.score[1].mark ?? 0
66
+ const raw = dataset.score[2].mark ?? 0
67
+ const percentile = dataset.score[3].mark ?? 0
68
+ levels[report.mark].selected = true
69
+ const selected = levels[report.mark]
70
+ const questions = []
71
+ dataset.questions.forEach((item, index) => {
72
+ const i = index + 1
73
+ const set = Math.floor(index / 12)
74
+ if(questions[set] === undefined){
75
+ questions[set] = {
76
+ key: setGroup[set],
77
+ items: [],
78
+ length: 0
79
+
80
+ }
81
+ }
82
+ const isTrue = answers[index] === parseInt(item.user_answered)
83
+ questions[set].length += isTrue ? 1 : 0
84
+ questions[set].items.push({
85
+ index: i, isTrue
86
+ })
87
+ });
88
+ const indic = iq === 100 ? levels['Average'] : (
89
+ iq > 100 ? levels['High average'] : levels['Low average']
90
+ )
91
+
92
+ return [{ levels, selected, questions, iq, raw, percentile, indic }];
93
+ }
94
+ }
95
+
96
+ module.exports = Raven93;
@@ -0,0 +1,101 @@
1
+ {{#> layout}}
2
+ <defs>
3
+ <linearGradient id="bg" x1="2.4" y1="112" x2="400" y2="112" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#FDF2F8" stop-opacity="0.25"/>
5
+ <stop offset="1" stop-color="#FCE7F3" stop-opacity="0.5"/>
6
+ </linearGradient>
7
+ <linearGradient id="totalbg" x1="0%" y1="0%" x2="0%" y2="100%">
8
+ <stop stop-color="#334155"/>
9
+ <stop offset="1" stop-color="#94A3B8"/>
10
+ </linearGradient>
11
+ <linearGradient id="bgrow">
12
+ <stop stop-color="#FBCFE8"/>
13
+ <stop offset="1" stop-color="#BE185D"/>
14
+ </linearGradient>
15
+ <clipPath id="totalRow">
16
+ {{bar 400 16 (object tr=2 br=2 tl=0 bl=0) (toRad 0) fill='black'}}
17
+ </clipPath>
18
+ <filter id="vsp" x="-1.52588e-05" y="0" width="7.00002" height="230" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
19
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
20
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
21
+ <feOffset dx="1"/>
22
+ <feGaussianBlur stdDeviation="1.5"/>
23
+ <feComposite in2="hardAlpha" operator="out"/>
24
+ <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
25
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3465_114726"/>
26
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3465_114726" result="shape"/>
27
+ </filter>
28
+ <filter id="totalvsp" x="0" y="0.5" width="34" height="14" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
29
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
30
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
31
+ <feOffset dx="2"/>
32
+ <feGaussianBlur stdDeviation="3"/>
33
+ <feComposite in2="hardAlpha" operator="out"/>
34
+ <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
35
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3465_114738"/>
36
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3465_114738" result="shape"/>
37
+ </filter>
38
+ </defs>
39
+ <g transform="translate({{spec.profile.padding.x}}, {{spec.profile.padding.y}})">
40
+ <g transform="translate(98, 21)">
41
+ <rect width="400" height="224" fill="url(#bg)"/>
42
+ <g transform="translate(0, 24)">
43
+ {{#each factors as |factor index|}}
44
+ <g transform="translate(0, {{math 40 '*' index}})">
45
+ {{bar 400 16 (object tr=2 br=2 tl=0 bl=0) (toRad 0) fill='black' opacity="0.04"}}
46
+ </g>
47
+ {{/each}}
48
+ </g>
49
+ <g transform="translate(38, 0)">
50
+ <line x1="0.5" y1="0.5" x2="0.50001" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
51
+ <line x1="40.5" y1="0.5" x2="40.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
52
+ <line x1="80.5" y1="0.5" x2="80.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
53
+ <line x1="120.5" y1="0.5" x2="120.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
54
+ <line x1="160.5" y1="0.5" x2="160.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
55
+ <line x1="200.5" y1="0.5" x2="200.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
56
+ <line x1="240.5" y1="0.5" x2="240.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
57
+ <line x1="280.5" y1="0.5" x2="280.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
58
+ <line x1="320.5" y1="0.5" x2="320.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
59
+ <line x1="361.5" y1="0.5" x2="361.5" y2="223.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="6 6"/>
60
+ </g>
61
+ <text y="-12" text-anchor="middle" font-weight="400" font-size="12" fill="#94A3B8">0</text>
62
+ <text x="200" y="-12" text-anchor="middle" font-weight="400" font-size="12" fill="#94A3B8">50 ٪</text>
63
+ <text x="400" y="-12" text-anchor="middle" font-weight="400" font-size="12" fill="#94A3B8">100 ٪</text>
64
+ <g transform="translate(0, 24)">
65
+ {{#each factors as |factor index|}}
66
+ <g transform="translate(0, {{math 40 '*' index}})">
67
+ <text x="-9" y="8" text-anchor="start" dy="0.25em" font-weight="400" font-size="12" fill="#475569">{{factor.label.title}}</text>
68
+ {{bar (math 400 '*' factor.p) 16 (object tr=2 br=2 tl=0 bl=0) (toRad 0) fill='url(#bgrow)' clip-path="url(#totalRow)"}}
69
+ {{#if (boolean factor.percentage '<=' 10) }}
70
+ <text x="{{math (math 400 '*' factor.p) '+' 6}}" y="8" text-anchor="end" dy="0.3em" font-weight="500" font-size="13" fill="#BE185D">{{factor.percentage}} ٪</text>
71
+ {{else}}
72
+ <text x="{{math (math 400 '*' factor.p) '-' 4}}" y="8" text-anchor="start" dy="0.3em" font-weight="500" font-size="13" fill="#FFFFFF">{{factor.percentage}} ٪</text>
73
+ {{/if}}
74
+ <text x="408" y="8" text-anchor="start" dy="0.3em" direction="ltr">
75
+ <tspan font-weight="700" font-size="18" fill="#BE185D">{{factor.mark}}</tspan>
76
+ <tspan font-weight="300" font-size="12" fill="#64748B">/</tspan>
77
+ <tspan font-weight="400" font-size="13" fill="#64748B">{{factor.label.max}}</tspan>
78
+ </text>
79
+ </g>
80
+ {{/each}}
81
+ </g>
82
+ <g opacity="0.5" filter="url(#vsp)" transform="translate(-3, -3)">
83
+ <line x1="2.5" y1="3.5" x2="2.5" y2="226.5" stroke="white" stroke-linecap="round"/>
84
+ </g>
85
+ </g>
86
+ <g transform="translate(655, 26)">
87
+ {{bar 18 217 (object tr=2 tl=2 br=0 bl=0) (toRad 0) fill="#F1F5F9"}}
88
+ {{bar 18 (math 217 '*' total.p) (object tr=2 tl=2 br=0 bl=0) (toRad 0) fill="url(#totalbg)" transform=total.transform}}
89
+ <g transform="translate(-6, 210.5)" opacity="0.5" filter="url(#totalvsp)">
90
+ <path d="M5 7.5H25" stroke="white" stroke-width="2" stroke-linecap="round"/>
91
+ </g>
92
+ <text x="-5.5" y="0" text-anchor="start" dy="0.3em" font-weight="400" font-size="12" fill="#475569">{{total.label.max}}</text>
93
+ <g transform="translate(24.5, {{math 217 '-' (math 217 '*' total.p)}})">
94
+ <text text-anchor="end" dy="-0.1em" font-weight="600" font-size="18" fill="#475569">{{total.mark}}</text>
95
+ <text text-anchor="end" dy="1em" font-weight="400" font-size="12" fill="#64748B">{{total.percentage}} ٪</text>
96
+ </g>
97
+ <text font-weight="400" font-size="12" fill="#475569" transform="rotate(-90,0, 0) translate(-183,-10)">نمره کل</text>
98
+ </g>
99
+ </g>
100
+
101
+ {{/layout}}
@@ -0,0 +1,184 @@
1
+ {{#> layout}}
2
+ <defs>
3
+ <clipPath id="clip-shape">
4
+ <path
5
+ d="M267.371 78.5C284.9 44.5 316.452 0 342.496 0C368.539 0 400.092 44.5 417.621 78.5C435.15 112.5 465.842 144.16 492.746 157.5C519.65 170.84 555.351 174 567.871 174H645V187.5H690V282H345L0 281.5V187.5H45V174H117.12C129.641 174 165.341 170.84 192.245 157.5C219.15 144.16 249.841 112.5 267.371 78.5Z" />
6
+ </clipPath>
7
+ <linearGradient id="levelgrd" x1="108" y1="0" x2="-7.4" y2="45.2" gradientUnits="userSpaceOnUse">
8
+ <stop stop-color="{{selected.color.[1]}}" />
9
+ <stop offset="1" stop-color="{{selected.color.[0]}}" />
10
+ </linearGradient>
11
+ <linearGradient id="trueItem" x1="26" y1="0" x2="0" y2="26" gradientUnits="userSpaceOnUse">
12
+ <stop stop-color="#F8FAFC"/>
13
+ <stop offset="1" stop-color="#F1F5F9"/>
14
+ </linearGradient>
15
+ <linearGradient id="falseItem" x1="26" y1="0" x2="0" y2="26" gradientUnits="userSpaceOnUse">
16
+ <stop stop-color="#FFF1F2" stop-opacity="0.5"/>
17
+ <stop offset="1" stop-color="#FFE4E6"/>
18
+ </linearGradient>
19
+ </defs>
20
+ <g transform="translate({{spec.profile.padding.x}}, {{spec.profile.padding.y}})">
21
+ <rect x="150.25" y="0.25" width="0.5" height="595.5" rx="0.25" fill="none" stroke="#E2E8F0" stroke-width="0.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="10 10"/>
22
+ <g transform="translate(3,0)">
23
+ <g transform="translate(201,33)">
24
+ <svg width="600" height="189" viewBox="0 0 600 189" fill="none" xmlns="http://www.w3.org/2000/svg">
25
+ <path
26
+ d="M222.371 79.5C239.9 45.5 271.452 1 297.496 1C323.539 1 355.092 45.5 372.621 79.5C390.15 113.5 420.842 145.16 447.746 158.5C474.65 171.84 510.351 175 522.871 175H600V188.5H300.5H0V175H36.5601H72.1202C84.6411 175 120.341 171.84 147.245 158.5C174.15 145.16 204.841 113.5 222.371 79.5Z"
27
+ fill="url(#paint0_linear_20_118)" />
28
+ <g clip-path="url(#clip0_20_118)">
29
+ <rect width="1" height="14" transform="translate(73 188) rotate(-180)" fill="#CBD5E1" />
30
+ </g>
31
+ <g clip-path="url(#clip1_20_118)">
32
+ <rect width="1" height="30" transform="translate(148 188) rotate(-180)" fill="#CBD5E1" />
33
+ </g>
34
+ <g clip-path="url(#clip2_20_118)">
35
+ <rect width="1" height="108" transform="translate(223 188) rotate(-180)" fill="#CBD5E1" />
36
+ </g>
37
+ <g clip-path="url(#clip3_20_118)">
38
+ <rect width="1" height="188" transform="translate(298 188) rotate(-180)" fill="#CBD5E1" />
39
+ </g>
40
+ <g clip-path="url(#clip4_20_118)">
41
+ <rect width="1" height="108" transform="translate(373 188) rotate(-180)" fill="#CBD5E1" />
42
+ </g>
43
+ <g clip-path="url(#clip5_20_118)">
44
+ <rect width="1" height="30" transform="translate(448 188) rotate(-180)" fill="#CBD5E1" />
45
+ </g>
46
+ <g clip-path="url(#clip6_20_118)">
47
+ <rect width="1" height="14" transform="translate(523 188) rotate(-180)" fill="#CBD5E1" />
48
+ </g>
49
+ <rect y="188" width="600" height="1" rx="0.5" fill="#64748B" />
50
+ <path
51
+ d="M1 175H72.1202C84.6411 175 120.341 171.84 147.245 158.5C174.15 145.16 204.841 113.5 222.371 79.5C239.9 45.5 271.452 1 297.496 1C323.539 1 355.092 45.5 372.621 79.5C390.15 113.5 420.842 145.16 447.746 158.5C474.65 171.84 510.351 175 522.871 175H599"
52
+ stroke="#64748B" stroke-width="2" stroke-linecap="round" />
53
+ <defs>
54
+ <linearGradient id="paint0_linear_20_118" x1="0" y1="90.75" x2="600" y2="90.75"
55
+ gradientUnits="userSpaceOnUse">
56
+ <stop stop-color="#FFE4E6" />
57
+ <stop offset="0.45" stop-color="#FFF1F2" stop-opacity="0.5" />
58
+ <stop offset="0.5" stop-color="#F8FAFC" />
59
+ <stop offset="0.55" stop-color="#ECFDF5" stop-opacity="0.5" />
60
+ <stop offset="1" stop-color="#D1FAE5" />
61
+ </linearGradient>
62
+ <clipPath id="clip0_20_118">
63
+ <rect width="5" height="14" fill="white" transform="translate(75 188) rotate(-180)" />
64
+ </clipPath>
65
+ <clipPath id="clip1_20_118">
66
+ <rect width="5" height="30" fill="white" transform="translate(150 188) rotate(-180)" />
67
+ </clipPath>
68
+ <clipPath id="clip2_20_118">
69
+ <rect width="5.00001" height="108" fill="white" transform="translate(225 188) rotate(-180)" />
70
+ </clipPath>
71
+ <clipPath id="clip3_20_118">
72
+ <rect width="5.00002" height="188" fill="white" transform="translate(300 188) rotate(-180)" />
73
+ </clipPath>
74
+ <clipPath id="clip4_20_118">
75
+ <rect width="5.00001" height="108" fill="white" transform="translate(375 188) rotate(-180)" />
76
+ </clipPath>
77
+ <clipPath id="clip5_20_118">
78
+ <rect width="5" height="30" fill="white" transform="translate(450 188) rotate(-180)" />
79
+ </clipPath>
80
+ <clipPath id="clip6_20_118">
81
+ <rect width="5" height="14" fill="white" transform="translate(525 188) rotate(-180)" />
82
+ </clipPath>
83
+ </defs>
84
+ </svg>
85
+ </g>
86
+ <text x="201" y="188" dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
87
+ direction="ltr">-4σ</text>
88
+ <g transform="translate(273.5, 174)">
89
+ <text dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
90
+ direction="ltr">-3σ</text>
91
+ <text dy="1.9em" text-anchor="middle" font-size="12" font-weight="400" fill="#64748B"
92
+ direction="ltr">55</text>
93
+ </g>
94
+ <g transform="translate(348.5, 158)">
95
+ <text dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
96
+ direction="ltr">-2σ</text>
97
+ <text dy="1.9em" text-anchor="middle" font-size="12" font-weight="400" fill="#64748B"
98
+ direction="ltr">70</text>
99
+ </g>
100
+ <g transform="translate(416, 80)">
101
+ <text dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
102
+ direction="ltr">-1σ</text>
103
+ <text dy="1.9em" text-anchor="middle" font-size="12" font-weight="400" fill="#64748B"
104
+ direction="ltr">85</text>
105
+ </g>
106
+ <g transform="translate(498.5, 0)">
107
+ <text dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
108
+ direction="ltr">0</text>
109
+ <text dy="1.9em" text-anchor="middle" font-size="12" font-weight="400" fill="#64748B"
110
+ direction="ltr">100</text>
111
+ </g>
112
+ <g transform="translate(582.5, 80)">
113
+ <text dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
114
+ direction="ltr">+1σ</text>
115
+ <text dy="1.9em" text-anchor="middle" font-size="12" font-weight="400" fill="#64748B"
116
+ direction="ltr">115</text>
117
+ </g>
118
+ <g transform="translate(648.5, 158)">
119
+ <text dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
120
+ direction="ltr">+2σ</text>
121
+ <text dy="1.9em" text-anchor="middle" font-size="12" font-weight="400" fill="#64748B"
122
+ direction="ltr">130</text>
123
+ </g>
124
+ <g transform="translate(723.5, 174)">
125
+ <text dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
126
+ direction="ltr">+3σ</text>
127
+ <text dy="1.9em" text-anchor="middle" font-size="12" font-weight="400" fill="#64748B"
128
+ direction="ltr">145</text>
129
+ </g>
130
+ <text x="800.5" y="188" dy=".75em" text-anchor="middle" font-size="12" font-weight="400" fill="#94A3B8"
131
+ direction="ltr">+4σ</text>
132
+ <g transform="translate(156, 35)" clip-path="url(#clip-shape)">
133
+ <g transform="translate({{math -185 '+' (math iq '*' 5)}}, 0)">
134
+ <path d="M25.5 205H28.5V0H25.5V205Z" fill="{{indic.color.[0]}}"/>
135
+ <path d="M0 219C0 213.477 4.47715 209 10 209H44C49.5228 209 54 213.477 54 219V234C54 239.523 49.5228 244 44 244H10C4.47715 244 0 239.523 0 234V219Z" fill="{{indic.color.[0]}}"/>
136
+ <path d="M27 203.343L32.6569 209H21.3431L27 203.343Z" fill="{{indic.color.[0]}}"/>
137
+ <text x="27" y="233" text-anchor="middle" font-size="20" font-weight="700" fill="#FFFFFF">{{iq}}</text>
138
+ <text x="-7" y="227" text-anchor="start" font-size="14" font-weight="500" fill="#334155">{{raw}}</text>
139
+ <text x="-7" y="237" text-anchor="start" font-size="12" font-weight="400" fill="#64748B">نمره خام</text>
140
+ <text x="62" y="227" text-anchor="end" font-size="14" font-weight="500" fill="#334155">{{raw}}</text>
141
+ <text x="62" y="237" text-anchor="end" font-size="12" font-weight="400" fill="#64748B">رتبه درصدی</text>
142
+ <text x="27" y="245" text-anchor="middle" dy="1em" font-size="14" font-weight="400" fill="#334155">هوشبهر</text>
143
+ <text x="27" y="245" text-anchor="middle" dy="2.75em" font-size="12" font-weight="400" fill="#64748B">(IQ)</text>
144
+ </g>
145
+ </g>
146
+
147
+ <g transform="translate(0, 32)">
148
+ {{#each levels as | level key | }}
149
+ <g transform="translate(0, {{math @index '*' 78}})">
150
+ <rect width="108" height="64" rx="8" stroke="#F1F5F9" stroke-width="{{ternary level.selected '0' '1'}}" fill="{{ternary level.selected 'url(#levelgrd)' '#F8FAFC'}}" />
151
+ <text x="54" y="24.5" dy=".2em" text-anchor="middle" font-size="13" font-weight="400"
152
+ fill="{{ternary level.selected '#FFFFFF' '#475569'}}">{{title}}</text>
153
+ <text x="54" y="42.5" dy=".4em" text-anchor="middle" font-size="12" font-weight="400"
154
+ fill="{{ternary level.selected '#FFFFFF' '#64748B'}}">
155
+ {{#if (boolean max '>=' 0)}}
156
+ {{min}}&#160;{{ternary max ' تا ' ''}}&#160;{{max}}
157
+ {{else}}
158
+ {{min}}
159
+ {{/if}}
160
+ </text>
161
+ </g>
162
+ {{/each}}
163
+ </g>
164
+ <g transform="translate(256, 338)">
165
+ {{#each questions as | question qi|}}
166
+ <g transform="translate(0, {{math qi '*' 54}})">
167
+ <rect width="432" height="42" rx="8" stroke="#E2E8F0" fill="none" />
168
+ <g transform="translate(16, 8)">
169
+ {{#each question.items as | item ii|}}
170
+ <g transform="translate({{math 374 '-' (math ii '*' 34)}}, 0)">
171
+ <rect width="26" height="26" rx="6" fill="url(#{{ternary item.isTrue 'trueItem' 'falseItem'}})" opacity="0.5" />
172
+ <text x="13" y="13" dy=".3em" text-anchor="middle" font-size="13" font-weight="400" fill="{{ternary item.isTrue '#475569' '#F43F5E'}}">{{item.index}}</text>
173
+ </g>
174
+ {{/each}}
175
+ </g>
176
+ <text x="451" y="21" dy=".3em" text-anchor="middle" font-size="16" font-weight="600" fill="#94A3B8">{{key}}</text>
177
+ <text x="466.5" y="21" dy=".3em" text-anchor="middle" font-size="16" font-weight="300" fill="#94A3B8">-</text>
178
+ <text x="475" y="21" dy=".3em" text-anchor="end" font-size="18" font-weight="600" fill="question">{{question.length}}</text>
179
+ </g>
180
+ {{/each}}
181
+ </g>
182
+ </g>
183
+ </g>
184
+ {{/layout}}