├── .gitignore ├── .styleci.yml ├── changelog.md ├── composer.json ├── config └── survey-manager.php ├── contributing.md ├── database └── migrations │ ├── 2018_02_21_000001_create_surveys_table.php │ └── 2018_05_25_053226_create_survey_results_table.php ├── license.md ├── mix-manifest.json ├── package-lock.json ├── package.json ├── phpunit.xml ├── public ├── css │ └── survey.css ├── js │ ├── survey-front.js │ └── survey-manager.js └── mix-manifest.json ├── readme.md ├── resources ├── assets │ └── js │ │ ├── App.vue │ │ ├── base.js │ │ ├── components │ │ ├── SurveyBuilder.vue │ │ ├── SurveyEditor.vue │ │ ├── SurveyList.vue │ │ ├── SurveyResult.vue │ │ └── SurveyShow.vue │ │ ├── router.js │ │ ├── survey-front.js │ │ └── survey-manager.js └── views │ ├── admin.blade.php │ └── survey.blade.php ├── src ├── LaravelSurveyJsServiceProvider.php ├── app │ ├── Http │ │ ├── Controllers │ │ │ ├── API │ │ │ │ ├── SurveyAPIController.php │ │ │ │ └── SurveyResultAPIController.php │ │ │ └── SurveyController.php │ │ ├── Requests │ │ │ ├── CreateSurveyRequest.php │ │ │ └── UpdateSurveyRequest.php │ │ └── Resources │ │ │ ├── SurveyResource.php │ │ │ └── SurveyResultResource.php │ └── Models │ │ ├── Survey.php │ │ └── SurveyResult.php └── routes │ ├── api.php │ └── web.php └── webpack.mix.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /vendor 6 | /.idea 7 | /.vscode 8 | /.vagrant 9 | Homestead.json 10 | Homestead.yaml 11 | npm-debug.log 12 | yarn-error.log 13 | .env 14 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `LaravelSurveyJs` will be documented in this file. 4 | 5 | ## Version 0.3.0 6 | 7 | ### Changes 8 | - Custom widgets support 9 | - Remove unnecessary dependecies 10 | - Refactoring front pages 11 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aidynmakhataev/laravelsurveyjs", 3 | "description": "Laravel wrapper for surveyjs library", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Aidyn Makhataev", 8 | "email": "makataev.7@gmail.com", 9 | "homepage": "https://github.com/AidynMakhataev" 10 | } 11 | ], 12 | "homepage": "https://github.com/aidynmakhataev/laravelsurveyjs", 13 | "keywords": [ 14 | "Laravel", "LaravelSurveyJs", "surveyjs", "survey manager", "laravel survey", "survey editor", "surveyjs builder", "aidynmakhataev" 15 | ], 16 | "require": { 17 | "illuminate/support": "^8", 18 | "cviebrock/eloquent-sluggable": "^8.0" 19 | }, 20 | "require-dev": { 21 | "phpunit/phpunit": "^9.3.3", 22 | "orchestra/testbench": "^3.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "AidynMakhataev\\LaravelSurveyJs\\": "src/" 27 | } 28 | }, 29 | "autoload-dev": { 30 | "psr-4": { 31 | "AidynMakhataev\\LaravelSurveyJs\\Tests\\": "tests" 32 | } 33 | }, 34 | "extra": { 35 | "laravel": { 36 | "providers": [ 37 | "AidynMakhataev\\LaravelSurveyJs\\LaravelSurveyJsServiceProvider" 38 | ], 39 | "aliases": { 40 | "LaravelSurveyJs": "AidynMakhataev\\LaravelSurveyJs\\Facades\\LaravelSurveyJs" 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /config/survey-manager.php: -------------------------------------------------------------------------------- 1 | 'survey', 13 | 14 | // The prefix used in api endpoints 15 | 'api_prefix' => 'api', 16 | 17 | // The prefix used in admin route 18 | 'admin_prefix' => 'admin', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Middleware 23 | |-------------------------------------------------------------------------- 24 | */ 25 | 26 | // route middleware 27 | 'route_middleware' => ['web'], 28 | 29 | // api middleware 30 | 'api_middleware' => ['api'], 31 | 32 | // admin middleware 33 | 'admin_middleware' => ['web'], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Other config 38 | |-------------------------------------------------------------------------- 39 | */ 40 | 41 | // Pagination in admin section 42 | 'pagination_perPage' => 12, 43 | 44 | // User model 45 | 'user_model' => 'App\User', 46 | 47 | // Default locale for survey 48 | 'locale' => 'en', 49 | 50 | // Default theme for survey 51 | 'theme' => 'darkblue', 52 | 53 | /* 54 | |-------------------------------------------------------------------------- 55 | | SurveyJS Builder Configuration 56 | | More: https://surveyjs.io/Documentation/Builder/?id=surveyeditor 57 | |-------------------------------------------------------------------------- 58 | */ 59 | 60 | 'builder' => [ 61 | 62 | 'theme' => 'darkblue', 63 | 64 | 'showEmbededSurveyTab' => false, 65 | 66 | 'showJSONEditorTab' => false, 67 | 68 | 'showTestSurveyTab' => true, 69 | 70 | 'showPropertyGrid' => true, 71 | 72 | 'showOptions' => false, 73 | 74 | 'showState' => false, 75 | 76 | 'haveCommercialLicense' => false, 77 | ], 78 | 79 | /* 80 | |-------------------------------------------------------------------------- 81 | | SurveyJS Custom Widgets 82 | |-------------------------------------------------------------------------- 83 | */ 84 | 'widgets' => [ 85 | 86 | 'icheck' => false, 87 | 88 | 'select2' => false, 89 | 90 | 'inputmask' => false, 91 | 92 | 'jquerybarrating' => false, 93 | 94 | 'jqueryuidatepicker' => false, 95 | 96 | 'nouislider' => false, 97 | 98 | 'select2tagbox' => false, 99 | 100 | 'signaturepad' => false, 101 | 102 | 'sortablejs' => false, 103 | 104 | 'ckeditor' => false, 105 | 106 | 'autocomplete' => false, 107 | 108 | 'bootstrapslider' => false, 109 | ], 110 | ]; 111 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Anyone is welcome to contribute. Fork, make your changes, and then submit a pull request. 4 | 5 | Contributions are accepted via Pull Requests on [Github](https://github.com/aidynmakhataev/laravelsurveyjs). 6 | 7 | # TODO 8 | If you want to contribute but do not know where to start, this list provides some starting points. 9 | 10 | - Add theme support 11 | - Add analytics and reports for survey results 12 | - Add supporting for Laravel < 5.5 13 | - Localization for Survey Builder 14 | - Set up TravisCI, StyleCI, ScrutinizerCI 15 | - Write a comprehensive ReadMe 16 | - Add license text 17 | 18 | ## Pull Requests 19 | 20 | - **Document any change in behaviour** - Make sure the `readme.md` and any other relevant documentation are kept up-to-date. 21 | 22 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. 23 | 24 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 25 | 26 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 27 | 28 | 29 | **Happy coding**! 30 | -------------------------------------------------------------------------------- /database/migrations/2018_02_21_000001_create_surveys_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name'); 19 | $table->string('slug'); 20 | $table->json('json'); 21 | $table->timestamps(); 22 | $table->softDeletes(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('surveys'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_05_25_053226_create_survey_results_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('survey_id'); 19 | $table->unsignedInteger('user_id')->nullable(); 20 | $table->string('ip_address')->nullable(); 21 | $table->json('json'); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('survey_results'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | # The license 2 | 3 | Copyright (c) Aidyn Makhataev 4 | 5 | ...Add your license text here... -------------------------------------------------------------------------------- /mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/C:/public/js/survey-manager.js": "/C:/public/js/survey-manager.js" 3 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "npm run development -- --watch", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "axios": "^0.18", 14 | "bootstrap": "^3.4.1", 15 | "popper.js": "^1.12", 16 | "cross-env": "^5.1", 17 | "laravel-mix": "^2.0", 18 | "vue": "^2.5.7", 19 | "survey-vue": "^1.0.15", 20 | "surveyjs-editor": "^1.0.15", 21 | "survey-knockout": "^1.0.22" 22 | }, 23 | "dependencies": { 24 | "surveyjs-widgets": "^1.0.61", 25 | "vue-router": "^3.0.1", 26 | "vuetify": "^1.0.18" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | 19 | src/ 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /public/css/survey.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * surveyjs - Survey JavaScript library v1.0.55 3 | * Copyright (c) 2015-2018 Devsoft Baltic OÜ - http://surveyjs.io/ 4 | * License: MIT (http://www.opensource.org/licenses/mit-license.php) 5 | */ 6 | .sv_window { 7 | position: fixed; 8 | bottom: 3px; 9 | right: 10px; 10 | background-color: cadetblue; 11 | padding: 1px; 12 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 13 | font-size: 14px; 14 | font-style: normal; 15 | font-weight: 400; 16 | line-height: 1.42857143; 17 | text-align: left; 18 | text-align: start; 19 | text-decoration: none; 20 | text-shadow: none; 21 | text-transform: none; 22 | letter-spacing: normal; 23 | word-break: normal; 24 | word-spacing: normal; 25 | word-wrap: normal; 26 | white-space: normal; 27 | background-color: #fff; 28 | -webkit-background-clip: padding-box; 29 | background-clip: padding-box; 30 | border: 1px solid #ccc; 31 | border: 1px solid rgba(0, 0, 0, 0.2); 32 | border-radius: 6px; 33 | -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); 34 | box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); 35 | line-break: auto; } 36 | 37 | .sv_window_title { 38 | padding: 8px 14px; 39 | margin: 0; 40 | font-size: 14px; 41 | background-color: #f7f7f7; 42 | border-bottom: 1px solid #ebebeb; 43 | border-radius: 5px 5px 0 0; } 44 | 45 | .sv_window_content { 46 | padding: 8px; 47 | margin: 0; } 48 | 49 | .sv_window_title a, 50 | .sv_window_title a:link, 51 | .sv_window_title a:visited { 52 | text-decoration: none; 53 | font-size: 14px; 54 | font-style: normal; 55 | color: black; } 56 | 57 | .sv_main.sv_frame .sv_container { 58 | max-width: 80%; 59 | margin: auto; 60 | padding: 0 1em; } 61 | .sv_main.sv_frame .sv_container .sv_header { 62 | padding-top: 5em; 63 | padding-bottom: 1em; } 64 | 65 | .sv_main { 66 | background-color: #f4f4f4; } 67 | .sv_main hr { 68 | border-bottom: 1px solid #e7e7e7; } 69 | .sv_main input[type="button"], 70 | .sv_main button { 71 | color: white; 72 | background-color: #1ab394; } 73 | .sv_main input[type="button"]:hover, 74 | .sv_main button:hover { 75 | background-color: #179d82; } 76 | .sv_main .sv_q_other input, 77 | .sv_main .sv_q_text_root, 78 | .sv_main .sv_q_dropdown_control, 79 | .sv_main input[type="text"], 80 | .sv_main select, 81 | .sv_main textarea { 82 | border: 1px solid #e7e7e7; 83 | color: #6d7072; 84 | background-color: white; } 85 | .sv_main .sv_q_other input:focus, 86 | .sv_main .sv_q_text_root:focus, 87 | .sv_main .sv_q_dropdown_control:focus, 88 | .sv_main input[type="text"]:focus, 89 | .sv_main select:focus, 90 | .sv_main textarea:focus { 91 | border: 1px solid #1ab394; } 92 | .sv_main .sv_select_wrapper { 93 | background-color: white; } 94 | .sv_main .sv_select_wrapper:before { 95 | background-color: #1ab394; } 96 | .sv_main .sv_header { 97 | color: #6d7072; } 98 | .sv_main .sv_custom_header { 99 | background-color: #e7e7e7; } 100 | .sv_main .sv_container { 101 | color: #6d7072; } 102 | .sv_main .sv_body { 103 | background-color: white; 104 | border-top: 2px solid #1ab394; } 105 | .sv_main .sv_progress { 106 | background-color: #e7e7e7; } 107 | .sv_main .sv_progress_bar { 108 | background-color: #1ab394; } 109 | .sv_main .sv_p_root > .sv_row { 110 | border-bottom: 1px solid #e7e7e7; } 111 | .sv_main .sv_p_root > .sv_row:nth-child(odd) { 112 | background-color: white; } 113 | .sv_main .sv_p_root > .sv_row:nth-child(even) { 114 | background-color: #f4f4f4; } 115 | .sv_main .sv_q_erbox:not([style*="display: none"]):not([style*="display:none"]) { 116 | border: 1px solid #ed5565; 117 | background-color: #fcdfe2; 118 | color: #ed5565; } 119 | .sv_main .sv_q_erbox:not([style*="display: none"]):not([style*="display:none"]) + input, 120 | .sv_main .sv_q_erbox:not([style*="display: none"]):not([style*="display:none"]) + textarea, 121 | .sv_main .sv_q_erbox:not([style*="display: none"]):not([style*="display:none"]) + .sv_select_wrapper select { 122 | border: 1px solid #ed5565; } 123 | .sv_main .sv_q_erbox:not([style*="display: none"]):not([style*="display:none"]) + input:focus, 124 | .sv_main .sv_q_erbox:not([style*="display: none"]):not([style*="display:none"]) + textarea:focus, 125 | .sv_main .sv_q_erbox:not([style*="display: none"]):not([style*="display:none"]) + .sv_select_wrapper select:focus { 126 | outline: #ed5565 auto 5px; } 127 | .sv_main table.sv_q_matrix tr, 128 | .sv_main table.sv_q_matrix_dropdown tr, 129 | .sv_main table.sv_q_matrix_dynamic tr { 130 | border-bottom: 1px solid #e7e7e7; } 131 | .sv_main .sv_q_m_cell_selected { 132 | color: white; 133 | background-color: #179d82; } 134 | .sv_main .sv_q_rating_item.active .sv_q_rating_item_text { 135 | background-color: #179d82; 136 | border-color: #179d82; 137 | color: white; } 138 | .sv_main .sv_q_rating_item .sv_q_rating_item_text { 139 | border: 1px solid #e7e7e7; } 140 | .sv_main .sv_q_rating_item .sv_q_rating_item_text:hover { 141 | border: 1px solid #179d82; } 142 | .sv_main .sv_q_imgsel.checked label > div { 143 | background-color: #1ab394; } 144 | .sv_main .sv_q_file_remove:hover { 145 | color: #1ab394; } 146 | 147 | .sv_main { 148 | position: relative; 149 | width: 100%; 150 | font-family: "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif; 151 | font-size: 14px; } 152 | .sv_main hr { 153 | border: none; } 154 | .sv_main input[type="button"], 155 | .sv_main button { 156 | font-size: 0.85em; 157 | font-weight: bold; 158 | line-height: 2em; 159 | border: none; 160 | min-width: 100px; 161 | cursor: pointer; 162 | padding: 0 2em; 163 | border-radius: 2px; } 164 | .sv_main .sv_custom_header { 165 | position: absolute; 166 | width: 100%; 167 | height: 74%; 168 | max-height: 275px; } 169 | .sv_main .sv_container { 170 | position: relative; } 171 | .sv_main .sv_container .sv_header { 172 | padding: 1em; } 173 | .sv_main .sv_container .sv_header h3 { 174 | font-size: 2em; 175 | font-weight: 300; 176 | text-align: left; 177 | margin: 0; } 178 | .sv_main .sv_container .sv_body { 179 | padding: 1em 1em 5em 1em; } 180 | .sv_main .sv_container .sv_body.sv_completed_page { 181 | text-align: center; 182 | padding: 5em 1em; } 183 | .sv_main .sv_container .sv_body.sv_completed_page > h3 { 184 | margin: 0; 185 | font-size: 30px; 186 | font-weight: 300; } 187 | .sv_main .sv_container .sv_body .sv_progress { 188 | height: 0.3em; } 189 | .sv_main .sv_container .sv_body .sv_progress .sv_progress_bar { 190 | height: 100%; 191 | min-width: 100px; 192 | position: relative; 193 | margin-top: 2em; } 194 | .sv_main .sv_container .sv_body .sv_progress .sv_progress_bar > span { 195 | position: absolute; 196 | top: -1.5em; 197 | display: inline-block; } 198 | .sv_main .sv_container .sv_body .sv_p_root .sv_page_title { 199 | font-size: 1em; 200 | margin-top: 0.1em; 201 | font-weight: normal; } 202 | .sv_main .sv_container .sv_body .sv_p_root .sv_p_title { 203 | font-weight: bold; 204 | font-size: 1.15em; 205 | margin: 1.5em 0 0 0; } 206 | .sv_main .sv_container .sv_body .sv_p_root > .sv_row { 207 | padding: 0; } 208 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_title { 209 | font-weight: bold; 210 | font-size: 1em; 211 | margin: 0.5em 0; } 212 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_description { 213 | margin-top: -0.6em; } 214 | .sv_main .sv_container .sv_body .sv_p_root .sv_q { 215 | padding: 0.5em 1em 1.5em 1em; 216 | box-sizing: border-box; 217 | overflow: auto; } 218 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_panel_dynamic .sv_q_title { 219 | font-weight: normal; } 220 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_erbox:not([style*="display: none"]):not([style*="display:none"]) { 221 | margin: 1em 0; 222 | padding: 1em; } 223 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_other input, 224 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_text_root, 225 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_dropdown_control, 226 | .sv_main .sv_container .sv_body .sv_p_root .sv_q input[type="text"], 227 | .sv_main .sv_container .sv_body .sv_p_root .sv_q select, 228 | .sv_main .sv_container .sv_body .sv_p_root .sv_q textarea { 229 | position: relative; 230 | width: 100%; 231 | box-sizing: border-box; 232 | font-size: 1em; 233 | line-height: 2em; 234 | padding-left: 1em; } 235 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_other input:focus, 236 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_text_root:focus, 237 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_dropdown_control:focus, 238 | .sv_main .sv_container .sv_body .sv_p_root .sv_q input[type="text"]:focus, 239 | .sv_main .sv_container .sv_body .sv_p_root .sv_q select:focus, 240 | .sv_main .sv_container .sv_body .sv_p_root .sv_q textarea:focus { 241 | outline: none; } 242 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_other input, 243 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_dropdown_control, 244 | .sv_main .sv_container .sv_body .sv_p_root .sv_q input[type="text"], 245 | .sv_main .sv_container .sv_body .sv_p_root .sv_q select { 246 | height: calc(2em + 1px); } 247 | .sv_main .sv_container .sv_body .sv_p_root .sv_q div.sv_q_text_root, 248 | .sv_main .sv_container .sv_body .sv_p_root .sv_q div.sv_q_dropdown_control { 249 | min-height: 2.43em; 250 | min-width: 7em; } 251 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_select_wrapper { 252 | width: 100%; 253 | position: relative; 254 | display: inline-block; } 255 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_select_wrapper select { 256 | display: block; 257 | background: transparent; 258 | appearance: none; 259 | -webkit-appearance: none; 260 | -moz-appearance: none; 261 | padding-right: 2.5em; } 262 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_select_wrapper select::-ms-expand { 263 | display: none; } 264 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_select_wrapper:before { 265 | padding: 1em; 266 | position: absolute; 267 | right: 1px; 268 | right: 0; 269 | top: 1px; 270 | background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIxLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzNCAzNCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzQgMzQ7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KPC9zdHlsZT4KPHBvbHlnb24gY2xhc3M9InN0MCIgcG9pbnRzPSIxMiwxNiAxNCwxNCAxNywxNyAyMCwxNCAyMiwxNiAxNywyMSAiLz4KPC9zdmc+Cg==); 271 | content: ""; 272 | background-repeat: no-repeat; 273 | background-position: center; } 274 | .sv_main .sv_container .sv_body .sv_p_root .sv_q input[type="color"] { 275 | min-height: 2em; 276 | padding: 0; } 277 | .sv_main .sv_container .sv_body .sv_p_root .sv_q input[type="radio"], 278 | .sv_main .sv_container .sv_body .sv_p_root .sv_q input[type="checkbox"] { 279 | margin: 0; 280 | margin-right: 0.55em; 281 | width: 1.2em; 282 | height: 1.2em; 283 | vertical-align: middle; 284 | font-size: 1em; 285 | margin-top: -0.1em; } 286 | .sv_main .sv_container .sv_body .sv_p_root .sv_q input[type="radio"]:focus, 287 | .sv_main .sv_container .sv_body .sv_p_root .sv_q input[type="checkbox"]:focus { 288 | outline: none; } 289 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_radiogroup.sv_q_radiogroup_inline:not(:last-child), 290 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_checkbox.sv_q_checkbox_inline:not(:last-child), 291 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_imgsel.sv_q_imagepicker_inline:not(:last-child) { 292 | margin-right: 1.5em; } 293 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_imgsel label > div { 294 | overflow: hidden; 295 | white-space: nowrap; 296 | text-overflow: ellipsis; 297 | padding: 4px; 298 | border: 1px solid lightgray; 299 | border-radius: 4px; } 300 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_imgsel label > div > img { 301 | display: block; } 302 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_radiogroup_clear { 303 | margin-top: 0.5em; } 304 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_checkbox_inline, 305 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_radiogroup_inline, 306 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_imagepicker_inline { 307 | line-height: 2em; 308 | display: inline-block; } 309 | .sv_main .sv_container .sv_body .sv_p_root .sv_q .sv_q_footer { 310 | padding: 1em 0; } 311 | .sv_main .sv_container .sv_body .sv_p_root table { 312 | width: 100%; 313 | border-collapse: collapse; } 314 | .sv_main .sv_container .sv_body .sv_p_root table.sv_q_matrix .sv_matrix_dynamic_button, .sv_main .sv_container .sv_body .sv_p_root table.sv_q_matrix_dropdown .sv_matrix_dynamic_button, .sv_main .sv_container .sv_body .sv_p_root table.sv_q_matrix_dynamic .sv_matrix_dynamic_button { 315 | padding: 0.3em 2em; } 316 | @media (min-width: 768px) { 317 | .sv_main .sv_container .sv_body .sv_p_root table.sv_q_matrix td { 318 | min-width: 10em; } } 319 | .sv_main .sv_container .sv_body .sv_p_root table.sv_q_matrix td .sv_q_m_label { 320 | position: static; } 321 | .sv_main .sv_container .sv_body .sv_p_root table.sv_q_matrix_dropdown .sv_qcbc .sv_q_checkbox_control_label { 322 | margin-right: 1.5em; } 323 | .sv_main .sv_container .sv_body .sv_p_root table td, 324 | .sv_main .sv_container .sv_body .sv_p_root table th { 325 | text-align: left; 326 | padding: 0 1em; } 327 | .sv_main .sv_container .sv_body .sv_p_root table td { 328 | padding: 0.5em; } 329 | .sv_main .sv_container .sv_body .sv_p_root table th { 330 | line-height: 1.3em; 331 | padding: 0.5em; 332 | vertical-align: bottom; 333 | font-weight: bold; } 334 | .sv_main .sv_container .sv_body .sv_p_root fieldset.sv_qcbc { 335 | line-height: 2em; 336 | padding-top: 0.1em; } 337 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_other { 338 | margin-left: 1em; } 339 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_rating { 340 | line-height: 2em; } 341 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_rating .sv_q_rating_item { 342 | cursor: pointer; 343 | word-spacing: -0.3em; 344 | font-weight: normal; 345 | display: inline; } 346 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_rating .sv_q_rating_item > * { 347 | word-spacing: initial; } 348 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_rating .sv_q_rating_item .sv_q_rating_item_text { 349 | display: inline-block; 350 | min-width: 2em; 351 | padding: 0 0.3em; 352 | margin-left: -1px; 353 | text-align: center; } 354 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_rating .sv_q_rating_item:not(:first-child) .sv_q_rating_item_text:not(:hover) { 355 | border-left-color: transparent; } 356 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_rating .sv_q_rating_min_text { 357 | margin-right: 0.5em; } 358 | .sv_main .sv_container .sv_body .sv_p_root .sv_q_rating .sv_q_rating_max_text { 359 | margin-left: 0.5em; } 360 | .sv_main .sv_container .sv_body .sv_nav { 361 | padding: 1em 0; 362 | min-height: 2em; } 363 | .sv_main .sv_container .sv_body .sv_nav .sv_start_btn, 364 | .sv_main .sv_container .sv_body .sv_nav .sv_next_btn, 365 | .sv_main .sv_container .sv_body .sv_nav .sv_complete_btn { 366 | float: right; } 367 | .sv_main .sv_container .sv_body .sv_nav .sv_prev_btn { 368 | float: left; } 369 | 370 | @media (max-width: 600px) { 371 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q, 372 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn { 373 | display: block; 374 | width: 100% !important; } 375 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q .title-left, 376 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn .title-left { 377 | float: none; } 378 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q .sv_q_radiogroup_inline, 379 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q .sv_q_checkbox_inline, 380 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q .sv_q_imagepicker_inline, 381 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn .sv_q_radiogroup_inline, 382 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn .sv_q_checkbox_inline, 383 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn .sv_q_imagepicker_inline { 384 | display: block; } 385 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix, 386 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dropdown, 387 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dynamic, 388 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix, 389 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dropdown, 390 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dynamic { 391 | display: block; } 392 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix thead, 393 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dropdown thead, 394 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dynamic thead, 395 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix thead, 396 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dropdown thead, 397 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dynamic thead { 398 | display: none; } 399 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix tbody, 400 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix tr, 401 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix td, 402 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dropdown tbody, 403 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dropdown tr, 404 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dropdown td, 405 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dynamic tbody, 406 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dynamic tr, 407 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dynamic td, 408 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix tbody, 409 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix tr, 410 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix td, 411 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dropdown tbody, 412 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dropdown tr, 413 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dropdown td, 414 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dynamic tbody, 415 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dynamic tr, 416 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dynamic td { 417 | display: block; } 418 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dropdown td:before, 419 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix_dynamic td:before, 420 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dropdown td:before, 421 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix_dynamic td:before { 422 | content: attr(headers); } 423 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_q table.sv_q_matrix td:after, 424 | .sv_main .sv_container .sv_body .sv_p_root .sv_row .sv_qstn table.sv_q_matrix td:after { 425 | content: attr(headers); } } 426 | 427 | /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjazovLy9zcmMvc3JjL21haW4uc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQU1BO0VBQ0UsZ0JBQWU7RUFDZixZQUFXO0VBQ1gsWUFBVztFQUNYLDRCQUEyQjtFQUMzQixhQUFZO0VBQ1osNERBQTJEO0VBQzNELGdCQUFlO0VBQ2YsbUJBQWtCO0VBQ2xCLGlCQUFnQjtFQUNoQix3QkFBdUI7RUFDdkIsaUJBQWdCO0VBQ2hCLGtCQUFpQjtFQUNqQixzQkFBcUI7RUFDckIsa0JBQWlCO0VBQ2pCLHFCQUFvQjtFQUNwQix1QkFBc0I7RUFDdEIsbUJBQWtCO0VBQ2xCLHFCQUFvQjtFQUNwQixrQkFBaUI7RUFDakIsb0JBQW1CO0VBQ25CLHVCQUFzQjtFQUN0QixxQ0FBb0M7RUFDcEMsNkJBQTRCO0VBQzVCLHVCQUFzQjtFQUN0QixxQ0FBb0M7RUFDcEMsbUJBQWtCO0VBQ2xCLGtEQUFpRDtFQUNqRCwwQ0FBeUM7RUFDekMsaUJBQWdCLEVBQ2pCOztBQUNEO0VBQ0Usa0JBQWlCO0VBQ2pCLFVBQVM7RUFDVCxnQkFBZTtFQUNmLDBCQUF5QjtFQUN6QixpQ0FBZ0M7RUFDaEMsMkJBQTBCLEVBQzNCOztBQUNEO0VBQ0UsYUFBWTtFQUNaLFVBQVMsRUFDVjs7QUFDRDs7O0VBR0Usc0JBQXFCO0VBQ3JCLGdCQUFlO0VBQ2YsbUJBQWtCO0VBQ2xCLGFBQVksRUFDYjs7QUFxQkQ7RUFFSSxlQUFjO0VBQ2QsYUFBWTtFQUNaLGVBQWMsRUFNZjtFQVZIO0lBT00saUJBQWdCO0lBQ2hCLG9CQUFtQixFQUNwQjs7QUFJTDtFQUNFLDBCQWhDdUMsRUErSnhDO0VBaElEO0lBSUksaUNBcEM2QixFQXFDOUI7RUFMSDs7SUFTSSxhQXBDeUI7SUFxQ3pCLDBCQXZDZ0IsRUE0Q2pCO0lBZkg7O01BYU0sMEJBekNvQyxFQTBDckM7RUFkTDs7Ozs7O0lBdUJJLDBCQXZENkI7SUF3RDdCLGVBakRnQjtJQWtEaEIsd0JBcER5QixFQXlEMUI7SUE5Qkg7Ozs7OztNQTRCTSwwQkF6RGMsRUEwRGY7RUE3Qkw7SUFpQ0ksd0JBNUR5QixFQWdFMUI7SUFyQ0g7TUFtQ00sMEJBaEVjLEVBaUVmO0VBcENMO0lBd0NJLGVBakVnQixFQWtFakI7RUF6Q0g7SUE0Q0ksMEJBNUU2QixFQTZFOUI7RUE3Q0g7SUFnREksZUF6RWdCLEVBMEVqQjtFQWpESDtJQW9ESSx3QkEvRXlCO0lBZ0Z6Qiw4QkFsRmdCLEVBbUZqQjtFQXRESDtJQXlESSwwQkF6RjZCLEVBMEY5QjtFQTFESDtJQTZESSwwQkExRmdCLEVBMkZqQjtFQTlESDtJQWtFTSxpQ0FsRzJCLEVBMEc1QjtJQTFFTDtNQXFFUSx3QkFoR3FCLEVBaUd0QjtJQXRFUDtNQXdFUSwwQkF2R2lDLEVBd0dsQztFQXpFUDtJQThFSSwwQkFuR2lCO0lBb0dqQiwwQkFuRytDO0lBb0cvQyxlQXJHaUIsRUErR2xCO0lBMUZIOzs7TUFxRk0sMEJBMUdlLEVBOEdoQjtNQXpGTDs7O1FBdUZRLDBCQUE4QixFQUMvQjtFQXhGUDs7O0lBZ0dNLGlDQWhJMkIsRUFpSTVCO0VBakdMO0lBcUdJLGFBaEl5QjtJQWlJekIsMEJBbElzQyxFQW1JdkM7RUF2R0g7SUE0R1EsMEJBeElrQztJQXlJbEMsc0JBeklrQztJQTBJbEMsYUF6SXFCLEVBMEl0QjtFQS9HUDtJQWtITSwwQkFsSjJCLEVBc0o1QjtJQXRITDtNQW9IUSwwQkFoSmtDLEVBaUpuQztFQXJIUDtJQTBISSwwQkF2SmdCLEVBd0pqQjtFQTNISDtJQThISSxlQTNKZ0IsRUE0SmpCOztBQUdIO0VBQ0UsbUJBQWtCO0VBQ2xCLFlBQVc7RUFFWCwyR0FDcUM7RUFDckMsZ0JBekpjLEVBd2lCZjtFQXJaRDtJQVNJLGFBQVksRUFFYjtFQVhIOztJQWVJLGtCQUFpQjtJQUNqQixrQkFBaUI7SUFFakIsaUJBbktrQjtJQXFLbEIsYUFBWTtJQUNaLGlCQUFnQjtJQUNoQixnQkFBZTtJQUNmLGVBQWM7SUFDZCxtQkFBa0IsRUFLbkI7RUE3Qkg7SUFnQ0ksbUJBQWtCO0lBQ2xCLFlBQVc7SUFDWCxZQXRMZTtJQXVMZixrQkFBaUIsRUFFbEI7RUFyQ0g7SUF1Q0ksbUJBQWtCLEVBNlduQjtJQXBaSDtNQTJDTSxhQUFZLEVBUWI7TUFuREw7UUE4Q1EsZUFBYztRQUNkLGlCQUFnQjtRQUNoQixpQkFBZ0I7UUFDaEIsVUFBUyxFQUNWO0lBbERQO01Ba0VNLHlCQUF3QixFQWlWekI7TUFuWkw7UUF1RFEsbUJBQWtCO1FBQ2xCLGlCQUFnQixFQU9qQjtRQS9EUDtVQTJEVSxVQUFTO1VBQ1QsZ0JBQWU7VUFDZixpQkFBZ0IsRUFDakI7TUE5RFQ7UUFzRVEsY0FBYSxFQWVkO1FBckZQO1VBMEVVLGFBQVk7VUFDWixpQkFBZ0I7VUFFaEIsbUJBQWtCO1VBQ2xCLGdCQUFlLEVBTWhCO1VBcEZUO1lBZ0ZZLG1CQUFrQjtZQUNsQixZQUFXO1lBQ1gsc0JBQXFCLEVBQ3RCO01BbkZYO1FBeUZVLGVBQWM7UUFDZCxrQkFBaUI7UUFDakIsb0JBQW1CLEVBQ3BCO01BNUZUO1FBK0ZVLGtCQUFpQjtRQUNqQixrQkFBaUI7UUFDakIsb0JBQW1CLEVBQ3BCO01BbEdUO1FBc0dVLFdBQVUsRUFRWDtNQTlHVDtRQWlIVSxrQkFBaUI7UUFDakIsZUFBYztRQUNkLGdCQUFlLEVBQ2hCO01BcEhUO1FBdUhVLG1CQUFrQixFQUNuQjtNQXhIVDtRQTJIVSw2QkFBNEI7UUFDNUIsdUJBQXNCO1FBQ3RCLGVBQWMsRUE4SmY7UUEzUlQ7VUFpSWMsb0JBQW1CLEVBQ3BCO1FBbEliO1VBd0lZLGNBQWE7VUFFYixhQUFZLEVBVWI7UUFwSlg7Ozs7OztVQTRKWSxtQkFBa0I7VUFDbEIsWUFBVztVQUNYLHVCQUFzQjtVQUV0QixlQUFjO1VBQ2QsaUJBbFRVO1VBb1RWLGtCQUFpQixFQVFsQjtVQTNLWDs7Ozs7O1lBd0tjLGNBQWEsRUFFZDtRQTFLYjs7OztVQWlMWSx3QkFBd0MsRUFDekM7UUFsTFg7O1VBc0xZLG1CQUFrQjtVQUNsQixlQUFjLEVBQ2Y7UUF4TFg7VUEyTFksWUFBVztVQUNYLG1CQUFrQjtVQUNsQixzQkFBcUIsRUEwQnRCO1VBdk5YO1lBaU1jLGVBQWM7WUFDZCx3QkFBdUI7WUFDdkIsaUJBQWdCO1lBQ2hCLHlCQUF3QjtZQUN4QixzQkFBcUI7WUFDckIscUJBQW9CLEVBS3JCO1lBM01iO2NBeU1nQixjQUFhLEVBQ2Q7VUExTWY7WUE4TWMsYUFBWTtZQUNaLG1CQUFrQjtZQUNsQixXQUFVO1lBQ1YsU0FBUTtZQUNSLFNBQVE7WUFFUixnREFBcUQ7WUEvYWpFLFlBQVc7WUFDWCw2QkFBNEI7WUFDNUIsNEJBQTJCLEVBK2FoQjtRQXROYjtVQTBOWSxnQkEzV1U7VUE0V1YsV0FBVSxFQUNYO1FBNU5YOztVQWdPWSxVQUFTO1VBQ1QscUJBQW9CO1VBQ3BCLGFBQVk7VUFDWixjQUFhO1VBQ2IsdUJBQXNCO1VBQ3RCLGVBQWM7VUFDZCxtQkFBa0IsRUFLbkI7VUEzT1g7O1lBeU9jLGNBQWEsRUFDZDtRQTFPYjs7O1VBZ1BZLG9CQUFtQixFQUNwQjtRQWpQWDtVQW9QWSxpQkFBZ0I7VUFDaEIsb0JBQW1CO1VBQ25CLHdCQUF1QjtVQUN2QixhQUFZO1VBQ1osNEJBQTJCO1VBQzNCLG1CQUFrQixFQUluQjtVQTdQWDtZQTJQYyxlQUFjLEVBQ2Y7UUE1UGI7VUE4UVksa0JBQWlCLEVBQ2xCO1FBL1FYOzs7VUFvUlksaUJBcmFVO1VBc2FWLHNCQUFxQixFQUN0QjtRQXRSWDtVQXlSWSxlQUFjLEVBQ2Y7TUExUlg7UUE4UlUsWUFBVztRQUNYLDBCQUF5QixFQThDMUI7UUE3VVQ7VUFxU2MsbUJBQWtCLEVBQ25CO1FBT0M7VUE3U2Q7WUE4U2dCLGdCQUFlLEVBS2xCO1FBblRiO1VBaVRnQixpQkFBZ0IsRUFDakI7UUFsVGY7VUF3VGdCLG9CQUFtQixFQUNwQjtRQXpUZjs7VUErVFksaUJBQWdCO1VBQ2hCLGVBQWMsRUFDZjtRQWpVWDtVQW9VWSxlQUFjLEVBQ2Y7UUFyVVg7VUF3VVksbUJBQWtCO1VBQ2xCLGVBQWM7VUFDZCx1QkFBc0I7VUFDdEIsa0JBQWlCLEVBQ2xCO01BNVVYO1FBZ1ZVLGlCQWplWTtRQWtlWixtQkFBa0IsRUFDbkI7TUFsVlQ7UUFxVlUsaUJBQWdCLEVBQ2pCO01BdFZUO1FBeVZVLGlCQTFlWSxFQW9oQmI7UUFuWVQ7VUE0VlksZ0JBQWU7VUFDZixxQkFBb0I7VUFDcEIsb0JBQW1CO1VBQ25CLGdCQUFlLEVBNkJoQjtVQTVYWDtZQWtXYyxzQkFBcUIsRUFDdEI7VUFuV2I7WUE2V2Msc0JBQXFCO1lBQ3JCLGVBL2ZRO1lBZ2dCUixpQkFBZ0I7WUFDaEIsa0JBQWlCO1lBRWpCLG1CQUFrQixFQUluQjtVQXRYYjtZQXlYZ0IsK0JBQThCLEVBQy9CO1FBMVhmO1VBOFhZLG9CQUFtQixFQUNwQjtRQS9YWDtVQWlZWSxtQkFBa0IsRUFDbkI7TUFsWVg7UUF1WVEsZUFBYztRQUNkLGdCQXpoQmMsRUFtaUJmO1FBbFpQOzs7VUE2WVUsYUFBWSxFQUNiO1FBOVlUO1VBZ1pVLFlBQVcsRUFDWjs7QUFNVDtFQUNFOztJQU9ZLGVBQWM7SUFDZCx1QkFBc0IsRUFxQ3ZCO0lBN0NYOztNQVVjLFlBQVcsRUFDWjtJQVhiOzs7Ozs7TUFlYyxlQUFjLEVBQ2Y7SUFoQmI7Ozs7OztNQW9CYyxlQUFjLEVBU2Y7TUE3QmI7Ozs7OztRQXNCZ0IsY0FBYSxFQUNkO01BdkJmOzs7Ozs7Ozs7Ozs7Ozs7Ozs7UUEyQmdCLGVBQWMsRUFDZjtJQTVCZjs7OztNQWtDa0IsdUJBQXNCLEVBQ3ZCO0lBbkNqQjs7TUF5Q2tCLHVCQUFzQixFQUN2QiIsImZpbGUiOiIuL3BhY2thZ2VzL3N1cnZleS1rbm9ja291dC9zdXJ2ZXkuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiQG1peGluIHN2Zy1pY29uKCkge1xuICBjb250ZW50OiBcIlwiO1xuICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7XG59XG5cbi5zdl93aW5kb3cge1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIGJvdHRvbTogM3B4O1xuICByaWdodDogMTBweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogY2FkZXRibHVlO1xuICBwYWRkaW5nOiAxcHg7XG4gIGZvbnQtZmFtaWx5OiBcIkhlbHZldGljYSBOZXVlXCIsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWY7XG4gIGZvbnQtc2l6ZTogMTRweDtcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xuICBmb250LXdlaWdodDogNDAwO1xuICBsaW5lLWhlaWdodDogMS40Mjg1NzE0MztcbiAgdGV4dC1hbGlnbjogbGVmdDtcbiAgdGV4dC1hbGlnbjogc3RhcnQ7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgdGV4dC1zaGFkb3c6IG5vbmU7XG4gIHRleHQtdHJhbnNmb3JtOiBub25lO1xuICBsZXR0ZXItc3BhY2luZzogbm9ybWFsO1xuICB3b3JkLWJyZWFrOiBub3JtYWw7XG4gIHdvcmQtc3BhY2luZzogbm9ybWFsO1xuICB3b3JkLXdyYXA6IG5vcm1hbDtcbiAgd2hpdGUtc3BhY2U6IG5vcm1hbDtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbiAgLXdlYmtpdC1iYWNrZ3JvdW5kLWNsaXA6IHBhZGRpbmctYm94O1xuICBiYWNrZ3JvdW5kLWNsaXA6IHBhZGRpbmctYm94O1xuICBib3JkZXI6IDFweCBzb2xpZCAjY2NjO1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMik7XG4gIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgLXdlYmtpdC1ib3gtc2hhZG93OiAwIDVweCAxMHB4IHJnYmEoMCwgMCwgMCwgMC4yKTtcbiAgYm94LXNoYWRvdzogMCA1cHggMTBweCByZ2JhKDAsIDAsIDAsIDAuMik7XG4gIGxpbmUtYnJlYWs6IGF1dG87XG59XG4uc3Zfd2luZG93X3RpdGxlIHtcbiAgcGFkZGluZzogOHB4IDE0cHg7XG4gIG1hcmdpbjogMDtcbiAgZm9udC1zaXplOiAxNHB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjdmN2Y3O1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2ViZWJlYjtcbiAgYm9yZGVyLXJhZGl1czogNXB4IDVweCAwIDA7XG59XG4uc3Zfd2luZG93X2NvbnRlbnQge1xuICBwYWRkaW5nOiA4cHg7XG4gIG1hcmdpbjogMDtcbn1cbi5zdl93aW5kb3dfdGl0bGUgYSxcbi5zdl93aW5kb3dfdGl0bGUgYTpsaW5rLFxuLnN2X3dpbmRvd190aXRsZSBhOnZpc2l0ZWQge1xuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gIGZvbnQtc2l6ZTogMTRweDtcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xuICBjb2xvcjogYmxhY2s7XG59XG5cbiRoZWFkZXItYmFja2dyb3VuZC1jb2xvcjogI2U3ZTdlNztcbiRib2R5LWNvbnRhaW5lci1iYWNrZ3JvdW5kLWNvbG9yOiAjZjRmNGY0O1xuXG4kbWFpbi1jb2xvcjogIzFhYjM5NDtcbiRtYWluLWhvdmVyLWNvbG9yOiBkYXJrZW4oJG1haW4tY29sb3IsIDUlKTtcbiRib2R5LWJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xuJGlucHV0cy1iYWNrZ3JvdW5kLWNvbG9yOiAkYm9keS1iYWNrZ3JvdW5kLWNvbG9yO1xuJHRleHQtY29sb3I6ICM2ZDcwNzI7XG4kaGVhZGVyLWNvbG9yOiAkdGV4dC1jb2xvcjtcbiRib3JkZXItY29sb3I6ICRoZWFkZXItYmFja2dyb3VuZC1jb2xvcjtcblxuJGVycm9yLWNvbG9yOiAjZWQ1NTY1O1xuJGVycm9yLWJhY2tncm91bmQtY29sb3I6IGxpZ2h0ZW4oJGVycm9yLWNvbG9yLCAzMCUpO1xuXG4kaGVhZGVyLWhlaWdodDogNzQlO1xuJGZvbnQtc2l6ZTogMTRweDtcblxuJGJhc2UtbGluZS1oZWlnaHQ6IDJlbTtcblxuLnN2X21haW4uc3ZfZnJhbWUge1xuICAuc3ZfY29udGFpbmVyIHtcbiAgICBtYXgtd2lkdGg6IDgwJTtcbiAgICBtYXJnaW46IGF1dG87XG4gICAgcGFkZGluZzogMCAxZW07XG5cbiAgICAuc3ZfaGVhZGVyIHtcbiAgICAgIHBhZGRpbmctdG9wOiA1ZW07XG4gICAgICBwYWRkaW5nLWJvdHRvbTogMWVtO1xuICAgIH1cbiAgfVxufVxuXG4uc3ZfbWFpbiB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRib2R5LWNvbnRhaW5lci1iYWNrZ3JvdW5kLWNvbG9yO1xuXG4gIGhyIHtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgJGJvcmRlci1jb2xvcjtcbiAgfVxuXG4gIGlucHV0W3R5cGU9XCJidXR0b25cIl0sXG4gIGJ1dHRvbiB7XG4gICAgY29sb3I6ICRib2R5LWJhY2tncm91bmQtY29sb3I7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJG1haW4tY29sb3I7XG5cbiAgICAmOmhvdmVyIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICRtYWluLWhvdmVyLWNvbG9yO1xuICAgIH1cbiAgfVxuXG4gIC5zdl9xX290aGVyIGlucHV0LFxuICAuc3ZfcV90ZXh0X3Jvb3QsXG4gIC5zdl9xX2Ryb3Bkb3duX2NvbnRyb2wsXG4gIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLFxuICBzZWxlY3QsXG4gIHRleHRhcmVhIHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAkYm9yZGVyLWNvbG9yO1xuICAgIGNvbG9yOiAkdGV4dC1jb2xvcjtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkaW5wdXRzLWJhY2tncm91bmQtY29sb3I7XG5cbiAgICAmOmZvY3VzIHtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICRtYWluLWNvbG9yO1xuICAgIH1cbiAgfVxuXG4gIC5zdl9zZWxlY3Rfd3JhcHBlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGJvZHktYmFja2dyb3VuZC1jb2xvcjtcbiAgICAmOmJlZm9yZSB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWFpbi1jb2xvcjtcbiAgICB9XG4gIH1cblxuICAuc3ZfaGVhZGVyIHtcbiAgICBjb2xvcjogJGhlYWRlci1jb2xvcjtcbiAgfVxuXG4gIC5zdl9jdXN0b21faGVhZGVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkaGVhZGVyLWJhY2tncm91bmQtY29sb3I7XG4gIH1cblxuICAuc3ZfY29udGFpbmVyIHtcbiAgICBjb2xvcjogJHRleHQtY29sb3I7XG4gIH1cblxuICAuc3ZfYm9keSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGJvZHktYmFja2dyb3VuZC1jb2xvcjtcbiAgICBib3JkZXItdG9wOiAycHggc29saWQgJG1haW4tY29sb3I7XG4gIH1cblxuICAuc3ZfcHJvZ3Jlc3Mge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRib3JkZXItY29sb3I7XG4gIH1cblxuICAuc3ZfcHJvZ3Jlc3NfYmFyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWFpbi1jb2xvcjtcbiAgfVxuXG4gIC5zdl9wX3Jvb3Qge1xuICAgICYgPiAuc3Zfcm93IHtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAkYm9yZGVyLWNvbG9yO1xuXG4gICAgICAmOm50aC1jaGlsZChvZGQpIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGJvZHktYmFja2dyb3VuZC1jb2xvcjtcbiAgICAgIH1cbiAgICAgICY6bnRoLWNoaWxkKGV2ZW4pIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGJvZHktY29udGFpbmVyLWJhY2tncm91bmQtY29sb3I7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLnN2X3FfZXJib3g6bm90KFtzdHlsZSo9XCJkaXNwbGF5OiBub25lXCJdKTpub3QoW3N0eWxlKj1cImRpc3BsYXk6bm9uZVwiXSkge1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICRlcnJvci1jb2xvcjtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkZXJyb3ItYmFja2dyb3VuZC1jb2xvcjtcbiAgICBjb2xvcjogJGVycm9yLWNvbG9yO1xuXG4gICAgJiArIGlucHV0LFxuICAgICYgKyB0ZXh0YXJlYSxcbiAgICAmICsgLnN2X3NlbGVjdF93cmFwcGVyIHNlbGVjdCB7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAkZXJyb3ItY29sb3I7XG4gICAgICAmOmZvY3VzIHtcbiAgICAgICAgb3V0bGluZTogJGVycm9yLWNvbG9yIGF1dG8gNXB4O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRhYmxlLnN2X3FfbWF0cml4LFxuICB0YWJsZS5zdl9xX21hdHJpeF9kcm9wZG93bixcbiAgdGFibGUuc3ZfcV9tYXRyaXhfZHluYW1pYyB7XG4gICAgdHIge1xuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICRib3JkZXItY29sb3I7XG4gICAgfVxuICB9XG5cbiAgLnN2X3FfbV9jZWxsX3NlbGVjdGVkIHtcbiAgICBjb2xvcjogJGJvZHktYmFja2dyb3VuZC1jb2xvcjtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWFpbi1ob3Zlci1jb2xvcjtcbiAgfVxuXG4gIC5zdl9xX3JhdGluZ19pdGVtIHtcbiAgICAmLmFjdGl2ZSB7XG4gICAgICAuc3ZfcV9yYXRpbmdfaXRlbV90ZXh0IHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1haW4taG92ZXItY29sb3I7XG4gICAgICAgIGJvcmRlci1jb2xvcjogJG1haW4taG92ZXItY29sb3I7XG4gICAgICAgIGNvbG9yOiAkYm9keS1iYWNrZ3JvdW5kLWNvbG9yO1xuICAgICAgfVxuICAgIH1cbiAgICAuc3ZfcV9yYXRpbmdfaXRlbV90ZXh0IHtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICRib3JkZXItY29sb3I7XG4gICAgICAmOmhvdmVyIHtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgJG1haW4taG92ZXItY29sb3I7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLnN2X3FfaW1nc2VsLmNoZWNrZWQgbGFiZWwgPiBkaXYge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRtYWluLWNvbG9yO1xuICB9XG5cbiAgLnN2X3FfZmlsZV9yZW1vdmU6aG92ZXIge1xuICAgIGNvbG9yOiAkbWFpbi1jb2xvcjtcbiAgfVxufVxuXG4uc3ZfbWFpbiB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgd2lkdGg6IDEwMCU7XG4gIC8vYmFja2dyb3VuZC1jb2xvcjogJGJvZHktY29udGFpbmVyLWJhY2tncm91bmQtY29sb3I7XG4gIGZvbnQtZmFtaWx5OiBcIlNlZ29lIFVJXCIsIEZydXRpZ2VyLCBcIkZydXRpZ2VyIExpbm90eXBlXCIsIFwiRGVqYXZ1IFNhbnNcIixcbiAgICBcIkhlbHZldGljYSBOZXVlXCIsIEFyaWFsLCBzYW5zLXNlcmlmO1xuICBmb250LXNpemU6ICRmb250LXNpemU7XG5cbiAgaHIge1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICAvL2JvcmRlci1ib3R0b206IDFweCBzb2xpZCAkaGVhZGVyLWJhY2tncm91bmQtY29sb3I7XG4gIH1cblxuICBpbnB1dFt0eXBlPVwiYnV0dG9uXCJdLFxuICBidXR0b24ge1xuICAgIGZvbnQtc2l6ZTogMC44NWVtO1xuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xuICAgIC8vY29sb3I6ICRib2R5LWJhY2tncm91bmQtY29sb3I7XG4gICAgbGluZS1oZWlnaHQ6ICRiYXNlLWxpbmUtaGVpZ2h0O1xuICAgIC8vYmFja2dyb3VuZC1jb2xvcjogJG1haW4tY29sb3I7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIG1pbi13aWR0aDogMTAwcHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIHBhZGRpbmc6IDAgMmVtO1xuICAgIGJvcmRlci1yYWRpdXM6IDJweDtcblxuICAgICY6aG92ZXIge1xuICAgICAgLy9iYWNrZ3JvdW5kLWNvbG9yOiAkbWFpbi1ob3Zlci1jb2xvcjtcbiAgICB9XG4gIH1cblxuICAuc3ZfY3VzdG9tX2hlYWRlciB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogJGhlYWRlci1oZWlnaHQ7XG4gICAgbWF4LWhlaWdodDogMjc1cHg7XG4gICAgLy9iYWNrZ3JvdW5kLWNvbG9yOiAkaGVhZGVyLWJhY2tncm91bmQtY29sb3I7XG4gIH1cbiAgLnN2X2NvbnRhaW5lciB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIC8vY29sb3I6ICR0ZXh0LWNvbG9yO1xuXG4gICAgLnN2X2hlYWRlciB7XG4gICAgICBwYWRkaW5nOiAxZW07XG5cbiAgICAgIGgzIHtcbiAgICAgICAgZm9udC1zaXplOiAyZW07XG4gICAgICAgIGZvbnQtd2VpZ2h0OiAzMDA7XG4gICAgICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAuc3ZfYm9keSB7XG4gICAgICAmLnN2X2NvbXBsZXRlZF9wYWdlIHtcbiAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgICBwYWRkaW5nOiA1ZW0gMWVtO1xuXG4gICAgICAgID4gaDMge1xuICAgICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgICBmb250LXNpemU6IDMwcHg7XG4gICAgICAgICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvL2JhY2tncm91bmQtY29sb3I6ICRib2R5LWJhY2tncm91bmQtY29sb3I7XG4gICAgICBwYWRkaW5nOiAxZW0gMWVtIDVlbSAxZW07XG4gICAgICAvL2JvcmRlci10b3A6IDJweCBzb2xpZCAkbWFpbi1jb2xvcjtcblxuICAgICAgLnN2X3Byb2dyZXNzIHtcbiAgICAgICAgaGVpZ2h0OiAwLjNlbTtcbiAgICAgICAgLy9iYWNrZ3JvdW5kLWNvbG9yOiAkaGVhZGVyLWJhY2tncm91bmQtY29sb3I7XG5cbiAgICAgICAgLnN2X3Byb2dyZXNzX2JhciB7XG4gICAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICAgIG1pbi13aWR0aDogMTAwcHg7XG4gICAgICAgICAgLy9iYWNrZ3JvdW5kLWNvbG9yOiAkbWFpbi1jb2xvcjtcbiAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgICAgbWFyZ2luLXRvcDogMmVtO1xuICAgICAgICAgID4gc3BhbiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICB0b3A6IC0xLjVlbTtcbiAgICAgICAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLnN2X3Bfcm9vdCB7XG4gICAgICAgIC5zdl9wYWdlX3RpdGxlIHtcbiAgICAgICAgICBmb250LXNpemU6IDFlbTtcbiAgICAgICAgICBtYXJnaW4tdG9wOiAwLjFlbTtcbiAgICAgICAgICBmb250LXdlaWdodDogbm9ybWFsO1xuICAgICAgICB9XG5cbiAgICAgICAgLnN2X3BfdGl0bGUge1xuICAgICAgICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xuICAgICAgICAgIGZvbnQtc2l6ZTogMS4xNWVtO1xuICAgICAgICAgIG1hcmdpbjogMS41ZW0gMCAwIDA7XG4gICAgICAgIH1cblxuICAgICAgICAmID4gLnN2X3JvdyB7XG4gICAgICAgICAgLy9ib3JkZXItYm90dG9tOiAxcHggc29saWQgJGhlYWRlci1iYWNrZ3JvdW5kLWNvbG9yO1xuICAgICAgICAgIHBhZGRpbmc6IDA7XG5cbiAgICAgICAgICAmOm50aC1jaGlsZChvZGQpIHtcbiAgICAgICAgICAgIC8vYmFja2dyb3VuZC1jb2xvcjogJGJvZHktYmFja2dyb3VuZC1jb2xvcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgJjpudGgtY2hpbGQoZXZlbikge1xuICAgICAgICAgICAgLy9iYWNrZ3JvdW5kLWNvbG9yOiAkYm9keS1jb250YWluZXItYmFja2dyb3VuZC1jb2xvcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAuc3ZfcV90aXRsZSB7XG4gICAgICAgICAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gICAgICAgICAgZm9udC1zaXplOiAxZW07XG4gICAgICAgICAgbWFyZ2luOiAwLjVlbSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgLnN2X3FfZGVzY3JpcHRpb24ge1xuICAgICAgICAgIG1hcmdpbi10b3A6IC0wLjZlbTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5zdl9xIHtcbiAgICAgICAgICBwYWRkaW5nOiAwLjVlbSAxZW0gMS41ZW0gMWVtO1xuICAgICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICAgICAgb3ZlcmZsb3c6IGF1dG87XG5cbiAgICAgICAgICAuc3ZfcGFuZWxfZHluYW1pYyB7XG4gICAgICAgICAgICAuc3ZfcV90aXRsZSB7XG4gICAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLnN2X3FfZXJib3g6bm90KFtzdHlsZSo9XCJkaXNwbGF5OiBub25lXCJdKTpub3QoW3N0eWxlKj1cImRpc3BsYXk6bm9uZVwiXSkge1xuICAgICAgICAgICAgLy9ib3JkZXI6IDFweCBzb2xpZCAkZXJyb3ItY29sb3I7XG4gICAgICAgICAgICAvL2JhY2tncm91bmQtY29sb3I6ICRlcnJvci1iYWNrZ3JvdW5kLWNvbG9yO1xuICAgICAgICAgICAgbWFyZ2luOiAxZW0gMDtcbiAgICAgICAgICAgIC8vY29sb3I6ICRlcnJvci1jb2xvcjtcbiAgICAgICAgICAgIHBhZGRpbmc6IDFlbTtcblxuICAgICAgICAgICAgJiArIGlucHV0LFxuICAgICAgICAgICAgJiArIHRleHRhcmVhLFxuICAgICAgICAgICAgJiArIC5zdl9zZWxlY3Rfd3JhcHBlciBzZWxlY3Qge1xuICAgICAgICAgICAgICAvL2JvcmRlcjogMXB4IHNvbGlkICRlcnJvci1jb2xvcjtcbiAgICAgICAgICAgICAgJjpmb2N1cyB7XG4gICAgICAgICAgICAgICAgLy9vdXRsaW5lOiAkZXJyb3ItY29sb3IgYXV0byA1cHg7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAuc3ZfcV9vdGhlciBpbnB1dCxcbiAgICAgICAgICAuc3ZfcV90ZXh0X3Jvb3QsXG4gICAgICAgICAgLnN2X3FfZHJvcGRvd25fY29udHJvbCxcbiAgICAgICAgICBpbnB1dFt0eXBlPVwidGV4dFwiXSxcbiAgICAgICAgICBzZWxlY3QsXG4gICAgICAgICAgdGV4dGFyZWEge1xuICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICAgICAgLy9ib3JkZXI6IDFweCBzb2xpZCAkaGVhZGVyLWJhY2tncm91bmQtY29sb3I7XG4gICAgICAgICAgICBmb250LXNpemU6IDFlbTtcbiAgICAgICAgICAgIGxpbmUtaGVpZ2h0OiAkYmFzZS1saW5lLWhlaWdodDtcbiAgICAgICAgICAgIC8vY29sb3I6ICR0ZXh0LWNvbG9yO1xuICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiAxZW07XG4gICAgICAgICAgICAvL2JhY2tncm91bmQtY29sb3I6ICRpbnB1dHMtYmFja2dyb3VuZC1jb2xvcjtcblxuICAgICAgICAgICAgJjpmb2N1cyB7XG4gICAgICAgICAgICAgIC8vYm9yZGVyLWNvbG9yOiAkbWFpbi1jb2xvcjtcbiAgICAgICAgICAgICAgb3V0bGluZTogbm9uZTtcbiAgICAgICAgICAgICAgLy9ib3JkZXI6IDFweCBzb2xpZCAkbWFpbi1jb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAuc3ZfcV9vdGhlciBpbnB1dCxcbiAgICAgICAgICAuc3ZfcV9kcm9wZG93bl9jb250cm9sLFxuICAgICAgICAgIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLFxuICAgICAgICAgIHNlbGVjdCB7XG4gICAgICAgICAgICBoZWlnaHQ6IGNhbGMoI3skYmFzZS1saW5lLWhlaWdodH0gKyAxcHgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRpdi5zdl9xX3RleHRfcm9vdCxcbiAgICAgICAgICBkaXYuc3ZfcV9kcm9wZG93bl9jb250cm9sIHtcbiAgICAgICAgICAgIG1pbi1oZWlnaHQ6IDIuNDNlbTtcbiAgICAgICAgICAgIG1pbi13aWR0aDogN2VtO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC5zdl9zZWxlY3Rfd3JhcHBlciB7XG4gICAgICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICAgICAgICAgIC8vYmFja2dyb3VuZC1jb2xvcjogJGJvZHktYmFja2dyb3VuZC1jb2xvcjtcblxuICAgICAgICAgICAgc2VsZWN0IHtcbiAgICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgICAgICAgICAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAgICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgICAgICAgIC1tb3otYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgICAgICAgcGFkZGluZy1yaWdodDogMi41ZW07XG5cbiAgICAgICAgICAgICAgJjo6LW1zLWV4cGFuZCB7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAmOmJlZm9yZSB7XG4gICAgICAgICAgICAgIHBhZGRpbmc6IDFlbTtcbiAgICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgICAgICByaWdodDogMXB4O1xuICAgICAgICAgICAgICByaWdodDogMDtcbiAgICAgICAgICAgICAgdG9wOiAxcHg7XG4gICAgICAgICAgICAgIC8vYmFja2dyb3VuZC1jb2xvcjogJG1haW4tY29sb3I7XG4gICAgICAgICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybChcIi4vaW1hZ2VzL0Fycm93RG93bl8zNHgzNC5zdmdcIik7XG4gICAgICAgICAgICAgIEBpbmNsdWRlIHN2Zy1pY29uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaW5wdXRbdHlwZT1cImNvbG9yXCJdIHtcbiAgICAgICAgICAgIG1pbi1oZWlnaHQ6ICRiYXNlLWxpbmUtaGVpZ2h0O1xuICAgICAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpbnB1dFt0eXBlPVwicmFkaW9cIl0sXG4gICAgICAgICAgaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdIHtcbiAgICAgICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgICAgIG1hcmdpbi1yaWdodDogMC41NWVtO1xuICAgICAgICAgICAgd2lkdGg6IDEuMmVtO1xuICAgICAgICAgICAgaGVpZ2h0OiAxLjJlbTtcbiAgICAgICAgICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gICAgICAgICAgICBmb250LXNpemU6IDFlbTtcbiAgICAgICAgICAgIG1hcmdpbi10b3A6IC0wLjFlbTtcblxuICAgICAgICAgICAgJjpmb2N1cyB7XG4gICAgICAgICAgICAgIG91dGxpbmU6IG5vbmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLnN2X3FfcmFkaW9ncm91cC5zdl9xX3JhZGlvZ3JvdXBfaW5saW5lOm5vdCg6bGFzdC1jaGlsZCksXG4gICAgICAgICAgLnN2X3FfY2hlY2tib3guc3ZfcV9jaGVja2JveF9pbmxpbmU6bm90KDpsYXN0LWNoaWxkKSxcbiAgICAgICAgICAuc3ZfcV9pbWdzZWwuc3ZfcV9pbWFnZXBpY2tlcl9pbmxpbmU6bm90KDpsYXN0LWNoaWxkKSB7XG4gICAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDEuNWVtO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC5zdl9xX2ltZ3NlbCBsYWJlbCA+IGRpdiB7XG4gICAgICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgICAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgICAgICAgICAgcGFkZGluZzogNHB4O1xuICAgICAgICAgICAgYm9yZGVyOiAxcHggc29saWQgbGlnaHRncmF5O1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgICAgICAgPiBpbWcge1xuICAgICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyAuc3ZfcV9yYWRpb2dyb3VwLFxuICAgICAgICAgIC8vIC5zdl9xX2NoZWNrYm94IHtcbiAgICAgICAgICAvLyAgICR0b3RhbC1jb2x1bW5zOiA1O1xuICAgICAgICAgIC8vICAgQGZvciAkaSBmcm9tIDEgdGhyb3VnaCAkdG90YWwtY29sdW1ucyB7XG4gICAgICAgICAgLy8gICAgICYuc3YtcS1jb2wtI3skaX0ge1xuICAgICAgICAgIC8vICAgICAgIHdpZHRoOiAxMDAlIC8gJGk7XG4gICAgICAgICAgLy8gICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgICAgICAgIC8vICAgICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDogNDgwcHgpIHtcbiAgICAgICAgICAvLyAgICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICAgIC8vICAgICAgIH1cbiAgICAgICAgICAvLyAgICAgfVxuICAgICAgICAgIC8vICAgfVxuICAgICAgICAgIC8vIH1cblxuICAgICAgICAgIC5zdl9xX3JhZGlvZ3JvdXBfY2xlYXIge1xuICAgICAgICAgICAgbWFyZ2luLXRvcDogMC41ZW07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLnN2X3FfY2hlY2tib3hfaW5saW5lLFxuICAgICAgICAgIC5zdl9xX3JhZGlvZ3JvdXBfaW5saW5lLFxuICAgICAgICAgIC5zdl9xX2ltYWdlcGlja2VyX2lubGluZSB7XG4gICAgICAgICAgICBsaW5lLWhlaWdodDogJGJhc2UtbGluZS1oZWlnaHQ7XG4gICAgICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLnN2X3FfZm9vdGVyIHtcbiAgICAgICAgICAgIHBhZGRpbmc6IDFlbSAwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRhYmxlIHtcbiAgICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlO1xuXG4gICAgICAgICAgJi5zdl9xX21hdHJpeCxcbiAgICAgICAgICAmLnN2X3FfbWF0cml4X2Ryb3Bkb3duLFxuICAgICAgICAgICYuc3ZfcV9tYXRyaXhfZHluYW1pYyB7XG4gICAgICAgICAgICAuc3ZfbWF0cml4X2R5bmFtaWNfYnV0dG9uIHtcbiAgICAgICAgICAgICAgcGFkZGluZzogMC4zZW0gMmVtO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHIge1xuICAgICAgICAgICAgICAvL2JvcmRlci1ib3R0b206IDFweCBzb2xpZCAkaGVhZGVyLWJhY2tncm91bmQtY29sb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgICYuc3ZfcV9tYXRyaXgge1xuICAgICAgICAgICAgdGQge1xuICAgICAgICAgICAgICBAbWVkaWEgKG1pbi13aWR0aDogNzY4cHgpIHtcbiAgICAgICAgICAgICAgICBtaW4td2lkdGg6IDEwZW07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLnN2X3FfbV9sYWJlbCB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246IHN0YXRpYztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAmLnN2X3FfbWF0cml4X2Ryb3Bkb3duIHtcbiAgICAgICAgICAgIC5zdl9xY2JjIHtcbiAgICAgICAgICAgICAgLnN2X3FfY2hlY2tib3hfY29udHJvbF9sYWJlbCB7XG4gICAgICAgICAgICAgICAgbWFyZ2luLXJpZ2h0OiAxLjVlbTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHRkLFxuICAgICAgICAgIHRoIHtcbiAgICAgICAgICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgICAgICAgICBwYWRkaW5nOiAwIDFlbTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0ZCB7XG4gICAgICAgICAgICBwYWRkaW5nOiAwLjVlbTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aCB7XG4gICAgICAgICAgICBsaW5lLWhlaWdodDogMS4zZW07XG4gICAgICAgICAgICBwYWRkaW5nOiAwLjVlbTtcbiAgICAgICAgICAgIHZlcnRpY2FsLWFsaWduOiBib3R0b207XG4gICAgICAgICAgICBmb250LXdlaWdodDogYm9sZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmaWVsZHNldC5zdl9xY2JjIHtcbiAgICAgICAgICBsaW5lLWhlaWdodDogJGJhc2UtbGluZS1oZWlnaHQ7XG4gICAgICAgICAgcGFkZGluZy10b3A6IDAuMWVtO1xuICAgICAgICB9XG5cbiAgICAgICAgLnN2X3Ffb3RoZXIge1xuICAgICAgICAgIG1hcmdpbi1sZWZ0OiAxZW07XG4gICAgICAgIH1cblxuICAgICAgICAuc3ZfcV9yYXRpbmcge1xuICAgICAgICAgIGxpbmUtaGVpZ2h0OiAkYmFzZS1saW5lLWhlaWdodDtcblxuICAgICAgICAgIC5zdl9xX3JhdGluZ19pdGVtIHtcbiAgICAgICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgICAgICAgIHdvcmQtc3BhY2luZzogLTAuM2VtO1xuICAgICAgICAgICAgZm9udC13ZWlnaHQ6IG5vcm1hbDtcbiAgICAgICAgICAgIGRpc3BsYXk6IGlubGluZTtcblxuICAgICAgICAgICAgPiAqIHtcbiAgICAgICAgICAgICAgd29yZC1zcGFjaW5nOiBpbml0aWFsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAmLmFjdGl2ZSB7XG4gICAgICAgICAgICAgIC5zdl9xX3JhdGluZ19pdGVtX3RleHQge1xuICAgICAgICAgICAgICAgIC8vYmFja2dyb3VuZC1jb2xvcjogJG1haW4taG92ZXItY29sb3I7XG4gICAgICAgICAgICAgICAgLy9ib3JkZXItY29sb3I6ICRtYWluLWhvdmVyLWNvbG9yO1xuICAgICAgICAgICAgICAgIC8vY29sb3I6ICRib2R5LWJhY2tncm91bmQtY29sb3I7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC5zdl9xX3JhdGluZ19pdGVtX3RleHQge1xuICAgICAgICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICAgICAgICAgIG1pbi13aWR0aDogJGJhc2UtbGluZS1oZWlnaHQ7XG4gICAgICAgICAgICAgIHBhZGRpbmc6IDAgMC4zZW07XG4gICAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiAtMXB4O1xuICAgICAgICAgICAgICAvL2JvcmRlcjogMXB4IHNvbGlkICRoZWFkZXItYmFja2dyb3VuZC1jb2xvcjtcbiAgICAgICAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgICAgICAgICAmOmhvdmVyIHtcbiAgICAgICAgICAgICAgICAvL2JvcmRlcjogMXB4IHNvbGlkICRtYWluLWNvbG9yO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmOm5vdCg6Zmlyc3QtY2hpbGQpIHtcbiAgICAgICAgICAgICAgLnN2X3FfcmF0aW5nX2l0ZW1fdGV4dDpub3QoOmhvdmVyKSB7XG4gICAgICAgICAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC5zdl9xX3JhdGluZ19taW5fdGV4dCB7XG4gICAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDAuNWVtO1xuICAgICAgICAgIH1cbiAgICAgICAgICAuc3ZfcV9yYXRpbmdfbWF4X3RleHQge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDAuNWVtO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAuc3ZfbmF2IHtcbiAgICAgICAgcGFkZGluZzogMWVtIDA7XG4gICAgICAgIG1pbi1oZWlnaHQ6ICRiYXNlLWxpbmUtaGVpZ2h0O1xuXG4gICAgICAgIC5zdl9zdGFydF9idG4sXG4gICAgICAgIC5zdl9uZXh0X2J0bixcbiAgICAgICAgLnN2X2NvbXBsZXRlX2J0biB7XG4gICAgICAgICAgZmxvYXQ6IHJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIC5zdl9wcmV2X2J0biB7XG4gICAgICAgICAgZmxvYXQ6IGxlZnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuQG1lZGlhIChtYXgtd2lkdGg6IDYwMHB4KSB7XG4gIC5zdl9tYWluIHtcbiAgICAuc3ZfY29udGFpbmVyIHtcbiAgICAgIC5zdl9ib2R5IHtcbiAgICAgICAgLnN2X3Bfcm9vdCB7XG4gICAgICAgICAgLnN2X3JvdyB7XG4gICAgICAgICAgICAuc3ZfcSxcbiAgICAgICAgICAgIC5zdl9xc3RuIHtcbiAgICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICAgIHdpZHRoOiAxMDAlICFpbXBvcnRhbnQ7XG4gICAgICAgICAgICAgIC50aXRsZS1sZWZ0IHtcbiAgICAgICAgICAgICAgICBmbG9hdDogbm9uZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAuc3ZfcV9yYWRpb2dyb3VwX2lubGluZSxcbiAgICAgICAgICAgICAgLnN2X3FfY2hlY2tib3hfaW5saW5lLFxuICAgICAgICAgICAgICAuc3ZfcV9pbWFnZXBpY2tlcl9pbmxpbmUge1xuICAgICAgICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRhYmxlLnN2X3FfbWF0cml4LFxuICAgICAgICAgICAgICB0YWJsZS5zdl9xX21hdHJpeF9kcm9wZG93bixcbiAgICAgICAgICAgICAgdGFibGUuc3ZfcV9tYXRyaXhfZHluYW1pYyB7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICAgICAgdGhlYWQge1xuICAgICAgICAgICAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGJvZHksXG4gICAgICAgICAgICAgICAgdHIsXG4gICAgICAgICAgICAgICAgdGQge1xuICAgICAgICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRhYmxlLnN2X3FfbWF0cml4X2Ryb3Bkb3duLFxuICAgICAgICAgICAgICB0YWJsZS5zdl9xX21hdHJpeF9keW5hbWljIHtcbiAgICAgICAgICAgICAgICB0ZCB7XG4gICAgICAgICAgICAgICAgICAmOmJlZm9yZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGF0dHIoaGVhZGVycyk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRhYmxlLnN2X3FfbWF0cml4IHtcbiAgICAgICAgICAgICAgICB0ZCB7XG4gICAgICAgICAgICAgICAgICAmOmFmdGVyIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogYXR0cihoZWFkZXJzKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrOi8vL3NyYy9zcmMvbWFpbi5zY3NzIl0sInNvdXJjZVJvb3QiOiIifQ==*/ -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/survey-manager.js": "/js/survey-manager.js", 3 | "/js/survey-front.js": "/js/survey-front.js" 4 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # LaravelSurveyJs 2 | 3 | [![Latest Version on Packagist][ico-version]][link-packagist] 4 | [![Total Downloads][ico-downloads]][link-downloads] 5 | 6 | Laravel Survey Manager system based on surveyjs library. Take a look at [contributing.md](contributing.md) to see a to do list. 7 |
8 | 9 |
10 | ## Installation 11 | 12 | 1) In your terminal: 13 | 14 | ``` bash 15 | $ composer require aidynmakhataev/laravelsurveyjs 16 | ``` 17 | 18 | 2) Publish the config file & run the migrations 19 | 20 | ```bash 21 | php artisan vendor:publish --provider="AidynMakhataev\LaravelSurveyJs\LaravelSurveyJsServiceProvider" 22 | php artisan migrate 23 | ``` 24 | 25 | 3) Create a new survey on your-project-domain/admin/survey 26 | 27 | 4) [optional] Change values in config/survey-manager.php (route prefix, middleware, builder theme etc.) 28 | 29 | ## Usage 30 | TODO 31 | ## Change log 32 | 33 | Please see the [changelog](changelog.md) for more information on what has changed recently. 34 | `` 35 | 36 | ## Contributing 37 | 38 | Please see [contributing.md](contributing.md) for details and a todolist. 39 | 40 | ## Security 41 | 42 | If you discover any security related issues, please email makataev.7@gmail.com instead of using the issue tracker. 43 | 44 | ## Credits 45 | 46 | - [Aidyn Makhataev][link-author] 47 | - [All Contributors][link-contributors] 48 | 49 | ## License 50 | 51 | MIT. Please see the [license file](license.md) for more information. 52 | 53 | [ico-version]: https://img.shields.io/packagist/v/aidynmakhataev/laravelsurveyjs.svg?style=flat-square 54 | [ico-downloads]: https://img.shields.io/packagist/dt/aidynmakhataev/laravelsurveyjs.svg?style=flat-square 55 | [ico-travis]: https://img.shields.io/travis/aidynmakhataev/laravelsurveyjs/master.svg?style=flat-square 56 | [ico-styleci]: https://styleci.io/repos/12345678/shield 57 | 58 | [link-packagist]: https://packagist.org/packages/aidynmakhataev/laravelsurveyjs 59 | [link-downloads]: https://packagist.org/packages/aidynmakhataev/laravelsurveyjs 60 | [link-travis]: https://travis-ci.org/aidynmakhataev/laravelsurveyjs 61 | [link-styleci]: https://styleci.io/repos/134269033 62 | [link-author]: https://github.com/aidynmakhataev 63 | [link-contributors]: ../../contributors] 64 | -------------------------------------------------------------------------------- /resources/assets/js/App.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | -------------------------------------------------------------------------------- /resources/assets/js/base.js: -------------------------------------------------------------------------------- 1 | /** 2 | * We'll load the axios HTTP library which allows us to easily issue requests 3 | * to our Laravel back-end. This library automatically handles sending the 4 | * CSRF token as a header based on the value of the "XSRF" token cookie. 5 | */ 6 | 7 | window.axios = require("axios"); 8 | 9 | window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; 10 | window.axios.defaults.baseURL = '/' + SurveyConfig.api_prefix; 11 | 12 | /** 13 | * Next we will register the CSRF Token as a common header with Axios so that 14 | * all outgoing HTTP requests automatically have it attached. This is just 15 | * a simple convenience so we don't have to attach every token manually. 16 | */ 17 | 18 | let token = document.head.querySelector("meta[name=\"csrf-token\"]"); 19 | 20 | if (token) { 21 | window.axios.defaults.headers.common["X-CSRF-TOKEN"] = token.content; 22 | } 23 | else{ 24 | console.error("CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token"); //eslint-disable-line 25 | } -------------------------------------------------------------------------------- /resources/assets/js/components/SurveyBuilder.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /resources/assets/js/components/SurveyEditor.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | -------------------------------------------------------------------------------- /resources/assets/js/components/SurveyList.vue: -------------------------------------------------------------------------------- 1 | 73 | 74 | 192 | 193 | -------------------------------------------------------------------------------- /resources/assets/js/components/SurveyResult.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | -------------------------------------------------------------------------------- /resources/assets/js/components/SurveyShow.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 50 | -------------------------------------------------------------------------------- /resources/assets/js/router.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Import admin spa components 3 | */ 4 | 5 | import SurveyList from './components/SurveyList.vue'; 6 | import SurveyEditor from './components/SurveyEditor.vue'; 7 | import SurveyResult from './components/SurveyResult.vue'; 8 | import VueRouter from "vue-router"; 9 | 10 | /** 11 | * SPA routes 12 | */ 13 | const routes = [ 14 | { path: '/', component: SurveyList, name: 'home'}, 15 | { path: '/:id', component: SurveyEditor, name: 'editor'}, 16 | { path: '/:id/results', component: SurveyResult, name: 'result'} 17 | ]; 18 | 19 | export default new VueRouter({ 20 | mode: 'history', 21 | base: '/' + SurveyConfig.admin_prefix + '/survey', 22 | routes 23 | }); -------------------------------------------------------------------------------- /resources/assets/js/survey-front.js: -------------------------------------------------------------------------------- 1 | require("./base") 2 | 3 | window.Vue = require("vue") 4 | 5 | Vue.component('survey-show', require('./components/SurveyShow.vue')) 6 | 7 | new Vue({ 8 | el: "#surveyElement" 9 | }) -------------------------------------------------------------------------------- /resources/assets/js/survey-manager.js: -------------------------------------------------------------------------------- 1 | require("./base") 2 | 3 | window.Vue = require("vue") 4 | 5 | import Vuetify from 'vuetify' 6 | import 'vuetify/dist/vuetify.min.css' 7 | import VueRouter from 'vue-router' 8 | import App from './App' 9 | import router from './router' 10 | Vue.use(VueRouter) 11 | Vue.use(Vuetify) 12 | 13 | Vue.component('survey-show', './components/SurveyShow.vue') 14 | 15 | new Vue({ 16 | router, 17 | data () { 18 | return { 19 | snackbar: false, 20 | snackbarMsg: '' 21 | } 22 | }, 23 | render: h => h(App) 24 | }).$mount('#survey-manager') 25 | -------------------------------------------------------------------------------- /resources/views/admin.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Survey Manager 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 | 17 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /resources/views/survey.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | Survey | {{$survey->name}} 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 |
21 |
22 |
23 |
24 |
{{$survey->name}}
25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 | 33 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/LaravelSurveyJsServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadTranslationsFrom(__DIR__.'/../resources/lang', 'aidynmakhataev'); 17 | $this->loadViewsFrom(__DIR__.'/../resources/views', 'survey-manager'); 18 | $this->loadRoutesFrom(__DIR__.'/routes/web.php'); 19 | $this->loadRoutesFrom(__DIR__.'/routes/api.php'); 20 | $this->loadMigrationsFrom(__DIR__.'../database/migrations'); 21 | 22 | // Publishing is only necessary when using the CLI. 23 | if ($this->app->runningInConsole()) { 24 | 25 | // Publishing the configuration file. 26 | 27 | $this->definePublishable(); 28 | } 29 | } 30 | 31 | /** 32 | * Register any package services. 33 | * 34 | * @return void 35 | */ 36 | public function register() 37 | { 38 | $this->mergeConfigFrom( 39 | __DIR__.'/../config/survey-manager.php', 'survey-manager' 40 | ); 41 | } 42 | 43 | /** 44 | * Get the services provided by the provider. 45 | * 46 | * @return array 47 | */ 48 | public function provides() 49 | { 50 | return ['survey-manager']; 51 | } 52 | 53 | private function definePublishable() 54 | { 55 | $this->publishes([ 56 | __DIR__.'/../config/survey-manager.php' => config_path('survey-manager.php'), 57 | ]); 58 | 59 | $this->publishes([ 60 | realpath(__DIR__.'/../database/migrations') => database_path('migrations'), 61 | ], 'migrations'); 62 | 63 | $this->publishes([ 64 | realpath(__DIR__.'/../public') => public_path('vendor/survey-manager'), 65 | ], 'public'); 66 | 67 | $this->publishes([ 68 | realpath(__DIR__.'/../resources/views') => resource_path('views/vendor/survey-manager'), 69 | ]); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/app/Http/Controllers/API/SurveyAPIController.php: -------------------------------------------------------------------------------- 1 | paginate(config('survey-manager.pagination_perPage', 10)); 16 | 17 | return SurveyResource::collection($surveys); 18 | } 19 | 20 | public function show($id) 21 | { 22 | $survey = Survey::find($id); 23 | 24 | if (is_null($survey)) { 25 | return response()->json('Survey not found', 404); 26 | } 27 | 28 | return response()->json([ 29 | 'data' => new SurveyResource($survey), 30 | 'message' => 'Survey successfully retrieved', 31 | ]); 32 | } 33 | 34 | public function store(CreateSurveyRequest $request) 35 | { 36 | $survey = Survey::create($request->all()); 37 | 38 | return response()->json([ 39 | 'data' => new SurveyResource($survey), 40 | 'message' => 'Survey saved successfully', 41 | ], 201); 42 | } 43 | 44 | public function update($id, UpdateSurveyRequest $request) 45 | { 46 | $survey = Survey::find($id); 47 | 48 | if (is_null($survey)) { 49 | return response()->json('Survey not found', 404); 50 | } 51 | 52 | $survey->update($request->all()); 53 | 54 | return response()->json([ 55 | 'data' => new SurveyResource($survey), 56 | 'message' => 'Survey successfully updated', 57 | ]); 58 | } 59 | 60 | public function destroy($id) 61 | { 62 | $survey = Survey::find($id); 63 | 64 | if (is_null($survey)) { 65 | return response()->json('Survey not found', 404); 66 | } 67 | $survey->delete(); 68 | 69 | return response()->json([ 70 | 'data' => $id, 71 | 'message' => 'Survey deleted successfully', 72 | ], 200); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/app/Http/Controllers/API/SurveyResultAPIController.php: -------------------------------------------------------------------------------- 1 | results()->paginate(config('survey-manager.pagination_perPage', 10)); 16 | 17 | return SurveyResultResource::collection($results) 18 | ->additional(['meta' => [ 19 | 'survey' => new SurveyResource($survey), 20 | ]]); 21 | } 22 | 23 | /** 24 | * @param Survey $survey 25 | * @param Request $request 26 | * @return \Illuminate\Http\JsonResponse 27 | */ 28 | public function store(Survey $survey, Request $request) 29 | { 30 | $request->validate([ 31 | 'json' => 'required', 32 | ]); 33 | 34 | $result = $survey->results()->create([ 35 | 'json' => $request->input('json'), 36 | 'user_id' => \Auth::check() ? \Auth::id() : null, 37 | 'ip_address' => $request->ip(), 38 | ]); 39 | 40 | return response()->json([ 41 | 'data' => new SurveyResultResource($result), 42 | 'message' => 'Survey Result successfully created', 43 | ], 201); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/app/Http/Controllers/SurveyController.php: -------------------------------------------------------------------------------- 1 | firstOrFail(); 17 | 18 | return view('survey-manager::survey', [ 19 | 'survey' => $survey, 20 | ]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/app/Http/Requests/CreateSurveyRequest.php: -------------------------------------------------------------------------------- 1 | 'required|max:255', 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/Http/Requests/UpdateSurveyRequest.php: -------------------------------------------------------------------------------- 1 | 'max:255', 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/Http/Resources/SurveyResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 19 | 'name' => $this->name, 20 | 'slug' => $this->slug, 21 | 'json' => $this->json, 22 | 'created_at' => $this->created_at->formatLocalized('%A %d %B %Y'), 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/app/Http/Resources/SurveyResultResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 19 | 'json' => $this->json, 20 | 'ip_address' => $this->ip_address, 21 | 'created_at' => $this->created_at->formatLocalized('%A %d %B %Y'), 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app/Models/Survey.php: -------------------------------------------------------------------------------- 1 | 'array', 21 | ]; 22 | 23 | public static function boot() 24 | { 25 | parent::boot(); 26 | 27 | static::creating(function ($survey) { 28 | $survey->slug = str_slug($survey->name); 29 | 30 | $latestSlug = static::whereRaw("slug = '$survey->slug' or slug LIKE '$survey->slug-%'") 31 | ->latest('id') 32 | ->value('slug'); 33 | if ($latestSlug) { 34 | $pieces = explode('-', $latestSlug); 35 | 36 | $number = intval(end($pieces)); 37 | 38 | $survey->slug .= '-'.($number + 1); 39 | } 40 | }); 41 | } 42 | 43 | /** 44 | * @return \Illuminate\Database\Eloquent\Relations\HasMany 45 | */ 46 | public function results() 47 | { 48 | return $this->hasMany('AidynMakhataev\LaravelSurveyJs\app\Models\SurveyResult', 'survey_id'); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/app/Models/SurveyResult.php: -------------------------------------------------------------------------------- 1 | 'array', 15 | ]; 16 | 17 | /** 18 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 19 | */ 20 | public function survey() 21 | { 22 | return $this->belongsTo('AidynMakhataev\LaravelSurveyJs\app\Models\Survey', 'survey_id'); 23 | } 24 | 25 | /** 26 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 27 | */ 28 | public function user() 29 | { 30 | return $this->belongsTo(config('survey-manager.user_model'), 'user_id'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/routes/api.php: -------------------------------------------------------------------------------- 1 | 'AidynMakhataev\LaravelSurveyJs\app\Http\Controllers\API', 6 | 'middleware' => config('survey-manager.api_middleware'), 7 | 'prefix' => config('survey-manager.api_prefix'), 8 | ], 9 | function () { 10 | Route::resource('/survey', 'SurveyAPIController', ['only' => [ 11 | 'index', 'store', 'update', 'destroy', 'show', 12 | ]]); 13 | Route::resource('/survey/{survey}/result', 'SurveyResultAPIController'); 14 | } 15 | ); 16 | -------------------------------------------------------------------------------- /src/routes/web.php: -------------------------------------------------------------------------------- 1 | 'AidynMakhataev\LaravelSurveyJs\app\Http\Controllers', 6 | 'middleware' => config('survey-manager.route_middleware'), 7 | 'prefix' => config('survey-manager.route_prefix'), 8 | ], 9 | function () { 10 | Route::get('/{surveySlug}', 'SurveyController@runSurvey')->name('survey-manager.run'); 11 | } 12 | ); 13 | 14 | Route::group( 15 | [ 16 | 'namespace' => 'AidynMakhataev\LaravelSurveyJs\app\Http\Controllers', 17 | 'prefix' => config('survey-manager.admin_prefix').'/survey/', 18 | 'middleware' => config('survey-manager.admin_middleware'), 19 | ], 20 | function () { 21 | Route::view('{vue?}', 'survey-manager::admin')->where('vue', '[\/\w\.-]*')->name('survey-manager.admin'); 22 | } 23 | ); 24 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | let mix = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Custom Mix setup 6 | |-------------------------------------------------------------------------- 7 | | 8 | */ 9 | 10 | mix 11 | .setPublicPath('public') 12 | .js('resources/assets/js/survey-manager.js', 'public/js/') 13 | .js('resources/assets/js/survey-front.js', 'public/js/'); --------------------------------------------------------------------------------