aboutsummaryrefslogtreecommitdiffstats
path: root/Tests/MODELS2020-CaseStudies/case.study.pledge.run/MODELS2020Plots-temp.ipynb
blob: cc342a87aa9f04eac86b3b08b6243c673ba7a00a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Data analysis for the paper \"Automated Generation of Consistent Models with Structural and Attribute Constraints\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, let's load some packages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading required package: tidyverse\n",
      "\n",
      "── \u001b[1mAttaching packages\u001b[22m ─────────────────────────────────────── tidyverse 1.3.0 ──\n",
      "\n",
      "\u001b[32m✔\u001b[39m \u001b[34mggplot2\u001b[39m 3.3.2     \u001b[32m✔\u001b[39m \u001b[34mpurrr  \u001b[39m 0.3.4\n",
      "\u001b[32m✔\u001b[39m \u001b[34mtibble \u001b[39m 3.0.3     \u001b[32m✔\u001b[39m \u001b[34mdplyr  \u001b[39m 1.0.0\n",
      "\u001b[32m✔\u001b[39m \u001b[34mtidyr  \u001b[39m 1.1.0     \u001b[32m✔\u001b[39m \u001b[34mstringr\u001b[39m 1.4.0\n",
      "\u001b[32m✔\u001b[39m \u001b[34mreadr  \u001b[39m 1.3.1     \u001b[32m✔\u001b[39m \u001b[34mforcats\u001b[39m 0.5.0\n",
      "\n",
      "Warning message:\n",
      "“package ‘ggplot2’ was built under R version 4.0.1”\n",
      "Warning message:\n",
      "“package ‘tibble’ was built under R version 4.0.2”\n",
      "── \u001b[1mConflicts\u001b[22m ────────────────────────────────────────── tidyverse_conflicts() ──\n",
      "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mfilter()\u001b[39m masks \u001b[34mstats\u001b[39m::filter()\n",
      "\u001b[31m✖\u001b[39m \u001b[34mdplyr\u001b[39m::\u001b[32mlag()\u001b[39m    masks \u001b[34mstats\u001b[39m::lag()\n",
      "\n",
      "Warning message in dir.create(\"plots\"):\n",
      "“'plots' already exists”\n"
     ]
    }
   ],
   "source": [
    "require(tidyverse)\n",
    "dir.create('plots')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "ProcessDetailedStatistics <- function(str) {\n",
    "    str <- sub('TransformationExecutionTime', 'TransformationExecutionTime:', str)\n",
    "    str <- sub('Backtrackingtime', 'BacktrackingTime', str)\n",
    "    str <- gsub('\\\\(|\\\\)', '', str)\n",
    "    str <- lapply(strsplit(str, '\\\\||:'), function (v) {\n",
    "        dim(v) <- c(2, 12)\n",
    "        values <- as.double(v[2,])\n",
    "        names(values) <- v[1,]\n",
    "        as.data.frame(t(values))\n",
    "    })\n",
    "    str\n",
    "}\n",
    "Load10Log <- function(filename, size) {\n",
    "    read_csv(filename, col_types = cols(\n",
    "      .default = col_double(),\n",
    "      Result = col_character(),\n",
    "      Solution1DetailedStatistics = col_character(),\n",
    "      Solution2DetailedStatistics = col_character(),\n",
    "      Solution3DetailedStatistics = col_character(),\n",
    "      Solution4DetailedStatistics = col_character(),\n",
    "      Solution5DetailedStatistics = col_character(),\n",
    "      Solution6DetailedStatistics = col_character(),\n",
    "      Solution7DetailedStatistics = col_character(),\n",
    "      Solution8DetailedStatistics = col_character(),\n",
    "      Solution9DetailedStatistics = col_character(),\n",
    "      Solution10DetailedStatistics = col_character()\n",
    "    )) %>% transmute(\n",
    "        n = size,\n",
    "        Run = Run,\n",
    "        preprocessingTime = get('Domain to logic transformation time') + get('Logic to solver transformation time') + ExplorationInitializationTime,\n",
    "        Solution0FoundAt = Solution0FoundAt,\n",
    "        additionalTime = Solution9FoundAt - Solution0FoundAt,\n",
    "        Solution1DetailedStatistics = ProcessDetailedStatistics(Solution1DetailedStatistics)\n",
    "    ) %>% unnest() %>% mutate(\n",
    "        # (Logical) constraint evluation should count as refinement.\n",
    "        ForwardTime = ForwardTime + GlobalConstraintEvaluationTime + FitnessCalculationTime,\n",
    "        preprocessingTime = preprocessingTime,\n",
    "        BacktrackingTime = Solution0FoundAt - (StateCoderTime + ForwardTime + NumericalSolverSumTime)\n",
    "    ) %>% select(n, Run, preprocessingTime, StateCoderTime, ForwardTime, BacktrackingTime, NumericalSolverSumTime, additionalTime)\n",
    "}\n",
    "Load1Log <- function(filename, size) {\n",
    "    read_csv(filename, col_types = cols(\n",
    "      .default = col_double(),\n",
    "      Result = col_character(),\n",
    "      Solution1DetailedStatistics = col_character()\n",
    "    )) %>% filter(Result == \"ModelResultImpl\") %>% transmute(\n",
    "        n = size,\n",
    "        Run = Run,\n",
    "        preprocessingTime = get('Domain to logic transformation time') + get('Logic to solver transformation time') + ExplorationInitializationTime,\n",
    "        Solution0FoundAt = Solution0FoundAt,\n",
    "        Solution1DetailedStatistics = ProcessDetailedStatistics(Solution1DetailedStatistics)\n",
    "    ) %>% unnest(cols = c(Solution1DetailedStatistics)) %>% mutate(\n",
    "        ForwardTime = ForwardTime + GlobalConstraintEvaluationTime + FitnessCalculationTime,\n",
    "        BacktrackingTime = Solution0FoundAt - (StateCoderTime + ForwardTime + NumericalSolverSumTime)\n",
    "    ) %>% select(n, Run, preprocessingTime, StateCoderTime, ForwardTime, BacktrackingTime, NumericalSolverSumTime)\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "ProcessRQ1 <- function(df) {\n",
    "    df %>% group_by(n) %>% summarize(\n",
    "        .groups = 'drop',\n",
    "        time = median(preprocessingTime + StateCoderTime + ForwardTime + BacktrackingTime + NumericalSolverSumTime) / 1000.0\n",
    "    )\n",
    "}\n",
    "ProcessRQ2 <- function(df) {\n",
    "    df %>% group_by(n) %>% summarize(\n",
    "        .groups = 'drop',\n",
    "        preprocessingTime = median(preprocessingTime) / 1000.0,\n",
    "        StateCoderTime = median(StateCoderTime) / 1000.0,\n",
    "        ForwardTime = median(ForwardTime) / 1000.0,\n",
    "        BacktrackingTime = median(BacktrackingTime) / 1000.0,\n",
    "        NumericalSolverSumTime = median(NumericalSolverSumTime) / 1000.0,\n",
    "        additionalTime = median(additionalTime) / 1000.0\n",
    "    )\n",
    "}\n",
    "ProcessRQ3 <- ProcessRQ1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "RQ2Plot <- function(df, name) {\n",
    "    df <- df %>% gather(name, value, -n) %>% filter(name != \"preprocessingTime\")\n",
    "    df$name <- factor(df$name, levels=rev(c('ForwardTime', 'BacktrackingTime', 'StateCoderTime', 'NumericalSolverSumTime', 'additionalTime')))\n",
    "    plot <- df %>% ggplot(aes(x=n, y=value, fill=name)) +\n",
    "        geom_bar(stat='identity') +\n",
    "        scale_fill_brewer(palette='Set2',\n",
    "                          labels=rev(c('Refinement', 'Backtracking', 'State Coding', 'SMT Solver Calls', 'Additional Model Generation')),\n",
    "                          guide=FALSE) +\n",
    "        scale_x_continuous(breaks=c(20, 30, 40, 50, 100), name=\"Model Size (# nodes)\") +\n",
    "        scale_y_continuous(name=\"Runtime (s)\") +\n",
    "        theme_bw()\n",
    "    ggsave(plot=plot, filename=paste0('plots/plot_RQ2_', name, '.pdf'), width=3.5, height=2.5)\n",
    "    plot\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fam domain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Warning message:\n",
      "“`cols` is now required when using unnest().\n",
      "Please use `cols = c(Solution1DetailedStatistics)`”\n",
      "Warning message:\n",
      "“`cols` is now required when using unnest().\n",
      "Please use `cols = c(Solution1DetailedStatistics)`”\n",
      "Warning message:\n",
      "“`cols` is now required when using unnest().\n",
      "Please use `cols = c(Solution1DetailedStatistics)`”\n",
      "Warning message:\n",
      "“`cols` is now required when using unnest().\n",
      "Please use `cols = c(Solution1DetailedStatistics)`”\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<caption>A tibble: 4 × 8</caption>\n",
       "<thead>\n",
       "\t<tr><th scope=col>n</th><th scope=col>Run</th><th scope=col>preprocessingTime</th><th scope=col>StateCoderTime</th><th scope=col>ForwardTime</th><th scope=col>BacktrackingTime</th><th scope=col>NumericalSolverSumTime</th><th scope=col>additionalTime</th></tr>\n",
       "\t<tr><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th></tr>\n",
       "</thead>\n",
       "<tbody>\n",
       "\t<tr><td>20</td><td>1</td><td>33339</td><td> 878</td><td> 2654</td><td>1610</td><td>  7655</td><td> 39044</td></tr>\n",
       "\t<tr><td>30</td><td>1</td><td>36670</td><td>2016</td><td> 5187</td><td>2687</td><td> 33695</td><td>103508</td></tr>\n",
       "\t<tr><td>40</td><td>1</td><td>48868</td><td>3907</td><td> 9219</td><td>4814</td><td> 99075</td><td>309361</td></tr>\n",
       "\t<tr><td>50</td><td>1</td><td>62541</td><td>5581</td><td>12720</td><td>5863</td><td>268490</td><td>552214</td></tr>\n",
       "</tbody>\n",
       "</table>\n"
      ],
      "text/latex": [
       "A tibble: 4 × 8\n",
       "\\begin{tabular}{llllllll}\n",
       " n & Run & preprocessingTime & StateCoderTime & ForwardTime & BacktrackingTime & NumericalSolverSumTime & additionalTime\\\\\n",
       " <dbl> & <dbl> & <dbl> & <dbl> & <dbl> & <dbl> & <dbl> & <dbl>\\\\\n",
       "\\hline\n",
       "\t 20 & 1 & 33339 &  878 &  2654 & 1610 &   7655 &  39044\\\\\n",
       "\t 30 & 1 & 36670 & 2016 &  5187 & 2687 &  33695 & 103508\\\\\n",
       "\t 40 & 1 & 48868 & 3907 &  9219 & 4814 &  99075 & 309361\\\\\n",
       "\t 50 & 1 & 62541 & 5581 & 12720 & 5863 & 268490 & 552214\\\\\n",
       "\\end{tabular}\n"
      ],
      "text/markdown": [
       "\n",
       "A tibble: 4 × 8\n",
       "\n",
       "| n &lt;dbl&gt; | Run &lt;dbl&gt; | preprocessingTime &lt;dbl&gt; | StateCoderTime &lt;dbl&gt; | ForwardTime &lt;dbl&gt; | BacktrackingTime &lt;dbl&gt; | NumericalSolverSumTime &lt;dbl&gt; | additionalTime &lt;dbl&gt; |\n",
       "|---|---|---|---|---|---|---|---|\n",
       "| 20 | 1 | 33339 |  878 |  2654 | 1610 |   7655 |  39044 |\n",
       "| 30 | 1 | 36670 | 2016 |  5187 | 2687 |  33695 | 103508 |\n",
       "| 40 | 1 | 48868 | 3907 |  9219 | 4814 |  99075 | 309361 |\n",
       "| 50 | 1 | 62541 | 5581 | 12720 | 5863 | 268490 | 552214 |\n",
       "\n"
      ],
      "text/plain": [
       "  n  Run preprocessingTime StateCoderTime ForwardTime BacktrackingTime\n",
       "1 20 1   33339              878            2654       1610            \n",
       "2 30 1   36670             2016            5187       2687            \n",
       "3 40 1   48868             3907            9219       4814            \n",
       "4 50 1   62541             5581           12720       5863            \n",
       "  NumericalSolverSumTime additionalTime\n",
       "1   7655                  39044        \n",
       "2  33695                 103508        \n",
       "3  99075                 309361        \n",
       "4 268490                 552214        "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<table>\n",
       "<caption>A tibble: 4 × 7</caption>\n",
       "<thead>\n",
       "\t<tr><th scope=col>n</th><th scope=col>preprocessingTime</th><th scope=col>StateCoderTime</th><th scope=col>ForwardTime</th><th scope=col>BacktrackingTime</th><th scope=col>NumericalSolverSumTime</th><th scope=col>additionalTime</th></tr>\n",
       "\t<tr><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th><th scope=col>&lt;dbl&gt;</th></tr>\n",
       "</thead>\n",
       "<tbody>\n",
       "\t<tr><td>20</td><td>33.339</td><td>0.878</td><td> 2.654</td><td>1.610</td><td>  7.655</td><td> 39.044</td></tr>\n",
       "\t<tr><td>30</td><td>36.670</td><td>2.016</td><td> 5.187</td><td>2.687</td><td> 33.695</td><td>103.508</td></tr>\n",
       "\t<tr><td>40</td><td>48.868</td><td>3.907</td><td> 9.219</td><td>4.814</td><td> 99.075</td><td>309.361</td></tr>\n",
       "\t<tr><td>50</td><td>62.541</td><td>5.581</td><td>12.720</td><td>5.863</td><td>268.490</td><td>552.214</td></tr>\n",
       "</tbody>\n",
       "</table>\n"
      ],
      "text/latex": [
       "A tibble: 4 × 7\n",
       "\\begin{tabular}{lllllll}\n",
       " n & preprocessingTime & StateCoderTime & ForwardTime & BacktrackingTime & NumericalSolverSumTime & additionalTime\\\\\n",
       " <dbl> & <dbl> & <dbl> & <dbl> & <dbl> & <dbl> & <dbl>\\\\\n",
       "\\hline\n",
       "\t 20 & 33.339 & 0.878 &  2.654 & 1.610 &   7.655 &  39.044\\\\\n",
       "\t 30 & 36.670 & 2.016 &  5.187 & 2.687 &  33.695 & 103.508\\\\\n",
       "\t 40 & 48.868 & 3.907 &  9.219 & 4.814 &  99.075 & 309.361\\\\\n",
       "\t 50 & 62.541 & 5.581 & 12.720 & 5.863 & 268.490 & 552.214\\\\\n",
       "\\end{tabular}\n"
      ],
      "text/markdown": [
       "\n",
       "A tibble: 4 × 7\n",
       "\n",
       "| n &lt;dbl&gt; | preprocessingTime &lt;dbl&gt; | StateCoderTime &lt;dbl&gt; | ForwardTime &lt;dbl&gt; | BacktrackingTime &lt;dbl&gt; | NumericalSolverSumTime &lt;dbl&gt; | additionalTime &lt;dbl&gt; |\n",
       "|---|---|---|---|---|---|---|\n",
       "| 20 | 33.339 | 0.878 |  2.654 | 1.610 |   7.655 |  39.044 |\n",
       "| 30 | 36.670 | 2.016 |  5.187 | 2.687 |  33.695 | 103.508 |\n",
       "| 40 | 48.868 | 3.907 |  9.219 | 4.814 |  99.075 | 309.361 |\n",
       "| 50 | 62.541 | 5.581 | 12.720 | 5.863 | 268.490 | 552.214 |\n",
       "\n"
      ],
      "text/plain": [
       "  n  preprocessingTime StateCoderTime ForwardTime BacktrackingTime\n",
       "1 20 33.339            0.878           2.654      1.610           \n",
       "2 30 36.670            2.016           5.187      2.687           \n",
       "3 40 48.868            3.907           9.219      4.814           \n",
       "4 50 62.541            5.581          12.720      5.863           \n",
       "  NumericalSolverSumTime additionalTime\n",
       "1   7.655                 39.044       \n",
       "2  33.695                103.508       \n",
       "3  99.075                309.361       \n",
       "4 268.490                552.214       "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "42.769"
      ],
      "text/latex": [
       "42.769"
      ],
      "text/markdown": [
       "42.769"
      ],
      "text/plain": [
       "[1] 42.769"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAIAAAByhViMAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nOzdfZyVdZ34/+ucM8MwA3MDciOEN4gIeBOGWpi3FZlppZaW6QbrTTLWfll0\nzdVyg7BNXddA0xapxQdboWxurrubuuJ9lrakqGTqGt58ASUcB+Yw9+fu+8f5dX7zQGYYmDke\n5jPP5x8+5lzncJ23n7k48+I6NxPL5XIRAAADX7zUAwAA0D+EHQBAIIQdAEAghB0AQCCEHQBA\nIIQdAEAghB0AQCCEHQBAIMpKPcCe+9a3vvX73/++X3aVy+VyuVw8LnOjKIqy2WwURVYjL5vN\nWoo8B0ZXDowCB0ZXDowCP1i7yv8yiFgs1i97Gzt27LJly7q7dgCHXUNDw6233rrffvv1fVfp\ndLqtra26urrvuxrostlsY2PjkCFDampqSj1L6eVyuW3bto0YMaLUg+wVGhsbY7GY1chrbGwc\nOXJkqafYKzQ1NaVSqX322ae/fmgNaMlkctiwYYlEotSDlF5zc3N7e3tdXV1Z2QAujf7S0tJS\nVlZWUVHR912lUqmzzz67hxtIaQCAQAg7AIBACDsAgEAIOwCAQAg7AIBACDsAgEAIOwCAQAg7\nAIBACDsAgEAIOwCAQAg7AIBACDsAgEAIOwCAQAg7AIBACDsAgEAIOwCAQAg7AIBACDsAgEAI\nOwCAQAg7AIBACDsAgEAIOwCAQAg7AIBACDsAgEAIOwCAQAg7AIBACDsAgEAIOwCAQAg7AIBA\nCDsAgEAIOwCAQAg7AIBACDsAgEAIOwCAQJSVegAAGBTm/mplqUeguG4/4bxSj+CMHQBAKIQd\nAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCE\nHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAg\nhB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIMqKuveNGzfecccdr7zy\nSjqdnjhx4le+8pVDDz00iqLm5uZly5a98MILqVRqypQp9fX1Y8aM6WE7AAC7VMQzdrlcbtGi\nRSNGjFi2bNmKFSsOP/zwhQsXbt++PYqiJUuWbNmyZcGCBTfeeGNVVdWiRYuy2WwP2wEA2KUi\nhl0ymdy8efOsWbOqqqoqKipOO+209vb2t99+u6GhYc2aNZdccsnEiRPHjx9fX1+/adOmdevW\ndbe9eBMCAISkiGFXW1s7derUBx54YPv27e3t7Q888MDYsWMPPPDAV199tby8fOLEifmbDR8+\nfMKECa+88kp324s3IQBASIr7Grurrrrq29/+9vnnnx9F0YgRI7797W8PGTIkmUxWV1fHYrHC\nzWpra5uammpra3e6vXDx+eefv/322wsXm5ubt2/f3vUGeyyXy2Wz2X7Z1UCXy+WiKEqn01Yj\nL5PJWIq8XC6Xy+WsRp5HjIJ0Oh1FUVNTU9dH70ErnU5v377dUgxa3T0sZDKZzs7O9vb2vt9F\nKpXq+VVqRQy7dDq9aNGiqVOn/v3f/315efl99923YMGCH/zgB1EUdXfQ9/yXobGx8X/+538K\nFydNmpROp1OpVH8N7PV8Bdls1moU9OMxFgCrUWApusrnHZGlGNx6fljIZDLFvouoqGG3bt26\n119//frrrx86dGgURWefffb999//5JNPjhkzJplM5nK5QsY1NTWNGDGirq5up9sLOzzhhBMe\neeSRwsUrrriirq5un3326fuo6XS6vb19+PDhfd/VQJfNZrdu3TpkyJDq6upSz1J6+RNUdXV1\npR5kr7B169ZYLGY18rZu3dr10WkwSyaTqVRq5MiRTlNFUbR9+/aqqqpEIlHqQSiN7pqktbU1\nkUhUVFT0/S5SqVQ83tPr6IoYdvknbrqe+Mn/O2by5MmpVGr9+vUHH3xwFEXJZHLDhg3Tpk0b\nN27cTrf//7OWldXU1BQuxv6s76Pmd+JRKeqyCFajwFJ0ZTUKLEVX/fVoHABLMZj18K3v32Lp\nQRHfPDF16tQRI0YsX768ubm5s7PzF7/4RUtLy9FHHz1y5Mhjjz32tttue/311zdt2rR48eJJ\nkyYdeuih3W0v3oQAACEp4hm7/AfRrVixor6+PpPJ7L///gsWLBg3blwURfPmzVu2bNnChQsz\nmcxhhx12zTXX5Au0u+0AAOxScd8Ve8ABB3z7299+7/aqqqr58+f3fjsAALvkd8UCAARC2AEA\nBELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgB\nAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELY\nAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC\n2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAE\nQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEA\nBELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgB\nAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABKKs\n1APsuWw229HR0d7e3i+7ymQy/bKrgS6Xy0VRlM1mrUYURblcLpfLWYq8/LFhNfIcGAXZbDaK\novb29lgsVupZSi//gyked9JkkOruYSGdTud/oPT9LlKpVM/7GcBhF/35526/7Kfw30GusBRW\nI3Jg7IzVKLAUXVmNPA8ag1wP3/r+LZYeDOCwi8fjQ4cOrays7Puu0ul0Npvtl10NdNlstrW1\nNZFIWI0oinK5XEdHh6XIa2tri8ViViOvra3NUuR1dnZmMpnKykpn7KIoSqVSFRUViUSi1INQ\nGt09LGSz2bKysoqKir7fRVlZWc9/15wuBgAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISw\nAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiE\nsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAI\nhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMA\nCISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLAD\nAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISw\nAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAiE\nsAMACISwAwAIhLADAAiEsAMACISwAwAIhLADAAhEWbHv4L777rvnnnvefffdD3zgA7Nnzz7m\n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\nU1NlZWV/jwQAwJ7oVdh98IMf/Md//Me2trauGxsbGxctWjRz5sziDAYAwO4p682NvvWtb82a\nNeuDH/zg6aefHkXRj370o6VLl95zzz1tbW1d304BAEAJ9eqM3cknn/zf//3f1dXVN998cxRF\ny5cvX7FixdSpU1evXn3ccccVeUIAAHqlV2fsoij6xCc+8eyzz27ZsuWtt96KouiAAw4YMWJE\nMQcDAGD39Dbs8iorKw888MD819u2bct/UVdX178zAQCwB3oVdq+99tq8efMee+yxlpaW916b\ny+X6eyoAAHZbr8LuoosuWrt27Zlnnjlu3LhEIlHsmQAA2AO9Crs1a9Y8+OCDH/3oR4s9DQAA\ne6xX74odNmxY4aV1AADsnXoVdl/5yleWL19e7FEAAOiLXj0V+73vfe/0009/4IEHjj322H32\n2WeHa6+66qoiDAYAwO7pVdh9//vff+ihh6Io+vWvf/3ea4UdQFdzf7Wy1CNQXLefcF6pR4Cd\n61XY3XLLLV/4whcuu+yyfffd17tiAQD2Tr0Ku8bGxltuuWX8+PHFngYAgD3WqzdPHHrooe+8\n806xRwEAoC96FXZLliy5/PLLX3jhhWJPAwDAHuvVU7Hf/OY333zzzenTpw8fPvy974p94403\n+n8uAAB2U6/CLh6PT5kyZcqUKcWeBgCAPdarsHviiSeKPQcAAH3Uq9fYAQCw9+vpjN3UqVPn\nzJlz9dVXT506tYebvfzyy/09FQAAu62nsKurq6usrMx/8X7NAwDAHuop7J5++ukdvgAAYK/V\nq9fYHX300S+99NJ7t//bv/3boYce2t8jAQCwJ3oVds8880xLS8sOG9Pp9Isvvrh+/foiTAUA\nwG7bxcedxGKx/BfHHHPMTm8wY8aMfp4IAIA9souwe+655x5//PG//uu/PuOMM0aNGtX1qlgs\nNn78+K9+9avFHA8AgN7aRdhNnz59+vTp991334033jh58uT3ZyYAAPZAr37zxAMPPFDsOQAA\n6KNehd2WLVuuvPLK1atXb968OZvN7nBtLpfb5R4efvjhm2+++Zvf/ObMmTOjKGpubl62bNkL\nL7yQSqWmTJlSX18/ZsyYHrYDALBLvQq7v/qrv7rnnntOOumkT37yk2VlvfojXW3btm3FihVD\nhgwpbFmyZElzc/OCBQsqKipWrly5aNGiW265JR6Pd7d9d+8RAGAQ6lWlPfLII3ffffcZZ5yx\nZ/exdOnSk08++bHHHstfbGhoWLNmzeLFiydOnBhFUX19/Ve+8pV169Z94AMf2On26dOn79n9\nAgAMKr0Ku7a2to9+9KN7dgdPPfXU+vXr58+fXwi7V199tby8PF9vURQNHz58woQJr7zySmtr\n6063F8Juy5YtL7zwQmHPqVSqs7Ozo6NjzwbrKpPJZDKZftnVQJd/Yj2bzVqNKIpyuVwul7MU\nefljw2rkOTAGue6++9lstrOz0xNNg1Z3B0Ymk+nN69Z6I5VK9byrXoXdUUcd9eKLL5588sm7\ne/fNzc1Lly697LLLhg4dWtiYTCarq6sLn5AXRVFtbW1TU1Ntbe1Otxcuvvjii1dddVXh4qRJ\nk1paWrZv3767U3WnH3c10KXTaatRYCkKcrmc1SiwFINZD9/9dDr9fk7CXqXnh4X29va+30X/\nhN3ixYu/9rWvLVmy5Nhjj92tu//nf/7nGTNmHHnkkTts71pvvdmeN2nSpP/zf/5P4eIjjzxS\nWVk5bNiw3Rppp7LZbCqVqqio6PuuBrpcLtfa2ppIJLq2+KCVy+Xa29srKytLPcheobW1NRaL\nWY281tbWqqqqUk9ByXT3o6ejo6O8vNwZu0GruwMjfx53D96l8F6pVKrnWOrVffz1X//122+/\n/dGPfrSqqmr06NE7XPvGG2/s9E8999xzzz777K233rrD9rq6umQymcvlCpM1NTWNGDGiu+2F\nP7j//vvPmTOncPE3v/nN0KFD++XHTDqdzmazfmJFUZTNZvNhZzWiPz/dZiny2trahF1BW1ub\npRjMuvvup1KpoUOHJhKJ93ke9hLdHRjZbLasrKxfzh+VlZX1Q9jF4/FDDjnkkEMO2a37Xr16\ndUtLS319ff5ic3Pz4sWLjzzyyLlz56ZSqfXr1x988MFRFCWTyQ0bNkybNm3cuHE73b5bdwoA\nMGj1KuyeeOKJPdh1fX39BRdcULh42WWXzZ49+yMf+UhNTc2xxx572223zZs3b8iQIT/+8Y8n\nTZp06KGHxmKxnW7fg7sGABiE+uHp3u5UV1dXV1cXLsZiserq6pqamiiK5s2bt2zZsoULF2Yy\nmcMOO+yaa67Jn1fsbjsAALvUq7AbNWpUd1d1dnYmk8ne7ORf/uVfCl9XVVXNnz//vbfpbjsA\nALvUq7A7/vjjd9jy9ttvr1u3btKkSSeddFIRpgIAYLf1Kuz+/d///b0bN2/e/KUvfenTn/50\nf48EAMCe2PPP2tl3331vuummBQsW9OM0AADssT59iOKECRP+8Ic/9NcoAAD0xZ6HXS6XW758\n+T777NOP0wAAsMd69Rq79/5OsEwms3nz5oaGhiuuuKIIUwEAsNv28HPsysvLP/jBD55xxhmF\nXywBAEBp9SrsnnvuuWLPAQBAH/XpzRNRFL3xxhv9MQYAAH21i7B74oknPvWpT02ePPlTn/rU\n/fff3/Wqjo6Ov//7v/e7XAEA9hI9hd3TTz89a9as1atXd3Z2Pvroo6effvrPf/7z/FUPPvjg\nEUcccc011+y///7vy5wAAOxCT2F3/fXXV1VVrV279s0339y4ceNRRx21YMGCjRs3nnPOOZ/6\n1KfeeeedxYsXr1u37n2bFQCAHvT05onnn3/+L//yL6dPnx5F0ZgxY6699tpPf/rTkydPTqVS\nl1566aJFi0aNGvV+zQkAwC70FHYbN2485JBDChenTZsWRdFHPvKRW2+99fDDDy/6aAAA7I6e\nnopNp9NDhgwpXKyoqIii6KqrrlJ1AAB7ob5+3AkAAHsJYQcAEIhd/OaJ11577emnn85/3djY\nGEXRyy+/XFdX1/U2M2fOLNJwAAD03i7C7rrrrrvuuuu6brnssst2uE0ul+vnoQAA2H09hd2C\nBQvetzkAAOijnsJu4cKF79cYAAD0lTdPAAAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELY\nAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC\n2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAE\nQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEA\nBELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgB\nAARC2AEABELYAQAEQtgBAARC2AEABELYAQAEQtgBAASirNQD7LlMJtPU1DR8+PB+2Vs2m926\ndWu/7GpAy+VyURSlUimrkZfJZCxFXi6Xy+VyViPPI8Yg1913P5vNJpPJ93kY9h49HBixWKy1\ntbXvd5FKpbLZbA83GMBhl0gkamtrR4wY0fddpdPptra26urqvu9qoMtms42NjZpwVW8AAB7E\n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\nB8YAfmCld7r77mez2c7Oznh85ydNHBjB6+7AyGQy+R+vfZdKpXre1QA+zHK5XDqdTqVS/bKr\nbDbbL7sa6AphZzXycrmcpRjMevju93DVAH5gpXe6++7nfzDFYrGdXuvACF53B0Y2m+3HsOv5\nBgP4MIvH41VVVcOHD+/7rtLpdFtbW7/saqDLn6srKyuzGtGfq85SDGbdffc7Ozt7ODAyRZuH\nvUR33/1kMllVVZVIJHZ6rQMjeN0dGC0tLWVlZRUVFX2/i1Qq1d2/HPK8xg4AIBDCDgAgEMIO\nACAQwg4AIBDCDgAgEMIOACAQwg4AIBDCDgAgEMIOACAQwg4AIBDCDgAgEMIOACAQwg4AIBDC\nDgAgEMIOACAQwg4AIBDCDgAgEMIOACAQwg4AIBDCDgAgEMIOACAQwg4AIBDCDgAgEMIOACAQ\nwg4AIBDCDgAgEMIOACAQwg4AIBDCDgAgEMIOACAQwg4AIBDCDgAgEMIOACAQwg4AIBDCDgAg\nEMIOACAQwg4AIBDCDgAgEMIOACAQZaUeYACY+6uVpR6B4rr9hPNKPQIA9ANn7AAAAiHsAAAC\nIewAAAIh7AAAAiHsAAAC4V2xsId+uObhUo9A8XnHNDCgOGMHABAIYQcAEAhhBwAQCGEHABAI\nYQcAEAhhBwAQCGEHABAIYQcAEAhhBwAQCGEHABAIYQcAEAhhBwAQCGEHABAIYQcAEAhhBwAQ\nCGEHABCIslIPAACDws37XFrqESiuy0s9QOSMHQBAMIQdAEAghB0AQCC8xg4A3g/nbWkv9QiE\nT9gB9DOvkQ/e3vAaedgpT8UCAARC2AEABMJTsQD9zEupgFIRdrv2wzUPl3oEiuyE80o9ARC+\nRz93c6lHoLi+HB1f6hE8FQsAEAphBwAQCE/Fwh7ykRaDwZ59qoVn3IK3NzzjBjsl7GAPeYE8\nAHsbT8UCAARi7zpj19zcvGzZshdeeCGVSk2ZMqW+vn7MmDGlHgoAYGDYu8JuyZIlzc3NCxYs\nqKioWLly5aJFi2655ZZ4vMSnFd/JXFDaASi2fffoT3kd1WDgpVTAwLIXPRXb0NCwZs2aSy65\nZOLEiePHj6+vr9+0adO6detKPRcAwMCwF52xe/XVV8vLyydOnJi/OHz48AkTJrzyyivTp08v\n7WBOzATPWRkAwrAXhV0ymayuro7FYoUttbW1TU1NhYtPP/30ddddV7g4bNiwpqam4cOH9/2u\nc7lcLpfbunVr33fFQNTDtz6bzTowBrPuvvseMQa57r772Ww2mUy+z8Ow9+jhEaOjo6O1tbXv\nd5FKpbLZbA832IvCLoqirlW39zh1zLJSj/D+yeVy2Ww2FouV/KWNe79BdWBEUZR/KHFg9Mag\nOjay2Wwul0skEqUeZAAYhAdGPB7fO3+yB2wvCru6urpkMpnL5QoHQVNT04gRIwo3mDlz5r33\n3lu4OHfu3Nra2q432GPpdLqtra26urrvuxrostlsY2NjeXl5TU1NqWcpvVwut23btn45xgLQ\n2NgYi8WsRl5jY6OlyGtqakqlUnV1dX5+R1GUTCaHDRsmc6Moam5ubm9vr6mpKSvbi0qjVFpa\nWsrKyioqKvq+q1Qq1fM/sPeif3xPnjw5lUqtX78+fzGZTG7YsGHatGmlnQoAYKDYi8Ju5MiR\nxx577G233fb6669v2rRp8eLFkyZNOvTQQ0s9FwDAwLB3nSCdN2/esmXLFi5cmMlkDjvssGuu\nuca5fQCAXtq7wq6qqmr+/PmlngIAYEDai56KBQCgL4QdAEAghB0AQCCEHQBAIIQdAEAghB0A\nQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQd\nAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCEHQBAIIQdAEAghB0AQCCE\nHQBAIMpKPUCf3HPPPbW1tX3fTzabTaVSFRUVfd/VQJfL5VpbW8vKyqxGFEW5XK69vb2ysrLU\ng+wVWltbY7GY1chrbW2tqqoq9RR7hfb29kwmU1VVFYvFSj1L6XV0dJSXl8fjTppEnZ2dqVSq\nsrLSakRR1NnZGY/Hy8r6IboymUzPN4jlcrm+301JPPHEEw0NDf2yq1wul81mE4lEv+xtQOvo\n6HjooYdGjx794Q9/uNSz7BXS6XS//FUMwOrVq8vKyj72sY+VepC9ggOj4KmnnmpsbPz0pz/t\n53cURel0OpFIaNwoitatW/d//+//Pf744/vl/MtAl81moyjqr78jw4cPP+WUU7q7dgCHHcWw\nbdu2WbNmnXDCCYsXLy71LOxdTjnllMrKynvvvbfUg7B3mTt37jPPPPOb3/xmyJAhpZ6FvcgN\nN9zw85///Kc//enUqVNLPcvg4h9YAACBEHYAAIEQdgAAgfAaOwCAQDhjBwAQCGEHABAIYQcA\nEAgfsDnYNTY2Ll++/Pnnn+/s7DzooIMuuOCCQw45JIqi5ubmZcuWvfDCC6lUasqUKfX19WPG\njCn1sLx/NmzYsGLFipdeeimXy02cOPErX/lK/sOoHBjkPfzwwzfffPM3v/nNmTNnRg6MQW/e\nvHlvvPFG4eLQoUP/9V//NXJglII3Twx2l19++ZAhQy655JLKysqVK1euXbv2xz/+8dChQ7/7\n3e82NzfPnTu3oqJi5cqVb7zxxi233OKT5QeJdDp98cUXT58+/Ytf/GI8Hl+1atVvf/vb5cuX\nV1ZWOjCIomjbtm3z5s1rbW294oor8mHnwBjkLrzwws9//vP5gyGKong8PnLkyMiBUQoWd1Db\nvn376NGjv/71rx900EHjxo2bPXt2MpncsGFDQ0PDmjVrLrnkkokTJ44fP76+vn7Tpk3r1q0r\n9by8T1paWs4444z6+voPfOAD48aNO+ecc1paWt5++20HBnlLly49+eSTC78t14HB9u3b9913\n31F/lq86B0ZJCLtBrbq6+uqrr95vv/3yF9999914PD5q1KhXX321vLx84sSJ+e3Dhw+fMGHC\nK6+8UrpJeV/V1taeddZZlZWVURRt3779P/7jPyZMmLDffvs5MIii6Kmnnlq/fv15551X2OLA\nGORSqVRHR8dTTz01f/78iy666Lrrrtu0aVPkwCgRr7Hj/7N9+/Yf/OAHZ5555ogRI5LJZHV1\nddffY11bW9vU1FTC8Xj/ZbPZc845J5VKHX744ddee215ebkDg+bm5qVLl1522WVDhw4tbHRg\nDHKtra11dXXpdPprX/taFEV33nnn1Vdf/U//9E8OjJIQdkRRFG3cuPHaa6898sgj58yZk9/S\n9a8ig1M8Hr/55pu3bt36y1/+8pvf/OZNN90UOTAGvX/+53+eMWPGkUceucN2B8ZgVltb+y//\n8i+Fi1deeeWcOXN+85vfRA6MUvBULNHzzz//t3/7t5/97GcvvfTS/F/Curq6ZDLZ9Y01TU1N\nI0aMKN2MlMaECROOOOKIK6+8sqmp6fHHH3dgDHLPPffcs88+e+GFF+6w3YFBV5WVlaNHj25o\naHBglISwG+z+8Ic/3HDDDZdffvlnPvOZwsbJkyenUqn169fnL+bfUTFt2rQSzcj7be3atZdc\ncklHR0f+YiwWKysrixwYg97q1atbWlrq6+vPP//8888/v6mpafHixdddd50DY5B78803b731\n1nQ6nb/Y3t7+zjvv7Lvvvg6MkkgsXLiw1DNQMp2dnd/+9rdPPfXUGTNmtP5ZPB6vrq5+8803\nH3300SlTprS2tv7whz8cNmzY+eef76T6IFFdXX3vvfe+9tprBxxwQFtb21133fXKK69cfPHF\no0ePdmAMZh/84Ac/3cVjjz12wQUXnHXWWXV1dQ6MwSyRSCxdunTTpk0HHnhgU1PT7bff3tzc\nfOmll/pRUhI+x25Qe/755//u7/5uh41z5849/fTTW1tbly1btnbt2kwmc9hhh9XX1zt/Pqi8\n+eabd9xxxx/+8IdYLLb//vv/xV/8xfTp06MocmBQMHv27K997Wv5jy5zYAxyr7322h133JF/\nG+yUKVO++tWvjh07NnJglIKwAwAIhNfYAQAEQtgBAARC2AEABELYAQAEQtgBAARC2AEABELY\nAQAEQtgBe27hwoWxWGzMmDGpVOq911588cWxWOz444/fs52fe+65w4cP780tjz/++KlTp3Z3\nbUNDw/e+972jjjpq1KhR5eXlY8aMOfXUU//7v/+7cIOZM2f28Mf74t133z3wwAMvuuiiwpZf\n/OIXX/ziF/Nfv/POO+PHjy/G/e6g9yvZnWuuuWafffZ54403+mkioFjKSj0AMLDF4/HGxsZf\n/vKXZ555ZtftbW1tP//5z8vLy0s1WF5jY+MxxxyzZcuWCy+88PLLL08kEuvXr1++fPlpp532\ns5/97Nxzz42i6Nxzz21ra+v3u85ms+edd15tbe2tt95a2Pjss89+6EMfeu/Xe7nvfOc7v/nN\nb84+++xf//rXFRUVpR4H6JawA/okHo9/+MMfvuOOO3YIu3vuuaetrS3/i8hKaMWKFW+88cZd\nd931pS99qbDxa1/72hFHHHHVVVd98YtfjMfj8+fPL8Zdr1y58sEHH3zssccqKysLG5955pnC\n3T377LMzZswoxl33u0Qicdtttx1++OG33nrr3/zN35R6HKBbnooF+iSdTn/mM5+57777/vSn\nP3XdvmLFio997GM7nN25//77TzzxxOrq6srKysMPP/z73/9+4bca5nK5RYsW7bfffkOHDj3i\niCPuvvvuHe7o8ccf/+QnP1lTU1NVVTVjxozly5f3Zry33347iqKjjjqq68YRI0Y8/fTTL730\nUjwej7o8Ffu73/0utjO///3vd3eGTCZz7bXXnnjiiSeddFLX7V1jroewO/HEE0844YS1a9d+\n4hOfqKmpGTNmzJe//OUtW7YUblCklXz77be/+tWvHnDAAUOHDt13332/8IUvvPzyy/mrpk2b\ndvbZZ//DP/xDS0tLd//XQOnlAPbUggULoih69dVX4/H4P/7jPxa2b9y4MR6PL1++fObMmccd\nd1x+4z333BOLxU499dR///d/f+ihhy6//PIoir7xjW/kr73hhhuiKDr//PNXr169atWqww8/\nfMqUKcOGDctf+9BDDyUSiRNPPPE///M/H3zwwfr6+iiKCvd43HHHTZkyZacT3nnnnVEUnXXW\nWVu3bu3u/+IjH/lI/o8nk8nVXfzXf/3X6NGjJ0yYsG3btl3OsIPHH388iqLly5fnL954440V\nFRX5zK34s1gslv9i48aNO/zxT3ziE/vtt98xxxyzevXqP/3pT3fffXcikZgzZ06xV3LmzJn7\n7rvvj3/840ceeeRnP/vZEUccMWbMmJaWlvy1v/zlL6MoWrVqVXcrCZScsAP2XD7s2traZs2a\nddhhhxW2X3/99ZWVlclk8iMf+Ugh7KZOnbr//vt3dHQUbnbmmWeWl5c3NDRks9nx48cffvjh\nhaveeuut8vLyQo586EMfOvjggwuFkcvlPve5z1VXV7e1teV6DLtMJpN/s0JFRcVpp512ww03\nPP3005lMputtCmG3gwsuuKCiouK3v/1tb2bYwd/93d9FUbRDsd19992f//zn819v3rx5/Pjx\nO505l8t94hOfiKLoySef7LqlcPsirWRTU1MURVdddVXhqj/+8Y/f+973Nm3alL/Y0tIyZMiQ\niy66qLuxgZLzVCzQD/7yL//yxRdfXLNmTf7iihUrzjzzzOrq6sIN3nrrrZdffvm0004bMmRI\nYeNnP/vZVCr19NNPb9iw4a233vr4xz9euGrcuHFHH310/ustW7asXbv29NNPj8fj7X922mmn\nbd++fd26dT0PFo/HV61a9cADD3zhC1947rnn/vZv/3bmzJljx469+uqrW1tbe/iD//RP/3TH\nHXfceuutH/7wh/dghmeffXbs2LEf+MAHum789a9/XXiP8K9//euPfvSjPQxQVVV13HHHFS5O\nmDBh8+bNUTFXsrKycp999rnzzjsffvjhbDYbRdGkSZOuvvrqwlt3q6qqpk6d+swzz/QwNlBa\nwg7oB2eddVZ1dfUdd9wRRdGaNWteeuml2bNnd73Bpk2boijaIXTGjRsXRdFbb72VT5bRo0d3\nvbbQE2+99VYURTfffHNlF/nnEDdu3Nib8T71qU/97Gc/27Rp0/r163/0ox9Nmzbt+uuvnzVr\nVj5f3uupp56aP3/+JZdccvHFF+/ZDO+8886oUaN22Pjkk08WWu3JJ5/sOex2WI2ysrL8tMVb\nyfLy8nvvvTcej8+aNWvMmDFnn332ypUr0+l0112NGjWqoaGhh7GB0vKuWKAfVFVVnXPOOXfe\neef3v//9FStWjBs37pOf/GTXG8RisSiKdgipXC4XRVE8Hs/9+YX/XWUyma4XL7zwwq9+9as7\n3Obggw/erTkPOuiggw466KKLLrr44ouXL1/+5JNPnnjiiTvcZvPmzWefffaHPvShH/zgBztc\n1fsZksnkyJEjCxcnTJjQ0NDQ0dFRuLvOzs7y8vKrr776vPPO6+UbQfKKupLHHXfcq6+++vjj\nj99///333Xff+eefv3jx4ieeeKLwxt66urpt27b1flrgfSbsgP4xZ86c5cuXP/jgg6tWrZoz\nZ04ikeh67YQJE6I/n20qyF+cMGFC/gxT/mxTQeHjcPfff/8oijKZzMyZM3drpI6OjrvvvnvY\nsGE7fBRLLBY76aSTli9fvmHDhh3+SCqV+uIXv5jJZP7t3/6t63OduztDTU1N/iVreRs3bnzq\nqaeuvPLKX/3qV1EUpdPpESNGNDQ07MFnwhV7JROJxMc//vGPf/zjN974/9q7v1Dm/jgO4Oes\n7ZA/U/JnkYiSC+NwoRS50I5c6SjFzZS0MrRyIRfmT7uyJzcoUqjdLAcjrbXWilJ2M2MXhDJX\nipxwNWJ2notT67Sf/PKwZ5zn/bo6++6c9tn3Yn36fHY+59f8/LzRaOQ4rru7W3z34eEhKyvr\nozEDwF+DViwAfI3GxsbS0lKLxcLzfFwfliAIjUZTWVnpdDqfnp5iiw6HIy0trb6+vqSkJCcn\nx+12xwpR5+fnwWBQPM7Ozq6rq9va2pLWimw22+joaFyjMA5FUZOTkwaDIRQKSddfX1/X1tYI\ngqiqqoq7ZGhoyOfzcRwX1+v8aAy5ublxLcujoyOapsXjk5OTsrKyP5v0m7idPDg46OzslA5V\nYRiGIIjb29vYCs/zcX1eAPhWkNgBwNcgSVKv1/v9/urq6v8mTARBTE1NXV9ft7W1bW9vu91u\no9HodrvNZrNarVYoFH19fRcXFx0dHQ6HY2FhgWEY6Yw3q9UaDoebmppsNpvH4zGbzb29vVdX\nV0rle20HkiQXFxcfHx9pmjYYDDMzM0tLSxaLpba21ul0Dg4OarVa6fkcx83NzbW3tz8/P3sl\nxLzwQzHQNH1zcyOtq0kTu8PDw8+MJk7QThYWFrpcLp1Ot7y87PV6V1dX9Xq9Wq1mWVa8NhwO\nn52d/ZSnZQD8o5J7Uy4A/GixcSfiy1AoRJLk9PR07ATpuBNBEDweT0NDQ3p6ekpKSk1NTWzM\nmyAIkUhkZGREo9FQFKXVajc3NwcGBiiKip2wt7en0+kyMzNVKlV5ebnVan15eRHfemfciSAI\nx8fHPT09YoVMqVTm5+e3traur69LgxQvN5lMb/5Ojo+P/28McXZ2dgiCWFlZkX6K3+8Xj00m\n0+zs7Dsb29zcXFxcLF0RHzib6J0MBoMsy+bl5alUqoKCApZlA4FA7EKXy0UQhN1ufydyAEgu\nUnjrn7YAAPAZkUikoqKiqKhIzPDkoaury+v1Xl5eZmRkJDsWAHgbWrEAAF9PqVSOjY3t7u6K\nd0vIwOnpKcdxw8PDyOoAvjNU7AAAEiIajba0tPA87/P5UlNTkx3Op0SjUYZh7u7u9vf3f/p3\nAZA3VOwAABJCoVDY7fb7+/v+/v5kx/JZExMTgUBgY2MDWR3AN4eKHQAAAIBMoGIHAAAAIBNI\n7AAAAABkAokdAAAAgEwgsQMAAACQCSR2AAAAADKBxA4AAABAJpDYAQAAAMjEb/85njrbF1HE\nAAAAAElFTkSuQmCC",
      "text/plain": [
       "plot without title"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 420,
       "width": 420
      },
      "text/plain": {
       "height": 420,
       "width": 420
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "FamilyTreeRQ2Raw <- rbind(\n",
    "#     Load10Log(\"measurements/stats/FamilyTree//size010to-1r10n10rt300nsdrealstats_06-0249.csv\", 10),\n",
    "    Load10Log(\"measurements1/stats1010.csv\", 20),\n",
    "    Load10Log(\"measurements1/stats1515.csv\", 30),\n",
    "    Load10Log(\"measurements1/stats2020.csv\", 40),\n",
    "    Load10Log(\"measurements1/stats2525.csv\", 50)\n",
    ")\n",
    "FamilyTreeRQ2Raw\n",
    "FamilyTreeRQ2 <- FamilyTreeRQ2Raw %>% ProcessRQ2\n",
    "FamilyTreeRQ2\n",
    "median(FamilyTreeRQ2Raw$preprocessingTime) / 1000.0\n",
    "FamilyTreeRQ2 %>% RQ2Plot('FamilyTree')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "R",
   "language": "R",
   "name": "ir"
  },
  "language_info": {
   "codemirror_mode": "r",
   "file_extension": ".r",
   "mimetype": "text/x-r-source",
   "name": "R",
   "pygments_lexer": "r",
   "version": "4.0.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}